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.
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.
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....
It's already set in the editor.
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.
The freezing is due to an oversight in the DialogProcs, A regular dialog proc used with CreateDialogParam looks a little like this:
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
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
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.
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.
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.
Use GetClientRect on the tabs and then MoveWindow the child dialog adjusting it to the height (25) of the tab itself.
Okay, thanks a lot for your efforts in helping me!
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?
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
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
Okay, I changed that and still nothing.
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)
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.
.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.
Many thanks for all the effort and the help! :)