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
Posted on 2002-04-24 10:56:40 by Mike
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 ;)
Posted on 2002-04-24 11:29:46 by f0dder
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
Posted on 2002-04-24 23:35:28 by Mike
Because 9x is more forgiving sometimes. Unfortunately this forgiveness
sometimes ends up causing some very mysterious and hard to find
bugs.
Posted on 2002-04-25 05:20:14 by f0dder
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.
Posted on 2002-04-26 15:05:26 by tenkey