68903

Скелет оконной программы

Лекция

Информатика, кибернетика и программирование

Функцию создания окна. Для его создания необходимо выполнить два шага: регистрацию класса окна и вызвать функцию создания окна. Оба этих действия определяют основные свойства видимые и невидимые характеристики окна.

Русский

2014-09-27

95.5 KB

0 чел.

Лекция 2 Скелет оконной программы

Вступление

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

Представьте себе автомобиль и его составные части. Внутри корпуса машины закреплены несколько независимых систем: управление (руль, система передачи, поворачиваемые колеса); двигатель, управляемый зажиганием, педалью акселератора, коробка распределения, ведущие колеса; тормозная система, электрооборудование и т.п. Все эти системы работают параллельно, и, в общем-то, независимо. Точно также проектируется и современная программа. В нее изначально закладываются составные элементы, которые, работая параллельно и обеспечивая реализацию специфической функции, в совокупности обеспечивают полноценное функционирование приложения в среде ОС WINDOWS.

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

Рассмотрим эти шаги и составные части программ.

Четыре составные части программы под WINDOWS

Любое оконное приложение, написанное под Windows должно содержать в себе следующие элементы:

  1.  Функцию регистрации класса окна.
  2.  Функцию создания окна.
  3.  Оконную процедуру.
  4.  Цикл обработки сообщений.

Ранее уже говорилось, что большинство программ под WINDOWS должны иметь хотя бы одно окно. Для его создания необходимо выполнить два шага: регистрацию класса окна и вызвать функцию создания окна. Оба этих действия определяют основные свойства (видимые и невидимые характеристики) окна. Основное отличие первого шага от второго заключается в том, что на основе зарегистрированного класса окна можно создавать бесконечное число окон. Таким образом, при регистрации класса окна задаются свойства, общие (одинаковые) для всех последующих окон свойства. Функция создания окна создает очередной экземпляр окна, добавляя уже конкретные свойства окна, такие как положение на экране, размеры, содержание текста и т.п.

Регистрация окна проводится в два этапа. Во-первых, заполняется структура WNDCLASSEX (поля которой как раз и содержат общую информацию), после чего выполняется функция RegisterClassEx, в которую передается указатель на заполненную структуру. Ниже приведен фрагмент программы с комментариями к полям заполняемой структуры:

 

WNDCLASSEX wcex; // объявление переменной типа структура оконного класса

wcex.cbSize = sizeof(WNDCLASSEX); // размер структуры в байтах

wcex.style  = CS_HREDRAW | CS_VREDRAW; // стиль окна

wcex.lpfnWndProc = (WNDPROC)WndProc; //адрес оконной процедуры

wcex.cbClsExtra  = 0;      

wcex.cbWndExtra = 0;

wcex.hInstance  = hInstance;  // описатель приложения

wcex.hIcon  = MyIcon1;  // определение иконки

wcex.hCursor  = LoadCursor(NULL, IDC_ARROW); // определение курсора

wcex.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); // установка фона

wcex.lpszMenuName = NULL;  // определение меню

wcex.lpszClassName = "MyWindow"; // имя класса

wcex.hIconSm  = NULL; //определение маленькой иконки

  RegisterClassEx(&wcex); // регистрация класса окна

В дальнейшем, мы вернемся к рассмотрению отдельных полей структуры.

После того, как класс окна зарегистрирован, можно создавать окна, что выполняется следующим образом:

hWnd=CreateWindow(      "MyWindow", // имя класса окна

"Строка заголовка",   // имя приложения

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

CW_USEDEFAULT, // положение по Х

CW_USEDEFAULT,  // положение по Y

CW_USEDEFAULT,    // размер по Х

CW_USEDEFAULT,    // размер по Y

NULL, // описатель родительского окна

NULL,       // описатель меню окна

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

NULL);     // параметры создания.

Функция CreateWindow возвращает описатель вновь созданного окна. Если возвращаемое значение равно NULL, это значит, что окно не было создано по какой-либо причине.

Чтобы созданное окно появилось на экране, необходимо выполнить последовательно две функции:

ShowWindow(hWnd, nCmdShow);  // Показать окно

UpdateWindow(hWnd);   // Обновить окно

Следующие важные элементы программы – это оконная процедура и цикл обработки сообщений. Адрес оконной процедуры использовался при регистрации класса окна (WndProc).  Для их рассмотрения сделаем небольшое отступление. В первой лекции обсуждался вопрос о событиях и сообщениях. Настало время более подробно рассмотреть этот вопрос.

Порядок обработки сообщений, цикл обработки сообщений

Когда в системе происходит какое-либо событие, на которое должна отреагировать исполняемая программа (например, нажата клавиша на клавиатуре, перемещена мышь или истекло время ожидания), операционная система посылает программе сообщение об этом событии. Программа получает сообщение и выполняет код (часть программы), реагирующий на это событие. На рис. 2.1. отображен этот процесс.

Рис. 2.1. Порядок прохождения сообщения

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

Цикл обработки сообщения выбирает очередное сообщение из программной очереди и вызывает оконную процедуру (ОП) того окна, которому оно предназначено. Если программа в это время занята обработкой другого сообщения, вновь прибывшее сообщение ожидает в очереди завершения обработки предыдущего сообщения (это особенно заметно на медленных машинах, когда например, набранное слово на клавиатуре появляется на экране спустя некоторое время).

Стандартный цикл обработки сообщений имеет вид:

 MSG msg;

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

{

  TranslateMessage(&msg);

  DispatchMessage(&msg);

}

Функция GetMessage выбирает очередное сообщение из программной очереди. Результатом выполнения функции является заполнение структуры msg, которая содержит всю необходимую информацию о полученном сообщении: описатель окна, которому предназначено сообщение, тип сообщения, параметры сообщения (зависящие от типа сообщения) и время возникновения сообщения. Функция также возвращает некоторое число, которое отлично от нуля для всех сообщений кроме сообщения о закрытии программы. В последнем случае цикл обработки сообщений прерывается и программа завершается.

Функция TranslateMessage преобразует сообщение в соответствии с системными настройками (например, преобразовывает код нажатой клавиши клавиатуры согласно выбранного в настоящее время языка).

Функция DispatchMessage определяет какому окну приложения послано сообщение и вызывает соответствующую оконную процедуру.

Оконная процедура

Оконная процедура является центральной частью программы. Не будет большим преувеличением сказать, что более девяносто процентов алгоритма программы заключено в оконной процедуре. Оконная процедура соответствует одному (или более)  окну программы и содержит в себе программную реализацию поведения окна. Подпрограммы рисования элементов окна, реакция на действия мыши, клавиатуры, закрытия окна – все это заключено внутри оконной процедуры.

Оконная процедура имеет стандартный вид:

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

{

. . . . .

switch (message)

{

 case WM_CREATE: // Сообщение приходит при создании окна

  . . . . . . .

  break;

 case WM_PAINT:  // Перерисовать окно

  . . . . . . .

  break;

 case WM_DESTROY: // Завершение работы

  . . . . . . .

  break;

 default:

// Обработка сообщений, которые не обработаны пользователем

  return DefWindowProc(hWnd, message, wParam, lParam);

  }

return 0;

}

Оконная процедура вызывается только тогда, когда пришло какое-либо сообщение, предназначенное соответствующему окну. Обратите внимание, что оконная процедура задается в классе регистрации окна, то есть для нескольких окон существует только один экземпляр оконной процедуры. Какому именно окну послано сообщение определят первый параметр функции WndProc – описатель окна hWnd.

Второй параметр функции - message -определяет  тип сообщения и принимает одно значение из множества WM_<сообщение>. Например, когда message равно WM_CREATE, это означает, что пришло сообщение о создании окна (данное сообщение является первым сообщением, приходящим в оконную процедуру после создания окна и приходит только один раз).

Третий и четвертый параметры - wParam  и lParam сопутствуют сообщению и зависит от его типа. Например, если приходит сообщение о нажатии мыши, в этих параметрах содержится информация о координатах мыши в момент нажатия и состоянии управляющих клавиш.

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

В заключение лекции приведем полностью текст программы, которая является полноправным оконным приложением. В результате выполнения программы на экране появляется окно, содержащее стандартные элементы (заголовок, рамку, кнопки управления)  и надпись "Первая программа для WINDOWS".  Окно можно перемещать, минимизировать, максимизировать, свертывать. Можно также изменять его размеры с помощью мыши и наблюдать программу на панели задач.

#include <windows.h>         // подключение библиотеки с функциями API

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

HINSTANCE hInst;  // Указатель приложения

// Предварительное описание функций

ATOM  MyRegisterClass(HINSTANCE hInstance);

BOOL  InitInstance(HINSTANCE, int);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

// Основная программа

int APIENTRY WinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance, LPSTR     lpCmdLine,

                    int       nCmdShow)

{

MSG msg;

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

MyRegisterClass(hInstance);

// Создание окна приложения

if (!InitInstance (hInstance, nCmdShow))

{

 return FALSE;

}

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

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

{

  TranslateMessage(&msg);

  DispatchMessage(&msg);

}

return msg.wParam;

}

//  FUNCTION: MyRegisterClass()

//  Регистрирует класс окна

ATOM MyRegisterClass(HINSTANCE hInstance)

{

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style  = CS_HREDRAW | CS_VREDRAW; // стиль окна

wcex.lpfnWndProc = (WNDPROC)WndProc; // оконная процедура

wcex.cbClsExtra  = 0;      

wcex.cbWndExtra = 0;

wcex.hInstance  = hInstance;  // указатель приложения

wcex.hIcon  = MyIcon1; // определение иконки

wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);  // определение курсора

wcex.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); // установка фона

wcex.lpszMenuName = NULL;  // определение меню

wcex.lpszClassName = "MyClass"; // имя класса

wcex.hIconSm  = NULL;

return RegisterClassEx(&wcex); // регистрация класса окна

}

// FUNCTION: InitInstance(HANDLE, int)

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

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

  HWND hWnd;

  hInst = hInstance; // сохраняет указатель приложения в переменной hInst

  hWnd=CreateWindow("MyClass", // имя класса окна

 "My first program",   // имя приложения

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

CW_USEDEFAULT, // положение по Х

CW_USEDEFAULT,  // положение по Y

CW_USEDEFAULT,    // размер по Х

CW_USEDEFAULT,    // размер по Y

NULL, // описатель родительского окна

NULL,       // описатель меню окна

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

NULL);     // параметры создания.

  if (!hWnd) // Если окно не создалось, функция возвращает FALSE

  {

     return FALSE;

  }

  ShowWindow(hWnd, nCmdShow); // Показать окно

  UpdateWindow(hWnd);   // Обновить окно

  return TRUE;    //Успешное завершение функции

}

//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)

//  Оконная процедура. Принимает и обрабатывает все сообщения, приходящие в приложение

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

{

PAINTSTRUCT ps;

HDC hdc;

RECT rt;

switch (message)

{

 case WM_CREATE: // Сообщение приходит при создании окна

  break;

 case WM_PAINT:  // Перерисовать окно

  hdc = BeginPaint(hWnd, &ps); // Начать графический вывод

  GetClientRect(hWnd, &rt); // Область окна для рисования

  DrawText(hdc, " Первая программа для WINDOWS ", -1, &rt,

DT_SINGLELINE|DT_CENTER | DT_VCENTER);

   EndPaint(hWnd, &ps); // Закончить графический вывод

  break;

 case WM_DESTROY: // Завершение работы

   PostQuitMessage(0);

  break;

 default:

// Обработка сообщений, которые не обработаны пользователем

  return DefWindowProc(hWnd, message, wParam, lParam);

  }

return 0;

}


 

А также другие работы, которые могут Вас заинтересовать

84288. Инфекции. Источники и пути передачи инфекции. Виды пищевых инфекций и характеристика возбудителей. Профилактика пищевых инфекций 39.59 KB
  Источники и пути передачи инфекции. Источники инфекции больной человек или животное а также бактерио бацилло и вируносители люди и животные невосприимчивые к данному заболеванию а также перенесшие это заболевание. Пути передачи инфекции: Прямой контакт от больного человека к здоровому. Пищевые инфекции такие инфекционные заболевания при которых пищевые продукты являются только передатчиками токсигенных микроорганизмов.
84289. Понятие об иммунитете. Виды иммунитета. Вакцины и сыворотки 29.58 KB
  Виды иммунитета. Вакцины и сыворотки Иммунитет невосприимчивость макроорганизма к инфекционным заболеваниям и чужеродным антигенам. Иммунитет может быть инфекционный и неинфекционный.
84290. Пищевые отравления: токсикоинфекции и интоксикации. Характеристика возбудителей пищевых отравлений 62.5 KB
  Пищевые токсикоинфекции – отравления, возникающие при приеме пищи, содержащей большое количество живых токсигенных бактерий. Возбудители токсикоинфекций образуют эндотоксины, прочно связанные с клеткой, которые при жизни микроорганизма в окружающую среду не выделяются
84291. Микробиологический контроль качества пищевых продуктов 36.74 KB
  Важнейшими характеристиками пищевых продуктов является их безопасность и микробиологическая стойкость. Для оценки качества пищевых продуктов пользуются количественными и качественными микробиологическими показателями. Поэтому при санитарной оценке продуктов пользуются косвенными методами позволяющими определить уровень загрязнения продукта выделениями человека уровень фекального загрязнения.
84292. Биосфера и распространение микроорганизмов в природе. Влияние на окружающую среду антропогенных факторов 33.94 KB
  Местообитание. В пределах экосистемы для каждого микроорганизма можно описать его местообитание. В рамках определенной экосистемы микрооганизм имеет как правило только одноединственное местообитание хотя некоторые микроорганизмы могут иметь несколько таких мест каждое в отдельной экосистеме. Иными словами местообитание это адрес данного организма.
84293. Микрофлора почвы. Ее роль в инфицировании пищевых продуктов. Санитарная оценка почвы 33.3 KB
  Санитарная оценка почвы Почва благоприятная среда для обитания и размножения различных микроорганизмов. В состав микробных биоценозов почвы входят бактерии грибы простейшие и бактериофаги. Микроорганизмы почвы участвуют в круговороте веществ в природе минерализации органических отбросов самоочищении почвы.
84294. Микрофлора воздуха. Оценка качества воздуха по микробиологическим показателям. Методы очистки и дезинфекции воздуха 32.84 KB
  Оценка качества воздуха по микробиологическим показателям. Методы очистки и дезинфекции воздуха Воздух является неблагоприятной средой для развития микроорганизмов что обусловлено недостатком питательных веществ и влаги а также бактерицидным действием солнечных лучей. Поэтому количественный и видовой состав микрофлоры воздуха зависит от ряда факторов: климатических метеорологических сезонных общего санитарного состояния местности и др.
84295. Микрофлора воды. Санитарная оценка воды по микробиологическим показателям. Способы очистки и дезинфекции воды 38.11 KB
  Санитарная оценка воды по микробиологическим показателям. Способы очистки и дезинфекции воды Вода является благоприятной средой для развития многих микроорганизмов. В состав микрофлоры воды входят сапрофиты: флуоресцирующие бактерии микрококки реже встречаются бактерии рода Bcillus.
84296. Предмет и задачи микробиологии. Основные свойства микроорганизмов 36.14 KB
  Основные свойства микроорганизмов Микробиология от греч. mikros малый bios жизнь logos учение наука изучающая мир мельчайших живых существ микроорганизмов и процессы вызываемые микроорганизмами. Микробиология изучает морфологию микроорганизмов закономерности их развития и процессы которые они вызывают в среде обитания а также их роль в природе и хозяйственной деятельности человека. К миру микроорганизмов относятся бактерии дрожжи микроскопические плесневые грибы.