rkorchagin Цитата: Если ты программировал в .NET на C#
посмотри мой вопрос - может знаешь....
не такого опыта нет
Цитата: if (bOutside>=0) {
На самом деле у меня bOutside всегда 0 или 1 и поэтому эта запись автоматически заставляет всегда считать, что курсор внутри, поэтому возникает другая проблема - не исчезает подсказка при уходе курсора из ListBox'a
---
Поборол - вот полный вариант на случай, если кто столкнется с подобной проболемой:
Код: //////////////////////////////////////////////////////////////////////////
// ListBoxTip.h
//////////////////////////////////////////////////////////////////////////
#pragma once
#include "popuptext.h"
class CListBoxTip : public CListBox {
protected:
UINTm_nCurItem;// index of current item
BOOLm_bCapture;// whether mouse is captured
CPopupText g_wndTip;// THE tip window
static UINT g_nTipTimeMsec;// msec wait before showing tip
CPoint m_LastMousePoint;
virtual void OnMouseMove(CPoint p);
virtual BOOL IsRectCompletelyVisible(const CRect& rc);
virtual UINT OnGetItemInfo(CPoint p, CRect& rc, CString& s);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
public:
CListBoxTip();
~CListBoxTip();
};
//////////////////////////////////////////////////////////////////////////
// ListBoxTip.cpp
//////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ListBoxTip.h"
UINT CListBoxTip::g_nTipTimeMsec=100;
CListBoxTip::CListBoxTip()
:m_nCurItem(-1)
,m_bCapture(FALSE)
,m_LastMousePoint(-1,-1)
{
g_wndTip.Create(CPoint(0,0), NULL, 0);
}
CListBoxTip::~CListBoxTip()
{
}
void CListBoxTip::OnMouseMove(CPoint pt)
{
if(m_LastMousePoint==pt) return; //mouse point has not changed
m_LastMousePoint=pt; //set new mouse point
//capture mouse
if (!m_bCapture) {
::SetCapture(m_hWnd);
m_bCapture = TRUE;
}
// Get text and text rectangle for item under mouse
CString sText;// item text
CRect rcText;// item text rect
UINT nItem = OnGetItemInfo(pt, rcText, sText);
if (nItem==-1 || nItem!=m_nCurItem) {
g_wndTip.Cancel(); // new item, or no item: cancel popup text
if (nItem>=0 && !IsRectCompletelyVisible(rcText))
{// new item, and not wholly visible: prepare popup tip
CRect rc = rcText;
ClientToScreen(&rc);// text rect in screen coords
g_wndTip.SetWindowText(sText);// set tip text to that of item
// move tip window over list text and set proper size of popup window
g_wndTip.SetWindowPos(NULL, rc.left, rc.top-2, rc.Width()+10,
rc.Height()+4, SWP_NOZORDER|SWP_NOACTIVATE);
g_wndTip.ShowDelayed(g_nTipTimeMsec); // show popup text delayed
}
};
m_nCurItem = nItem;
if (nItem==-1 && m_bCapture)//move out of the listbox
{
::ReleaseCapture();
m_bCapture=FALSE;
};
}
//////////////////
// Determine if given rectangle is completely visible withing list box
//
BOOL CListBoxTip::IsRectCompletelyVisible(const CRect& rc)
{
CRect rcClient;
GetClientRect(&rcClient);
return rcClient.Width() > rc.Width();
}
//////////////////
// Get info (rectangle and text) for item under point
//
UINT CListBoxTip::OnGetItemInfo(CPoint p, CRect& rc, CString& s)
{
BOOL bOutside;
UINT nItem = ItemFromPoint(p,bOutside);
s.Empty();
if (!bOutside) {
GetText(nItem, s);
GetItemRect(nItem, &rc);
CFont *pFont = GetFont();
CClientDC dc(this);
CFont* pOldFont = dc.SelectObject(pFont);
dc.DrawText(s,&rc,DT_CALCRECT);
dc.SelectObject(pOldFont);
return nItem;
}
return -1;
}
BEGIN_MESSAGE_MAP(CListBoxTip, CListBox)
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
void CListBoxTip::OnMouseMove(UINT nFlags, CPoint point)
{
OnMouseMove(point);
CListBox::OnMouseMove(nFlags, point);
}
BOOL CListBoxTip::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
BOOL res=CListBox::OnMouseWheel(nFlags, zDelta, pt);
OnMouseMove(pt);//to view changed item under mouse
return res;
}
void CListBoxTip::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_bCapture)
{
::ReleaseCapture();
m_bCapture = FALSE;
}
CListBox::OnLButtonDown(nFlags, point);
//here is potential problem - if we capture mouse, messages do not go to the parent,
//so send them to parent manually
GetOwner()->SendMessage(WM_COMMAND,(LBN_SELCHANGE<<16)|GetDlgCtrlID(),(LPARAM)m_hWnd);
//capture mouse input again
::SetCapture(m_hWnd);
m_bCapture = TRUE;
}