Главная функция имеет четыре параметра. Первый параметр является идентификатором данной программы, второй параметр всегда имеет значение NULL, третий параметр содержит командную строку, с помощью которой программа была запущена, а четвертый параметр содержит информацию о том, как будет отображаться окно программы.
Оконная функция может иметь произвольное имя, но тип возвращаемого результата и количество и тип передаваемых параметров для нее строго определены. Прототип оконной функции должен выглядеть так:
LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Где первый параметр - идентификатор окна, которое обслуживается данной оконной функцией, второй параметр - идентификатор сообщения операционной системы, которое передается на обслуживание, третий и четвертый параметры - дополнительные данные, передаваемые вместе с сообщением. Обычно прототип оконной функции записывают в начале программы, до функции WinMain (), а сам код функции помещают в конец программы. Это делается потому, что функция должна быть определена до ее использования в WinMain ().
Таким образом, первым шагом, создания каркасного приложения будет определение прототипа оконной функции в начале программы (до функции WinMain).
Вторым шагом создания каркасного приложения будет создание и инициализация структуры с информацией класса окна. Для этого необходимо в функции WinMain объявить переменную данного типа и заполнить все десять полей структуры:
WNDCLASS wcl;
// объявление переменной типа структуры класса окна
wcl. style=CS_HREDRAW|CS_VREDRAW;
// стиль окна. В данном случае показывает, что окно // будет перерисовываться при изменении горизонтального // и вертикального размеров.
wcl. lpfnWndProc=WindowProc;
// указатель на оконную функцию, которая будет // вызываться операционной системой для данного окна.
wcl. cbClsExtra=0;
// количество дополнительных байт для следующей // структуры.
wcl. cbWndExtra=0;
// количество дополнительных байт для следующего окна.
wcl. hInstance=hInstance;
// идентификатор процедуры (программы), владеющей // данным окном.
wcl. hIcon=LoadIcon (NULL, IDI_APPLICATION);
// идентификатор класса значка (иконки) для данного // окна. Значок включается в проект в виде ресурса. В // данном случае функцией LoadIcon () загружается // стандартный значок для приложений Windows.
wcl. hCursor=LoadCursor (NULL, IDC_ARROW);
// идентификатор класса курсора для данного окна. Курсор // включается в проект в виде ресурса. В данном случае // функцией LoadCursor () загружается стандартный курсор // в виде стрелки.
wcl. hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH);
// идентификатор класса кисти для фона окна. В данном // случае используется белый цвет фона.
wcl. lpszMenuName=”MENU”;
// указатель на строку, идентифицирующую ресурс главного // меню окна.
wcl. lpszClassName="Pass";
// имя класса окна
Третьим шагом является создание окна. Он состоит из регистрации класса окна, создания окна, показа и перерисовки окна. Регистрация класса окна выполняется функцией RegisterClass ():
if (! RegisterClass (&wcl)) return 0;
В качестве параметра функции используется указатель на заполненную структуру класса окна. В случае успешной регистрации функция возвращает ненулевой результат. В противном случае функция возвращает ноль и приложение необходимо завершить.
Создание окна выполняется функцией CreateWindow (), имеющей прототип
HWND CreateWindow (
LPCTSTR lpClassName, // адрес имени зарегистрированного класса
LPCTSTR lpWindowName, // адрес имени окна
DWORD dwStyle, // стиль окна, константы WS_xxxxxx
int x, // горизонтальная позиция окна
int y, // вертикальная позиция окна
int nWidth, // ширина окна
int nHeight, // высота окна
HWND hWndParent, // идентификатор "внешнего" окна
HMENU hMenu, // идентификатор меню окна
HANDLE hInstance, // идентификатор приложения
LPVOID lpParam // адрес дополнительных данных
);
Функция возвращает идентификатор открытого окна.
В данном случае в функцию WinMain можно добавить такую строку:
HWND hWnd = CreateWindow (wcl. lpszClassName, "Window", WS_OVERLAPPEDWINDOW, // окно с заголовком и бордюром CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, // положение и размер "по умолчанию" NULL, NULL, hInstance, NULL);
// нет "внешнего" окна (это главное окно программы),
// используется меню класса окна,
// идентификатор программы - второй параметр функции WinMain ()
// нет дополнительных данных.
Далее, для показа окна на экране, используется функция ShowWindow ():
ShowWindow (hWnd, nCmdShow);
Где первый параметр - идентификатор окна (которое должно быть уже зарегистрировано и открыто), а второй параметр - способ отображения окна. В качестве второго параметра используется способ отображения, переданный операционной системой функции WinMain (четвертый параметр).
И, наконец, для перерисовки окна используется функция UpdateWindow ():
UpdateWindow (hWnd);
В которую в качестве параметра передается идентификатор окна.
Четвертым шагом создания каркасного приложения будет создание цикла обработки сообщений:
MSG lpMsg;
while (GetMessage (&lpMsg, NULL, 0,0))
{
TranslateMessage (&lpMsg);
DispatchMessage (&lpMsg);
}
return lpMsg. wParam;
Функция GetMessage () выбирает сообщение из очереди сообщений и помещает его в структуру, адрес которой указан в качестве первого параметра. Функция работает только с сообщениями, адресованными данному приложению или его дочерним процессам. Данная функция возвращает 0, если было выбрано сообщение WM_QUIT и не ноль во всех остальных случаях. Таким образом, цикл обработки сообщений завершается после получения сообщения WM_QUIT. А затем завершается и сама функция WinMain ().
Минимальный цикл обработки сообщений должен состоять из вызова системной функции DispatchMessage (), которая передает сообщение оконной функции, связанной с данным окном. Перед вызовом функции DispatchMessage () сообщение может подвергаться обработке. Так, функция TranslateMessage преобразует сообщения от клавиатуры. В Windows от клавиатуры идут сообщения WM_KEYDOUN и WM_KEYUP, соответствующие нажатию и отпусканию клавиш. Эти сообщения содержат виртуальные коды клавиш. Функция TranslateMessage () преобразует эти сообщения в сообщения WM_CHAR, содержащие Пятым, и последним, шагом создания каркасного приложения является написание оконной функции. Она выглядит так:
LRESULT CALLBACK WindowProc (HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
static HINSTANCE hInstance;
switch (message)
{
case WM_CREATE:
{
hInstance = ( (LPCREATESTRUCT) lParam) - >hInstance;
DialogBox (hInstance, IDD_DIAL,hWnd, MyDlgProc);
break;
}
case WM_DESTROY:
{
PostQuitMessage (0);
break;
}
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
Оконная процедура получает сообщение и анализирует его. После анализа сообщение либо обрабатывается, либо передает сообщение процедуре обработки сообщений по умолчанию. Например оконная функция обрабатывает сообщение - WM_DESTROY. Это сообщение передается оконной функции при закрытии окна. Нормальной реакцией на такое сообщение является посылка сообщения WM_QUIT для завершения приложения. Это сообщение посылается путем вызова функции PostQuitMessage (). Параметром этой функции является код завершения программы.
Таким образом получено минимальное каркасное приложение Windows.
Создание меню.
Для добавления меню к программе необходимо создать соответствующий ресурс. Для создания ресурса меню в проекте необходимо воспользоваться пунктом меню "Insert - > Resourse - > ResursType: Menu - > New". При этом в окне редактора появится возможность в интерактивном режиме создать систему меню. Для редактирования свойств элементов меню можно использовать "View‑>Properties". Каждому пункту меню необходимо присвоить свой идентификатор. После завершения создания ресурса необходимо его сохранить. При этом автоматически будут созданы два файла - resource. h и script. rc (где script- имя файла ресурсаd). После этого необходимо файл ресурса script. rc включить в проект в папку SourceFiles, а в файл StdAfh. h включить строку #include "resource. h". После того, как файл ресурса будет включен в проект, в окне проекта станет, доступна закладка ResourceView. Используя эту закладку можно просмотреть древовидную структуру ресурсов проекта. В папке menu будут показаны идентификаторы ресурсов меню.
Для того чтобы созданное меню отображалось в окне программы его надо указать при инициализации структуры класса окна:
wcl. lpszMenuName=“MENU”;
где “MENU" - выбранный мною идентификатор меню. После компиляции такого проекта в окне программы будет отображаться меню.
Для того, чтобы назначить пунктам меню конкретные действия, необходимо включить их в обработку оконной функцией. Выбор пунктов меню с помощью мыши отслеживается автоматически операционной системой и формируются сообщения WM_COMMAND. В качестве параметра такого сообщения передается идентификатор выбранного пункта меню. Таким образом, в оконной функции необходимо перехватить сообщение типа WM_COMMAND и проверить его параметр. А далее, в зависимости от параметра, выполнить то или иное действие.
Следует отметить, что используемые переменные следует объявить вне тела оператора switch.
Вывод сообщений в отдельном окне.
Самым простым способом вывода сообщений в отдельном окне является использование функции MessageBox (). Эта функция имеет следующий формат:
intMessageBox (
HWNDhWnd,
LPCTSTRlpText,
LPCTSTRlpCaption,
UINTuType);
Где параметры имеют следующее значение:
hWnd - идентификатор окна-владельца создаваемого окна с сообщением;
lpText - указатель на строку с сообщением, строка должна заканчиваться символом с кодом 0;
lpCaption - указатель на строку с заголовком окна, строка должна заканчиваться символом с кодом 0;
uType - тип окна с сообщением, может быть комбинацией различных констант.д.опустимы следующие константы в этом параметре:
MB_YESNO - окно будет иметь две кнопки: Yes и No.
MB_YESNOCANCEL - окно будет иметь три кнопки: Yes, No, и Cancel.
Функция возвращает ноль в случае нехватки памяти для открытия окна. При успешном завершении функции она возвращает одно из следующих значений: