Hello,

My problem is that I'm writing an interface for a project of mine and I wanted to use the Tab Control. I created it successfully and can go from one to the other with no problem. However, the problem occurs when I try to stick a child window to each tab. By doing so, the tab freezes and the CPU usage jumps to 100% and the child frames gets a caption bar. I am also attaching the project (interface) for you to see if am doing something wrong.
Attachments:
Posted on 2008-04-27 17:42:38 by halsten
Yeah, I had this problem before and can't remember what the solution is. I think, though this was years back you have to set the WS_EX_CONTROLPARENT style bit, don't quote me on it though....
Posted on 2008-04-27 17:55:59 by donkey
It's already set in the editor.
Posted on 2008-04-27 21:31:29 by halsten
I remember this. The problem is that our resource editors set the line CAPTION "IDD_DLG1005" in our child dialogs. This appearantly tells windows to ignore the style and force a caption. delete that line or set the caption to blank and the problem will be gone.
Posted on 2008-04-28 03:44:15 by JimmyClif
The freezing is due to an oversight in the DialogProcs, A regular dialog proc used with CreateDialogParam looks a little like this:


DlgInformation proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax,uMsg
.if eax==WM_INITDIALOG
push hWin
pop hTab
.elseif eax==WM_CLOSE
invoke EndDialog,hWin,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgInformation endp


As you can see you forgot the else part. Also you create all your dialogs with the visible style, while you assume they'd be invisible when starting the app.

Here is a TabStrib/Child Window tut I once did on the board. Maybe it can help you somehow. Although I use RadAsm I believe WinAsm should come pretty close.

Cheers,
Jimmy

Posted on 2008-04-28 04:04:37 by JimmyClif
Hello,

I removed that line and it fixed the problem, however the childs are now drawn on the tabs itself and I can't see it. Any ideas on how to fix that? Thanks in advance.
Posted on 2008-04-28 04:40:13 by halsten
Yes, you need to resize the dialog to position it under the tabs. Check out the link I gave you - the attachment is a few posts up.

Use GetClientRect on the tabs and then MoveWindow the child dialog adjusting it to the height (25) of the tab itself.
Posted on 2008-04-28 06:02:37 by JimmyClif
Okay, thanks a lot for your efforts in helping me!
Posted on 2008-04-28 06:06:09 by halsten
Hello,

Sorry to bother again, but I did as you suggested. And I checked the sample as well. But, it's still drawn on the tab itself.
Here's my code, do you see something wrong about it?


.486
.model flat, stdcall
option casemap :none

include windows.inc

include kernel32.inc
include user32.inc
include masm32.inc
include comctl32.inc
include advapi32.inc
include comdlg32.inc
include gdi32.inc

includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
includelib comctl32.lib
includelib advapi32.lib
includelib comdlg32.lib
includelib gdi32.lib

WinMain proto
DlgMain proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
DlgLog proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
DlgInformation proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
DlgProtection proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

.const
IDD_MAINDLG equ 1001
IDD_LOGDLG equ 1002
IDD_INFORMATIONDLG equ 1005
IDD_PROTECTIONDLG equ 1006

DLG_LOG equ 4000
DLG_INFORMATION equ 4001
DLG_PROTECTION equ 4002
DLG_ADVANCEDPROTECTION equ 4003

IDC_TAB equ 100

.data
szApplicationTitle db "mQUBE", 0h
szApplicationVersion db "v1.0", 0h

szTabLog db "Log", 0h
szTabInformation db "Information", 0h
szTabProtection db "Protection", 0h
szTabAdvancedProtection db "Advanced Protection", 0h


.data?
hInstance HINSTANCE ?

ItemStruct TC_ITEM <?>

hTab HWND ?

hDlgLog HWND ?
hDlgInformation HWND ?
hDlgProtection HWND ?
hDlgAdvancedProtection HWND ?

PrevSelTab HWND ?

.code

WinMain proc
invoke InitCommonControls
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke DialogBoxParam, hInstance, IDD_MAINDLG, NULL, offset DlgMain, NULL
invoke ExitProcess, NULL
ret
WinMain endp


DlgMain proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL rect:RECT

.if uMsg == WM_INITDIALOG
invoke GetDlgItem, hWin, IDC_TAB
mov hTab, eax

mov ItemStruct.imask, TCIF_TEXT

mov ItemStruct.pszText, offset szTabLog
invoke SendMessage, hTab, TCM_INSERTITEM, 0, offset ItemStruct

mov ItemStruct.pszText, offset szTabInformation
invoke SendMessage, hTab, TCM_INSERTITEM, 1, offset ItemStruct

mov ItemStruct.pszText, offset szTabProtection
invoke SendMessage, hTab, TCM_INSERTITEM, 3, offset ItemStruct

mov ItemStruct.pszText, offset szTabAdvancedProtection
invoke SendMessage, hTab, TCM_INSERTITEM, 4, offset ItemStruct

invoke CreateDialogParam, hInstance, IDD_LOGDLG, hTab, Offset DlgLog, 0
mov hDlgLog, eax

invoke CreateDialogParam, hInstance, IDD_INFORMATIONDLG, hTab, Offset DlgInformation, 0
mov hDlgInformation, eax

invoke CreateDialogParam, hInstance, IDD_INFORMATIONDLG, hTab, Offset DlgProtection, 0
mov hDlgProtection, eax

invoke ShowWindow, hDlgLog, SW_SHOWDEFAULT

push PrevSelTab
pop hDlgLog

invoke GetClientRect,hTab,addr rect
sub rect.bottom, 25
invoke MoveWindow,hTab,0,25,rect.right,rect.bottom,TRUE

.elseif eax==WM_SIZE
invoke GetClientRect, hWin,addr rect
invoke GetDlgItem, hWin, 1002
invoke MoveWindow, eax, 0, 0, rect.right, rect.bottom, TRUE

.elseif uMsg == WM_COMMAND
;.if wParam == IDM_EXIT ; -> Exit
; invoke EndDialog,hWin,NULL
;.elseif wParam == IDM_ABOUT ; -> About
; invoke MessageBox,hWin,addr lpAbout,addr App,MB_OK
;.endif
.elseif uMsg == WM_NOTIFY
mov eax, lParam
assume eax:ptr NMHDR
.if wParam == IDC_TAB && .code == TCN_SELCHANGE
Invoke SendMessage, hTab, TCM_GETCURSEL, 0, 0
.if eax == 0
mov edi, hDlgLog
.elseif eax == 1
mov edi, hDlgInformation
.elseif eax == 2
mov edi, hDlgProtection
.elseif eax == 3
mov edi, hDlgAdvancedProtection
.endif
Invoke ShowWindow, PrevSelTab, SW_HIDE
Invoke ShowWindow, edi, SW_SHOWDEFAULT
mov PrevSelTab, edi

invoke GetClientRect, hTab, addr rect
sub rect.bottom, 25
invoke MoveWindow,hTab, 0, 25, rect.right, rect.bottom, TRUE
.endif
assume eax:nothing
.elseif uMsg == WM_CLOSE
invoke EndDialog, hWin, NULL
.endif
xor eax,eax
ret
DlgMain endp

DlgLog proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax, uMsg
.if eax == WM_INITDIALOG
push hWin
pop hTab
.elseif eax == WM_CLOSE
invoke EndDialog, hWin, NULL
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
DlgLog endp

DlgInformation proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax, uMsg
.if eax == WM_INITDIALOG
push hWin
pop hTab
.elseif eax == WM_CLOSE
invoke EndDialog, hWin, NULL
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
DlgInformation endp

DlgProtection proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax, uMsg
.if eax == WM_INITDIALOG
push hWin
pop hTab
.elseif eax == WM_CLOSE
invoke EndDialog, hWin, NULL
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
DlgProtection endp

end WinMain
Posted on 2008-04-28 06:21:57 by halsten
Instead of hTab use PrevSelTab in the following snippet:


invoke GetClientRect, hTab, addr rect
sub rect.bottom, 25
invoke MoveWindow,hTab, 0, 25, rect.right, rect.bottom, TRUE
Posted on 2008-04-28 06:29:33 by JimmyClif
Okay, I changed that and still nothing.
Posted on 2008-04-28 06:46:02 by halsten
I played around with it and got it almost working... there are many mistakes all over but here's what I got so far (I really need to do some work now so good luck with it)


.486
.model flat, stdcall
option casemap :none

include windows.inc

include kernel32.inc
include user32.inc
include masm32.inc
include comctl32.inc
include advapi32.inc
include comdlg32.inc
include gdi32.inc

includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
includelib comctl32.lib
includelib advapi32.lib
includelib comdlg32.lib
includelib gdi32.lib

WinMain proto
DlgMain proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
DlgLog proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
DlgInformation proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
DlgProtection proto hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

.const
IDD_MAINDLG equ 1001
IDD_LOGDLG equ 1002
IDC_EDIT_LOG equ 1004
IDD_INFORMATIONDLG equ 1005
IDD_PROTECTIONDLG equ 1006

DLG_LOG equ 4000
DLG_INFORMATION equ 4001
DLG_PROTECTION equ 4002
DLG_ADVANCEDPROTECTION equ 4003

IDC_TAB equ 100

.data
szApplicationTitle db "mQUBE", 0h
szApplicationVersion db "v1.0", 0h

szTabLog db "Log", 0h
szTabInformation db "Information", 0h
szTabProtection db "Protection", 0h
szTabAdvancedProtection db "Advanced Protection", 0h


.data?
hInstance HINSTANCE ?

ItemStruct TC_ITEM <?>

hTab HWND ?

hDlgLog HWND ?
hDlgInformation HWND ?
hDlgProtection HWND ?
hDlgAdvancedProtection HWND ?

PrevSelTab HWND ?

.code

WinMain proc
invoke InitCommonControls
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke DialogBoxParam, hInstance, IDD_MAINDLG, NULL, offset DlgMain, NULL
invoke ExitProcess, NULL
ret
WinMain endp


DlgMain proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL rect:RECT

.if uMsg == WM_INITDIALOG
invoke GetDlgItem, hWin, IDC_TAB
mov hTab, eax

mov ItemStruct.imask, TCIF_TEXT

mov ItemStruct.pszText, offset szTabLog
invoke SendMessage, hTab, TCM_INSERTITEM, 0, offset ItemStruct

mov ItemStruct.pszText, offset szTabInformation
invoke SendMessage, hTab, TCM_INSERTITEM, 1, offset ItemStruct

mov ItemStruct.pszText, offset szTabProtection
invoke SendMessage, hTab, TCM_INSERTITEM, 2,offset ItemStruct

mov ItemStruct.pszText, offset szTabAdvancedProtection
invoke SendMessage, hTab, TCM_INSERTITEM, 3,offset ItemStruct

invoke CreateDialogParam, hInstance, IDD_LOGDLG, hTab, Offset DlgLog, 0
mov hDlgLog, eax
invoke ShowWindow, eax, SW_HIDE

invoke CreateDialogParam, hInstance, IDD_INFORMATIONDLG, hTab, Offset DlgInformation, 0
mov hDlgInformation, eax
invoke ShowWindow, eax, SW_HIDE

invoke CreateDialogParam, hInstance, IDD_PROTECTIONDLG, hTab, Offset DlgProtection, 0
mov hDlgProtection, eax
invoke ShowWindow, eax, SW_HIDE

push hDlgLog
pop PrevSelTab

.elseif uMsg==WM_SIZE
invoke GetClientRect, hWin,addr rect
invoke MoveWindow, hTab, 0, 0, rect.right, rect.bottom, TRUE

.elseif uMsg == WM_COMMAND
;.if wParam == IDM_EXIT ; -> Exit
; invoke EndDialog,hWin,NULL
;.elseif wParam == IDM_ABOUT ; -> About
; invoke MessageBox,hWin,addr lpAbout,addr App,MB_OK
;.endif
.elseif uMsg == WM_NOTIFY
mov eax, lParam
.if .NMHDR.code == TCN_SELCHANGE
Invoke SendDlgItemMessage, hWin,IDC_TAB, TCM_GETCURSEL, 0, 0
.if eax == 0
mov edi, hDlgLog
.elseif eax == 1
mov edi, hDlgInformation
.elseif eax == 2
mov edi, hDlgProtection
.elseif eax == 3
mov edi, hDlgAdvancedProtection
.endif
Invoke ShowWindow, PrevSelTab, SW_HIDE
Invoke ShowWindow, edi, SW_SHOW
mov PrevSelTab, edi
invoke GetClientRect, hWin,addr rect
invoke MoveWindow, hTab, 0, 0, rect.right, rect.bottom, TRUE
invoke MoveWindow, PrevSelTab, 0, 25, rect.right, rect.bottom, TRUE
.endif
.elseif uMsg == WM_CLOSE
invoke EndDialog, hWin, NULL
.endif
xor eax,eax
ret
DlgMain endp

DlgLog proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax, uMsg
.if eax == WM_INITDIALOG
.elseif eax == WM_CLOSE
invoke EndDialog, hWin, NULL
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
DlgLog endp

DlgInformation proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax, uMsg
.if eax == WM_INITDIALOG
.elseif eax == WM_CLOSE
invoke EndDialog, hWin, NULL
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
DlgInformation endp

DlgProtection proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax, uMsg
.if eax == WM_INITDIALOG

.elseif eax == WM_CLOSE
invoke EndDialog, hWin, NULL
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
DlgProtection endp

end WinMain


You were overwriting hTab in the Child Dialogs, you were pushing and popping an empty PrevSelTab in WM_INITDIALOG, your TCN_SELCHANGE handler had the options, 1,2,3,4 but you are creating the tabs 0,1,2,3, and many more...

Sometimes it's worth it to start all over after one has figured out how to do it.
Posted on 2008-04-28 07:48:46 by JimmyClif
Many thanks for all the effort and the help! :)
Posted on 2008-04-28 08:33:54 by halsten