опубликован 22-01-2002 06:01 MSK
Сильно нужен сабж. Вот написал, нужно чтобы как бы встраивался в др. приложения и всплывал, когда надо и был многострочным, и не терялся при движении мыши. Беда в том, что когда он всплывает в собственном приложении, он захватывает фокус со всеми последствиями. 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;
}