скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыУчебное пособие: Работа с окнами приложений

SS_SIMPLE, SS_LEFT, SS_LEFTNOWORDWRAP, SS_RIGHT, SS_CENTER

При этом надо обратить внимание на стиль SS_NOPREFIX; Обычно последовательность из & и любого символа обозначает подчеркнутый символ. Однако это не всегда удобно - например, если выводимый текст является именем файла или директории (в этом случае & может содержаться в строке как обычный символ). Для того, что бы запретить использование & в качестве префикса, используется стиль SS_NOPREFIX.

Кнопки

Самый “богатый” класс - класс кнопок. Для создания окна, принадлежащего этому классу надо указать имя класса “BUTTON”. Большинство кнопок (но не все) являются активными элементами (то есть могут принимать фокус ввода). Обычно кнопки посылают родительскому окну только один код извещения - BN_CLICKED, указывающий на то, что кнопка была нажата. Все остальные коды извещения кнопок (BN_???) соответствуют частному случаю кнопок, который не рекомендуется использовать в Windows 3.1.

К этому классу принадлежат следующие разновидности управляющих элементов:

BS_PUSHBUTTON и BS_DEFPUSHBUTTON обозначают кнопку, на которую можно “нажать”. Нажимают на кнопку или пробелом, или мышкой. Стиль BS_DEFPUSHBUTTON обозначает кнопку, которая должна нажиматься клавишей Enter, даже если фокус ввода принадлежит другому управляющему элементу.

BS_CHECKBOX и BS_AUTOCHECKBOX обозначают флажок – элемент, который состоит из небольшого квадрата и строки текста. В квадрате может быть поставлен крестик (check mark) - то есть этот элемент является “двухпозиционным переключателем” - отмечен/неотмечен.

BS_AUTOCHECKBOX отличается от обычного флажка тем, что автоматически переключается из одного состояния в другое при нажатии на него, а для простого BS_CHECKBOX вы должны сами подать команду для переключения.

BS_3STATE и BS_AUTO3STATE очень похож на флажок, но может быть в трех состояниях - отмечен/неотмечен/запрещен (в запрещенном состоянии не принимает сообщения от клавиатуры и мыши и рисуется серым. Это состояние включается и выключается только программным способом).

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

BS_GROUPBOX редставляет собой прямоугольную рамку, в верхней части которой может быть выведен текст. Используется для визуального объединения нескольких управляющих элементов в одну группу. Хотя GroupBox и является кнопкой, но он не может получать фокус ввода - то есть больше похож на статические элементы.

Кнопки могут обрабатывать 5 специфичных сообщений:

BM_SETCHECK  nCheck                     0L

устанавливает состояние кнопки:
0 – неотмечена
1 – отмечена
2 – запрещена (только BS_3STATE и BS_AUTO3STATE)

BM_SETSTATE    nState                        0L

устанавливает состояние кнопки
0 – нормальное состояние
1 – выделена (изобразить кнопку в “нажатом” состоянии)

BM_SETSTYLE    wStyle                       bRedraw & 0

изменить стиль кнопки. wStyle является комбинацией BS_??? стилей, а bRedraw указывает, надо ли перерисовать кнопку.

BM_GETCHECK  0                                0L
BM_GETSTATE            0                                0L

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

Списки

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

Список распознает большое количество специфичных сообщений, поэтому здесь будут рассмотрены лишь некоторые из них.

LB_RESETCONTENT                           0 0L

это сообщение приводит к удалению всех данных из списка.

LB_ADDSTRING  0                                lpszString

добавить строку в конец списка

LB_FINDSTRING nIndexStart              lpszString

найти нужную строку в списке и получить ее индекс

LB_DELETESTRING                            nIndex  0L

удалить строку из списка

LB_GETTEXT      nIndex                      lpsBuffer

прочитать строку с индексом nIndex в списке и разместить ее в указаном буфере.

LB_GETCURSEL 0                                0

получить индекс текущего выбранного элемента

LB_DIR                  nAttr                         lpszMask

заполнить список именами файлов, директорий и дисков. Иногда удобно пользоваться специальной функцией, посылаеющей это сообщение: DlgDirList и DlgDirSelect.

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

      LBN_ERRSPACE – о произошедшей ошибке, связанной с нехваткой памяти;

      LBN_KILLFOCUS и LBN_SETFOCUS – о получении или потере фокуса ввода;

      LBN_DBLCLK – о двойном нажатии на кнопку мыши;

      LBN_SELCHANGE – об изменении текущего выбранного элемента;

      LBN_SELCANCEL – процесс выбора прерван, например, переходом к другому окну.

Существует еще одна разновидность списков - так называемые комбинированные списки, состоящие из небольшого окошка редактора и простого списка, размещенного под ним. Эти списки принадлежат к классу COMBOBOX. Выделяют три разновидности комбинированных списков, определяемых его стилем:

·   простой комбинированный список – CBS_SIMPLE когда и редактор и список постоянно видны;

·   выпадающий комбинированный список – CBS_DROPDOWN когда постоянно видимо окошко редактора и специальная кнопка справа, при нажатии на которую под редактором появляется (выпадает) список.

·   неизменяемый комбинированный список – CBS_DROPDOWNLIST аналогичный CBS_DROPDOWN, но текст в редакторе не может быть изменен.

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

Такой список может иметь стиль CBS_OEMCONVERT, который приводит к автоматическому преобразованию записываемых в него строк из OEM в ANSI, и к обратному преобразованию при чтении из него данных.

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

Редактор

Один из самых удобных стандартных классов - класс редактора EDIT. Окна, принадлежащие к этому классу могут представлять собой как однострочные, так и многострочные редакторы, возможно имеющие полосы прокрутки и даже окошки просмотра - ввод и редактирование в которых запрещены. К таким редакторам легко добавлять дополнительные операции, например, поиск или замену текста. Самым существенным недостатком является то, что весь редактируемый текст размещается в локальном блоке памяти, и, соответственно, ограничен размером этой памяти - не более 64K минус уже занятое пространство.

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

Простейший способ создать собственный редактор - при создании собственного окна на всю его внутреннюю область установить окно стандартного редактора и добавить несколько дополнительных функций - меню, чтение/запись файла, поиск/замену и пр. Строго говоря, текстовой редактор NotePad сделан именно таким методом.

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

void      SetWindowText( hWnd, lpszText );

int         GetWindowText( hWnd, lpsBuffer, nMaxCount );

int         GetWindowTextLength( hWnd );

или сообщениями WM_SETTEXT, WM_GETTEXT и WM_GETTEXTLENGTH, которые в случае платформы Win32 позволят получить или изменить текст в окне, принадлежащем другому процессу, в то время как рассмотренные функции могут работать только с окнами, принадлежащими данному процессу.

Однако с большими текстами удобнее работать как с отдельными блоками памяти. Для этого надо будет воспользоваться сообщениями:

EM_GETHANDLE                                 0 0L

для получения хендла блока, содержащего текст;

EM_SETHANDLE                                  hLocal   0L

для задания хендла блока, содержащего текст;

EM_LIMITTEXT  nMaxChars              0L

для задания максимального размера текста;

Как все стандартные классы дочерних окна, окна EDIT посылают родительскому окну извещения о происходящих событиях – ошибке из‑за нехватки памяти, получении и потере фокуса, изменении редактируемого текста и о прокрутке” текста в окошке редактора.

Полосы прокрутки

Последний рассматриваемый нами стандартный класс дочерних окон – полосы прокрутки, принадлежащие к классу SCROLLBAR. Взаимодействие полос прокрутки с родительским окном отличается от взаимодействия всех остальных стандартных классов.

Вы можете сами создавать полосы прокрутки, но, если вам надо одну-две полосы прокрутки снизу и справа от окна, то проще создать окно со стилями WS_VSCROLL и/или WS_HSCROLL. При этом окно автоматически получит нужные полосы прокрутки. Удобство заключается еще и в том, что эти полосы прокрутки размещаются вне внутренней области окна, то есть Вам не надо учитывать их размер.

Для извещения родительского окна полосы прокрутки посылают сообщения WM_VSCROLL и WM_HSCROLL в зависимости от типа полосы - горизонтальная или вертикальная, а для управления полосами прокрутки используются специальные функции.

Сначала рассмотрим сообщения полосы прокрутки:

WM_VSCROLL    ScrollCode                wndScroll & nPos
WM_HSCROLL             ScrollCode                wndScroll & nPos

в параметре wPar размещается код, указывающий что происходит с полосой прокрутки, старшее слово lPar содержит хендл полосы прокрутки, а младшее слово может указывать на положение “движка полосы.

Коды полосы прокрутки могут быть следующие:


Для всех кодов, кроме SB_THUMBTRACK и SB_THUMBPOSITION, младшее слово lPar не используется. Коды SB_THUMBTRACK посылаются когда Вы, “зацепив” мышкой движок полосы прокрутки, начинаете перемещать его. При этом они посылаются так часто, как успевают обрабатываться - информируя Вас о текущем положении движка. Код SB_THUMBPOSITION посылается только в тот момент, когда Вы отпускаете кнопку мыши для позиционирования движка в новом месте.

Помимо этих кодов зарезервировано еще два - SB_TOP и SB_BOTTOM, которые никогда не посылаются полосой прокрутки. Собственно полосы прокрутки поддерживают интерфейс только с мышью, фокуса ввода они не получают, поэтому при использовании полос прокрутки возникает необходимость добавления интерфейса с клавиатурой.

Часто делают так, что родительское окно, обрабатывая сообщения от клавиатуры просто посылает само себе сообщения “от имени” полосы прокрутки. Вся обработка прокрутки окна сосредоточена на сообщениях WM_VSCROLL и WM_HSCROLL. В этом случае клавишам Home и End должны соответствовать какие-то коды полосы прокрутки, для чего и добавлены коды SB_TOP и SB_BOTTOM.

Конечно, Вы можете идти иным путем, тогда эти два кода Вам не понадобятся.

Приведем небольшой пример обработки сообщения WM_KEYDOWN родительским окном:

UINT n;

switch ( wMsg ) {

...

case WM_KEYDOWN:

switch ( wPar ) {

case VK_HOME: n= SB_TOP; goto post_vscroll;

case VK_END:     n= SB_BOTTOM; goto post_vscroll;

case VK_PRIOR: n= SB_PAGEUP; goto post_vscroll;

case VK_NEXT:  n= SB_PAGEDOWN; goto post_vscroll;

case VK_DOWN: n= SB_LINEDOWN; goto post_vscroll;

case VK_UP:        n= SB_LINEUP;

 post_vscroll:

  PostMessage( hWnd, WM_VSCROLL, n, 0L );

  break;

default:           break;

 }

return 0;

...

}

Далее нас будут интересовать средства для управления полосами прокрутки. Каждая полоса прокрутки характеризуется диапазоном прокрутки, то есть минимальным и максимальным значениями позиции движка. При создании полосы прокрутки ее диапазон устанавливается в 0..100;

Для того, что бы можно было узнать или изменить диапазон полосы прокрутки предназначены функции:

void      GetScrollRange( hWnd, nBar, lpnMin, lpnMax );

int         SetScrollRange( hWnd, nBar, nMin, nMax, bRepaint );

Удобно устанавливать диапазон прокрутки равным, например, числу строк в редактируемом файле.

Некоторых пояснений требуют параметры hWnd и nBar. Параметр hWnd может задавать хендл окна-родителя, тогда с помощью параметра nBar Вы указываете, какая конкретно полоса прокрутки имеется в виду: SB_VERT или SB_HORZ. А если hWnd является хенлом полосы прокрутки, то Вы должны указать nBar равным SB_CTL.

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

Int        GetScrollPos( hWnd, nBar );

int         SetScrollPos( hWnd, nBar, nPos, bRepaint );

Последняя функция позволяет показать или спрятать полосы прокрутки. Она может использовать еще одно значение параметра nBar – SB_BOTH, указывая, что обе полосы показываются или скрываются.

Void     ShowScrollBar( hWnd, nBar, bShow );

Окна, рисуемые пользователем

Для некоторых стандартных классов дочерних окон возможно создание окон нестандартного вида. Это так называемые рисуемые пользователем (Owner Draw) окна. Вы можете создавать такие кнопки, и элементы списков (то есть Вы можете наполнять список произвольными объектами, например, рисунками). Тот же способ может быть применен для рисования пунктов меню.

Для того, что бы воспользоваться этой возможностью, Вы должны указать соответсвующий стиль - BS_OWNERDRAW для кнопки, LBS_OWNERDRAWFIXED, LBS_OWNERDRAWVARIABLE, CBS_OWNERDRAWFIXED, CBS_OWNERDRAWVARIABLE для списков. В случае списков различаются два вида рисуемых пользователем элементов - элементы одинаковой высоты (...FIXED) и элементы произвольной высоты (...VARIABLE).

Дочерние окна таких стилей будут посылать своему родительскому окну сообщения WM_MEASUREITEM и WM_DRAWITEM. Обрабатывая эти сообщения родительское окно определяет размеры требуемых элементов и осуществляет их рисование. (Эти же сообщения могут применяться для рисования меню).

WM_MEASUREITEM                           nID  lpMI

это сообщение посылается для определения размеров рисуемого элемента. Параметр wPar содержит идентификатор дочернего окна, а параметр lPar - дальний указатель на структуру MEASUREITEMSTRUCT, которую надо заполнить.

typedef struct tagMEASUREITEMSTRUCT { /* mi */

UINT   CtlType;  // тип рисуемого элемента

UINT   CtlID;      // идентификатор

UINT   itemID;          // идентификатор элемента (номер пункта)

UINT   itemWidth;    // ширина элемента

UINT   itemHeight;   // высота элемента

DWORD   itemData; // данные элемента

} MEASUREITEMSTRUCT;

Поля CtlType, CtlID, itemID и itemData заполняются Windows, вы будете их использоватьь для определения нужного элемента.

Поле CtlType может быть одним из следующих:

ODT_BUTTON         - кнопка

ODT_COMBOBOX  - элемент комбинированного список

ODT_LISTBOX        - элемент простого список

ODT_MENU        - элемент меню

Поля CtlID и ItemID определяют идентификаторы дочернего окна и элемента этого дочернего окна (если дочернее окно является списком или рисуется элемент меню).

Поле ItemData является значением, которое Вы передали либо при создании дочернего окна (имя кнопки) либо при добавлении элемента в список или меню (см. сообщения CB_ADDSTRING, CB_INSERTSTRING, LB_ADDSTRING, LB_INSERTSTRING и функции InsertMenu, AddMenu). Обычно это поле является указателем на название окна/элемента.

Два поля itemHeight и itemWidth вы должны определить сами. При этом надо иметь в виду, что некорректное задание этих полей или некорректная обработка сообщения WM_DRAWITEM может привести к непредсказуемым результатам, так как Windows не проверяет корректности значений и выполненых действий).

WM_DRAWITEM nID                            lpDI

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

typedef struct tagDRAWITEMSTRUCT { /* ditm */

UINT   CtlType;  // тип рисуемого элемента

UINT   CtlID;      // идентификатор

UINT   itemID;          // идентификатор элемента (номер пункта)

UINT   itemAction;   // из-за чего надо рисовать

UINT   itemState; // как надо рисовать

HWND hwndItem;    // хендл окна рисуемого элемента

HDC          hDC;        // хендл контекста устройства для рисования

RECT  rcItem;           // прямоугольник, в котором надо рисовать

DWORD   itemData; // данные элемента

} DRAWITEMSTRUCT;

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

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

void      DrawFocusRect( hDC, lpRect );

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

Управление цветом дочерних окон

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

WM_CTLCOLOR DC                            CtlType&hwndChild

Параметры этого сообщения следующие:

wPar содержит хендл контекста устройства рисуемого окна младшее слово lPar содержит хендл этого окна, а старшее - тип рисуемого окна:

CTLCOLOR_BTN, CTLCOLOR_DLG, CTLCOLOR_EDIT, CTLCOLOR_LISTBOX, CTLCOLOR_MSGBOX, CTLCOLOR_SCROLLBAR, CTLCOLOR_STATIC

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

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


Страницы: 1, 2


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

Обратная связь

Поиск
Обратная связь
Реклама и размещение статей на сайте
© 2010.