News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

ControlProc Problems

Started by msmith, July 05, 2006, 01:24:39 AM

Previous topic - Next topic

msmith

The following code is my DLL init and ControlProc routines:


proc !DllEntryPoint, hinstDLL,fdwReason,lpvReserved
enter
mov eax,[hinstDLL]
mov [hInstance],eax
mov [!ControlClass.hInstance],eax
mov [!ControlClass.cbSize],48
mov [!ControlClass.hIcon],0
mov [!ControlClass.hIconSm],0
invoke LoadCursor,0,IDC_ARROW
mov [!ControlClass.hCursor],eax
mov [!ControlClass.style],CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS+CS_PARENTDC+CS_DBLCLKS
mov [!ControlClass.lpfnWndProc],!ControlProc
mov [!ControlClass.cbClsExtra],0
mov [!ControlClass.cbWndExtra],4
mov [!ControlClass.hbrBackground],0
mov [!ControlClass.lpszMenuName],0
mov [!ControlClass.lpszClassName],!ControlClassName
invoke RegisterClassEx,!ControlClass
mov [ControlClassAtom],eax
mov eax,TRUE
endp

proc !ControlProc,!hwnd,wmsg,wparam,lparam
enter
push ebx esi edi
mov [!PassEvent],0
mov ebx,[wmsg]
cmp ebx,WM_CREATE
jne !Notwmcreate

invoke GetProcessHeap
invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,[ControlData+4]
cmp eax,0
je !DefWndProc
mov [ControlData],eax
invoke SetWindowLong,[!hwnd],0,eax
mov eax,[lparam]
mov [CreateData],eax
call ProcessMsg
jmp !DefWndProc

!Notwmcreate:
invoke GetWindowLong,[!hwnd],0
cmp eax,0
je !DefWndProc
mov [ControlData],eax
cmp ebx,WM_DESTROY
jne !ProcessMsg
call ProcessMsg
invoke GetProcessHeap
invoke HeapFree,eax,NULL,[ControlData]
jmp !DefWndProc

!ProcessMsg:
mov eax,[lparam]
mov [_IOBuffer],eax
call ProcessMsg
cmp [!PassEvent],0
jne !DefWndProc
jmp !Finish
!DefWndProc:
invoke DefWindowProc,[!hwnd],[wmsg],[wparam],[lparam]
!Finish:
pop edi esi ebx
endp


I am having several problems. The first is that !hwnd sometimes contains the handle of the calling exe's main window handle. This code was written assuming that the ContrlProc would only be called if the value in !hwnd was a valid handle for one of the controls created in this DLL.

Why would the system call this ControlProc with the handle of the main window in !hwnd? I am also getting invalid values in the Createwindow structure pointed to by lparam. I have gone over the docs for over a day and cannot see what the problem is.

Also, sometime the GetWindowLong returns a null pointer which the code checks for at which time it bails out to DefaultWindowProc.

msmith

I have added more decoding to the RegisterClass DLLEntry section. This dis not fix any problem but should make it more bullet-proof.


proc !DllEntryPoint, hinstDLL,fdwReason,lpvReserved
enter
cmp [fdwReason],DLL_PROCESS_ATTACH
jne !Detach
mov eax,[hinstDLL]
mov [hInstance],eax
mov [!ControlClass.hInstance],eax
mov [!ControlClass.cbSize],48
mov [!ControlClass.hIcon],0
mov [!ControlClass.hIconSm],0
invoke LoadCursor,0,IDC_ARROW
mov [!ControlClass.hCursor],eax
mov [!ControlClass.style],CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS+CS_PARENTDC+CS_DBLCLKS
mov [!ControlClass.lpfnWndProc],!ControlProc
mov [!ControlClass.cbClsExtra],0
mov [!ControlClass.cbWndExtra],4
mov [!ControlClass.hbrBackground],0
mov [!ControlClass.lpszMenuName],0
mov [!ControlClass.lpszClassName],!ControlClassName
invoke RegisterClassEx,!ControlClass
mov [ControlClassAtom],eax
jmp !DLLFinish
!Detach:
invoke UnregisterClass,!ControlClassName,[hInstance]
!DLLFinish:
mov eax,TRUE
endp


The problem with the CreateWindow structure is now fixed. This data is extremely volatile, so you must copy it to a safe place immediately.

I still get calls with the owner window handle... why, I don't know. I have fixed this at least temporarily by eliminating any fall-thru (loose) decoding of wmsg.

As to the null pointers that I throw out, they must be the product of doing a GetWindowLong on a handle that does not have a compatible WindowsExtra data section. Again this would be caused by the ControlProc being called by other than its own registered <created> members (such as the handle of the parent window).

Mark Jones

Hi, can I ask why you prefix everything with an exclamation point? "!"

Is that allowed syntaxially? (Sorry I do not know.)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

msmith

Hi Mark,

This is part of a compiler. Most internal stuff like what you asked about is written with a "!" prefix so that users of the compiler cannot access the code. For a user, "!" is an illegal character.

Most system variables are done this way also. The compiler is written in itself and there is a secret key to enable the use of "!". The only program that I have with this key turned on is the compiler itself. It is allowable syntax in FASM which is what I am using for a backend.