Re: Tracking tooltips don't display at all
- From: "Ajay Kalra" <ajaykalra@xxxxxxxxx>
- Date: Wed, 11 Mar 2009 23:06:58 -0400
I think you are scaring him :-)
--
Ajay
"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> wrote in message news:k7tgr4d300ed070cqqp2emtgoimdrfdeiq@xxxxxxxxxx
I see many things wrong here.
For one thing, this is an MFC group and this is not MFC code.
More, below.
On Wed, 11 Mar 2009 18:34:55 -0700 (PDT), anurag <yourstrulyanurag@xxxxxxxxx> wrote:
I want to display a tooltip that changes as the mouse moves to****
different positions in the client area showing the pixel co-ordinates
in the tooltip. So, the tool here is the whole client area. Following
is the code i picked up from MSDN and used "as is" , everything
(messages, mouse tracking) works fine but the problem is that no
tooltips are displayed.
Any help will be greatly appreciated.
Following is the code i'm using:
// code begins
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
int count;
TCHAR str[1000];
Global variables make no sense
****
****
HWND g_hwndTrackingTT;
TOOLINFO g_toolItem;
HINSTANCE g_hInst;
BOOL g_TrackingMouse;
None of these should be global
****
****
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
HWND CreateTrackingToolTip(int toolID, HWND hDlg, char *pText);
TCHAR szWinName[] = TEXT("MyWin");
int WINAPI WinMain(HINSTANCE hThisInst,HINSTANCE hPrevInst,LPSTR
lpszArgs,int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;
INITCOMMONCONTROLSEX ic;
BOOL ret;
g_hInst = hThisInst;
ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
ic.dwICC = ICC_STANDARD_CLASSES|ICC_BAR_CLASSES;
ret = InitCommonControlsEx(&ic);
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hInstance = hThisInst;
wcl.lpszClassName = szWinName;
wcl.lpfnWndProc = WindowFunc;
wcl.style = CS_HREDRAW|CS_VREDRAW;
wcl.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wcl.hIconSm = NULL;
wcl.hCursor = LoadCursor(NULL,IDC_ARROW);
wcl.lpszMenuName = NULL;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
if(!RegisterClassEx(&wcl)) return 0;
hwnd = CreateWindowEx(
WS_EX_WINDOWEDGE,
szWinName,
TEXT("Window Title"),
You are using the TEXT macro here (Unicode-compliant) but you are using the obsolete char
type elsewhere. Why the inconsistency?
****WS_OVERLAPPEDWINDOW,****
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
hThisInst,
NULL
);
ShowWindow(hwnd,nWinMode);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hwnd,UINT message,WPARAM
wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static int cxClient = 0, cyClient = 0, oldX, oldY;
THe appearance of a static variable inside a window function is so horrendously wrong that
it is hard to imagine why anyone would want to use it. This is absolutely
horrible-beyond-belief code.
Why do you think this could possibly make sense? If you have more than one instance of
the window, you are totally screwed. It is so far beyond worst-possible-practice that
even looking at it is giving me a headache.
NEVER do this!
****
int newX, newY;****
char coords[12];
POINT pt;
None of these variables make sense here. Also, you should at least use the macros in
windowsx.h to create something that looks like it was written by someone who understands
code structure. This is a horrible example of The Switch Statement From Hell.
********
switch(message){
case WM_CREATE:
g_hwndTrackingTT = CreateTrackingToolTip(456, hwnd, "");
This should not be a global variable. It should be a "local" variable of the main window
class, stored in a structure accessed via the GWLP_USERDATA field.
I'm not sure where the magical value 456 came from. But it is a random number, and 0 or 1
would work as well.
********
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
These cannot be saved or retained across calls; to do so is erroneous design. If you ever
need the client rectangle, you should call GetClientRect at the point where you need it,
not do something as silly as a static local variable!
********
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
case WM_MOUSELEAVE:
// The mouse pointer has left our window.
// Deactivate the ToolTip.
SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE, (WPARAM)
FALSE, (LPARAM)&g_toolItem);
g_TrackingMouse = FALSE;
Given the correction below, you will need to hide the tooltip at this point
ShowWindow(g_hwndTrackingTT, SW_HIDE);
****return FALSE;****
case WM_MOUSEMOVE:
if (!g_TrackingMouse)
// The mouse has just entered the window.
{
// Request notification when the mouse leaves.
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
tme.hwndTrack = hwnd;
tme.dwFlags = TME_LEAVE;
TrackMouseEvent(&tme);
// Activate the ToolTip.
SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE,
(WPARAM)TRUE, (LPARAM)&g_toolItem);
You have "activated" tracking but you have not actually made the tooltip visible. I would
suggest at this point that you call
ShowWindow(g_hwndTrackingTT, SW_SHOW);
****g_TrackingMouse = TRUE;****
}
newX = LOWORD(lParam);
newY = HIWORD(lParam);
Note also that the use of LOWORD and HIWORD is erroneous. The correct values are
GET_X_LPARAM and GET_Y_LPARAM. This code will fail if the screen coordinates go negative,
which they can in a multimonitor system.
********
// Make sure the mouse has actually moved. The presence of the
ToolTip
// causes Windows to send the message continuously.
if ((newX != oldX) || (newY != oldY))
{
oldX = newX;
oldY = newY;
These would be variables stored in a structure whose pointer is stored in the
GWLP_USERDATA field of the tooltip, not static variables of the handler or global
variables. Of course, if you used MFC, all of this would be trivial.****
// Update the text.
sprintf(coords, "%d, %d", newX, newY);
The use of the obsolete data type char, the use of a fixed-size stack structure of tiny
size, the use of the unsafe sprintf function, all represent poor programming methodology
for modern programming
*****g_toolItem.lpszText = coords;****
SendMessage(g_hwndTrackingTT, TTM_SETTOOLINFO, 0, (LPARAM)
&g_toolItem);
// Position the ToolTip.
// The coordinates are adjusted so that the ToolTip does
not
// overlap the mouse pointer.
pt.x = newX;
pt.y = newY;
ClientToScreen(hwnd, &pt);
SendMessage(g_hwndTrackingTT, TTM_TRACKPOSITION,
0, (LPARAM)MAKELONG(pt.x + 10, pt.y - 20));
}
return FALSE;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
HWND CreateTrackingToolTip(int toolID, HWND hDlg, char *pText)
{
// Create a ToolTip.
HWND hwndTT = CreateWindowEx(WS_EX_TOPMOST,
TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hDlg, NULL, g_hInst,NULL);
if (!hwndTT)
{
return NULL;
}
// Set up tool information.
// In this case, the "tool" is the entire parent window.
g_toolItem.cbSize = sizeof(TOOLINFO);
g_toolItem.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE;
g_toolItem.hwnd = hDlg;
g_toolItem.hinst = g_hInst;
g_toolItem.lpszText = pText;
g_toolItem.uId = (UINT_PTR)hDlg;
GetClientRect (hDlg, &g_toolItem.rect);
// Associate the ToolTip with the tool window.
SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO)
Why is there an LPTOOLINFO cast here? This is unnecessary, since &g_toolItem is
implicitly an LPTOOLINFO object.
****&g_toolItem);Joseph M. Newcomer [MVP]
return hwndTT;
}
// code ends
Thanks,
--Anurag.
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: Tracking tooltips don't display at all
- From: Joseph M . Newcomer
- Re: Tracking tooltips don't display at all
- References:
- Tracking tooltips don't display at all
- From: anurag
- Re: Tracking tooltips don't display at all
- From: Joseph M . Newcomer
- Tracking tooltips don't display at all
- Prev by Date: Re: Tracking tooltips don't display at all
- Next by Date: Re: CPtrArray/Heap failed...
- Previous by thread: Re: Tracking tooltips don't display at all
- Next by thread: Re: Tracking tooltips don't display at all
- Index(es):
Relevant Pages
|