Hi!
This very simple program works properly under Win95 and Win98 but under Win2000 produce a strange error. Why?
Thanks to everybody who can help me.
Mike
PS Full text in attach file
;******************************************
.386
.MODEL FLAT, STDCALL
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\comctl32.lib
WinMain PROTO :HINSTANCE, :HINSTANCE, :SDWORD
ChildDlgProc PROTO :HWND, :UINT, :WPARAM, :LPARAM
.CONST
IDI_ICON equ 105
IDC_BUTTON EQU 110
IDC_TAB1 EQU 1000
IDC_BUTTON1 EQU 1001
.DATA
MainDlgName DB "IDD_DIALOG1",0 ; ??? ???????,
Child1Name DB "IDD_CHILD1",0 ; ?????? ????????
Child2Name DB "IDD_CHILD2",0 ; ? ??????
Child3Name DB "IDD_CHILD3",0 ; ?????? ????????
Child4Name DB "IDD_CHILD4",0 ; ? ??????
TabTitle1 DB "Tab1",0
TabTitle2 DB "Tab2",0
TabTitle3 DB "Tab3",0
TabTitle4 DB "Tab4",0
.DATA?
hIcon dd ?
hInstance HINSTANCE ? ; ?????????
hwndTab HANDLE ? ; ????????? ???????? ?????????? Tab Control
Handles LABEL DWORD ; ?????????? ??? ??? ?????? ???? ???????? ?????????
Child1hWnd HANDLE ? ; ????????? ???????,
Child2hWnd HANDLE ? ; ???????
Child3hWnd HANDLE ?
Child4hWnd HANDLE ?
ItemStruct TC_ITEM <?> ; ??? ????????? ???????????? Tab Control
WhichTabChosen DWORD ? ; ????????? ????????
.CODE
start:
INVOKE GetModuleHandle, NULL
MOV hInstance,EAX
INVOKE WinMain, hInstance,NULL,SW_SHOWDEFAULT
INVOKE ExitProcess,EAX
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdShow:SDWORD
MOV EAX, OFFSET DlgProc
INVOKE DialogBoxParam, hInst, OFFSET MainDlgName,NULL,EAX,NULL
RET
WinMain endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_CLOSE
invoke PostQuitMessage,NULL
;INVOKE ExitProcess,0
.ELSEIF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_COMMAND
mov ax, word ptr
.if ax == IDC_BUTTON
invoke SendMessage, hWnd, WM_CLOSE, 0, 0
.endif
.ELSEIF uMsg==WM_INITDIALOG
INVOKE InitCommonControls
invoke LoadIcon, hInstance, IDI_ICON
mov hIcon, eax
invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, hIcon
INVOKE GetDlgItem,hWnd,IDC_TAB1
MOV hwndTab,EAX
MOV ItemStruct.imask,TCIF_TEXT
MOV ItemStruct.lpReserved1,0
MOV ItemStruct.lpReserved2,0
; Make 1
MOV ItemStruct.pszText,OFFSET TabTitle1
MOV ItemStruct.cchTextMax,sizeof TabTitle1
MOV ItemStruct.iImage,0
MOV ItemStruct.lParam,0
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,0,OFFSET ItemStruct
; Make 2nd
MOV ItemStruct.pszText,OFFSET TabTitle2
MOV ItemStruct.cchTextMax,sizeof TabTitle2
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,1,OFFSET ItemStruct
; 3d
MOV ItemStruct.pszText,OFFSET TabTitle3
MOV ItemStruct.cchTextMax,sizeof TabTitle3
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,2,OFFSET ItemStruct
; 4th
MOV ItemStruct.pszText,OFFSET TabTitle4
MOV ItemStruct.cchTextMax,sizeof TabTitle4
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,3,OFFSET ItemStruct
; Create dialog1
INVOKE CreateDialogParam,hInstance,OFFSET Child1Name,hwndTab,ADDR ChildDlgProc,0
MOV Child1hWnd,EAX
; 2
INVOKE CreateDialogParam,hInstance,OFFSET Child2Name,hwndTab,ADDR ChildDlgProc,0
MOV Child2hWnd,EAX
; 3
INVOKE CreateDialogParam,hInstance,OFFSET Child3Name,hwndTab,ADDR ChildDlgProc,0
MOV Child3hWnd,EAX
; 4
INVOKE CreateDialogParam,hInstance,OFFSET Child4Name,hwndTab,ADDR ChildDlgProc,0
MOV Child4hWnd,EAX
MOV WhichTabChosen,0 ; select 0 tab
INVOKE ShowWindow,Child1hWnd,SW_SHOWDEFAULT
;invoke SetFocus, Child1hWnd
.ELSEIF uMsg==WM_NOTIFY
MOV EAX,lParam
MOV EAX, (NMHDR PTR ).code
CMP EAX, TCN_SELCHANGE
JZ ChangingTab
RET
ChangingTab:
MOV EBX,WhichTabChosen
MOV EAX,
INVOKE ShowWindow,EAX,SW_HIDE
INVOKE SendMessage,hwndTab,TCM_GETCURSEL,0,0 ; Ok which one is BEING chosen right now?
MOV WhichTabChosen,EAX
MOV EBX,
INVOKE ShowWindow,EBX,SW_SHOWDEFAULT
.ELSE
xor EAX,EAX
.ENDIF
RET
DlgProc endp
ChildDlgProc PROC SmallhWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_COMMAND
;.IF wParam==IDC_BUTTON1
; invoke MessageBox, SmallhWnd, ADDR Message1, ADDR TabTitle2, MB_OK
;.ENDIF
.ENDIF
XOR EAX,EAX
RET
ChildDlgProc ENDP
END start
This very simple program works properly under Win95 and Win98 but under Win2000 produce a strange error. Why?
Thanks to everybody who can help me.
Mike
PS Full text in attach file
;******************************************
.386
.MODEL FLAT, STDCALL
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\comctl32.lib
WinMain PROTO :HINSTANCE, :HINSTANCE, :SDWORD
ChildDlgProc PROTO :HWND, :UINT, :WPARAM, :LPARAM
.CONST
IDI_ICON equ 105
IDC_BUTTON EQU 110
IDC_TAB1 EQU 1000
IDC_BUTTON1 EQU 1001
.DATA
MainDlgName DB "IDD_DIALOG1",0 ; ??? ???????,
Child1Name DB "IDD_CHILD1",0 ; ?????? ????????
Child2Name DB "IDD_CHILD2",0 ; ? ??????
Child3Name DB "IDD_CHILD3",0 ; ?????? ????????
Child4Name DB "IDD_CHILD4",0 ; ? ??????
TabTitle1 DB "Tab1",0
TabTitle2 DB "Tab2",0
TabTitle3 DB "Tab3",0
TabTitle4 DB "Tab4",0
.DATA?
hIcon dd ?
hInstance HINSTANCE ? ; ?????????
hwndTab HANDLE ? ; ????????? ???????? ?????????? Tab Control
Handles LABEL DWORD ; ?????????? ??? ??? ?????? ???? ???????? ?????????
Child1hWnd HANDLE ? ; ????????? ???????,
Child2hWnd HANDLE ? ; ???????
Child3hWnd HANDLE ?
Child4hWnd HANDLE ?
ItemStruct TC_ITEM <?> ; ??? ????????? ???????????? Tab Control
WhichTabChosen DWORD ? ; ????????? ????????
.CODE
start:
INVOKE GetModuleHandle, NULL
MOV hInstance,EAX
INVOKE WinMain, hInstance,NULL,SW_SHOWDEFAULT
INVOKE ExitProcess,EAX
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdShow:SDWORD
MOV EAX, OFFSET DlgProc
INVOKE DialogBoxParam, hInst, OFFSET MainDlgName,NULL,EAX,NULL
RET
WinMain endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_CLOSE
invoke PostQuitMessage,NULL
;INVOKE ExitProcess,0
.ELSEIF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_COMMAND
mov ax, word ptr
.if ax == IDC_BUTTON
invoke SendMessage, hWnd, WM_CLOSE, 0, 0
.endif
.ELSEIF uMsg==WM_INITDIALOG
INVOKE InitCommonControls
invoke LoadIcon, hInstance, IDI_ICON
mov hIcon, eax
invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, hIcon
INVOKE GetDlgItem,hWnd,IDC_TAB1
MOV hwndTab,EAX
MOV ItemStruct.imask,TCIF_TEXT
MOV ItemStruct.lpReserved1,0
MOV ItemStruct.lpReserved2,0
; Make 1
MOV ItemStruct.pszText,OFFSET TabTitle1
MOV ItemStruct.cchTextMax,sizeof TabTitle1
MOV ItemStruct.iImage,0
MOV ItemStruct.lParam,0
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,0,OFFSET ItemStruct
; Make 2nd
MOV ItemStruct.pszText,OFFSET TabTitle2
MOV ItemStruct.cchTextMax,sizeof TabTitle2
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,1,OFFSET ItemStruct
; 3d
MOV ItemStruct.pszText,OFFSET TabTitle3
MOV ItemStruct.cchTextMax,sizeof TabTitle3
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,2,OFFSET ItemStruct
; 4th
MOV ItemStruct.pszText,OFFSET TabTitle4
MOV ItemStruct.cchTextMax,sizeof TabTitle4
INVOKE SendMessage,hwndTab,TCM_INSERTITEM,3,OFFSET ItemStruct
; Create dialog1
INVOKE CreateDialogParam,hInstance,OFFSET Child1Name,hwndTab,ADDR ChildDlgProc,0
MOV Child1hWnd,EAX
; 2
INVOKE CreateDialogParam,hInstance,OFFSET Child2Name,hwndTab,ADDR ChildDlgProc,0
MOV Child2hWnd,EAX
; 3
INVOKE CreateDialogParam,hInstance,OFFSET Child3Name,hwndTab,ADDR ChildDlgProc,0
MOV Child3hWnd,EAX
; 4
INVOKE CreateDialogParam,hInstance,OFFSET Child4Name,hwndTab,ADDR ChildDlgProc,0
MOV Child4hWnd,EAX
MOV WhichTabChosen,0 ; select 0 tab
INVOKE ShowWindow,Child1hWnd,SW_SHOWDEFAULT
;invoke SetFocus, Child1hWnd
.ELSEIF uMsg==WM_NOTIFY
MOV EAX,lParam
MOV EAX, (NMHDR PTR ).code
CMP EAX, TCN_SELCHANGE
JZ ChangingTab
RET
ChangingTab:
MOV EBX,WhichTabChosen
MOV EAX,
INVOKE ShowWindow,EAX,SW_HIDE
INVOKE SendMessage,hwndTab,TCM_GETCURSEL,0,0 ; Ok which one is BEING chosen right now?
MOV WhichTabChosen,EAX
MOV EBX,
INVOKE ShowWindow,EBX,SW_SHOWDEFAULT
.ELSE
xor EAX,EAX
.ENDIF
RET
DlgProc endp
ChildDlgProc PROC SmallhWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_COMMAND
;.IF wParam==IDC_BUTTON1
; invoke MessageBox, SmallhWnd, ADDR Message1, ADDR TabTitle2, MB_OK
;.ENDIF
.ENDIF
XOR EAX,EAX
RET
ChildDlgProc ENDP
END start
Dunno if it' the problem, but I see you're changing EBX in the dlgproc
without preserving it...
edit: yep, added a "uses ebx" to the proc, and now it works. Read
up on calling conventions, register preserving, and perhaps programming
style ;)
without preserving it...
edit: yep, added a "uses ebx" to the proc, and now it works. Read
up on calling conventions, register preserving, and perhaps programming
style ;)
Thank you, f0dder!
I know calling conventions but can't understand why this program WORKS PROPERLY in Windows'95 and Windows'98 too if this conventions are the same?
Mike
I know calling conventions but can't understand why this program WORKS PROPERLY in Windows'95 and Windows'98 too if this conventions are the same?
Mike
Because 9x is more forgiving sometimes. Unfortunately this forgiveness
sometimes ends up causing some very mysterious and hard to find
bugs.
sometimes ends up causing some very mysterious and hard to find
bugs.
The reason is a different code base. Some 9x functionality is in 16-bit code. The switch to 16-bit mode preserves registers that would not be preserved in 32-bit code.