68893

Дочерние окна. Общие сведения

Лекция

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

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

Русский

2014-09-26

68 KB

0 чел.

Лекция 6

Дочерние окна

 Общие сведения

До сих пор, мы создавали приложение с одним окном, в которое выводили текст, графику, рисунки. Все сообщения приложению, фактически, обрабатывались оконной процедурой этого самого единственного окна. Предположим, что на окно положили какой-либо объект, обладающий совокупностью функций и особенностей отображения внутри вашего окна. Этот объект, конечно же, может формировать ваша программа (рисовать объект при помощи сообщения WM_PAINT, проверять, ни попал ли курсор мыши на объект при обработке WM_LBUTTONDOWN и т.п.). Однако, согласно объектно-ориентированному подходу к программированию, более красивый и удобный путь – выделить характеристики и функции поведения этого объекта в некоторую логическую структуру, которая сама будет обрабатывать предназначенные ей сообщения, будет сама себя рисовать и т.п. Существует возможность создания таких объектов, а также имеется некоторое число предопределенных в Windows объектов. Они получили название "Дочерние окна управления".

Такое название они получили потому, что неразрывно связаны с теми окнами, на которых они находятся и их поведение во многом определяется поведением главного или родительского окна. Каждый из вас видел дочерние окна: это кнопки (buttons), флажки (check boxes), окна редактирования (edit boxes), списки (list boxes), комбинированные списки (combo boxes), строки текста (text strings) и полосы прокрутки (scroll bars). Все перечисленные окна управления зарегистрированы в Windows (поэтому для них нет необходимости в выполнении функции RegisterClass) и для их создания достаточно выполнить функцию CreateWindow, указав одно из следующих имен: "button" – для кнопки, "static" – для текста, "scrollbar" –для полосы прокрутки, "edit" – для окна редактирования, "listbox" – для окна списка, "combobox" –для окна комбинированного списка.

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

Класс кнопок

Всем кнопкам, которые пользователь видит на экране, соответствует один предопределенный класс окна "button". Windows поддерживает  10 стандартных стилией кнопок. Любую из них можно создать при помощи вызова функции CreateWindow с определением следующих параметров:

Имя класса   "button"

Текст окна  " Моя кнопка"

Стиль окна   WS_CHILD|WS_VISIBLE|BS_<style>

Положение по х  50

Положение по х  50

Ширина   60

Высота  30

Родительское окно   hwnd

Идентификатор дочернего окна (HMENU) i

Описатель программы hInstance

Дополнительный параметр NULL

Третий параметр функции указывает на создание дочернего видимого окна, а также определяет стиль кнопки: нажимаемая кнопка (BS_PUSHBUTTON или BS_DEFPUSHBUTTON), флажки (check boxes – BS_CHECKBOX, BS_AUTOCHECKBOX), переключатели (radio buttons – BS_RADIOBUTTON, BS_AUTORADIOBUTTON), групповое окно (group boxes – BS_GROUPBOX), флажки на три состояния (BS_3STATE, BS_AUTO3STATE), кнопки, определяемые пользователем (BS_OWERDRAW).

Обратите внимание на 9 параметр, который является идентификатором (номером, "именем") кнопки. С помощью его родительское и дочернее окна могут опознавать друг друга. Следует отметить, что данный параметр определен в Windows как параметр типа HMENU, в следствии чего перед переменной стоит директива преобразования типов.

Все кнопки, когда вы щелкаете на их поверхности, посылают родительскому окну сообщение WM_COMMAND, указывая в параметре lParam описатель дочернего окна (возвращаемый также функцией CreateWindow при создании кнопок), в LOWORD(wParam) – идентификатор дочернего окна, о котором говорилось ранее,  в HIWORD (wParam) – код уведомления.

Кратко остановимся на особенностях некоторых кнопок.

Нажимаемая кнопка является самой широко используемой. Она представляет собой прямоугольник, внутри которого задан текст. При нажатии на кнопку (клик мыши на поверхности кнопки), она перерисовывается в виде нажатого состояния, а при отпускании мыши – переходит в первоначальное состояние. При отпускании мыши кнопка посылает родительскому окну сообщение WM_COMMAND с кодом уведомления BN_CLICKED. Вы можете имитировать нажатие кнопки, посылая окну сообщение WM_SETSTATE. Так, строка программы:

SendMessage(hwndButton, BM_SETSTATE,1,0);

приводит к нажатию кнопки, а строка

SendMessage(hwndButton, BM_SETSTATE,0,0);

возвращает кнопку к своему нормальному состоянию.

Флажки

Флажки представляют собой маленькие квадратные окна с текстом; текст обычно размещается справа от флажка. Флажки, как правило, действуют как двухпозиционные переключатели: один щелчок вызывает появление контрольной метки (птички); другой щелчок приводит к исчезновению контрольной метки. Часть флажки объединяют в группы, чтобы сконцентрироваться на опциях какого-то одного объекта. В последнем случае состояния одних из кнопок могут зависеть от состояний других. При использовании стиля BS_CHECKBOX программа должна сама устанавливать и снимать контрольную метку, посылая окну кнопки сообщение BM_SETCHECK и 1 или 0 в параметре wParam. В случае стиля BS_AUTOCHECKBOX флажок сам включает и выключает себя. Оба окна посылают традиционное для кнопок сообщение WM_COMMAND родительскому окну при щелчке  мыши на поверхности кнопки.

Можно также получить текущее состояние флажка послав в кнопку сообщение BM_GETCHECK:

int Result = (int) SendMessage(hwndButton, BM_GETCHACK, 0, 0);

Существует еще два типа флажков на три состояния - BS_3STATE, BS_AUTO3STATE. Их поведение аналогично описанным флажкам, но они могут иметь третье состояние – квадрат метки закрашивается серым цветом и к возможным состояниям 0 и 1 добавляется состояние 2.

Переключатели

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

Кнопки, определяемые пользователем.

Данный стиль кнопки применяется тогда, когда есть необходимость (или желание) управлять внешним обликом кнопки, а логику обработки клавиатуры и мыши можно оставить самой кнопке. Сообщения родительскому окну такие же, как и у всех кнопок, однако, при необходимости перерисовки кнопки, она посылает родительскому  окну сообщение WM_DRAWITEM c указателем на структуру типа DRAWITEMSTRUCT, используемую при рисовании кнопки, в параметре lParam.

Класс статических дочерних окон

Статическое окно имеет предопределенный класс с именем "static". Данное окно не получает сообщений от мыши и клавиатуры: оно как бы прозрачно для сообщений и сообщения, адресованные статическому окну переправляются родительскому окну (расположенному под ним). Существует 12 стилей статического окна.

Три из них – (SS_LEFT, SS_RIGHT, SS_CENTER) позволяют выводить текст, заданный в поле текста окна соответственно с выравниванием влево, вправо, по центру. Фактически, окно выводит заданный текст с помощью функции DrawText. Текст окна может быть изменен при помощи функции SetWindowText.

Существует девять стилей, позволяющих рисовать прямоугольники и рамки – SS_BLACKRECT, SS_GRAYRECT, SS_WHITERECT – рисуют закрашенные прямоугольники, SS_BLACKFRAME, SS_GRAYFRAME, SS_WHITEFRAME –прямоугольные рамки без закрашивания, SS_ETCHEDHORZ, SS_ETCHEDVERT, SS_ETCHEDFRAME – рамки с тенью, состоящей из серого и белого цветов). Текст во всех этих случаях игнорируется.

Существуют еще два стиля статических окон: SS_ICON – стиль, позволяющий отображать в окне иконку и SS_USERITEM – для создания пунктов, выбираемых пользователем (например, пунктов меню) .

Класс полос прокрутки

Полосы прокрутки или полосы скроллинга могут быть автоматически добавлены к окну, если вы укажете в стиле окна идентификаторы горизонтальной WS_VSCROLL и вертикальной WS_HSCROLL полос прокрутки. Однако вы в любой момент можете создать свое дочернее окно прокрутки, используя предопределенный класс окна "scrollbar" и один из двух стилей для полос прокрутки: SBS_VERTS  для вертикальной и SBS_HORZ – для горизонтальной полос прокрутки. Пользователь сам определяет положение полосы скроллинга внутри родительского окна и его размеры через соответствующие параметры функции CreateWindow при создании или MoveWindow при дальнейшей работе.

Вы можете установить диапазон и положение полосы прокрутки при помощи функций:

SetScrollRange(hwndScroll, SB_CTL, iMin, iMax, bRedraw);

SetScrollPos(hwndScroll, SB_CTL, iPos, bRedraw);

где параметры iMin и iMax устанавливают соответственно минимальное (при котором отметка полосы прокрутки устанавливаются либо в крайнее верхнее для вертикальной полосы прокрутки, либо в крайнее левое положение – для горизонтальной) и максимальное значение, bRedraw устанавливается в TRUE если необходима перерисовка полосы скроллинга и в FALSE в обратном случае, iPos определяет текущее положение полосы скроллинга (и лежит в диапазоне от iMax до iMax). Следует отметить, что если вы используете полосы прокрутки, созданные с помощью стилей окна, то непосредственного описателя полосы прокрутки hwndScroll вы не имеете. Для их управления вы должны использовать описатель окна, которому принадлежат полосы прокрутки:

SetScrollRange(hwnd, SB_VERT, iMin, iMax, bRedraw);

SetScrollPos(hwndScroll, SB_HORZ, iPos, bRedraw);

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

Все полосы прокрутки посылают сообщения родительскому окну при щелчке мыши или перетаскивании маркера полосы прокрутки. При этом в родительское окно приходит сообщение WM_VSCROLL или WS_HSCROLL. Для полос прокрутки окна параметр lParam равен 0, а для полос прокрутки, созданных на родительском окне, в этом параметре передается описатель полосы прокрутки, пославшей сообщение. Младшее слово параметра wParam определяет то действие, которое совершается с полосой прокрутки. Вот его некоторые значения:  SB_LINEUP, SB_PAGEUP, SB_THUMBTRACK, SB_THUMBPOSITION, SB_PAGEDOWN, SB_PAGEDOWN, SB_LINEDOWN, SB_ENDSCROLL. Старшее слово параметра wParam указывает текущее положение полосы прокрутки.

Класс редактирования

Когда используется класс "edit" при создании дочернего окна, тем самым создается прямоугольник заданного размера и положения на родительском окне, в котором содержится редактируемый текст. Когда данное дочернее окно имеет фокус ввода, вы можете набирать текст, двигать каретку, выбирать (отмечать) группы символов, используя либо мышь, либо клавиатуру, копировать текст и вставлять текст, находящийся в Clipboard.

Одним из простейших применений окон редактирования является простое однострочное окно ввода данных, которое, например, используется в окнах открытия и сохранения файлов для указания имени файла.

При создании указывается стиль окна редактирования (присутствие параметра WM_CHILD обязательно), который может использовать следующие значения: ES_LEFT, ES_RIGHT, ES_CENTER для выравнивания редактируемого текста соответственно по левому или правому краю, либо по центру; ES_MULTILINE – для создания многострочного окна редактирования; ES_AUTOHSCROOL и ES_AUTOVSCROOL для включения соответственно горизонтальной и вертикальной полосы прокрутки.

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

EN_SETFOCUS  окно получило фокус ввода;

EN_KILLFOCUS  окно потеряло фокус ввода;

EN_CHANGE   содержимое окна будет меняться;

EN_UPDATE   содержимое окна изменилось;

EN_ERRSPACE  произошло переполнение буфера ввода;

EN_MAXTEXT  произошло переполнение буфера ввода при вставке;

EN_HSCROLL  на горизонтальной полосе прокрутки был щелчок мыши;

EN_VSCROLL  на вертикальной полосе прокрутки был щелчок мыши;

Поместить либо прочитать текст из окна редактирования можно при помощи функций SetWindowText и GetWindowText.

Существует множество сообщений, которые родительское окно может послать в окно редактирования. Приведем некоторые из них, которые позволяют выполнять работу с текстом, содержащимся в окне редактирования.

Вы можете выделить текст, указав начальное и конечное положение выделения:

SendMessage(hwndEdit, EM_SETSEL, iStart, iEnd);

а также получить начальное и конечное положение текущего выделения:

SendMessage(hwndEdit, EM_GETSEL, (wParam) &iStart, (lParam) &iEnd);

Длину строки можно получить используя номер строки в окне редактирования:

int iLength = SendMessage(hwndEdit, EM_LINELENGTH, iLine, 0);

а также скопировать саму строку в буфер:

int iLength = SendMessage(hwndEdit, EM_GETLINE, (LPARAM) szBuffer);

С выделенным в окне редактирования текстом можно выполнить те же действия, которые предоставляются большинством текстовых редакторов: копирование, вставку, удаление, удаление с копированием, послав в окно редактирование соответствующие сообщения (WM_COPY, WM_PASTE, WM_CLEAR, WM_CUT). Параметры сообщения в этом случае равны 0.

Класс окна списка

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

Чаще всего списки используются в окнах диалога, например, при открытии файла в окне списка отображаются имена файлов текущего каталога. Список позволяет выбирать один пункт списка или несколько. Если окно списка имеет фокус ввода, то один из пунктов списка выводится окруженным штриховой линией. Такая индикация не означает, что данный пункт выбран. Выбранный пункт индицируется световым выделением.

Дочернее окно списка создается с помощью вызова функции CreateWindow, с использованием имени "listbox" в качестве класса окна и WS_CHILD в качестве идентификатора стиля. Кроме этого, окно списка имеет ряд предопределенных стилей:

LBS_NOTIFY инициирует посылку сообщений от списка родительскому окну;

LBS_SORT  дает возможность сортировки элементов списка;

LBS_MULTIPLESEL дает возможность выбора сразу нескольких пунктов списка

LBS_STANDART = (LBS_NOTIFY|LBS_SORT|WS_VSCROLL|WS_BORDER)

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

SendMessage(hwndList, LB_INSERTSTRING, iIndex, (LPARAM) szString);

где iIndex – значение индекса. Если вы используете стиль LBS_SORT , то можно использовать сообщение:

SendMessage(hwndList, LB_ADDSTRING,0, (LPARAM) szString);

Удалить строку из списка можно путем посылки сообщения:

SendMessage(hwndList, LB_DELETESTRING, iIndex, 0);

 Полностью очистить список:

SendMessage(hwndList, LB_RESETCONTENT,0,0);

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

int iCount = SendMessage(hwndList, LB_GETCOUNT,0,0);

int iIndex= SendMessage(hwndList, LB_GETCURSEL,0, 0);

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

iLength = SendMessage(hwndList, LB_GETTEXTLEN, iIndex, 0);

iLength = SendMessage(hwndList, LB_GETTEXT, LB_GETTEXT, (LPARAM) szBuffer);

Кроме этого вы можете сами устанавливать выделяемый пункт списка:

SendMessage(hwndList, LB_SETCURSEL, iIndex, 0);

Данные функции работают для списка с одним выбором. Для списка с множественным выбором нужно использовать сообщения LB_SETSEL,  LB_GETSEL:

SendMessage(hwndList, LB_SETSEL, wParam, iIndex);

Данное сообщение изменяет состояние элемента списка с номером iIndex. Если параметр iIndex = -1, то действие распространяется на все элементы списка. Параметр wParam определяет будет ли элемент выбран (значение не равно 0) или у данного элемента выделение будет отменено (равен 0). Проверить выделен ли конкретный элемент списка или нет в данном случае можно с помощью:

int iSelect = SendMessage(hwndList, LB_GETSEL, iIndex, 0);

где iSelect не равно 0, если пункт выбран, и равно 0 – в противном случае.

Окно списка посылает родительскому окну сообщения WM_COMMAND. lParam является описателем дочернего окна, младшее слово wParam определяет идентификатор дочернего окна, а в старшем слове содержится код уведомления:

LBN_ERRSPASE показывает, что превышен объем памяти, выделенный для списка;

LBN_SELCHANGE изменен текущий выбор;

LBN_DBCLK  был двойной щелчок мыши на окне списка;

LBN_SELCANSEL отмена выделения;

LBN_SELFOCUS окно списка получило фокус ввода;

LBN_KILLFOCUS окно списка потеряло фокус.


 

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

73417. Повествование и его композиция (композиционно-речевые формы) 31 KB
  Организация повествования возникла давно на Западе. Она включает в себя: структуру повествовательного текста фигуру которая является источником повествования Повествование – весь текст повествовательного произведения; весь текст за вычетом прямых речей.
73418. Образ повествователя и его историческая трансформация 41.5 KB
  Образ автора -– автор создает повествователя который похож на автора. Повествователь Находится за пределами изображаемого мира Близок к автору По речевому строю По восприятию Близок к образу автора Главный признак повествователя: Вне изображаемого мира в отличие от рассказчика...
73419. Образ рассказчика 35.5 KB
  Образ автора – автор создает повествователя, который похож на автора. Рассказ, который ведется от 3-его лица, называется безличным. Повествователь находится вне изображаемого мира, а рассказчик – внутри него. Автор ближе к повествователю, а рассказчик – к герою.
73420. Художественная речь. Поэтический язык 38.5 KB
  На такие вопросы как чем вызывается эстетический эффект чем обусловлена художественность речи пытаются ответить теоретики начиная с античности. Русская литературная теория занимается вопросом художественной речи чем обусловлена эта художественность.
73421. Традиционная теория художественной речи. Стилистика 36.5 KB
  Стилистика Занимается изучением художественной речи (поэтического языка). Рассматривает архаизмы, неологизмы, варваризмы и т.д. Но потом начинаются значительные изменения, связанные с тем, что менялась литература. Литература 19 в. оказывалась очень далекой от Античных схем.
73422. Дорожні огорожі 462 KB
  На небезпечних ділянках доріг з метою запобігання виїзду автомобілів за межі земляного полотна встановлюють спеціальні дорожні огородження мал. Розташування однобічних і двосторонніх утримуючих огороджень бічних і фронтальних для автомобілів: 1 узбіччя; 2 бічне однобічне огородження...
73423. Дорожні знаки як технічні засоби організації дорожнього руху 36 KB
  Дорожні знаки ставляться до технічних засобів організації дорожнього руху і є обов’язковою приналежністю всіх доріг і вулиць населених пунктів. Усі дорожні знаки діляться на вісім груп: попереджуючі знаки; знаки пріоритету; заборонні знаки; знаки що пропонують...
73424. Сигнальні стовпці та розмітка 302 KB
  Використання стовпців та розмітки Застосування і типи стовпців Вимоги до використання стовпців Вимоги до сучасної розмітки Дорожні стовпчики маркіровані светоотражающими елементами призначені для позначення узбіч автомобільних доріг відповідають гос.
73425. Штучні нерівності на дорозі 577.5 KB
  Довжина кожної нерівності повинна бути не менш ширини проїзної частини. Припустиме відхилення — не більш 0,2 м з кожної сторони дороги. На ділянці дороги для обладнання нерівностей повинен бути забезпечений водовідвід із проїзної частини дороги.