News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

WM_PARENTNOTIFY: no handle or ID!

Started by jj2007, February 17, 2015, 06:57:20 AM

Previous topic - Next topic

jj2007

I wanted to check for a right-click on one of a series of static controls. The message is there, but documentation says you won't get the handle or ID of the clicked control. Below a workaround - anybody aware of a better/more elegant solution?

  CASE WM_PARENTNOTIFY
.if word ptr wParam==WM_RBUTTONDOWN
movsx ecx, word ptr lParam+2
movsx eax, word ptr lParam
mov hRcCtrl, rv(ChildWindowFromPoint, hWnd, eax, ecx)
.endif


Antariy

Jochen, I'm not sure, but if there is a simple way (without subclassing) to make the "static" window to not return HTTRANSPARENT as an "answer" to NC_HITTEST, maybe you will get the handle or ID?

dedndave

not sure it's really more elegant, but...

you could use SetWindowLong after each control is created with GWL_USERDATA
set the value to the ID number

then, when you get the notification message, use GetWindowLong with GWL_USERDATA

one advantage - you end up with a control ID - easier to deal with than a handle in many cases

dedndave

ok - that's not going to work because you need the handle - lol

i guess you could combine it with ChildWindowFromPoint
that way, you don't have to search a list of handles to get the ID

jj2007

Alex, Dave: thanks a lot :icon14:

WM_NCHITTEST won't return a handle, and (as Dave rightly noted) you need the handle to get the handle. But the SetWindowLong thing will allow me at least to mark the control with the index of the string array that it was created from, so that is progress :t

The only other message I see when monitoring a right-click is WM_MOUSEACTIVATE - but again, no handle, no ID. Bad design, Redmond :(

dedndave

you could super class the static control - not really elegant

ragdog

Hello Jochen

I know only this 2 ways

WM_CONTEXMENU


.elseif uMsg == WM_CONTEXTMENU
invoke GetDlgCtrlID,wParam
.if eax==1001
invoke MessageBox,hWnd,0,0,MB_OK
.endif



or subclassing

xor ebx,ebx
mov ebx,1001
.repeat
push ebx
invoke GetDlgItem,hWnd,ebx
invoke SetWindowLong,eax,GWL_WNDPROC,offset NewProc
mov lpCtrlProc,eax
pop ebx
inc ebx
.until ebx==1004

NewProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

    .if uMsg==WM_RBUTTONDOWN
    invoke GetDlgCtrlID,hWnd    ; get id from static control
    .endif
invoke    CallWindowProc,lpCtrlProc,hWnd,uMsg,wParam,lParam
ret
NewProc endp


You must set the Static style to SS_NOTIFY

Greets,

jj2007

  CASE WM_CONTEXTMENU      ; thanks, ragdog  :t
      mov rcIndex, rv(GetWindowLong, wParam, GWL_USERDATA)

dedndave

GetDlgCtrlID seems to eliminate the need for Set/GetWindowLong

jj2007

Quote from: dedndave on February 18, 2015, 05:33:36 AM
GetDlgCtrlID seems to eliminate the need for Set/GetWindowLong

That's right, would save some bytes :t