Hi All,

Why SetDlgItemText doesn't clear content of editboxs in tutorial #24 : Windows Hooks?




;--------------------------------------------- This is the source code of the main program --------------------------------------
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include mousehook.inc
includelib mousehook.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

wsprintfA proto C :DWORD,:DWORD,:VARARG
wsprintf TEXTEQU

.const
IDD_MAINDLG equ 101
IDC_CLASSNAME equ 1000
IDC_HANDLE equ 1001
IDC_WNDPROC equ 1002
IDC_HOOK equ 1004
IDC_EXIT equ 1005
WM_MOUSEHOOK equ WM_USER+6

DlgFunc PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data
HookFlag dd FALSE
HookText db "&Hook",0
UnhookText db "&Unhook",0
template db "%lx",0

.data?
hInstance dd ?
hHook dd ?
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_MAINDLG,NULL,addr DlgFunc,NULL
invoke ExitProcess,NULL

DlgFunc proc hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL hLib:DWORD
LOCAL buffer[128]:byte
LOCAL buffer1[128]:byte
LOCAL rect:RECT
.if uMsg==WM_CLOSE
.if HookFlag==TRUE
invoke UninstallHook
.endif
invoke EndDialog,hDlg,NULL
.elseif uMsg==WM_INITDIALOG
invoke GetWindowRect,hDlg,addr rect
invoke SetWindowPos, hDlg, HWND_TOPMOST, rect.left, rect.top, rect.right, rect.bottom, SWP_SHOWWINDOW
.elseif uMsg==WM_MOUSEHOOK
invoke GetDlgItemText,hDlg,IDC_HANDLE,addr buffer1,128
invoke wsprintf,addr buffer,addr template,wParam
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_HANDLE,addr buffer
.endif
invoke GetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer1,128
invoke GetClassName,wParam,addr buffer,128
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer
.endif
invoke GetDlgItemText,hDlg,IDC_WNDPROC,addr buffer1,128
invoke GetClassLong,wParam,GCL_WNDPROC
invoke wsprintf,addr buffer,addr template,eax
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_WNDPROC,addr buffer
.endif
.elseif uMsg==WM_COMMAND
.if lParam!=0
mov eax,wParam
mov edx,eax
shr edx,16
.if dx==BN_CLICKED
.if ax==IDC_EXIT
invoke SendMessage,hDlg,WM_CLOSE,0,0
.else
.if HookFlag==FALSE
invoke InstallHook,hDlg
.if eax!=NULL
mov HookFlag,TRUE
invoke SetDlgItemText,hDlg,IDC_HOOK,addr UnhookText
.endif
.else
invoke UninstallHook
[COLOR=blue]invoke SetDlgItemText,hDlg,IDC_HOOK,addr HookText [/COLOR] ;Here it works
mov HookFlag,FALSE
[COLOR=red]invoke SetDlgItemText,hDlg,IDC_CLASSNAME,NULL ;Here it does't
invoke SetDlgItemText,hDlg,IDC_HANDLE,NULL
invoke SetDlgItemText,hDlg,IDC_WNDPROC,NULL [/COLOR]
.endif
.endif
.endif
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgFunc endp

end start



Regards, GJ
Posted on 2003-05-07 20:48:46 by Green Joe
As far as I know, the SetDlgItemText function needs a valid address of a null-terminated string. Using NULL for that parameter does not seem to be a valid option according to the description of the function.

I do agree that Tutorial 24 does show it as you posted it. If you want to verify if it is improper coding, check if an error is being reported after the call to the function with NULL as the parameter.

My suggestion would be to use the address of a 0 byte for that parameter if you need to clear an edit control.

Raymond
Posted on 2003-05-07 21:59:03 by Raymond
I will check it tomorrow. But in tutorial #10 it works just fine with NULL constant.



.....
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.IF lParam==0
.IF ax==IDM_GETTEXT
invoke GetDlgItemText,hWnd,IDC_EDIT,ADDR buffer,512
invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK
.ELSEIF ax==IDM_CLEAR
[COLOR=blue]invoke SetDlgItemText,hWnd,IDC_EDIT,NULL [/COLOR]
.ELSE
invoke DestroyWindow,hWnd
.ENDIF
....


Maybe problem with styles in resource file:



#define IDD_MAINDLG 101
#define IDC_CLASSNAME 1000
#define IDC_HANDLE 1001
#define IDC_WNDPROC 1002
#define IDC_HOOK 1004
#define IDC_EXIT 1005
#define IDC_STATIC -1
#define DS_MODALFRAME 0x80
#define WS_POPUP 0x80000000
#define WS_CAPTION 0xC00000
#define WS_SYSMENU 0x80000
#define ES_AUTOHSCROLL 0x80
#define ES_READONLY 0x800

IDD_MAINDLG DIALOG DISCARDABLE 0, 0, 229, 85
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Mouse Hook Demo"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "Window Information",IDC_STATIC,7,7,214,67
LTEXT "Class name:",IDC_STATIC,21,22,39,8
EDITTEXT IDC_CLASSNAME,69,20,139,12,ES_AUTOHSCROLL | ES_READONLY
LTEXT "Handle:",IDC_STATIC,33,37,26,8
EDITTEXT IDC_HANDLE,69,36,77,12,ES_AUTOHSCROLL | ES_READONLY
LTEXT "Window Proc:",IDC_STATIC,13,52,46,8
EDITTEXT IDC_WNDPROC,69,51,77,12,ES_AUTOHSCROLL | ES_READONLY
DEFPUSHBUTTON "&Hook",IDC_HOOK,159,35,50,14
PUSHBUTTON "E&xit",IDC_EXIT,159,50,50,14
END



Thank you for reply.
Regards,GJ
Posted on 2003-05-07 22:37:52 by Green Joe
I checked SetDlgItemText calls for errors with GetLastError. It returns 0.

I found out that if to put a call for MessageBox before SetDlgItemText calls, they clearing edit boxes.

like this:



invoke MessageBox, hDlg, addr buffer,NULL,MB_OK)
invoke SetDlgItemText,hDlg,IDC_CLASSNAME,NULL
invoke SetDlgItemText,hDlg,IDC_HANDLE,NULL
invoke SetDlgItemText,hDlg,IDC_WNDPROC,NULL
Posted on 2003-05-09 07:55:53 by Green Joe
Anyone??

At least give me a hint is my question too difficult or too simple (maybe silly).
Posted on 2003-05-13 11:16:54 by Green Joe
Hello Joe Green:
I've just been working through the Windows Hook demo and ran into your problem.
I could not find a solution either. Have you come with any other information regarding the problem of not being able to clear the edit boxes in Tutorial 24?
Regards, Fumio

Edited a few minutes later: Green Joe something I forgot to mention if mouse if moved over a control, button, window etc and you press "ALT-U" the boxes are cleared as you would expect the code to do if the unhook key is clicked with the mouse. Regards, Fumio
Posted on 2003-05-24 10:25:22 by Fumio
Hi Fumio,

No I have no new information. I posted my question 2 times, in HLA section and here, and planning to post it one more time, on Hutch's masmforum, to drive people around crazy:)
Posted on 2003-05-24 11:41:45 by Green Joe
Hi Green Joe: You may have considered the following:

From Windows API UnhookWindowsHookEx

The hook procedure can be in the state of being called by another thread even after UnhookWindowsHookEx returns. If the hook procedure is not being called concurrently, the hook procedure is removed immediately before UnhookWindowsHookEx returns.

If the the mouse positioned over the unhook button is creating a WM_MOUSEHOOK message at the same time the .dll is asked to unhook; would that somehow cause the problem we see?
Regards, Fumio
Posted on 2003-05-24 12:36:12 by Fumio
I think the problem in some specs of edit controls. Maybe styles .... anyway something trivial.
I believe in it becouse the same function in the same place behaves different (i.e. it changes text on the button
and at the same time refuses to change text in edit boxes).

Edit:

If the the mouse positioned over the unhook button is creating a WM_MOUSEHOOK message at the same time the .dll is asked to unhook; would that somehow cause the problem we see?


You are right! When button clicked by mouse WM_MOUSEHOOK message also created and in response to
this message edit boxes show Classname, handle and Window proc of clicked button control AFTER
they were already cleared. When button activated by keys (ALT+U or Enter) WM_MOUSEHOOK message isn't created, so text in edit boxes couldn't be updated and it disapears.

The problem can be solved by adding one more .if to the WM_MOUSEHOOK section.

like this:



.elseif uMsg==WM_MOUSEHOOK
[COLOR=BLUE] .if HookFlag == TRUE[/COLOR]
invoke GetDlgItemText,hDlg,IDC_HANDLE,addr buffer1,128
invoke wsprintf,addr buffer,addr template,wParam
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_HANDLE,addr buffer
.endif
invoke GetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer1,128
invoke GetClassName,wParam,addr buffer,128
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer
.endif
invoke GetDlgItemText,hDlg,IDC_WNDPROC,addr buffer1,128
invoke GetClassLong,wParam,GCL_WNDPROC
invoke wsprintf,addr buffer,addr template,eax
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_WNDPROC,addr buffer
.endif
[COLOR=BLUE].endif [/COLOR]


Thank you a lot for your insight.
Regards, GJ
Posted on 2003-05-24 14:38:20 by Green Joe