А заканчивается вызовом функции EndPaint

                  ... // вызов функций GDI для контекста HDC

                   EndPaint(hWnd, &ps);

       }; break;

В обеих функциях первый параметр – это дескриптор окна приложения, а второй – это указатель на структуру типа PAINTSTRUCT. В этой структуре содержится некоторая информация, которую оконная процедура может использовать для рисования в рабочей области окна.

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

При обработке вызова BeginPaint, Windows:

- обновляет фон рабочей области с помощью кисти, которая указывалась при регистрации класса окна;

- делает всю рабочую область действительной (не требующей перерисовки);

- возвращает дескриптор контекста устройства (этот дескриптор необходим для вывода в рабочую область текста и графики).

При использовании дескриптора контекста устройства, возвращаемого функцией BeginPaint, приложение не может рисовать вне рабочей области. Функция EndPaint освобождает дескриптор устройства, после чего его нельзя использовать.

Функцию BeginPaint следует вызывать только в ответ на сообщение WM_PAINT. Каждый вызов этой функции должен сочетаться с последующим вызовом функции EndPaint.

        Так как приложение практически никогда при обработке сообщения WM_PAINT не знает размеров всей своей клиентской области, то перед рисованием оно может получить эту информацию при помощи функции

       BOOL GetClientRect(HWND hWnd, LPRECT rect);

Первый параметр – дескриптор окна, второй – указатель на переменную типа RECT, в эту переменную функция GetClientRect помещает информацию о размере рабочей области в пикселях.

 

Удаление окна, сообщение WM_DESTROY

Сообщение WM_DESTROY является еще одним важным сообщением. Оно показывает, что Windows находится в процессе ликвидации окна в ответ на полученную от пользователя команду (пользователь вызывает поступление этого сообщения, если нажмет клавишей мыши по пиктограмме “Close”, выберет пункт “Close” из системного меню или нажмет комбинацию клавиш Alt+F4). Главное окно стандартно реагирует на это сообщение, вызывая функцию

       PostQuitMessage(0);

Эта функция ставит сообщение WM_QUIT в очередь сообщений приложения. Это заставляет функцию WinMain прервать цикл обработки сообщений и выйти в систему, завершив работу приложения.

ЗАДАНИЕ

 

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

 

ПРАКТИЧЕСКАЯ ЧАСТЬ

 

Ниже приведен исходный текст приложения, которое создает главное окно и выводит текст в клиентской области.

 

// --- Обязательный включаемый файл

#include <windows.h>

 

// --- Описание функции главного окна

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

 

// --- Глобальные переменные

HINSTANCE hInst;         // Дескриптор экземпляра приложения

char ClassName[]="Window";                // Название класса окна

char AppTitle[]="Application Win32"; // Заголовок главного окна

 

// --- Функция WinMain

int WINAPI WinMain(HINSTANCE hInstance,

       // Дескриптор экземпляра приложения

       HINSTANCE hPrevInstance, // В Win32 всегда равен NULL

       LPSTR lpCmdLine,

       // Указатель на командную строку. Он // позволяет

       // приложению получать данные из командной строки.

       int nCmdShow

       // Определяет, как приложение первоначально

       // отображается на дисплее: пиктограммой

       // (nCmdShow = SW_SHOWMINNOACTIVE)

       // или в виде открытого окна                                                      //(nCmdShow = SW_SHOWNORMAL).

      )

{

       WNDCLASS wc; // Структура для информации о классе окна

       HWND hWnd;      // Дескриптор главного окна приложения

       MSG msg; // Структура для хранения сообщения

// Сохраняем дескриптор экземпляра приложения в глобальной

// переменной, чтобы при необходимости воспользоваться им в

// функции окна.

       hInst=hInstance;

 

       // --- Проверяем, было ли приложение запущено ранее.

       // Воспользуемся функцией FindWindow, которая позволяет

       // найти окно верхнего

       // уровня по имени класса или по заголовку окна:

       // HWND FindWindow(LPCTSTR lpClassName,

       // LPCTSTRlpWindowName);

       // Через параметр lpClassName передается указатель на

       // текстовую строку, в которую необходимо записать имя

       // класса искомого окна. На базе одного и того же класса

       // можно создать несколько окон. Если необходимо найти

       // окно с заданным заголовком, то имя заголовка следует

       // передать через параметр lpWindowName. Если же подойдет

       // любое окно, то параметр lpWindowName может иметь

       // значение NULL.

       if((hWnd=FindWindow(ClassName, NULL))!=NULL)

       {

       // Пользователь может не помнить, какие приложения уже

       // запущены, а какие нет. Когда он запускает приложение,

       // то ожидает, что на экране появится его главное окно.

       // Поэтому, если приложение было запущено ранее,

       // целесообразно активизировать и выдвинуть на передний

       // план его главное окно. Это именно то, к чему приготовился

       // пользователь.

                   if(IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE);

                   SetForegroundWindow(hWnd);

 

       // Найдена работающая копия - работа новой копии

       // прекращается.

                   return FALSE;

       }

 

       // --- Работающая копия не найдена - функция WinMain

       // приступает к инициализации. Заполнение структуры

       // WNDCLASS для регистрации класса окна.

       memset(&wc, 0, sizeof(wc));

       wc.lpszClassName=ClassName;              // Имя класса окон

       wc.lpfnWndProc=(WNDPROC)WndProc;

       // Адрес оконной функции

       wc.style=CS_HREDRAW|CS_VREDRAW;     // Стиль класса

       wc.hInstance=hInstance;              // Экземпляр приложения

       wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);

       // Пиктограмма для окон

       wc.hCursor=LoadCursor(NULL,IDC_ARROW);  

       // Курсор мыши для окон

wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);      

       // Кисть для окон

       wc.lpszMenuName=NULL;                     // Ресурс меню окон

       wc.cbClsExtra=0;                          // Дополнительная память

       wc.cbWndExtra=0;                       // Дополнительная память

       // Pегистрация класса окна.

       RegisterClass(&wc);

 

       // Создаем главное окно приложения.

       hWnd=CreateWindow(

                   ClassName,                        // Имя класса окон

                   AppTitle,                           // Заголовок окна

                   WS_OVERLAPPEDWINDOW,             // Стиль окна

                   CW_USEDEFAULT,                               // X-координаты

                   CW_USEDEFAULT,                               // Y-координаты

                   CW_USEDEFAULT,                               // Ширина окна

                   CW_USEDEFAULT,                               // Высота окна

                   NULL,                    // Дескриптор окна-родителя

                   NULL,                    // Дескриптор меню окна

                   hInst,          // Дескриптор экземпляра приложения

                   NULL);                  // Дополнительная информация

       if(!hWnd)

       {

                   // Окно не создано, выдаем предупреждение.

              MessageBox(NULL,

                   "Create: error",AppTitle,MB_OK|MB_ICONSTOP);

                   return FALSE;

       }

 

       // Отображаем окно.

       ShowWindow(hWnd, nCmdShow);

 

       // Обновляем содержимое клиентской области окна.

       UpdateWindow(hWnd);

 

       // Запускаем цикл обработки очереди сообщений.

       // Функция GetMessage получает сообщение из очереди,

       // выдает false при выборке из очереди сообщения WM_QUIT

       while(GetMessage(&msg, NULL, 0, 0))

       {

              // Преобразование некоторых сообщений,

                   // полученных с помощью клавиатуры

                   TranslateMessage(&msg);

                   // Отправляем сообщение оконной процедуре

                   DispatchMessage(&msg);

       }

 

       return msg.wParam;

}

 

// --- Функция окна

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

       char *str="First Windows aplication";

 

       switch(msg)

       {

       // Необходимо обновить содержимое клиентской области окна.

                   case WM_PAINT:

                   {

                                HDC hDC;

                                PAINTSTRUCT ps;

 

                                hDC=BeginPaint(hWnd,&ps);        

                                // Получить контекст окна

                                TextOut(hDC,20,20,str,strlen(str)); 

                                // Нарисовать текст

                                EndPaint(hWnd,&ps);         

                                // Освободить контекст окна

                   }; break;

 

       // Нажата левая клавиша мыши в клиентской области окна.

                   case WM_LBUTTONDOWN:

                   {

                                MessageBox(hWnd, "32-bit aplication", "Window",

                                            MB_OK|MB_ICONINFORMATION);

 

                   }; break;

 

                   // Пользователь удалил окно.

                   case WM_DESTROY:

                   {

                   // Если данная функция является оконной функцией

                   // главного окна, то следует в очередь сообщений

                   // приложения послать сообщение WM_QUIT

                                PostQuitMessage(0);

                   }; break;

 

                   // Необработанные сообщения передаем в стандартную

                   // функцию обработки сообщений по умолчанию.

       default: return DefWindowProc(hWnd, msg, wParam, lParam);

       }

       return 0l;

}

 

 

КОНТРОЛЬНЫЕ ВОПРОСЫ

1. Какая функция является точкой входа в Windows-программу?

2. Что такое дескриптор копии приложения? Что он идентифицирует?

3. Какие действия обычно выполняет функция WinMain?

4. Для чего необходимо регистрировать класс окна?

5. Какие характеристики класса окон можно задать при его регистрации? Какие поля структуры, описывающей класс окна, являются наиболее важными?

6. Что такое оконная процедура? Для чего она предназначена? Кто ее вызывает в процессе работы приложения?

7. Может ли приложение создавать окна, принадлежащие классам, которые приложение самостоятельно не регистрировало?

8. Что такое дескриптор окна? Для чего он необходим?

9. После создания окна, оно обязательно должно появиться на экране? Что необходимо сделать для отображения окна?

10. Для чего служит цикл обработки сообщений? Откуда приложение извлекает очередное сообщение? Каким образом и кем сообщения создаются?

11. Сколько очередей сообщений существует? Для кого предназначены сообщения?

12. Каким образом цикл обработки сообщений прерывается, давая возможность приложению завершить свою работу?

13. Кто обычно посылает сообщение (и какое), которое прерывает цикл обработки сообщений?

14. Что должно сделать приложение, если оно не обрабатывает некоторое сообщение?

15. Из каких источников оконная процедура получает сообщения?

16. Какое сообщение приходит окну, если часть его рабочей области (или вся она) требует перерисовки? Что такое недействительная область?

17. В каких ситуациях рабочая область может становиться недействительной?

18. С вызова какой функции должна начинаться обработка сообщения WM_PAINT? Вызовом какой функции она должна заканчиваться? Для чего вызываются эти функции?

19. Как обычно реагирует стандартное главное окно приложения на получение сообщения о его удалении? Что при этом происходит с приложением?

20. Когда приходит сообщение об удалении окна? Что произойдет, если остальные окна приложения будут реагировать на это сообщение так же, как и главное окно?

 

 

СПИСОК РЕКОМЕНДУЕМОЙ ЛИТЕРАТУРЫ

 

1. Рихтер, Д. Windows для профессионалов: создание эффективных Win32-приложений (с CD-ROM)./Д. Рихтер. – М.: Русская редакция, 2000. – 752с.

2. Шилдт, Г. "MFC основы программирования". /Г. Шилдт. - Киев: BHV, 1997. – 452с.

3. Румянцев, П.В. Азбука программирования в Win32 API. / П.В. Румянцев. – М.: Радио и связь, 1999. – 242с.

4. Соломон, Г. Внутреннее устройство Microsoft Windows 2000. / Г. Соломон, М. Руссинович. – 4-е изд. – Спб.: Питер, 2001. - 752с.

5. Роббинс, Д. Отладка Windows-приложений (+ CD-ROM)./ Д. Роббинс. - Спб.: BHV, 2001. - 512с.

6. Финогенов, К. Г. Win32. Основы пpогpаммиpования/К.Г. Финогенов. – М.:Диалог - МИФИ, 2002.-416 с.

7. MSDN. http://msdn.microsoft.com

8. RSDN. http://www.rsdn.ru

 

Программирование под Windows. Оконное приложение с использованием WinAPI 32: методические указания к выполнению лабораторной работы № 1 для студентов дневной формы обучения специальности 230105 «Программное обеспечение ВТ и АС»

 

БЕЛОВ ЕВГЕНИЙ АЛЕКСАНДРОВИЧ

 

Научный редактор Д.И. Копелиович

Редактор издательства Л.И. Афонина

Компьютерный набор М.В. Березина

 

 

Темплан 2005г., п.185

Подписано в печать __.__.05. Формат 60х80 1/16 Бумага офсетная. Офсетная печать. Усл.печ.л. 1,51 Уч.-изд.л.1,51  Тираж 30 экз. Заказ     Бесплатно ____

 

Брянский государственный технический университет.

241035, Брянск, бульвар 50-летия Октября, 7, БГТУ. 54-90-49.

Лаборатория оперативной полиграфии БГТУ, ул. Институтская, 16.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: