The MASM Forum

General => The Campus => Topic started by: jj2007 on February 17, 2015, 06:57:20 AM

Title: WM_PARENTNOTIFY: no handle or ID!
Post by: jj2007 on February 17, 2015, 06:57:20 AM
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

Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: Antariy on February 17, 2015, 07:20:15 AM
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?
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: dedndave on February 17, 2015, 08:35:48 AM
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
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: dedndave on February 17, 2015, 09:12:49 AM
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
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: jj2007 on February 17, 2015, 11:42:07 AM
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 :(
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: dedndave on February 17, 2015, 11:56:50 AM
you could super class the static control - not really elegant
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: ragdog on February 17, 2015, 08:33:24 PM
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,
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: jj2007 on February 17, 2015, 10:51:31 PM
  CASE WM_CONTEXTMENU      ; thanks, ragdog (http://masm32.com/board/index.php?topic=4033.msg42501#msg42501)  :t
      mov rcIndex, rv(GetWindowLong, wParam, GWL_USERDATA)
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: dedndave on February 18, 2015, 05:33:36 AM
GetDlgCtrlID seems to eliminate the need for Set/GetWindowLong
Title: Re: WM_PARENTNOTIFY: no handle or ID!
Post by: jj2007 on February 18, 2015, 10:52:22 AM
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