hi all,

sorry I post another msg.

I am making a mdi program,

the mdi's child window have few controls, and i need to size the controls to fit in the child window,

however, since its a mdi program, I can't just create one global variable for each controls in the child window,

coz if I create more than 1 child window, the handles got overwriten eachother in the global variable,


so how can this problem solved?

I need to make sure I can save each controls' handle in the child window, and must do the same for every other child windows in my mdi program


sorry my bad english,


please help me,


thankx in adv,
Posted on 2002-12-09 01:40:48 by Yanda
To get the handle of a child window you can simply call GetDlgItem(<hwnd of MDIChildwindow>,<ID of your control>)
Posted on 2002-12-09 04:38:40 by japheth
If I understand your problem correctly another solution is:

(1) define yourself a structure to hold all the control handles for one mdi child window

(2) set WNDCLASSEX.cbWndExtra to 4 (just for the pointer to this structure) when you register your mdi child class

(3) during WM_CREATE for each mdi child window, call HeapAlloc for SIZEOF your structure

(4) use this memory pointer in a call to SetWindowLong with GWL_USERDATA as the index

(5) fill the structure with the control handles as you create them

anytime you need to get the handles just call GetWindowLong with GWL_USERDATA and you have the pointer to the unique structure for that window - this works for any number of mdi child windows

remember to HeapFree at WM_CLOSE (or WM_DESTROY) for the mdi child windows

Incidentally, if you require your control handles in response to lots of window messages, rather than call GetWindowLong each time, a useful trick is to just call it once in response to the WM_CHILDACTIVATE message and save the pointer in a global variable - this works fine because I assume we can only have one mdi child window active at a time

I hope I've managed to express this idea clearly enough - eGo
Posted on 2002-12-09 10:23:00 by eGo
thankx!

eGo! you got my it ^_^ thats what I looking for thankx:alright:

since I have not tried this way yet,,

after I finished coding the problem,,

I will post the code here.. can u check it out for me?


thankx in adv,
Posted on 2002-12-09 13:42:43 by Yanda
hi, I am back,

as I though of,, this is my first tried, but also failed,,

not sure y,, I follow exact things you have mention, but not work,

here is what I did:

ChildWindowHandles STRUCT
ToolBar1 dd ?
ToolBar2 dd ?
ChildWindowHandles ENDS

.....................

;================================================
; Register the MDI child window class
;================================================
mov wc.cbWndExtra, 4
mov wc.lpfnWndProc,offset ChildProc
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszClassName,offset MDIChildClassName
invoke RegisterClassEx,addr wc

..........................

ChildProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL Tmp:DWORD, hMem:DWORD
.if uMsg==WM_CREATE

;invoke MessageBox,hWnd,addr ClosePromptMessage,addr AppName,MB_OK

invoke GlobalAlloc, GPTR, SIZEOF ChildWindowHandles
mov hMem, eax
invoke SetWindowLong, hWnd, GWL_USERDATA, hMem
mov Tmp, eax


invoke CreateWindowEx, 0, addr szToolbarClassName, 0,\
WS_CHILD or WS_VISIBLE or TBSTYLE_TOOLTIPS or CCS_NOPARENTALIGN or\
CCS_NORESIZE or WS_BORDER or TBSTYLE_FLAT,\
0, -1, 1200, 46, hWnd, 0, hInstance, 0
mov ebx, Tmp
mov , eax

invoke CreateWindowEx, 0, addr szToolbarClassName, 0,\
WS_CHILD or WS_VISIBLE or TBSTYLE_TOOLTIPS or CCS_NOPARENTALIGN or\
CCS_NORESIZE or WS_BORDER or TBSTYLE_FLAT,\
0, -1, 1200, 46, hWnd, 0, hInstance, 0
mov ebx, Tmp
mov , eax

.elseif uMsg==WM_DESTROY
invoke GlobalFree, hMem
........................
....................
ChildProc endp
....


so what did I do wrong???
Posted on 2002-12-09 14:52:44 by Yanda
Yanda - it's the pointer that you get from GlobalAlloc (that you've put in hMem) that points to your ChildWindowHandles structure, you call SetWindowLong to associate this memory with the child window. (SetWindowLong returns the previous value of GWL_USERDATA which is meaningless in this context)

If you're going to use ebx to point to the structure you should preserve it in ChildProc (and it will still be valid after the first CreateWindowEx so you don't need to reload it)

If you're interested, there is at least one good thread on the forum discussing the merits of using HeapAlloc etc rather than GlobalAlloc - use the search function

Regards
eGo
Posted on 2002-12-09 17:06:42 by eGo
eGo,

hm,, thats not the way??

whats the differ btw globalalloc and heapalloc???

I am kinna lost.... coz I have not tried the setwindowlong api or the getwindowlong api,,,

please help me out more >_<

:stupid:


thankx in adv,
Posted on 2002-12-09 22:13:25 by Yanda
hi,

hahaha nevermind, I solved my problem now.

I associated the mem pointer from HeapAlloc with setwindowlong, but I forgot to use that mem pointer to fill in the structure data ^_^

hahahah thankx

eGo and beaster!!!

without you two's help I am lost for sure :grin:


thankx alots!!!:alright:
Posted on 2002-12-10 03:53:34 by Yanda
The code you posted looks ok with the 2 changes I suggested

(1) after the first toolbar is created use:

mov ebx,hMem
mov ,eax

and after the second toolbar is created, ebx still points to the structure in memory so just:

mov ,eax

(mov .ChildWindowHandles.ToolBar2,eax would be clearer code but works ok)

(you don't need the return value from SetWindowLong therefore you don't need the variable Tmp)

(2) ChildProc should preserve ebx

----------------

Personally, I wouldn't use the local hMem at all - do a mov ebx,eax immediately after GlobalAlloc and use ebx as a parameter to SetWindowLong

I hope it works this time - eGo
Posted on 2002-12-10 03:55:30 by eGo
Yeah - we posted at the same time

Actually, I wasn't paying close enough attention - there is another error

when you handle WM_DESTROY you must invoke GetWindowLong with GWL_USERDATA which will give you the pointer to the allocated memory which you can then free

eGo
Posted on 2002-12-10 04:06:51 by eGo