Для чего необходимы функции showwindow updatewindow и какие переменные в них указываются
ShowWindow function (winuser.h)
Sets the specified window’s show state.
Syntax
Parameters
A handle to the window.
Controls how the window is to be shown. This parameter is ignored the first time an application calls ShowWindow, if the program that launched the application provides a STARTUPINFO structure. Otherwise, the first time ShowWindow is called, the value should be the value obtained by the WinMain function in its nCmdShow parameter. In subsequent calls, this parameter can be one of the following values.
Value | Meaning |
---|---|
SW_HIDE 0 | Hides the window and activates another window. |
SW_SHOWNORMAL SW_NORMAL 1 | Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time. |
SW_SHOWMINIMIZED 2 | Activates the window and displays it as a minimized window. |
SW_SHOWMAXIMIZED SW_MAXIMIZE 3 | Activates the window and displays it as a maximized window. |
SW_SHOWNOACTIVATE 4 | Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except that the window is not activated. |
SW_SHOW 5 | Activates the window and displays it in its current size and position. |
SW_MINIMIZE 6 | Minimizes the specified window and activates the next top-level window in the Z order. |
SW_SHOWMINNOACTIVE 7 | Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not activated. |
SW_SHOWNA 8 | Displays the window in its current size and position. This value is similar to SW_SHOW, except that the window is not activated. |
SW_RESTORE 9 | Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window. |
SW_SHOWDEFAULT 10 | Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application. |
SW_FORCEMINIMIZE 11 | Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when minimizing windows from a different thread. |
Return value
If the window was previously visible, the return value is nonzero.
If the window was previously hidden, the return value is zero.
Remarks
To perform certain special effects when showing or hiding a window, use AnimateWindow.
The first time an application calls ShowWindow, it should use the WinMain function’s nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the given list, instead of the one specified by the WinMain function’s nCmdShow parameter.
As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in the first call to ShowWindow if the program that launched the application specifies startup information in the structure. In this case, ShowWindow uses the information specified in the STARTUPINFO structure to show the window. On subsequent calls, the application must call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup information provided by the program that launched the application. This behavior is designed for the following situations:
Для перерисовки рабочей области затем необходимо сделать вызов функции
Ректор университета
__________А.В. Лагерев
“__”________ 2005 г.
ПРОГРАММИРОВАНИЕ ПОД WINDOWS
ОКОННОЕ ПРИЛОЖЕНИЕ
С ИСПОЛЬЗОВАНИЕМ WinAPI 32
Методические указания к выполнению
Лабораторной работы № 1
для студентов дневной формы обучения
специальности 230105 «Программное обеспечение ВТ и АС»
Брянск 2005
Рекомендовано кафедрой «Информатика и программное обеспечение» БГТУ (протокол №4 от 06.12.04)
ЦЕЛЬ РАБОТЫ
Изучить простейшее оконное приложения Windows, разработанное с использованием WinAPI 32. В результате выполнения работы студент должен знать структуру приложения, конструкции и функции составляющие простейшее оконное приложение, представлять процессы, лежащие в основе его работы.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Точка входа в программу
При запуске приложения в Windows операционная система вызывает в программе функцию WinMain. В любом приложении обязательно должна присутствовать эта функция, на которую возлагается ряд специфических задач. И самая важная из них – создание основного окна программы, с которым должен быть связан код, способный обрабатывать сообщения, передаваемые операционной системой этому окну.
Существенное различие между консольной и Windows-программами в том, что первая для получения данных, введенных пользователем, вызывает операционную систему, а вторая делает это через сообщения, передаваемые программе операционной системой.
Точкой входа программы для Windows является функция WinMain, которая всегда определяется следующим образом:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
Эта функция использует последовательность вызовов WINAPI (паскалевское соглашение о передаче аргументов при вызове функций) и по завершению, возвращает операционной системе Windows целое число.
Параметры функции WinMain:
Действия, обычно выполняемые функцией WinMain:
Если найдена работающая копия приложения, то работа новой копии прекращается.
§ сохранение дескриптора экземпляра приложения в глобальной переменной;
§ регистрация класса окна приложения и другие инициализации;
§ создание главного окна приложения и, возможно, других, подчиненных окон;
§ отображение созданного окна и отрисовка содержимого его внутренней части;
§ запуск цикла обработки сообщений, помещаемых в очередь приложения;
§ завершение работы приложения при извлечении из очереди сообщения WM_QUIT.
Поиск работающей копии приложения
Для проверки того, было ли приложение запущено ранее, можно воспользоваться функцией FindWindow, которая позволяет найти окно верхнего уровня по имени класса или по заголовку окна:
HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);
Через параметр lpClassName передается указатель на текстовую строку, в которую необходимо записать имя класса искомого окна. На базе одного и того же класса может быть создано несколько окон. Если необходимо найти окно с заданным заголовком, то имя заголовка следует передать через параметр lpWindowName. Если же подойдет любое окно, то параметр lpWindowName может иметь значение NULL.
Фрагмент кода функции WinMain, проверяющий, было ли ранее приложение запущено,и при положительном ответе выдвигающий на передний план главное окно ранее запущенной копии:
HWND hWndOld=FindWindow(ClassName, NULL);
// к инициализации приложения и запуску цикла обработки сообщений
Если необходимо, чтобы каждая копия приложения работала как отдельный процесс, то приведенный фрагмент кода следует не включать в функцию WinMain.
Регистрация класса окна
Как уже говорилось, самая важная задача функции WinMain – создание основного окна программы, с которым должен быть связан код, способный обрабатывать сообщения, передаваемые операционной системой этому окну.
Обычно приложение создает окно за два шага. Сначала с помощью функцииRegisterClassрегистрируется класс окна, а затем создается само окно зарегистрированного класса с помощью функции CreateWindow.
Класс окна определяет общее поведение нового типа окон, включая адрес новой оконной процедуры. Такие второстепенные аспекты как размер, расположение и внешний вид окна определяются при его создании.
Новый класс окна регистрируется при вызове приложением следующей функции:
ATOM RegisterClass(const WNDCLASS *lpwc);
Единственный параметр этой функции lpwc указывает на структуру типа WNDCLASS, описывающую тип нового окна. Возвращаемое значение является атомом Windows – 16-разрядным значением, идентифицирующим уникальную символьную строку в таблице Windows.
Фрагмент кода функции WinMain, в котором заполняются поля структуры, описывающей класс окна, регистрируется класса окна:
// Сохраняем дескриптор экземпляра приложения в
// глобальной переменной hInst типа HINSTANCE, чтобы
// при необходимости воспользоваться им в функции окна.
// Заполнение структуры WNDCLASS для регистрации класса окна.
memset(&wc, 0, sizeof(wc)); // Очистка полей структуры
// Адрес оконной функции
wc.hInstance=hInst; // Экземпляр приложения
// Пиктограмма для окон
// Курсор мыши для окон
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); // Кисть для окон
wc.lpszMenuName=NULL; // Ресурс меню окон
wc.cbClsExtra=0; // Дополнительная память
wc.cbWndExtra=0; // Дополнительная память
// Pегистрация класса окна
Поля структуры WNDCLASS
Название нового регистрируемого класса окон задается при помощи параметра-строки lpszClassName.
Наиболее важными параметрами структуры WNDCLASS являются style и lpfnWndProc. Основная часть того, что представляетокно как уникальную и сложную сущность, управляется через стиль класса окна и оконную процедуру.
Параметр lpfnWndProc указывает адрес функции оконной процедуры. Эта функция отвечает за обработку всех сообщений, получаемых окном. Она может обрабатывать эти сообщения сама или вызывать оконную процедуру по умолчанию DefWindowProc.
Сообщения могут быть разнообразными: изменение размера и перемещение окна, события от мыши, клавиатуры, команды меню, запросы на перерисовку, события от таймера и другого аппаратного обеспечения и т.д.
Некоторые глобальные характеристики окна управляются через параметр стиля окна – style. Для этого параметра можно установить комбинацию значений, используя операцию поразрядного ИЛИ. Например, значение CS_DBLCLKS указывает Windows генерировать события о двойном щелчке кнопкой мыши. Значения CS_HREDRAW и CS_VREDRAW указывают, что окно должно перерисовываться полностью каждый раз при изменении горизонтального или вертикального размера.
Менее важные для функционирования окна поля структуры WNDCLASS:
Регистрация нового класса является первым шагом в создании окна. Затем приложение должно создать само окно с помощью функции CreateWindow, которая возвращает дескриптор созданного окна типа HWND:
HWND CreateWindow(LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID *lpParam);
У каждого окна в Windows имеется уникальный дескриптор типа HWND. Дескриптор окна – это один из важнейших описателей, которыми оперирует программа для Windows. Для многих функций Windows требуется дескриптор окна, благодаря которому Windows знает, к какому окну применить функцию.
Фрагмент кода функции WinMain, в котором создается окно зарегистрированного ранее класса с именем «MyWindowClassName»:
// Создаем главное окно приложения.
«MyWindowClassName», // Имя класса окон
«MyWindowTitle», // Заголовок окна
WS_OVERLAPPEDWINDOW, // Стиль окна
// Ширина и высота окна
NULL, // Дескриптор окна-родителя
NULL, // Дескриптор меню окна
hInst, // Дескриптор экземпляра приложения
NULL); // Дополнительная информация
// Окно не создано, выдаем предупреждение.
Параметры функции CreateWindow
Первый параметр lpClassName указывает имя класса, поведение которого наследует данное окно. Этот класс должен быть зарегистрирован с помощью фунцкии RegisterClass или быть одним из предопределенных классов элементов управления. Эти переопределенные классы включают в себя стандартные классы элементов управления с именами “button”, “combobox”, “listbox”, “edit”, “scrollbar” и “static”.
Параметр lpWindowName определяет строку, которая выводится в заголовке создаваемого окна.
Параметр dwStyle определяет стиль окна. Не следует путать стиль окна со стилем класса, передаваемым в RegisterClass через структуру WNDCLASS.
Хотя стиль класса определяет некоторые постоянные свойства окон, принадлежащих классу, стиль окна, передаваемый CreateWindow, используется для инициализации локальных свойств окна.
Как и в случае стиля класса, стиль окна также обычно является комбинацией значений (объединенных операцией поразрядного ИЛИ).
Для определения стиля главного окна чаще всего используют стиль перекрывающегося окна, для чего через параметр dwStyle передают символическую константу WS_OVERLAPPEDWINDOW, определенную во включаемых файлах следующим образом:
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED| \
После указания типа окна нужно задать начальные геометрические размеры окна. Если при задании параметров x, y, nWidth и nHeight использовать константу CW_USEDEFAULT, то Windows установит расположение и размеры окна самостоятельно.
При создании окна указываются также дескрипторы его окна-родителя и меню. Если окно является главным окном приложения, то параметру hWndParent присваивается значение NULL. Значение NULL на месте дескриптора меню hMenu говорит о том, что у окна будет только меню класса, общее для всех окон этого класса.
При создании окна необходимо указать, какой экземпляр приложения, которое создает окно, что и делается при помощи параметра hInstance.
Последний параметр lpParam используется для передачи окну дополнительных данных (если их нет, то он должен быть равен NULL). При необходимости этот параметр используется в качестве указателя на какие-нибудь данные, на которые программа в дальнейшем могла бы ссылаться.
Хотя функция CreateWindow и создает окно, это не значит, что оно будет автоматически отображаться на экране дисплея. Для отображения окна следует воспользоваться функцией ShowWindow. Первым параметром в эту функцию передается дескриптор окна, вторым параметром обычно (для главного окна приложения) является величина, передаваемая в качестве параметра функции WinMain, она задает начальный вид окна на экране.
BOOL ShowWindow(HWND hwnd, int nCmdShow);
Функция ShowWindow выводит окно на экран. Если второй параметр этой функции имеет значение SW_SHOWNORMAL, то фон рабочей области окна закрашивается той кистью, которая задана в классе окна.
Для перерисовки рабочей области затем необходимо сделать вызов функции
void UpdateWindow(HWND hwnd);
Функция UpdateWindow передает функции окна сообщение WM_PAINT. Получив это сообщение, функция обновляет содержимое экрана.
Фрагмент кода функцииWinMain,в котором отображается созданное окно и рисуется содержимое его внутренней части:
ShowWindow(hWnd, nCmdShow); // Отображаем окно.
// Обновляем его содержимое клиентской области окна
Функции отображения и обновления вызываются, как правило, после создания окна, но, порядок и место вызова функций ShowWindow и UpdateWindow не является обязательным. Окно может быть отображено не в момент создания, а позже, по желанию программиста.
Итак, для отображения окна в типичном приложении необходимо:
— зарегистрировать класс окна функцией RegisterClass;
— создать окно функцией CreateWindow;
— отобразить окно функцией ShowWindow;
— обновить рабочую (клиентскую) область окна функцией UpdateWindow.
Цикл обработки очереди сообщений
После создания и отображения окна функция WinMain должна подготовить приложение к получению информации от пользователя через клавиатуру и мышь.
Windows поддерживает очередь сообщений (message queue) для каждой программы, работающей в данный момент в системе. Когда происходит ввод информации, Windows преобразовывает ее в сообщение, которое помещается в очередь сообщений приложения.
Программа извлекает сообщения из очереди сообщений, выполняя блок команд, известный как цикл обработки сообщений (message loop). Простейший цикл обработки сообщений имеет следующий вид:
while( GetMessage(&msg, NULL, 0, 0))
//преобразование клавиатурных сообщениий в символьные
// отправка сообщения окну-адресату приложения
Для чего необходимы функции showwindow updatewindow и какие переменные в них указываются
Теперь вы умеете выводить в окно текст, и хотя пока вы пользовались только одним шрифтом, окна наших приложений не останутся пустыми. В этой главе вы познакомитесь с различными типами окон, которые может создать приложение Windows. Обычно ни одно приложение не ограничивается созданием главного окна приложения. Как правило, внутри главного окна создаются другие окна.
Напомним, что для создания окна вам необходимо зарегистрировать класс окна. Есть классы окон, зарегистрированные при инициализации Windows. Ваше приложение может создавать окна либо на базе собственных классов (созданных и зарегистрированных приложением), либо на базе готовых классов, созданных и зарегистрированных самой операционной системой Windows. В этой главе мы расскажем вам только об окнах, созданных приложениями на базе своих собственных классов окон.
Стиль класса окна определяется при регистрации класса окна. Во всех предыдущих примерах приложений мы не задавали стиль окна, определяя содержимое соответствующего поля в структуре WNDCLASS следующим образом:
Стиль класса окна задается в виде отдельных битов, для которых в файле windows.h определены символические константы с префиксом CS_:
Чаще всего используются стили CS_HREDRAW и CS_VREDRAW:
Если для класса заданы стили CS_HREDRAW и CS_VREDRAW, при изменении размеров окна функция окна может получить сообщение WM_PAINT. В этом случае функция окна должна перерисовать часть окна или все окно. Разумеется, если вы просто уменьшили размер окна, перерисовывать ничего не надо, и функция окна в этом случае не получит сообщения WM_PAINT.
Стиль CS_DBLCLKS используется при необходимости отслеживать двойные щелчки мышью. При этом в функцию окна посылаются сообщения WM_LBUTTONDBLCLK и WM_RBUTTONDBLCLK. Если этот стиль не будет задан, как бы быстро вы ни щелкали мышью, функция окна получит только идущие парами сообщения о том, что вы нажимаете и отпускаете левую или правую клавишу мыши.
Остальные приведенные выше классы окна используются реже. Мы будем рассказывать о них по мере необходимости.
Для определения стиля окна используются символические константы с префиксом WS_, определенные в файле windows.h. С помощью этих констант можно определить примерно два десятка стилей окна, однако чаще всего используются несколько основных стилей.
Перекрывающиеся (overlapped) окна
Перекрывающиеся окна обычно используются в качестве главного окна приложения. Такие окна имеют заголовок (title bar), рамку и, разумеется, внутреннюю часть окна (client region). Дополнительно перекрывающиеся окна могут иметь (а могут и не иметь) системное меню, кнопки для максимального увеличения размера окна и для сворачивания окна в пиктограмму, вертикальную и горизонтальную полосу просмотра (scroll bar) и меню.
Файл windows.h содержит следующее определение стиля перекрывающегося окна:
В нашем приложении для определения стиля перекрывающегося окна мы использовали символическую константу WS_OVERLAPPEDWINDOW, определенную как логическое ИЛИ нескольких констант:
Вы можете попробовать в предыдущем примере изменить стиль окна, создав свой собственный с использованием приведенных выше констант.
Приложение Windows может создавать несколько окон, связанных между собой «узами родства» и «отношениями собственности». В частности, при создании перекрывающегося окна при помощи функции CreateWindow в качестве восьмого параметра функции вы можете указать так называемый идентификатор окна-владельца. Окно-владелец уже должно существовать на момент создания второго окна, имеющего владельца.
Таким образом, если вы создаете несколько перекрывающихся окон, одни окна могут принадлежать другим.
Если окно-хозяин сворачивается в пиктограмму, все окна, которыми оно владеет, становятся невидимыми. Если вы сначала свернули в пиктограмму окно, которым владеет другое окно, а затем и окно-хозяин, пиктограмма первого (подчиненного) окна исчезает.
Если вы уничтожили окно, автоматически уничтожаются и все принадлежащие ему окна.
Обычное перекрывающееся окно, не имеющее окна-владельца, может располагаться в любом месте экрана и принимать любые размеры. Подчиненные окна располагаются всегда над поверхностью окна-владельца, загораживая его.
Координаты создаваемых функцией CreateWindow перекрывающихся окон указываются по отношению ко всему экрану. Таким образом, если вы создаете перекрывающееся окно с координатами (0, 0), оно будет расположено в верхнем левом углу экрана.
Временные (pop-up) окна
Другим базовым стилем является стиль временных окон, которые обычно используются для вывода информационных сообщений и остаются на экране непродолжительное время.
Временные окна имеют стиль WS_POPUP, определенный в файле windows.h следующим образом:
Временные окна, в отличие от перекрывающихся, могут не иметь заголовок (title bar). Если для временного окна определен заголовок, оно может иметь и системное меню. Часто для создания временных окон, имеющих рамку, используется стиль WS_POPUPWINDOW, определенный в файле windows.h следующим образом:
Если надо добавить к временному окну системное меню и заголовок, стиль WS_POPUPWINDOW следует использовать в комбинации со стилем WS_CAPTION, добавляющим заголовок.
Временные окна могут иметь окно владельца и могут сами владеть другими окнами. Все замечания, сделанные нами относительно владения перекрывающимися окнами, справедливы и для временных окон.
Начало системы координат, используемой при создании временных окон, находится в левом верхнем углу экрана. Поэтому при создании временных окон используются экранные координаты (так же, как и при создании перекрывающихся окон).
При изменении размеров временного окна (так же, как и дочернего) функция окна получает сообщение WM_PAINT, в параметрах которого указаны новые размеры окна.
В общем случае вы можете рассматривать временные окна как специальный вид перекрывающихся окон.
Дочерние окна
Базовый стиль дочерних окон определяется при помощи константы WS_CHILD:
По аналогии с другими базовыми стилями в файле windows.h определена константа WS_CHILDWINDOW, которая полностью эквивалентна константе WS_CHLD:
В отличие от перекрывающихся и временных окон дочерние окна, как правило, не имеют рамки, заголовка, кнопок минимизации и максимального увеличения размера окна, а также полос просмотра. Дочерние окна сами рисуют все, что в них должно быть изображено.
Перечислим особенности дочерних окон.
Само собой разумеется, что дочерние окна должны иметь окно-родителя (окон-сирот не бывает!). Только дочерние окна могут иметь родителей, перекрывающие и временные окна могут иметь окно-хозяина, но не родителя. У дочерних окон могут быть «братья» (или «сестры», кому что больше нравится).
Дочерние окна всегда располагаются на поверхности окна-родителя. При создании дочернего окна начало системы координат расположено в левом верхнем углу внутренней поверхности окна-родителя (но не в верхнем углу экрана, как это было для перекрывающихся и временных окон).
Так как дочерние окна перекрывают окно-родителя, если вы сделаете щелчок мышью над поверхностью дочернего окна, сообщение от мыши попадет в функцию дочернего, но не родительского окна.
При создании дочернего окна в качестве девятого параметра (вместо идентификатора меню, которого не может быть у дочернего окна) функции CreateWindow необходимо указать созданный вами идентификатор дочернего окна. Таким образом, если для какого-либо окна приложения вы создаете несколько дочерних окон, необходимо для каждого окна указать свой идентификатор (типа int). Этот идентификатор будет использован дочерним окном при отправлении сообщений родительскому окну, поэтому вы должны при создании разных дочерних окон использовать разные идентификаторы, хотя это и не обязательно.
Дочернее окно как бы «прилипает» к поверхности родительского окна и перемещается вместе с ним. Оно никогда не может выйти за пределы родительского окна. Все дочерние окна скрываются при сворачивании окна-родителя в пиктограмму и появляются вновь при восстановлении родительского окна.
При изменении размеров родительского окна дочерние окна, на которых отразилось такое изменение (которые вышли за границу окна и появились вновь), получают сообщение WM_PAINT. При изменении размеров родительского окна дочерние окна не получают сообщение WM_SIZE. Это сообщение попадает только в родительское окно.
Список стилей окна
Приведем полный список возможных стилей окна, определенных в виде символических констант в файле windows.h. Некоторые из приведенных здесь стилей будут подробно рассмотрены в соответствующих главах этого тома или в следующих томах «Библиотеки системного программиста».
Приведенные выше стили не всегда совместимы друг с другом. Например, перекрывающееся окно не может быть одновременно еще и временным. Пользуясь приведенной ниже таблицей, вы сможете определить совместимость стилей. В этой таблице символом «+» отмечены стили, которые можно использовать для создания перекрывающихся, временных и дочерних окон.
Имя константы | Перекрывающееся окно | Временное окно | Дочернее окно |
WS_BORDER | + | + | + |
WS_CAPTION | + | + | + |
WS_CHILD | + | ||
WS_CHILDWINDOW | + | ||
WS_CLIPCHILDREN | + | + | + |
WS_CLIPSIBLINGS | + | ||
WS_DISABLED | + | + | + |
WS_DLGFRAME | + | + | + |
WS_GROUP | + | ||
WS_HSCROLL | + | + | + |
WS_ICONIC | + | ||
WS_MAXIMIZE | + | ||
WS_MAXIMIZEBOX | + | + | + |
WS_MINIMIZE | + | ||
WS_MINIMIZEBOX | + | + | + |
WS_OVERLAPPED | + | ||
WS_OVERLAPPEDWINDOW | + | ||
WS_POPUP | + | ||
WS_POPUPWINDOW | + | ||
WS_SYSMENU | + | + | + |
WS_TABSTOP | + | ||
WS_THICKFRAME | + | + | + |
WS_VISIBLE | + | + | |
WS_VSCROLL | + | + | + |
WS_TILED | + | ||
WS_SIZEBOX | + | + | + |
WS_TILEDWINDOW | + | ||
MDIS_ALLCHILDSTYLES |
В дополнение к перечисленным выше стилям, используемым при создании окон функцией CreateWindow, существуют так называемые расширенные стили окна (extended window styles). Окна с расширенными стилями должны создаваться функцией CreateWindowEx. Эта функция имеет следующий прототип:
Функции CreateWindowEx в качестве первого параметра (dwExStyle) необходимо указать расширенный стиль окна. Остальные параметры в точности соответствуют параметрам функции CreateWindow.
Приведем список расширенных стилей окна.
Имя константы | Описание стиля |
WS_EX_ACCEPTFILES | Окно способно принимать файлы, перенесенные с использованием технологии drag-drop |
WS_EX_DLGMODALFRAME | Окно имеет двойную рамку и дополнительно может иметь стиль WS_CAPTION |
WS_EX_NOPARENTNOTIFY | Дочернее окно с этим стилем не будет посылать родительскому окну сообщение WM_PARENTNOTIFY. Обычно, когда дочернее окно создается или уничтожается или когда вы щелкаете мышью над дочерним окном, это сообщение посылается родительскому окну |
WS_EX_TOPMOST | Окно будет видно всегда, даже когда оно заблокировано |
WS_EX_TRANSPARENT | Этот стиль позволяет создать прозрачное окно. Оно получает сообщение WM_PAINT только после того, как все окна-братья получили сообщение WM_PAINT и обновили свои окна |
Приведем таблицу совместимости расширенных стилей с перекрывающимися, временными и дочерними окнами.
Имя константы | Перекрывающееся окно | Временное окно | Дочернее окно |
WS_EX_ACCEPTFILES | + | + | + |
WS_EX_DLGMODALFRAME | + | + | + |
WS_EX_NOPARENTNOTIFY | + | ||
WS_EX_TOPMOST | + | + | |
WS_EX_TRANSPARENT | + | + | + |
Для того чтобы вы смогли проводить эксперименты со стилями окон и классов, мы подготовили приложение WSTYLE (листинг 3.1). В этом приложении создается одно главное окно, одно перекрывающееся (этим окном владеет главное), одно временное (также принадлежащее главному окну) и одно дочернее окно.
Листинг 3.1. Файл wstyle\wstyle.cpp
Приложение регистрирует три класса окна со следующими именами:
Первый класс с именем, записанным в массиве szMainClassName, используется для создания главного окна приложения и одного дополнительного перекрывающегося окна.
Для каждого окна определен свой заголовок:
Так как приложение создает четыре различных окна, в функции WinMain определены четыре переменные, предназначенные для хранения идентификаторов окон. Эти переменные имеют имена MainHwnd, ChildHwnd, PopUpHwnd и OwnedHwnd.
Переменная MainHwnd используется для хранения идентификатора главного окна приложения. Переменные ChildHwnd и PopUpHwnd предназначены соответственно для хранения идентификаторов дочернего и временного окна. В переменной OwnedHwnd хранится идентификатор дополнительного перекрывающегося окна, принадлежащего главному окну приложения.
Выполнение приложения начинается с регистрации классов окон, выполняемых функцией Register, определенной в приложении.
Регистрация класса для главного окна приложения не имеет никаких особенностей по сравнению с аналогичной операцией, выполняемой нашими предыдущими приложениями:
При регистрации класса для дочернего окна для упрощения программы используется проинициализированная ранее структура wc. В этой структуре необходимо заменить указатель на функцию окна (дочернее окно работает с функцией ChildWndProc) и имя класса (поле lpszClassName). Дополнительно для дочернего окна мы изменили форму курсора мыши и цвет фона:
Когда вы поместите курсор мыши в дочернее окно, он будет иметь форму четырех стрелок, указывающих в разные стороны. Фон окна будет закрашен в серый цвет.
При регистрации класса временного окна мы указываем адрес функции окна с именем PopUpWndproc, определяем форму курсора в виде перекрестия, используем системный цвет для фона, а также указываем другое имя класса:
В случае успешной регистрации всех классов функция Register возвращает значение TRUE.
После регистрации классов окна в функции WinMain создаются четыре окна.
Первым создается главное окно приложения:
Главное окно приложения представляет собой обычное перекрывающееся окно класса WS_OVERLAPPEDWINDOW. Так как главное окно не может никому принадлежать, для параметра функции CreateWindow, определяющего идентификатор родительского окна или окна-владельца, используется нулевое значение.
Для того чтобы сделать окно видимым и нарисовать его внутреннюю область, вызываются функции ShowWindow и UpdateWindow.
После главного окна создается перекрывающееся окно. Это окно создается на базе того же класса, что и главное окно приложения, поэтому оно, как и главное окно приложения, работает с функцией окна MainWndProc.
Для перекрывающегося окна мы определяем свой заголовок, стиль WS_OVERLAPPEDWINDOW, явно указываем координаты левого верхнего угла окна (20, 200), размеры окна (300, 100), а также (вместо идентификатора родительского окна) идентификатор окна-владельца:
Для того чтобы сделать перекрывающееся окно видимым и нарисовать его внутреннюю область, вызываются функции ShowWindow и UpdateWindow. В качестве параметра им передается идентификатор перекрывающегося окна OwnedHwnd.
Расположение и размеры окна задаются для простоты абсолютными значениями, что не всегда удобно. Через некоторое время вы познакомитесь с функциями программного интерфейса Windows, позволяющими узнать различные метрические характеристики, такие, как размер окна, размер системного шрифта, размеры пиктограммы и т. д. Используя эти функции вы можете определять размеры и расположение окон, исходя из размеров экрана или главного окна приложения.
Далее приложение создает дочернее окно:
В качестве стиля окна используется константа WS_CHILDWINDOW, к которой добавлены константы WS_CAPTION и WS_VISIBLE. Константа WS_CAPTION добавляет к дочернему окну заголовок, благодаря чему окно можно перемещать по поверхности экрана. Если указана константа WS_VISIBLE, окно создается сразу видимым, поэтому у нас нет необходимости для отображения дочернего окна вызывать функцию ShowWindow.
Для дочернего окна указан идентификатор родительского окна, в качестве которого выступает главное окно приложения.
Временное окно создается аналогично дочернему:
Для стиля временного окна используется комбинация констант WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE. При этом создается временное окно, которое имеет строку заголовка и становится видимым сразу после его создания функцией CreateWindow.
После создания всех окон запускается цикл обработки сообщений.
Окна приложения WSTYLE показаны на рис. 3.1.
Рис. 3.1. Окна приложения WSTYLE
Теперь займемся функциями окна, определенными в приложении.
Функция MainWndProc обрабатывает сообщения WM_PAINT, WM_LBUTTONDOWN и WM_DESTROY.
По сообщению WM_PAINT в окно выводится строка «WM_PAINT». Если в функцию окна приходит сообщение WM_LBUTTONDOWN, в окно выводится строка «WM_LBUTTONDOWN». Заметьте, что строка «WM_LBUTTONDOWN» выводится в то окно, в котором вы нажали на левую клавишу мыши. Если в функцию окна приходит сообщение WM_DESTROY, вызывается функция PostQuitMessage и приложение завершает свою работу.
Функция окна ChildWndProc используется для обработки сообщений, поступающих в дочернее окно. Эта функция также обрабатывает сообщения WM_PAINT и WM_LBUTTONDOWN, выводя соответствующие строки в дочернее окно. Дополнительно функция дочернего окна обрабатывает сообщение WM_RBUTTONDOWN. Если приходит это сообщение, вызывается функция MessageBeep, которая выдает звуковой сигнал.
Функция временного окна PopUpWndProc аналогична функции ChildWndProc, но не обрабатывает сообщение WM_RBUTTONDOWN.
Таким образом, два окна приложения (главное и перекрывающееся) используют одну общую функцию окна MainWndProc. Дочернее окно и временное окно используют свои собственные функции окна.
Несмотря на то что главное окно приложения и созданное дополнительно перекрывающееся окно используют общую функцию окна, когда вы нажимаете в том или другом окне на левую клавишу мыши, строка «WM_LBUTTONDOWN» выводится именно в том окне, где была нажата клавиша. Так и должно быть, ведь в функцию окна передается идентификатор окна, который используется для вывода текста. Главное и перекрывающееся окна используют разные идентификаторы, поэтому общая для этих окон функция окна выводит текст в нужное окно.
Файл определения модуля, использованный приложением WSTYLE, приведен в листинге 3.2.