| netlib.narod.ru | < Назад | Оглавление | Далее > |
Ниже приведен код полнофункциональной и очень простой программы для Windows. Лучше всего просто следовать за кодом. В следующих разделах мы исследуем его строка за строкой. Мы рекомендуем вам в качестве упражнения создать проект в вашей среде разработки, вручную набрать код, скомпилировать его и запустить. Обратите внимание, что выбирая тип проекта надо указать Win32 Application, а не Win32 Console Application.
/////////////////////////////////////////////////////////////////////
//
// Файл: hello.cpp
//
// Автор: Фрэнк Д. Луна (C) All Rights Reserved
//
// Система: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP,
// MSVC++ 7.0
//
// Описание: Демонстрация создания приложения для Windows.
//
/////////////////////////////////////////////////////////////////////
// Включение заголовочного файла, содержащего все объявления структур,
// типов данных и функций Win32 API необходимых для Windows-программы.
#include <windows.h>
// Дескриптор главного окна. Используется для идентификации
// главного окна, которое мы создадим
HWND MainWindowHandle = 0;
// Обертка для кода, необходимого для инициализации приложения Windows.
// Функция возвращает true если инициализация произведена успешно
// и false в ином случае.
bool InitWindowsApp(HINSTANCE instanceHandle, int show);
// Обертка для кода цикла сообщений.
int Run();
// Оконная процедура, обрабатывающая получаемые нашим окном
// сообщения
LRESULT CALLBACK WndProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);
// Эквивалент main() для Windows
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR pCmdLine,
int nShowCmd)
{
// Сперва мы создаем и инициализируем наше приложение Windows
// Обратите внимание, что значения hInstance и nShowCmd
// передаются WinMain в параметрах.
if(!InitWindowsApp(hInstance, nShowCmd))
{
::MessageBox(0, "Init - Failed", "Error", MB_OK);
return 0;
}
// После создания и инициализации приложения мы входим
// в цикл обработки сообщений. В нем мы остаемся до тех пор
// пока не будет получено сообщение WM_QUIT, говорящее, что
// работа приложения должна быть завершена.
return Run(); // вход в цикл сообщений
}
bool InitWindowsApp(HINSTANCE instanceHandle, int show)
{
// Первая задача при создании окна - описать его
// характеристики путем заполнения структуры WNDCLASS
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground =
static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
wc.lpszMenuName = 0;
wc.lpszClassName = "Hello";
// Затем мы регистрируем описание класса окна в Windows
// чтобы потом мы смогли создать окно с объявленными
// характеристиками
if(!::RegisterClass(&wc))
{
::MessageBox(0, "RegisterClass - Failed", 0, 0);
return false;
}
// После регистрации описания нашего класса окна мы можем
// создать окно с помощью функции CreateWindow.
// Обратите внимание, что функция возвращает значение HWND
// для созданного окна, которое мы сохраняем в переменной
// MainWindowHandle. В дальнейщем переменная MainWindowHandle
// позволит обращаться именно к тому окну, которое мы создали.
MainWindowHandle = ::CreateWindow(
"Hello",
"Hello",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
instanceHandle,
0);
if(MainWindowHandle == 0)
{
::MessageBox(0, "CreateWindow - Failed", 0, 0);
return false;
}
// Теперь мы отображаем и обновляем только что созданное
// окно. Обратите внимание, что в качестве параметра обоим
// функциям передается значение MainWindowHandle, чтобы они
// знали какое именно окно надо отображать и обновлять.
::ShowWindow(MainWindowHandle, show);
::UpdateWindow(MainWindowHandle);
return true;
}
int Run()
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
// Цикл выполняется, пока мы не получим сообщение WM_QUIT.
// Функция GetMessage возвращает 0 (false) только когда
// получено сообщение WM_QUIT, что приводит к выходу из цикла.
while(::GetMessage(&msg, 0, 0, 0))
{
// Трансляция сообщения и его перенаправление
// соответствующей оконной процедуре.
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND windowHandle,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
// Обработка заданных сообщений:
switch( msg )
{
case WM_LBUTTONDOWN:
// Если нажата левая кнопка мыши,
// отображаем диалоговое окно.
::MessageBox(0, "Hello, World", "Hello", MB_OK);
return 0;
case WM_KEYDOWN:
// Если нажата клавиша Esc, уничтожаем
// главное окно приложения, идентифицируемое
// дескриптором MainWindowHandle.
if( wParam == VK_ESCAPE )
::DestroyWindow(MainWindowHandle);
return 0;
case WM_DESTROY:
// Если получено сообщение о завершении работы,
// отправляем сообщение, которое завершит работу
// цикла обработки сообщений.
::PostQuitMessage(0);
return 0;
}
// Переправляем все остальные сообщения, которые
// наша программа не обрабатывает сама, системной
// процедуре обработки сообщений.
return ::DefWindowProc(windowHandle,
msg,
wParam,
lParam);
}

Рис. 3. Окно приведенной выше программы. Обратите внимание, что окно сообщений появляется, если вы нажмете левую кнопку мыши, когда указатель находится в клиентской области окна
| netlib.narod.ru | < Назад | Оглавление | Далее > |