netlib.narod.ru< Назад | Оглавление | Далее >

Windows-приложение Hello World

Ниже приведен код полнофункциональной и очень простой программы для 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. Окно приведенной выше программы

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



netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz