Шаг 11.
Структура программы

    На этом шаге мы приведем общую структуру Windows-программы.

    Теперь обратимся к структуре всей программы. Как мы уже отмечали, мы будем рассматривать классическую структуру программы под Windows. В такой программе имеется главное окно, а следовательно, и процедура главного окна. В целом, в коде программы можно выделить следующие разделы:

    Конечно, в программе могут быть и другие разделы, но данные разделы образуют основной скелет программы. Разберем эти разделы по порядку.

Регистрация класса окон

    Регистрация класса окон осуществляется с помощью функции RegisterClassA, единственным параметром которой является указатель на структуру WNDCLASS, содержащую информацию об окне.

    К оглавлению

Создание окна

    На основе зарегистрированного класса с помощью функции CreateWindowExA (или CreateWindowA) можно создать экземпляр окна. Как можно заметить, это весьма напоминает объектную модель программирования.

    К оглавлению

Цикл обработки очереди сообщений

    Вот как выглядит этот цикл на языке C:

while   (GetMessage (&msg,NULL,0,0))
{
  //Разрешить использование клавиатуры
  //путем трансляции сообщений о виртуальных клавишах
  //в сообщения об алфавитно-цифровых клавишах.
    TranslateMessage(&msg); 
 //Вернуть управление Windows и передать сообщение 
дальше
 //процедуре окна.
   DispatchMessage(&msg) ;
}

    Функция GetMessage() "отлавливает" очередное сообщение из ряда сообщений данного приложения и помещает его в структуру msg.

    Что касается функции TranslateMessage, то ее компетенция касается сообщений WM_KEYDOWN и WM_KEYUP, которые транслируются в WM_CHAR и WM_DEDCHAR, а также WM_SYSKEYDOWN и WM_SYSKEYUP, преобразующиеся в WM_SYSCHAR и WM_SYSDEADCHAR. Смысл трансляции заключается не в замене, а в отправке дополнительных сообщений. Так, например, при нажатии и отпускании алфавитно-цифровой клавиши в окно сначала придет сообщение WM_KEYDOWN, затем WM_KEYUP, а затем уже WM_CHAR.

    Как можно видеть, выход из цикла ожиданий имеет место только в том случае, если функция GetMessage возвращает 0. Это происходит только при получении сообщения о выходе (сообщение WM_QUIT). Таким образом, цикл ожидания играет двоякую роль: определенным образом преобразуются сообщения, предназначенные для какого-либо окна, и ожидается сообщение о выходе из программы.

    К оглавлению

Процедура главного окна

    Вот прототип функции окна на языке C:

      LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,
                                         WPARAM wParam, LPARAM lParam);

    Оставив в стороне тип возвращаемого функцией значения, обратите внимание на передаваемые параметры. Вот смысл этих параметров:

    Все четыре параметра, как вы, наверное, уже догадались, имеют тип DWORD.

    А теперь рассмотрим "скелет" этой функции на языке ассемблера.

WNDPROC  PROC 
         PUSH EBP
         MOV EBP,ESP  ;Теперь EBP указывает на вершину стека.
         PUSH EBX
         PUSH ESI 
         PUSH EDI
         PUSH DWORD PTR [EBP+14H]; LPARAM (lParam) 
         PUSH DWORD PTR [EBP+10H]; WPARAM (wParam) 
         PUSH DWORD PTR [EBP+OCH]; MES (message) 
         PUSH DWORD PTR [EBP+08H]; HWND (hwnd) 
         CALL DefWindowProcA@16 
         POP EDI 
         POP ESI 
         POP EBX 
         POP EBP 
         RET 16 
WNDPROC ENDP

    Прокомментируем приведенный фрагмент.

    RET 16 - выход с освобождением стека от четырех параметров (16 = 4 х 4).

    Доступ к параметрам осуществляется через регистр ЕВР:

    Функция DefWindowProc вызывается для тех сообщений, которые не обрабатываются в функции окна. В данном примере, как вы понимаете, никакие из сообщений, приходящих в функцию окна, не обрабатываются.

    К оглавлению

    На следующем шаге мы приведем пример простой программы для Windows.




Предыдущий шаг Содержание Следующий шаг