windows messages

Started by
11 comments, last by yadango 17 years, 8 months ago
I create a button like so:
HWND button1 = CreateWindow("BUTTON", "button1", WS_CHILD | BS_PUSHBUTTON, 10, 10, 100, 30, form1, NULL, hinstance, NULL);

ShowWindow(button1, true);
form1 is a HWND that the main window is stored in. hinstance is the application instance. So that works. The button appears. But because there's no user defined WNDCLASS struct that I passed to create the button, I have no control over the messages (or so I think anyways). How do I catch the events that the button produces? I'm assuming they come to the main window's message handler.. but not sure how to seperate them from the other ones. Thanks for the help.
Advertisement
Buttons send WM_COMMAND messages with the low word of WPARAM set to the id of the button, and the high word set to the notification message. The LPARAM value is the handle of the button control. It also sends some notifications via the WM_NOTIFY message, and a couple other special messages, WM_CTLCOLORBTN and in XP BCN_HOTITEMCHANGE.
.
That works sorta like I hoped.

When I catch WM_COMMAND, it only registers when I release the button. Is it possible to catch when the button is pressed, released, and if the mouse moves over it? Is it possible to find out where on the button the user clicks?

Thanks a bucnh.
You have two options, either subclass the button control, which I doubt you are ready to tackle, or use the BS_OWNERDRAW button style and handle the WM_DRAWITEM messages. See this: Using Buttons
.
From what I've read so far, I can do this to create a "subclass" of the button.

SetWindowLongPtr(button1, GWL_WNDPROC, buttonproc);


So now, my buttonproc handles all messages from the button. I went ahead and tried this, but now the button doesn't show up. Am I now responsible for drawing the button? If so, I'm assuming WM_PAINT or more likely WM_DRAWITEM is the event where I draw it. Do I need to handle more events too?

Is there a windows function that I can pass some values to to draw a standard windows button? Or do I need to create a custom drawn button (which wouldn't be such a bad idea because the standard one is pretty crappy).

Thanks.

Edit:

I think I get it now actually. I need to store the original button proceudre, then change it to mine. After I catch the messages I want, I need to call CallWindowProc and use the original call back function. Then the button will be drawn?

Thanks again.
If you subclass a function that way YOU are responsible to pass the messages on to the default function.

Use the function CallWindowProc with the old WNDPROC pointer you got as return code from SetWindowLong(Ptr).

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Yep, cool.

Thanks.
you can also superclass the button so you can get all the messages as well.
Here's my windows loop.

while (!done){   if (PeekMessage(&msg, form1, NULL, NULL, PM_REMOVE))   {      TranslateMessage(&msg);      DispatchMessage(&msg);   }}


After I do a subclass for the random controls I have, will this loop still pop the messages off the message queue for the controls? Or do I need to do a PeekMessage for each of the controls now as well?

Thanks.
yes, PeekMessage examines messages from the hwnd and all of it's children:

MSDN: PeekMessage retrieves messages associated with the window identified by the hWnd parameter or any of its children as specified by the IsChild function.

however, if you have other windows or forms around you shouldn't filter the hwnd in your message loop (it shouldn't effect modal dialogs or anything running a modal loop, but if there are other windows around...). i, personally, would never filter the hwnd of my main message loop or any looping message pump (i would, however, if it was a one shot testing thing).

This topic is closed to new replies.

Advertisement