WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  C / C++ / Visual C++
  Самодельный tooltip

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   Самодельный tooltip
ADK опубликован 22-01-2002 06:01 MSK   Click Here to See the Profile for ADK   Click Here to Email ADK  
Сильно нужен сабж. Вот написал, нужно чтобы как бы встраивался в др. приложения и всплывал, когда надо и был многострочным, и не терялся при движении мыши. Беда в том, что когда он всплывает в собственном приложении, он захватывает фокус со всеми последствиями. Help!!!

Вот как оно делалось:

// Класс подсказки

class CReplaceTip : public CWnd
{
// Construction
public:
CReplaceTip();

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CReplaceTip)
//}}AFX_VIRTUAL

// Implementation
public:
void UpdateCurrentCaretPos(const POINT& pt);
void ShowTip(LPCSTR szTip, HWND hwndFocus);
virtual ~CReplaceTip();

// Generated message map functions
protected:
//{{AFX_MSG(CReplaceTip)
afx_msg void OnPaint();
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
void SplitStrings(LPCSTR szString, CSimpleStrArray& straResult);
CSize CalculateTipSize(LPCSTR szString);
CPoint m_ptCaret;
};


// Реализация

void CReplaceTip::OnPaint()
{
CPaintDC dc(this); // device context for painting

CRect rc;
GetClientRect(&rc);

rc.OffsetRect(2, 0);

CString strText;
GetWindowText(strText);

dc.SelectStockObject(DEFAULT_GUI_FONT);
dc.SetBkMode(TRANSPARENT);
dc.DrawText(strText, -1, &rc, DT_LEFT);

// Do not call CWnd::OnPaint() for painting messages
}

void CReplaceTip::ShowTip(LPCSTR szTip, HWND hwndFocus)
{
SetWindowText(szTip);

CSize szExtent = CalculateTipSize(szTip);
szExtent += CSize(6, 4);

::SetWindowPos(m_hWnd, HWND_TOPMOST,
m_ptCaret.x + 16,
m_ptCaret.y - szExtent.cy,
szExtent.cx, szExtent.cy, 0);

ShowWindow(SW_SHOWNA);
Invalidate();
SetTimer(ID_TIMER_HIDE_TIP, TIMER_HIDE_TIP_ELAPSE, 0);
}

void CReplaceTip::OnTimer(UINT nIDEvent)
{
if(nIDEvent == ID_TIMER_HIDE_TIP)
{
KillTimer(ID_TIMER_HIDE_TIP);
ShowWindow(SW_HIDE);
}

CWnd::OnTimer(nIDEvent);
}

void CReplaceTip::UpdateCurrentCaretPos(const POINT &pt)
{
m_ptCaret = pt;
}

CSize CReplaceTip::CalculateTipSize(LPCSTR szString)
{
CDC* pdc = GetDC();
CSize szRetVal(0, 0);

pdc->SelectStockObject(DEFAULT_GUI_FONT);

CRect rc(0, 0, 0, 0);
UINT nTotalWidth = 0, nCurWidth, nTotalHeight;

CSimpleStrArray sa;
SplitStrings(szString, sa);

for(int i = 0; i <= sa.GetUpperBound(); i++)
{
pdc->DrawText(sa[i], -1, &rc, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
nCurWidth = rc.right;
//TRACE("nCurWidth = %d\n", nCurWidth);
if(nCurWidth > nTotalWidth) nTotalWidth = nCurWidth;
}

rc.right = nTotalWidth;
nTotalHeight = pdc->DrawText(szString, -1, &rc, DT_CALCRECT | DT_LEFT);

ReleaseDC(pdc);

return CSize(nTotalWidth, nTotalHeight);
}


void CReplaceTip::SplitStrings(LPCSTR szString, CSimpleStrArray& straResult)
{
LPSTR strCopy = new char[lstrlen(szString) + 1];
lstrcpy(strCopy, szString);

LPSTR szCurrentPos, szCurString = (LPSTR) strCopy;

for(szCurrentPos = (LPSTR) strCopy; *szCurrentPos; szCurrentPos++)
{
if(*szCurrentPos == '\n')
{
*szCurrentPos = 0;
straResult.Add(szCurString);
//TRACE("CReplaceTip::SplitStrings - äîáàâëåíà ñòðîêà \"%s\"\n", szCurString);
szCurString = szCurrentPos + 1;
}

}

straResult.Add(szCurString);
//TRACE("CReplaceTip::SplitStrings - \"%s\"\n", szCurString);

delete[] strCopy;
}

ADK опубликован 22-01-2002 06:06 MSK     Click Here to See the Profile for ADK  Click Here to Email ADK     
Потом, в главном окне создаю как тултип член класса и в OnInitDialog:

m_wndTip.CreateEx(WS_EX_TOOLWINDOW,
AfxRegisterWndClass(CS_DBLCLKS, ::LoadCursor(0, IDC_ARROW),
CreateSolidBrush(GetSysColor(COLOR_INFOBK)), 0),
"", WS_POPUP | WS_BORDER, CRect(0, 0, 0, 0), 0, 0);


/// В нужный момент для показа

m_wndTip.ShowTip(m_saChangeTo[nIndex], hwndFocus);

короче, всякие там подробности не смотрите типа hwndFocus, я потом без него обошёлся.

m_wndTip.UpdateCurrentCaretPos(CPoint(wParam, lParam)); периодически считывает через хук позицию каретки (при наборе на клаве), так что тип вылезает около клавиатурного курсора (каретки).

Что тут неправильно (совсем неправильно, в части показа окна)?

ADK опубликован 22-01-2002 10:23 MSK     Click Here to See the Profile for ADK  Click Here to Email ADK     
Всё, я въехал. Надо было в SetWindowPos в последнем параметре указать SWP_NOACTIVATE.

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.