Hello Again
I´m a little confused about the windows messages i work with WM_Notify and this procedur works fine
My code use a Costum control this send Notify code and handle WM_Char /WM_Keydown etc messages
And send it to my dialog.
Works fine
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov wc.cbSize,sizeof WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc,offset WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,IDM_MENU
mov wc.lpszClassName,offset ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,addr wc
invoke CreateDialogParam,hInstance,IDD_DIALOG,NULL,addr WndProc,NULL
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
.while TRUE
invoke GetMessage,addr msg,NULL,0,0
.BREAK .if !eax
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL rc:RECT
mov eax,uMsg
.if eax==WM_INITDIALOG
push hWin
pop hWnd
.elseif uMsg==WM_NOTIFY
mov ebx, lParam ; Get pointer to NMHDR
mov eax, (NMHDR ptr [ebx]).hwndFrom
.if (eax == hMain)
.endif
.elseif uMsg==WM_SIZE
.elseif eax==WM_CLOSE
invoke DestroyWindow,hWin
.elseif uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
But use i a Dialog Proc and Dialog in resource can i not work with other Messages like WM_CHAR or WM_KEYDOWN etc
Fail
DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.if uMsg==WM_INITDIALOG
.elseif uMsg==WM_NOTIFY
mov ebx, lParam ; Get pointer to NMHDR
mov eax, (NMHDR ptr [ebx]).hwndFrom
.if (eax == hMain)
.endif
invoke SetWindowLong,hWnd,DWL_MSGRESULT, TRUE
mov eax,TRUE
ret
.elseif uMsg==WM_SIZE
.elseif uMsg==WM_CLOSE
invoke EndDialog,hWnd,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
Is my SetWindowLong,hWnd,DWL_MSGRESULT wrong?
Or any an idea?
EBX should be preserved
push ebx
mov ebx, lParam ; Get pointer to NMHDR
mov eax, [ebx].NMHDR.hwndFrom
;
;
;
pop ebx
i'm not sure that you use SetWindowLong to return a result
https://msdn.microsoft.com/en-us/library/windows/desktop/bb775583%28v=vs.85%29.aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/bb775583%28v=vs.85%29.aspx)
Hi Dave
My first address before i ask here Msdn
You have right with EBX should be preserved i have forgot ist but this is not the problem
Greets,
Custom Controls usually send WM_NOTIFY messages. Its conceivable they could send WM_CHAR or WM_KEYDOWN, but in any I have made (and I've made a lot), I always create my own custom messages and send them within the NMHDLR object. The custom messages might be my version of WM_CHAR or WM_KEYDOWN. Do you have a reference to how the custom control is sending the messages?
Also, maybe it would be easier to use CreateWindow() than resource dialog windows. I think DlgProcs might be more limited than dialog procedures. Not sure why you are calling SetWindowLong().
Quote
can i not work with other Messages like WM_CHAR or WM_KEYDOWN
To elaborate, the custom controls I write package WM_CHAR and WM_KEYDOWN message notifications within an 'extended' NMHDLR struct. It may be possible that the custom control you are attempting to use behaves similiarly. Here are some of the details of a grid custom control I wrote. In the dll I have these equates...
%GRID_CELL_CHAR = 40000 'sends keypress, keydown, lbuttondown, paste and cell
%GRID_CELL_KEYDOWN = 40001 'double click notifications back to its host in the WM_NOTIFY
%GRID_CELL_LBUTTONDOWN = 40002 'message.
%GRID_CELL_LBUTTONDBLCLK = 40003
%GRID_CELL_PASTE = 40004 'My intentions in creating this control were three-fold. First,
%GRID_VBUTTON_CLICK = 40005 'I wanted to replace the SIGrid control which I'm presently
Then, I have this PowerBASIC Type...
Type dllGridMessage 'Used for shipping data back to client through WM_NOTIFY message
lpnmh As NMHDR
ptCell As Points
iCol As Long
iRow As Long
wParam As Long
lParam As Long
End Type
When the dll is loaded and its window created, there are grid cells that register WM_CHAR and WM_KEYDOWN messages, and they are handled there. But here is, for example, my code to handle a WM_CHAR message in the grid...
Select Case As Long wMsg
Case %WM_CHAR
#If %Def(%DEBUG)
Print #fp, " Got WM_CHAR Message In fnEditSubClass!"
#EndIf
dgm.lpnmh.code=%GRID_CELL_CHAR
iReturn=SendMessage(hHost,%WM_NOTIFY,GetDlgCtrlID(hGrid),Varptr(dgm))
#If %Def(%DEBUG)
Print #fp, " iReturn = " iReturn
#EndIf
If iReturn=-1 Then
Function=0 : Exit Function
End If
If wParam=%VK_RETURN Then
#If %Def(%DEBUG)
Print #fp, " Got WM_CHAR Message %VK_RETURN In fnEditSubClass!"
#EndIf
Call blnFlushEditControl(hGrid)
Call Refresh(hGrid)
#If %Def(%DEBUG)
Print #fp, " Leaving fnEditSubClass"
Print #fp,
#EndIf
Exit Function
Else
@pGridData.hEdit=hEdit
End If
Case %WM_KEYDOWN
#If %Def(%DEBUG)
Print #fp, " Got WM_KEYDOWN Message In fnEditSubClass!"
#EndIf
dgm.lpnmh.code=%GRID_CELL_KEYDOWN
iReturn=SendMessage(hHost,%WM_NOTIFY,GetDlgCtrlID(hGrid),Varptr(dgm))
#If %Def(%DEBUG)
Print #fp, " iReturn = " iReturn
#EndIf
And the most critical part of that is this...
dgm.lpnmh.code=%GRID_CELL_CHAR
iReturn=SendMessage(hHost,%WM_NOTIFY,GetDlgCtrlID(hGrid),Varptr(dgm))
What that is doing is filling in the dgm object of Type dllGridMessage with the info on what occurred in the grid cell, i.e., a key press (WM_CHAR), and sending that message back to the client in WM_NOTIFY transport. Note that a WM_NOTIFY is being sent to the client/host of the custom control, but the fact that the message is informing the client of a WM_CHAR is part of the LPNMHDLR::code member. Also note what is being sent is the address in the dll of the object.
So, getting to the client, here is a rather wordy and verbose WM_NOTIFY handler showing how the WM_CHAR was extracted from the pointer sent from the custom control...
Function fnWndProc_OnNotify(Wea As WndEventArgs) As Long
Local dgm As dllGridMessage Ptr
Local hGrid As Dword
Print #fp, "Entering fnWndProc_OnNotify()"
hGrid=GetWindowLong(Wea.hWnd,0)
dgm=Wea.lParam
Select Case As Long @dgm.lpnmh.idFrom
Case %IDC_GRID1
Select Case As Long @dgm.lpnmh.code
Case %GRID_CELL_KEYDOWN
Print #fp, " %GRID_CELL_KEYDOWN"
Print #fp, " hGrid = " hGrid
Print #fp, " Wea.lParam = " Wea.lParam
Print #fp, " @dgm.ptCell.x = " @dgm.ptCell.x
Print #fp, " @dgm.ptCell.y = " @dgm.ptCell.y
Print #fp, " @dgm.iCol = " @dgm.iCol
Print #fp, " @dgm.iRow = " @dgm.iRow
Print #fp, " @dgm.lpnmh.idFrom = " @dgm.lpnmh.idFrom
Print #fp, " @dgm.lpnmh.code = " @dgm.lpnmh.code
Print #fp, " @dgm.lpnmh.hwndFrom = " @dgm.lpnmh.hwndFrom
Print #fp, " @dgm.wParam = " @dgm.wParam
Print #fp, " Chr$$(@dgm.wParam) = " Chr$$(@dgm.wParam)
Print #fp, "Leaving fnWndProc_OnNotify()"
Print #fp,
Case %GRID_CELL_CHAR
Print #fp, " %GRID_CELL_CHAR"
Print #fp, " hGrid = " hGrid
Print #fp, " Wea.lParam = " Wea.lParam
Print #fp, " @dgm.ptCell.x = " @dgm.ptCell.x
Print #fp, " @dgm.ptCell.y = " @dgm.ptCell.y
Print #fp, " @dgm.iCol = " @dgm.iCol
Print #fp, " @dgm.iRow = " @dgm.iRow
Print #fp, " @dgm.lpnmh.idFrom = " @dgm.lpnmh.idFrom
Print #fp, " @dgm.lpnmh.code = " @dgm.lpnmh.code
Print #fp, " @dgm.lpnmh.hwndFrom = " @dgm.lpnmh.hwndFrom
Print #fp, " @dgm.wParam = " @dgm.wParam
Print #fp, " Chr$$(@dgm.wParam) = " Chr$$(@dgm.wParam)
Print #fp, "Leaving fnWndProc_OnNotify()"
Print #fp,
Case %GRID_CELL_LBUTTONDOWN
Print #fp, " %GRID_CELL_LBUTTONDOWN"
Print #fp, " hGrid = " hGrid
Print #fp, " Wea.lParam = " Wea.lParam
Print #fp, " @dgm.ptCell.x = " @dgm.ptCell.x
Print #fp, " @dgm.ptCell.y = " @dgm.ptCell.y
Print #fp, " @dgm.iCol = " @dgm.iCol
Print #fp, " @dgm.iRow = " @dgm.iRow
Print #fp, " @dgm.lpnmh.idFrom = " @dgm.lpnmh.idFrom
Print #fp, " @dgm.lpnmh.code = " @dgm.lpnmh.code
Print #fp, " @dgm.lpnmh.hwndFrom = " @dgm.lpnmh.hwndFrom
Print #fp, " @dgm.wParam = " @dgm.wParam
Print #fp, " Chr$$(@dgm.wParam) = " Chr$$(@dgm.wParam)
Print #fp, "Leaving fnWndProc_OnNotify()"
Print #fp,
Case %GRID_CELL_LBUTTONDBLCLK
Print #fp, " %GRID_CELL_LBUTTONDBLCLK"
Print #fp, " hGrid = " hGrid
Print #fp, " Wea.lParam = " Wea.lParam
Print #fp, " @dgm.ptCell.x = " @dgm.ptCell.x
Print #fp, " @dgm.ptCell.y = " @dgm.ptCell.y
Print #fp, " @dgm.iCol = " @dgm.iCol
Print #fp, " @dgm.iRow = " @dgm.iRow
Print #fp, " @dgm.lpnmh.idFrom = " @dgm.lpnmh.idFrom
Print #fp, " @dgm.lpnmh.code = " @dgm.lpnmh.code
Print #fp, " @dgm.lpnmh.hwndFrom = " @dgm.lpnmh.hwndFrom
Print #fp, " @dgm.wParam = " @dgm.wParam
Print #fp, " Chr$$(@dgm.wParam) = " Chr$$(@dgm.wParam)
Print #fp, "Leaving fnWndProc_OnNotify()"
Print #fp,
Case %GRID_CELL_PASTE
Print #fp, " %GRID_CELL_PASTE"
Print #fp, " hGrid = " hGrid
Print #fp, " Wea.lParam = " Wea.lParam
Print #fp, " @dgm.ptCell.x = " @dgm.ptCell.x
Print #fp, " @dgm.ptCell.y = " @dgm.ptCell.y
Print #fp, " @dgm.iCol = " @dgm.iCol
Print #fp, " @dgm.iRow = " @dgm.iRow
Print #fp, " @dgm.lpnmh.idFrom = " @dgm.lpnmh.idFrom
Print #fp, " @dgm.lpnmh.code = " @dgm.lpnmh.code
Print #fp, " @dgm.lpnmh.hwndFrom = " @dgm.lpnmh.hwndFrom
Print #fp, " @dgm.wParam = " @dgm.wParam
Print #fp, " Chr$$(@dgm.wParam) = " Chr$$(@dgm.wParam)
Print #fp, "Leaving fnWndProc_OnNotify()"
Print #fp,
End Select
End Select
fnWndProc_OnNotify=0
End Function
Hope this helps!