Выбрать главу

                                         ; и создадим окно

IFNDEF VER2

       call   CreateWindowExA,    WS_EX_OVERLAPPEDWINDOW, \ extended window style

                                  offset classTitle, \ pointer to registered class name

                                  offset wndTitle,\ pointer to window name

                                  WS_OVERLAPPEDWINDOW,       \ window style

                                  CW_USEDEFAULT,      \ horizontal position of window

                                  CW_USEDEFAULT,      \ vertical position of window

                                  CW_USEDEFAULT,      \ window width

                                  CW_USEDEFAULT,      \ window height

                                  0,           \ handle to parent or owner window

                                  0,     \ handle to menu, or child-window identifier

                                  [hInst],     \ handle to application instance

                                  0            ; pointer to window-creation data

ELSE

       call   LoadMenu,           hInst, MyMenu

       mov    [hMenu],eax

       call   CreateWindowExA,    WS_EX_OVERLAPPEDWINDOW,    \ extended window style

                                  offset classTitle, \ pointer to registered class name

                                  offset wndTitle,    \ pointer to window name

                                  WS_OVERLAPPEDWINDOW,       \ window style

                                  CW_USEDEFAULT,      \ horizontal position of window

                                  CW_USEDEFAULT,      \ vertical position of window

                                  CW_USEDEFAULT,      \ window width

                                  CW_USEDEFAULT,      \ window height

                                  0,           \ handle to parent or owner window

                                  eax,   \ handle to menu, or child-window identifier

                                  [hInst],     \ handle to application instance

                                  0            ; pointer to window-creation data

ENDIF

       mov    [hWnd],eax

       call   ShowWindow,         eax, SW_SHOW        ; show window

       call   UpdateWindow,       [hWnd]              ; redraw window

IFDEF  VER3

       call   LoadMenuA,          [hInst], MyMenu

       mov    [hMenu],eax

       call   SetMenu,            [hWnd], eax

ENDIF

msg_loop:

       call   GetMessageA,        offset msg, 0, 0, 0

       or     ax,ax

       jz     exit

       call   TranslateMessage,   offset msg

       call   DispatchMessageA,   offset msg

       jmp    msg_loop

exit:  call   ExitProcess,        0

public stdcall      WndProc

proc   WndProc      stdcall

arg    @@hwnd:      dword, @@msg: dword, @@wPar:      dword, @@lPar:      dword

       mov    eax,[@@msg]

       cmp    eax,WM_COMMAND

       je     @@command

       cmp    eax,WM_DESTROY

       jne    @@default

       call   PostQuitMessage,    0

       xor    eax,eax

       jmp    @@ret

@@default:

       call   DefWindowProcA,     [@@hwnd], [@@msg], [@@wPar], [@@lPar]

@@ret: ret

@@command:

       mov    eax,[@@wPar]

       cmp    eax,ID_OPEN

       je     @@open

       cmp    eax,ID_SAVE

       je     @@save

       call   SendMessageA,       [@@hwnd], WM_CLOSE, 0, 0

       xor    eax,eax

       jmp    @@ret

@@open:      mov    eax, offset msg_open_txt

       mov    edx, offset msg_open_tlt

       jmp    @@mess

@@save:      mov    eax, offset msg_save_txt

       mov    edx, offset msg_save_tlt

@@mess:      call   MessageBoxA,        0, eax, edx, MB_OK

       xor    eax,eax

       jmp    @@ret

endp   WndProc

end    Start

Комментарии к программе

Здесь мне хотелось в первую очередь продемонстрировать использование прототипов функций API Win32. Конечно их (а также описание констант и структур из API Win32) следует вынести в отдельные подключаемые файлы, поскольку, скорее всего Вы будете использовать их и в других программах. Описание прототипов функций обеспечивает строгий контроль со стороны компилятора за количеством и типом параметров, передаваемых в функции. Это существенно облегчает жизнь программисту, позволяя избежать ошибок времени исполнения, тем более, что число параметров в некоторых функциях API Win32 весьма значительно.

Существо данной программы заключается в демонстрации вариантов работы с оконным меню. Программу можно откомпилировать в трёх вариантах (версиях), указывая компилятору ключи VER2 или VER3 (по умолчанию используется ключ VER1). В первом варианте программы меню определяется на уровне класса окна и все окна данного класса будут иметь аналогичное меню. Во втором варианте, меню определяется при создании окна, как параметр функции CreateWindowEx. Класс окна не имеет меню и в данном случае, каждое окно этого класса может иметь своё собственное меню. Наконец, в третьем варианте, меню загружается после создания окна. Данный вариант показывает, как можно связать меню с уже созданным окном.