hello me again. well im trying to determine what mdi child is being activated when clicked on by the mouse. the problem is that im recieving a whole bunch of messages when responding to the WM_MDIACTIVATE message. is there another approach i can use besides the what i have in the follow code? if you test the code you will notice that my message handler seems to reveive about 30 messages per activation. just open a few mdi child windows and then activate the nonactivated window and you will see what i mean.
.586

.model flat, stdcall
option casemap :none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
include /masm32/include/comctl32.inc
include /masm32/include/Gdi32.inc

includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib
includelib /masm32/lib/comctl32.lib
includelib /masm32/lib/Gdi32.lib

WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
MakeMDIchild PROTO
MDIclass PROTO

.data
ClassName db "Starting Template",0
CaptionText db "MDI TEST",0
tMenu db "Press Me to Create a MDI Child",0
mdiCl db "MDICLIENT",0
MDIchildClass db "mdi_child",0
tText db "MDI Child",0
tTest db "You Can Only Make 3",13,10,
"MDI Child Windows",0
counter dd 0
tChild1 db "Child 1 Activated",0
tChild2 db "Child 2 Activated",0
tChild3 db "Child 3 Activated",0

.data?
hWnd HANDLE ?
hInstance HANDLE ?
hEdit1 HANDLE ?
hMenu HANDLE ?
hClient HANDLE ?
hChild0 HANDLE ?
hChild1 HANDLE ?
hChild2 HANDLE ?
cc CLIENTCREATESTRUCT <?>
mdi WNDCLASSEX <?>

.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
invoke ExitProcess,eax

; ##############################

WinMain proc hInst:DWORD, hPrevIns:DWORD, CmdLine:DWORD, CmdShow:DWORD

LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD

mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
mov eax, hInstance
mov wc.hInstance, eax
invoke LoadIcon, NULL,IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL,IDC_ARROW
mov wc.hCursor, eax
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName,OFFSET ClassName
invoke RegisterClassEx, addr wc

mov Wwd, 500
mov Wht, 350

invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax

invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax

invoke CreateWindowEx, NULL,
ADDR ClassName,
ADDR CaptionText,
WS_OVERLAPPEDWINDOW,
Wtx,Wty,Wwd,Wht,
NULL,
NULL,
hInst,
NULL
mov hWnd,eax
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd

StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:

mov eax,msg.wParam
ret

WinMain endp

; ###############################

WndProc proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

.IF uMsg == WM_CREATE
invoke InitCommonControls
invoke CreateMenu
mov hMenu,eax
invoke AppendMenu,hMenu,MF_POPUP + MF_STRING,8000,addr tMenu
invoke SetMenu,hWin,hMenu
invoke MDIclass

invoke GetSubMenu,hMenu,1
mov cc.hWindowMenu,eax
mov cc.idFirstChild,100
invoke CreateWindowEx, WS_EX_CLIENTEDGE,
addr mdiCl,
0,
WS_CHILD + WS_VISIBLE,
0,0,0,0,
hWin,
0,
hInstance,
ADDR cc
mov hClient, eax

.ELSEIF uMsg == WM_COMMAND
.if wParam == 8000
invoke MakeMDIchild
.endif

.ELSEIF uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
ret
.ENDIF

invoke DefFrameProc,hWin,hClient,uMsg,wParam,lParam
ret

WndProc endp

; ##########################

MDIproc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

.IF uMsg == WM_MDIACTIVATE ;handle the window that gets activated here
mov eax,lParam
.if eax == hChild0
invoke MessageBox,0,addr tChild1,0,0
.elseif eax == hChild1
invoke MessageBox,0,addr tChild2,0,0
.elseif eax == hChild2
invoke MessageBox,0,addr tChild3,0,0
.endif
.ENDIF

invoke DefMDIChildProc,hwnd,uMsg,wParam,lParam
ret
MDIproc endp

; ######################

MDIclass proc

mov mdi.cbSize, SIZEOF WNDCLASSEX
mov mdi.style, CS_BYTEALIGNWINDOW
mov mdi.lpfnWndProc, OFFSET MDIproc
mov mdi.cbClsExtra, NULL
mov mdi.cbWndExtra, NULL
mov eax, hInstance
mov mdi.hInstance, eax
mov mdi.hbrBackground,COLOR_WINDOW+1
invoke LoadCursor, NULL,IDC_ARROW
mov mdi.hCursor, eax
mov mdi.lpszClassName,OFFSET MDIchildClass
invoke RegisterClassEx, addr mdi

ret

MDIclass endp

; ###########################

MakeMDIchild proc
.if counter == 3 ;we dont support more than 3 mdi childs in this example so dont make more
invoke MessageBox,0,addr tTest,0,MB_OK
jmp @F
.endif
invoke SendMessage,hClient,WM_MDICASCADE,0,0
invoke CreateWindowEx,WS_EX_MDICHILD,
ADDR MDIchildClass,
addr tText,
0,
0,0,200,200,
hClient,
100,
hInstance,
0
.if counter == 0 ;this just assigns unique handles to each child
mov hChild0,eax
.elseif counter == 1
mov hChild1,eax
.elseif counter == 2
mov hChild2,eax
.endif
inc counter

@@:
ret
MakeMDIchild endp


; ###########################

TopXY proc wDim:DWORD, sDim:DWORD

shr sDim, 1
shr wDim, 1
mov eax, wDim
sub sDim, eax
mov eax,sDim
ret

TopXY endp

; ###########################

end start
Posted on 2002-05-21 14:14:39 by smurf
Thats because your handling it in the child proc. Whats going on is that each child gets a message in the form of:

// Message received by MDI child
hwndChildDeact = (HWND) wParam; // child being deactivated
hwndChildAct = (HWND) lParam; // child being activated


You want to handle this (in this case) in the parent:

WM_MDIACTIVATE

// Message sent to MDI client
wParam = (WPARAM) (HWND) hwndChildAct; // child to activate
lParam = 0; // not used; must be zero

:alright:

Ahh actually just two get sent out, one for the child deactivating and one for the one becoming active. The multiples might have something to do with the message boxes stealing the focus right after they got it...
Posted on 2002-05-21 16:31:44 by Graebel
hi Graebel,

did you test what you posted? ive already tryed that but my WndProc doesnt receive that message at all.

also i was able to limit the amount of messages i received by the method im using. i use a counter but its very strange because if i increment my counter right after i invoke the messagebox it doesnt work right because i still get a whole bunch of messages. it like a whole bunch of messages are coming through in one shot. here is the updated method and with this i was able to filter all but 2 messages coming through at one time:

   .IF uMsg == WM_MDIACTIVATE   ;handle the window that gets activated here

mov eax,lParam
.if eax == hChild0
.if count == 0 ;just using a counter here
inc count
invoke MessageBox,0,addr tChild1,0,0
mov count,0
.endif
.endif
.ENDIF
Posted on 2002-05-21 17:14:46 by smurf
Ahh Smurf. No I did not. I took those two blurps directly from my Win32 reference. I have found it be accurate 95% of the time. I rarely if ever find an error in what it says. Usually it is not about what it says rather it is something they left out. As that was spelled out rather clearly I did not feel testing was warrented and just posted the info. I will bat it around however.
Posted on 2002-05-22 09:08:49 by Graebel
Ok I think I am done with my testing. I ran the program as posted and of course I was spammed to death with pop up windows.

I then modified it slightly to use DbgWin as follows


include \masm32\include\masm32.inc
include \masm32\include\debug.inc

includelib \masm32\lib\debug.lib
includelib \masm32\lib\masm32.lib




.IF uMsg == WM_MDIACTIVATE ;handle the window that gets activated here
mov eax,lParam
.if eax == hChild0
PrintDec 1
.elseif eax == hChild1
PrintDec 2
.elseif eax == hChild2
PrintDec 3
.endif


And the problem of the never ending message boxes disappeared. Which leads me to what I think was happening.

If you click on Child1 on the original program

1) MDI child1 gets message for focus which creates pop-up
2) MDI child which had focus gets same message creating pop-up
3) pop-ups are causing MDI child to lose focus
4) When you close a pop-up

Its just a big recursive focus loop. I am still unsure of how after about 30 or 40 pop-ups the program breaks the cycle but it does. DbgWin is a seperate window and when shifting between different windows the WM_MDIACTIVATE message is not sent again so this fixes the problem. Basically its working just fine, just take out the message boxes. Or if you need a visual clue, add a status bar and post the messages to it.

:alright:
Posted on 2002-05-22 09:51:30 by Graebel
thanks graebel,

its very clear to me now what was going on. im going to have to learn how to use the debuging macros instead of using message boxes all the time.:alright:

one thing troubles me though. i still get two messages coming through when a mdi is being activated. this is a quote from the MSDN:
As the client window processes this message, it sends WM_MDIACTIVATE to the child window being deactivated and to the child window being activated. The message parameters received by an MDI child window are as follows:

wParam
Handle to the MDI child window being deactivated.
lParam
Handle to the MDI child window being activated.


to me it appears that im reveiving both the activated and deactivated messages. but i should be only receiving the activated one because im using the lParm value. to test this i opened up a single mdi child which has focus and then clicked on the close button. when the mdi closed i received a message in my handler. any ideas?
Posted on 2002-05-22 10:25:13 by smurf
Hey Smurf =) not true

To steal part of your quote

wParam
Handle to the MDI child window being deactivated.
lParam
Handle to the MDI child window being activated.


Look closely at the wParam and lParam from the quote. It does not matter if the MDI child is being actived or being deactivated. They both recieve the exact same message so filtering it from the lParam does little good.
Posted on 2002-05-22 13:30:03 by Graebel