Click here to Skip to main content
15,885,876 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello,

how can i intercept WM_NCPAINT message of a popup menu window created with CreatePopupMenu and displayed with TrackPopupMenu? Is there a way to assign an application defined WindowProc to a menu having only a HMENU handle?

I can get the handle to the popup window in the parent window's WM_INITMENUPOPUP handler with
HWND hMenuWnd = FindWindow("#32768", NULL);


Now, will this work if i set the GWL_WNDPROC property through SetWindowLong at this point?

Your advice will be highly appreciated!
Posted
Updated 23-Oct-11 23:55pm
v3
Comments
Malli_S 24-Oct-11 5:46am    
What exactly you wanna to achieve ?
mardul 24-Oct-11 6:33am    
I'm customizing the appearance of the context menu. Almost everything works with owner draw functionality. It just happens that the frame of the popup menu is not accessible. As a workaround i'm trying to intercept the WM_NCPAINT to prevent the system defined frame to be drawn.

I can intercept the message in the manner described above. My only worry is about whether it is safe to reassign the WindowProc like that or not?

Of course if there's a better way i would be very happy to hear about it.

Take a look here[^], there may be a message that will help to capture what you want.
 
Share this answer
 
v2
Comments
mardul 24-Oct-11 6:07am    
Thank you for your help. I looked into the menu notification messages but none of them allow changing the appearance of the menu.
Yes, you are right. Just subclass to a new wndproc, it should be safe, sample code:
C++
LRESULT CALLBACK MenuButton::WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
	{
		TRACE("menubutton::wndproc message = %x, wparam = %x\n", message, wparam);
		if (message == WM_KEYDOWN && wparam == VK_LEFT) {
			MenuButton* prev = dynamic_cast<menubutton*>(prevWidget());
			if (prev) {
				cancelMenu(Widget::hwnd());
				fnNativePoint pt(1,1);
				prev->clientToNativePt(pt);
				PostMessage(Widget::hwnd(), WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
				return 0;
			}
			return 0;
		} else if (message == WM_KEYDOWN && wparam == VK_RIGHT) {
			MenuButton* next = dynamic_cast<menubutton*>(nextWidget());
			if (next) {
				cancelMenu(Widget::hwnd());
				fnNativePoint pt(1,1);
				next->clientToNativePt(pt);
				PostMessage(Widget::hwnd(), WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
				return 0;
			}
		}
		return CallWindowProc(prevWndProc_, hwnd, message, wparam, lparam);
	}


In above I simulate the next/prev feature of window's default menu bar. cancelMenu(hwnd) send WM_CANCELMODE to parent window.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900