
;-----------------------------------------
;   Wizard.asm -- A wizard demo
;
;	   by	Ron Thomas 13/1/01
;
;   Ron_Thom@Compuserve.com	
;-----------------------------------------

.386				; 32 bit when .386 appears before .MODEL
.MODEL FLAT,STDCALL

include windows.inc

include user32.inc
include kernel32.inc
include gdi32.inc
include	comctl32.inc

includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib
includelib comctl32.lib

WinMain		PROTO :DWORD, :DWORD, :DWORD, :SDWORD

IDM_DIALOG	EQU	100
IDM_EXIT	EQU	101
IDM_HELP	EQU	102

IDD_TOP		EQU	204
IDD_BOTTOM	EQU	205
IDD_INVERT	EQU	207

IDD_LB1		EQU	301

IDD_CB1		EQU	501
IDD_CB2		EQU	502
IDD_CB3		EQU	503

IDD_RB1		EQU	601
IDD_RB2		EQU	602
IDD_RB3		EQU	603

NUMPAGES	EQU	3
NUMSTRINGS	EQU	6
BITMAPSIZEX	EQU	120
BITMAPSIZEY	EQU	226

PSN_FIRST	EQU	-200	

.data

cb1		dd	0			; 3 Check boxes
cb2		dd	0
cb3		dd	0
rb1		dd	1			; 3 Radio buttons
rb2		dd	0
rb3		dd	0
lb1sel		dd	0			; 1 list box

list		db	"Red","   ","         ",0;	Allow string up to 15 chars long 
		db	"Green"," ","         ",0
		db	"Yellow",   "         ",0
		db	"Black"," ","         ",0
		db	"White"," ","         ",0
		db	"A long string !",0
  
MYMENU		db	"MYMENU",0	
mydb		db	"MYDB",0
mydb2		db	"MYDB2",0
mydb3		db	"MYDB3",0	
psztitle	db	" ",0
caption		db	" ",0
help		db	"Help",0
quit		db	"Quit the Program?",0 
selmade		db	"Selection Made",0
szWinName	db	"MyWin",0
szTitle		db	"Demonstrate a Wizard",0
exit		db	"Exit",0	
fmt		db	"%s",0			; format control for sprintf
wizbmp		db	"wizbmp",0

.data?

hPs		DD 	3 DUP (?)
hPropSheet	HWND	?
hBit		HBITMAP ?

hInstance HINSTANCE 	?
CommandLine LPSTR 	?

hAccel		dd	?
hTBWnd		dd	?
index		dd	?

;Macros

include macros.mac
;----------------------------------------------------------------------------
.code
start:
	invoke GetModuleHandle, NULL
	mov    hInstance,eax
	invoke GetCommandLine
        invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
	invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD

	LOCAL wc:WNDCLASSEX, msg:MSG, hwnd:HWND

	.IF	!hPrevInst

	    mov   wc.cbSize,SIZEOF WNDCLASSEX
	    mov   wc.lpszClassName,OFFSET szWinName
	    M2M   wc.hInstance,hInstance
	    mov   wc.lpfnWndProc, OFFSET WndProc
	    invoke LoadCursor,NULL,IDC_ARROW
	    mov   wc.hCursor,eax			; Cursor style
	    invoke LoadIcon, 0, IDI_APPLICATION		
 	    mov   wc.hIcon,eax				; Large icon
 	    mov   wc.hIconSm,eax			; Small icon
	    mov   wc.lpszMenuName,offset MYMENU
	    mov   wc.hbrBackground,COLOR_WINDOW+1
	    mov   wc.style, 0				; default style
	    mov   wc.cbClsExtra,NULL
	    mov   wc.cbWndExtra,NULL
       
            invoke RegisterClassEx, addr wc

	    .IF   !eax
		  return 0
	    .ENDIF

	.ENDIF
			
        invoke CreateWindowEx,NULL,ADDR szWinName,ADDR szTitle,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, \
	   CW_USEDEFAULT,CW_USEDEFAULT,HWND_DESKTOP,NULL, hInst,NULL
        mov   hwnd,eax

	invoke LoadAccelerators, hInst, ADDR MYMENU
	mov	hAccel,eax

        invoke LoadBitmap, hInst, ADDR wizbmp
	mov	hBit, eax

	.IF	!eax
		return 0
	.ENDIF

        invoke ShowWindow, hwnd, CmdShow	
        invoke UpdateWindow, hwnd

        .WHILE TRUE
                INVOKE GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)

		invoke	TranslateAccelerator, hwnd, hAccel, ADDR msg

		.IF !eax
                    invoke TranslateMessage, ADDR msg
                    invoke DispatchMessage, ADDR msg
		.ENDIF

        .ENDW

        mov     eax,msg.wParam
        ret
WinMain endp

WndProc proc  hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

LOCAL PropSheet[3]:PROPSHEETPAGE, PropHdr:PROPSHEETHEADER

	mov   eax,uMsg

	.IF eax==WM_COMMAND

	    LOWORD  wParam
	  
	    .IF     eax==IDM_DIALOG

;	Set up the 1st property sheet

	    	mov PropSheet.dwSize, sizeof PROPSHEETPAGE
		M2M PropSheet.dwFlags, PSP_DEFAULT
		M2M PropSheet.hInstance, hInstance
		M2M PropSheet.pszTemplate, offset mydb
		mov PropSheet.pszIcon, 0
		M2M PropSheet.pfnDlgProc, offset DialogFunc
		M2M PropSheet.pszTitle, offset psztitle
		mov PropSheet.lParam, 0
		mov PropSheet.pfnCallback, 0

;	Set up the 2nd property sheet

		mov PropSheet[(sizeof PROPSHEETPAGE)].dwSize, sizeof PROPSHEETPAGE
		M2M PropSheet[(sizeof PROPSHEETPAGE)].dwFlags, PSP_DEFAULT
		M2M PropSheet[(sizeof PROPSHEETPAGE)].hInstance, hInstance
		M2M PropSheet[(sizeof PROPSHEETPAGE)].pszTemplate, offset mydb2
		mov PropSheet[(sizeof PROPSHEETPAGE)].pszIcon, 0
		M2M PropSheet[(sizeof PROPSHEETPAGE)].pfnDlgProc, offset DialogFunc2
		M2M PropSheet[(sizeof PROPSHEETPAGE)].pszTitle, offset psztitle
		mov PropSheet[(sizeof PROPSHEETPAGE)].lParam, 0
		mov PropSheet[(sizeof PROPSHEETPAGE)].pfnCallback, 0

;	Set up the 3rd property sheet
 
		mov PropSheet[(sizeof PROPSHEETPAGE)*2].dwSize, sizeof PROPSHEETPAGE
		M2M PropSheet[(sizeof PROPSHEETPAGE)*2].dwFlags, PSP_DEFAULT
		M2M PropSheet[(sizeof PROPSHEETPAGE)*2].hInstance, hInstance
		M2M PropSheet[(sizeof PROPSHEETPAGE)*2].pszTemplate, offset mydb3
		mov PropSheet[(sizeof PROPSHEETPAGE)*2].pszIcon, 0
		M2M PropSheet[(sizeof PROPSHEETPAGE)*2].pfnDlgProc, offset DialogFunc3
		M2M PropSheet[(sizeof PROPSHEETPAGE)*2].pszTitle, offset psztitle
		mov PropSheet[(sizeof PROPSHEETPAGE)*2].lParam, 0
		mov PropSheet[(sizeof PROPSHEETPAGE)*2].pfnCallback, 0

;	Create the 3 Pages

		invoke CreatePropertySheetPage, ADDR PropSheet
		mov	hPs,  eax
		invoke CreatePropertySheetPage, ADDR PropSheet[sizeof PROPSHEETPAGE]
		mov	hPs[4],eax
		invoke CreatePropertySheetPage, ADDR PropSheet[(sizeof PROPSHEETPAGE)*2]
		mov	hPs[8],eax

;	Set up the property sheet header

		mov	PropHdr.dwSize, sizeof PROPSHEETHEADER
		mov	PropHdr.dwFlags, PSH_WIZARD
		M2M	PropHdr.hwndParent,hWnd
		M2M	PropHdr.hInstance, hInstance
		mov	PropHdr.pszIcon, 0
		M2M	PropHdr.pszCaption, offset caption
		mov	PropHdr.nPages, 3
		mov	PropHdr.nStartPage, 0
		M2M	PropHdr.phpage, offset hPs
		mov	PropHdr.pfnCallback, 0

;	Display the property sheet control
		
		invoke  PropertySheet, ADDR PropHdr
	
	    .ELSEIF eax==IDM_EXIT
	
		invoke  MessageBox, hWnd, ADDR quit, ADDR exit, MB_YESNO

		.IF eax==IDYES
		    invoke PostQuitMessage,NULL
		.ENDIF

	    .ELSEIF eax==IDM_HELP
 
		invoke  MessageBox, hWnd, ADDR help, ADDR help, MB_OK

 	    .ENDIF
	 
        .ELSEIF eax==WM_DESTROY

	      invoke PostQuitMessage,NULL 
	.ELSE
              invoke DefWindowProc,hWnd,uMsg,wParam,lParam
              ret
	.ENDIF

	return 0

WndProc endp

DialogFunc	proc uses ebx, hdwnd:HWND, uMsg:DWORD, wParam:WPARAM, lParam:LPARAM 

;	This dialog processes property page 1

LOCAL   ps:PAINTSTRUCT,DC:HDC,memDC:DWORD
LOCAL   strr[80]:BYTE

	mov	eax, uMsg

	.IF	eax==WM_PAINT			; Display icon

	    invoke BeginPaint, hdwnd, ADDR ps
	    mov	DC, eax
	    invoke CreateCompatibleDC, DC
	    mov	memDC, eax
	    invoke SelectObject, memDC, hBit

	    invoke BitBlt, DC, 0,0, BITMAPSIZEX, BITMAPSIZEY, memDC, 0,0, SRCCOPY

	    invoke EndPaint, hdwnd, ADDR ps
	    invoke DeleteDC, memDC
	    return TRUE

	.ELSEIF	eax==WM_NOTIFY

	    mov	ebx, lParam
	    mov	eax, NMHDR.code[ebx]
			
	    .IF eax==PSN_SETACTIVE		; page gaining focus

		M2M  hPropSheet, NMHDR.hwndFrom[ebx]
		M2M  index, lb1sel
	        invoke SendMessage, hPropSheet, PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT  
	
		invoke SetWindowLong, hdwnd, DWL_MSGRESULT, 0
		return TRUE

            .ELSEIF eax==PSN_KILLACTIVE		; page loosing focus

		M2M  lb1sel, index
		invoke SetWindowLong, hdwnd, DWL_MSGRESULT, 0
		return TRUE

	    .ELSEIF eax==PSN_RESET		; Add own cancel code here

      
            .ENDIF

        .ELSEIF eax==WM_COMMAND

	    LOWORD wParam

	    .IF eax==IDD_LB1		; Process a list box LBN_DBLCLK

		invoke SendMessage, hPropSheet, PSM_CHANGED, hdwnd, 0
	
;		See if user made a selection
	
                HIWORD wParam
 
		.IF eax==LBN_DBLCLK		; Process double click on list item

 		    invoke SendDlgItemMessage, hdwnd, IDD_LB1, LB_GETCURSEL, 0, 0; Get index
		    mov	   ebx, eax
		    shl	   ebx,4		; Allow for 15 bytes (+0) string length  	
		    invoke wsprintf, ADDR strr, ADDR fmt, ADDR list[ebx]  
		    invoke MessageBox, hdwnd, ADDR strr, ADDR selmade, MB_OK ; Displays selection

		.ENDIF

 	    .ENDIF

        .ELSEIF eax==WM_INITDIALOG		; Initialise the list box

		xor  ebx,ebx

		.WHILE ebx < NUMSTRINGS*16
		    invoke SendDlgItemMessage, hdwnd, IDD_LB1, LB_ADDSTRING, 0, ADDR list[ebx]
		    add ebx, 16 
		.ENDW

;	Select 1st item

		invoke SendDlgItemMessage, hdwnd, IDD_LB1, LB_SETCURSEL, lb1sel,0
		return TRUE

        .ENDIF

	return FALSE

DialogFunc	endp

DialogFunc2	proc uses ebx, hdwnd:HWND, uMsg:DWORD, wParam:WPARAM, lParam:LPARAM 

;	This dialog processes property sheet 2

LOCAL	ps:PAINTSTRUCT, DC:DWORD, memDC:DWORD

	mov	eax, uMsg

	.IF	eax==WM_PAINT

	    invoke BeginPaint, hdwnd, ADDR ps
	    mov	DC, eax
	    invoke CreateCompatibleDC, DC
	    mov	memDC, eax
	    invoke SelectObject, memDC, hBit

	    invoke BitBlt, DC, 0,0, BITMAPSIZEX, BITMAPSIZEY, memDC, 0,0, SRCCOPY

	    invoke EndPaint, hdwnd, ADDR ps
	    invoke DeleteDC, memDC
	    return TRUE

	.ELSEIF	eax==WM_NOTIFY

	    mov	ebx, lParam
	    mov	eax, NMHDR.code[ebx]

	    .IF eax==PSN_SETACTIVE		; page gaining focus

		M2M  hPropSheet, NMHDR.hwndFrom[ebx]
   		invoke SendMessage, hPropSheet, PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT or PSWIZB_BACK	 
		invoke SetWindowLong, hdwnd, DWL_MSGRESULT, 0
	
		return TRUE

            .ELSEIF eax==PSN_KILLACTIVE		; page loosing focus

		invoke SendDlgItemMessage, hdwnd, IDD_CB1, BM_GETCHECK,0,0
		mov  cb1, eax

		invoke SendDlgItemMessage, hdwnd, IDD_CB2, BM_GETCHECK,0,0
		mov  cb2, eax

		invoke SendDlgItemMessage, hdwnd, IDD_CB3, BM_GETCHECK,0,0
		mov  cb3, eax

		invoke SetWindowLong, hdwnd, DWL_MSGRESULT, 0
		return TRUE

	    .ELSEIF eax==PSN_RESET		; Add own cancel code here
      
            .ENDIF

        .ELSEIF eax==WM_COMMAND

	    LOWORD wParam

	    .IF eax==IDD_CB1 || eax==IDD_CB2 || eax==IDD_CB3

		invoke SendMessage, hPropSheet, PSM_CHANGED, hdwnd, 0
		return TRUE

	    .ELSEIF eax==IDD_INVERT		; Invert checkbox selection

	        invoke SendMessage, hPropSheet, PSM_CHANGED, hdwnd, 0
	
		invoke SendDlgItemMessage, hdwnd, IDD_CB1, BM_GETCHECK, 0,0
		xor    eax,1			; reverse status truth
		invoke SendDlgItemMessage, hdwnd, IDD_CB1, BM_SETCHECK, eax,0

		invoke SendDlgItemMessage, hdwnd, IDD_CB2, BM_GETCHECK, 0,0
	        xor    eax,1
		invoke SendDlgItemMessage, hdwnd, IDD_CB2, BM_SETCHECK, eax,0
			
		invoke SendDlgItemMessage, hdwnd, IDD_CB3, BM_GETCHECK, 0,0
	        xor    eax,1
		invoke SendDlgItemMessage, hdwnd, IDD_CB3, BM_SETCHECK, eax,0

		return TRUE
	   
	    .ENDIF
 	
        .ELSEIF eax==WM_INITDIALOG		; Initialise the list box
		
		invoke SendDlgItemMessage, hdwnd, IDD_CB1, BM_SETCHECK, cb1, 0
		invoke SendDlgItemMessage, hdwnd, IDD_CB2, BM_SETCHECK, cb2, 0
		invoke SendDlgItemMessage, hdwnd, IDD_CB3, BM_SETCHECK, cb3, 0

		return TRUE

        .ENDIF

	return FALSE

DialogFunc2	endp

DialogFunc3	proc uses ebx, hdwnd:DWORD, uMsg:DWORD, wParam:WPARAM, lParam:LPARAM 

;	This dialog processes property sheet 2

	mov	eax, uMsg

	.IF	eax==WM_NOTIFY

	    mov	ebx, lParam
	    mov	eax, NMHDR.code[ebx]
	
	    .IF eax==PSN_SETACTIVE		; page gaining focus

		M2M  hPropSheet, NMHDR.hwndFrom[ebx]
		invoke SendMessage, hPropSheet, PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH or PSWIZB_BACK	 
		invoke SetWindowLong, hdwnd, DWL_MSGRESULT, 0
		return TRUE

            .ELSEIF eax==PSN_WIZFINISH || eax==PSN_KILLACTIVE		; page loosing focus

		invoke SendDlgItemMessage, hdwnd, IDD_RB1, BM_GETCHECK, 0,0
		mov    rb1, eax
		invoke SendDlgItemMessage, hdwnd, IDD_RB2, BM_GETCHECK, 0,0
		mov    rb2, eax
		invoke SendDlgItemMessage, hdwnd, IDD_RB3, BM_GETCHECK, 0,0
		mov    rb3, eax
	
		invoke SetWindowLong, hdwnd, DWL_MSGRESULT, 0
		return TRUE
 
	    .ELSEIF eax==PSN_RESET		; Add own cancel code here

      
            .ENDIF

        .ELSEIF eax==WM_COMMAND

	    LOWORD wParam

	    .IF eax==IDD_RB1 || eax==IDD_RB2 || eax== IDD_RB3

 		invoke SendMessage, hPropSheet, PSM_CHANGED, hdwnd, 0
		return TRUE

	    .ELSEIF eax==IDD_TOP

		invoke SendMessage, hPropSheet, PSM_CHANGED, hdwnd, 0
		invoke SendDlgItemMessage, hdwnd, IDD_RB2, BM_SETCHECK, 0,0	;Clear RB2 & 3
		invoke SendDlgItemMessage, hdwnd, IDD_RB3, BM_SETCHECK, 0,0
		invoke SendDlgItemMessage, hdwnd, IDD_RB1, BM_SETCHECK, 1,0	;Set RB1

		return TRUE

	    .ELSEIF eax==IDD_BOTTOM

 		invoke SendMessage, hPropSheet, PSM_CHANGED, hdwnd, 0
		invoke SendDlgItemMessage, hdwnd, IDD_RB1, BM_SETCHECK, 0,0	;Clear RB1 & 2
		invoke SendDlgItemMessage, hdwnd, IDD_RB2, BM_SETCHECK, 0,0
		invoke SendDlgItemMessage, hdwnd, IDD_RB3, BM_SETCHECK, 1,0	;Set RB3

		return TRUE

	    .ENDIF
 	
        .ELSEIF eax==WM_INITDIALOG		; Initialise the list box
		
		invoke SendDlgItemMessage, hdwnd, IDD_RB1, BM_SETCHECK, rb1, 0  ;1st set as default
		invoke SendDlgItemMessage, hdwnd, IDD_RB2, BM_SETCHECK, rb2, 0
		invoke SendDlgItemMessage, hdwnd, IDD_RB3, BM_SETCHECK, rb3, 0
	
		return TRUE

        .ENDIF

	return FALSE

DialogFunc3	endp

        end start

