Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Tooltip в ClistBox (MFC)

Автор: WiseAlex
Дата сообщения: 02.08.2004 19:47
Нужно, что бы для длинных названий в ListBox появлялись подсказки - взял пример из MSDN? но так и не смо побороть одну проьлему из примера - при сдвиге курсора ниже последнего элемента вместо исчезновения надписи появляется серое пустое место
еще нормально
http://strim.at.tut.by/ok-last.JPG
Уже плохо
http://strim.at.tut.by/bad-last.JPG
вод сама прога с исходниками - http://strim.at.tut.by/listbox.zip
Автор: rkorchagin
Дата сообщения: 03.08.2004 15:59
Это связано с тем что в ф-ции
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;
}
при наводке мыши за предел последнего элемента в ЛистБоксе
строка

UINT nItem = ItemFromPoint(p,bOutside);
возвращает лабуду типа:

nItem =3435973836


и соответсвенно всё сбивается.
сейчас попытаюсь как нибудь это поправить.



Добавлено
Поставь там

if (bOutside>=0) {


эффект странноват - но серого квадрата больше нету


Добавлено
То есть вместо


Цитата:

BOOL bOutside;
UINT nItem = ItemFromPoint(p,bOutside);
s.Empty();
if (!bOutside) {
GetText(nItem, s);


напиши

Цитата:

BOOL bOutside;
UINT nItem = ItemFromPoint(p,bOutside);
s.Empty();
if (bOutside>=0) {
GetText(nItem, s);

Автор: WiseAlex
Дата сообщения: 03.08.2004 16:46
rkorchagin
Действительно заработало - большое спасибо,

Цитата:
ItemFromPoint(p,bOutside);
- ведет себя действительно странно
Автор: rkorchagin
Дата сообщения: 03.08.2004 16:59
WiseAlex
Пожалуйста

Если ты программировал в .NET на C#
посмотри мой вопрос - может знаешь....
http://forum.ru-board.com/topic.cgi?forum=33&topic=3621#1
Автор: WiseAlex
Дата сообщения: 03.08.2004 18:03
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;
}

Страницы: 1

Предыдущая тема: C++: Выделение подстроки...


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.