; ######################################################################### .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\gdi32.inc include \masm32\include\masm32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\masm32.lib ; ######################################################################### ;============= ; Local macros ;============= szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM m2m MACRO M1, M2 push M2 pop M1 ENDM return MACRO arg mov eax, arg ret ENDM ;================= ; Local prototypes ;================= WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD TopXY PROTO :DWORD,:DWORD NcPaint_Proc PROTO :DWORD,:DWORD Paint_Proc PROTO :DWORD,:DWORD .data szDisplayName db "Template",0 CommandLine dd 0 hWnd dd 0 hInstance dd 0 .code start: invoke GetModuleHandle, NULL mov hInstance, eax invoke GetCommandLine mov CommandLine, eax invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT invoke ExitProcess,eax ; ######################################################################### WinMain proc hInst :DWORD, hPrevInst :DWORD, CmdLine :DWORD, CmdShow :DWORD ;==================== ; Put LOCALs on stack ;==================== LOCAL wc :WNDCLASSEX LOCAL msg :MSG LOCAL Wwd :DWORD LOCAL Wht :DWORD LOCAL Wtx :DWORD LOCAL Wty :DWORD ;================================================== ; Fill WNDCLASSEX structure with required variables ;================================================== mov wc.cbSize, sizeof WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW \ or CS_BYTEALIGNWINDOW mov wc.lpfnWndProc, offset WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL m2m wc.hInstance, hInst ;<< NOTE: macro not mnemonic mov wc.hbrBackground, COLOR_WINDOW+1 mov wc.lpszMenuName, NULL mov wc.lpszClassName, offset szClassName invoke LoadIcon,hInst,500 ; icon ID mov wc.hIcon, eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor, eax mov wc.hIconSm, 0 invoke RegisterClassEx, ADDR wc ;================================ ; Centre window at following size ;================================ mov Wwd, 500 mov Wht, 350 invoke GetSystemMetrics,SM_CXSCREEN invoke TopXY,Wwd,eax mov Wtx, eax invoke GetSystemMetrics,SM_CYSCREEN invoke TopXY,Wht,eax mov Wty, eax szText szClassName,"Template_Class" invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW, ADDR szClassName, ADDR szDisplayName, WS_POPUP or WS_THICKFRAME, Wtx,Wty,Wwd,Wht, NULL,NULL, hInst,NULL mov hWnd,eax ;invoke LoadMenu,hInst,600 ; menu ID ;invoke SetMenu,hWnd,eax invoke ShowWindow,hWnd,SW_SHOWNORMAL invoke UpdateWindow,hWnd ;=================================== ; Loop until PostQuitMessage is sent ;=================================== StartLoop: invoke GetMessage,ADDR msg,NULL,0,0 cmp eax, 0 je ExitLoop invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg jmp StartLoop ExitLoop: return msg.wParam WinMain endp ; ######################################################################### WndProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD LOCAL hDC :DWORD LOCAL Ps :PAINTSTRUCT .if uMsg == WM_COMMAND ;======== menu commands ======== .if wParam == 1000 invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL .elseif wParam == 1900 szText TheMsg,"Assembler, Pure & Simple" invoke MessageBox,hWin,ADDR TheMsg,ADDR szDisplayName,MB_OK .endif ;====== end menu commands ====== .elseif uMsg == WM_PAINT invoke BeginPaint,hWin,ADDR Ps mov hDC, eax invoke Paint_Proc,hWin,hDC invoke EndPaint,hWin,ADDR Ps return 0 .elseif uMsg == WM_NCPAINT szText scrn,"DISPLAY" invoke CreateDC,ADDR scrn,NULL,NULL,NULL mov hDC, eax invoke NcPaint_Proc,hWin,hDC invoke DeleteDC,hDC return 0 .elseif uMsg == WM_CLOSE .elseif uMsg == WM_DESTROY invoke PostQuitMessage,NULL return 0 .endif invoke DefWindowProc,hWin,uMsg,wParam,lParam ret WndProc endp ; ######################################################################## TopXY proc wDim:DWORD, sDim:DWORD shr sDim, 1 ; divide screen dimension by 2 shr wDim, 1 ; divide window dimension by 2 mov eax, wDim ; copy window dimension into eax sub sDim, eax ; sub half win dimension from half screen dimension return sDim TopXY endp ; ######################################################################## NcPaint_Proc proc hWin:DWORD,hDC:DWORD LOCAL btn_hi :DWORD LOCAL btn_lo :DWORD LOCAL Rct :RECT invoke GetSysColor,COLOR_BTNHIGHLIGHT mov btn_hi, eax invoke GetSysColor,COLOR_BTNSHADOW mov btn_lo, eax invoke GetWindowRect,hWin,ADDR Rct add Rct.left, 2 add Rct.top, 2 sub Rct.right, 2 sub Rct.bottom, 2 invoke Frame3D,hDC,btn_hi,btn_lo, Rct.left,Rct.top, Rct.right,Rct.bottom,2 add Rct.left, 1 add Rct.top, 1 sub Rct.right, 1 sub Rct.bottom, 1 invoke Frame3D,hDC,btn_lo,btn_hi, Rct.left,Rct.top, Rct.right,Rct.bottom,1 add Rct.left, 2 add Rct.top, 2 sub Rct.right, 2 sub Rct.bottom, 2 invoke Frame3D,hDC,btn_hi,btn_lo, Rct.left,Rct.top, Rct.right,Rct.bottom,2 ret NcPaint_Proc endp ; ######################################################################### Paint_Proc proc hWin:DWORD, hDC:DWORD invoke FrameWindow,hWin,2,1,1 invoke FrameWindow,hWin,4,1,0 return 0 Paint_Proc endp ; ######################################################################## end start