program Project1; { Types and Structures Definition } type WNDCLASSEX = packed record cbSize: LongWord; style: LongWord; lpfnWndProc: Pointer; cbClsExtra: Integer; cbWndExtra: Integer; hInstance: LongWord; hIcon: LongWord; hCursor: LongWord; hbrBackground: LongWord; lpszMenuName: PAnsiChar; lpszClassName: PAnsiChar; hIconSm: LongWord; end; POINT = packed record X: Longint; Y: Longint; end; MSG = packed record hwnd: LongWord; message: LongWord; wParam: Longint; lParam: Longint; time: LongWord; pt: POINT; end; { Application Specific Variables and constants } const szBuf = 255; // Size of buffer used to handle strings WndClsSize = SizeOf(WNDCLASSEX); // Size of WNDCLASSEX Structure wnd_class: PChar = 'TMainWindow'; // Main window class name. wnd_title: PChar = 'Closer to the Metal'; // Main window caption. var wcx : WNDCLASSEX; // Main window structure msgbuf : MSG; // Message structure hwnd : LongWord; // A window handle { Windows Specific Constants } const { Class styles } CS_VREDRAW = LongWord(1); CS_HREDRAW = LongWord(2); CS_GLOBALCLASS = $4000; { Color Types } COLOR_WINDOW = 5; { Window Styles } WS_OVERLAPPED = 0; WS_CAPTION = $C00000; { WS_BORDER or WS_DLGFRAME } WS_SYSMENU = $80000; WS_THICKFRAME = $40000; WS_MINIMIZEBox = $20000; WS_MAXIMIZEBox = $10000; WS_VISIBLE = $10000000; { Common Window Styles } WS_OVERLAPPEDWINDOW = (WS_VISIBLE or WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_THICKFRAME or WS_MINIMIZEBox or WS_MAXIMIZEBox); { Messages } WM_DESTROY = $0002; { Windows API's } function GetModuleHandle(lpModuleName: PChar): HMODULE; stdcall; external 'kernel32.dll' name 'GetModuleHandleA'; procedure ExitProcess(uExitCode: LongWord); stdcall; external 'kernel32.dll' name 'ExitProcess'; function DefWindowProc(hWnd: LongWord; Msg: LongWord; wParam: Longint; lParam: Longint): Longint; stdcall; external 'user32.dll' name 'DefWindowProcA'; function RegisterClassEx(const WndClass: WNDCLASSEX): Word; stdcall; external 'user32.dll' name 'RegisterClassExA'; function CreateWindowEx(dwExStyle: LongWord; lpClassName: PChar; lpWindowName: PChar; dwStyle: LongWord; X,Y,nWidth,nHeight: Integer; hWndParent: LongWord; hMenu: LongWord; hInstance: LongWord; lpParam: Pointer): LongWord; stdcall; external 'user32.dll' name 'CreateWindowExA'; function GetMessage(var lpMsg: MSG; hWnd: LongWord; wMsgFilterMin,wMsgFilterMax: LongWord): LongBool; stdcall; external 'user32.dll' name 'GetMessageA'; function DispatchMessage(const lpMsg: MSG): Longint; stdcall; external 'user32.dll' name 'DispatchMessageA'; procedure PostQuitMessage(nExitCode: Integer); stdcall; external 'user32.dll' name 'PostQuitMessage'; { Windows Procedure } function WindowProc(hWnd,Msg: LongWord; wParam,lParam: Longint): Longint; stdcall; asm // The inline assembler will take care of setting the stack, // preserving the registers and returning. mov EAX,[Msg] // WM_DESTROY: cmp EAX,WM_DESTROY je @@m_destroy // All Other Messages: jmp @@defwndproc @@m_destroy: push 0 call PostQuitMessage // Quit. jmp @@return @@defwndproc: push [lParam] push [wParam] push [Msg] push [hWnd] call DefWindowProc jmp @@finish @@return: xor eax,eax @@finish: end; { Main Program Block } asm // GetModuleHandle with a NULL pointer gives us the instance handle // of the EXE file. This is the module that will "own" the window class. push 0 call GetModuleHandle // Define our window properties: mov [wcx.cbSize],WndClsSize; mov [wcx.style],CS_VREDRAW or CS_HREDRAW or CS_GLOBALCLASS mov [wcx.lpfnWndProc],offset WindowProc mov [wcx.cbClsExtra],0 mov [wcx.cbWndExtra],0 mov eax,hInstance mov [wcx.hInstance],EAX mov [wcx.hIcon],0 mov [wcx.hCursor],0 mov [wcx.hbrBackground],COLOR_WINDOW + 1 mov dword ptr [wcx.lpszMenuName],0 mov dword ptr [wcx.lpszClassName],offset wnd_class mov [wcx.hIconSm],0 mov EAX,wnd_class mov [wcx.lpszClassName],EAX // Register window class: push offset wcx call RegisterClassEx // Create window: push 0 // lpParam push [wcx.hInstance] // hInstance push 0 // hMenu push 0 // hWndParent push 200 // nHeight push 200 // nWidth push 100 // y (top) push 100 // x (left) push WS_OVERLAPPEDWINDOW // dwStyle mov EAX,wnd_title // lpWindowName push EAX mov EAX,wnd_class // lpClassName push EAX push 0 // dwExStyle call CreateWindowEx mov hwnd,EAX // Message Loop/Pump: @@msg_loop: push 0 // wMsgFileterMax push 0 // wMsgFilterMin push 0 // hWnd (0 = all windows) push offset msgbuf // lpMsg call GetMessage cmp eax,0 // Returns 0 (zero) if WM_QUIT jz @@end_loop push offset msgbuf call DispatchMessage jmp @@msg_loop @@end_loop: // Terminating the program: push 0 // Error return code. call ExitProcess end.