Установка цвета и режима фона



По умолчанию для фона операции вывода в контекст устройства выбран белый цвет. Функция SetBkColor() устанавливает новый цвет для фона вывода:

COLORREF SetBkColor(HDC hdc, COLORREF crColor);

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

Функция RGB() используется для получения значения цвета типа COLORREF:

COLORREF RGB(BYTE bRed, BYTE bGreen, BYTE bBlue);

Она возвращает значение цвета в формате COLORREF в виде ин­тенсивности красной (bRed), зеленой (bGreen) и синей (bBlue) состав­ляющих цвета. Интенсивность каждого аргумента может принимать зна­чения в диапазоне от 0 до 255. Если все три значения равны нулю, ре­зультат - черный. Если все три- 255, результат - белый.

В случае неудачи возвращаемое значение функции RGB() равно CLRINVALID.

Примеры задания различных цветов:

RGB(80,80,80) – серый цвет

RGB(255,255,0) – желтый цвет

RGB(255,0,255) – малиновый цвет

 

Существует два режима фона - непрозрачный (OPAQUE - значение по умолчанию) и прозрачный (TRANSPARENT). В режиме непрозрачно­го вывода цвет фона текущей позиции заменяется цветом фона вывода. В режиме TRANSPARENT цвет фона не заменяется.

Режим фона уста­навливает функция:

int SetBkMode( HDC hdc, int iBkMode);

Параметр iBkMode принимает значение TRANSPARENT или OPAQUE. В случае успешного выполнения функция возвращает значе­ние предыдущего режима, иначе - нуль.

 

Установка цвета текста

По умолчанию цвет вывода текста выбран черным. Другой цвет вы­вода символов текста устанавливает функция:

COLORREF SetTextColor(HDC hdc, COLORREF crColor);

Параметр crColor задает новый цвет. В случае успешной установки нового цвета возвращается значение предыдущего цвета, иначе – CLR_INVALID.

 

Определение метрик шрифта

Метрику шрифта, выбранного в контекст устройства hdc, опреде­ляют с помощью функции:

BOOL GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm);

Параметр lptm указывает на структуру типа TEXTMETRIC, в кото­рую нужно записать метрики шрифта. Все размеры записываются в ло­гических единицах контекста устройства hdc. В случае успешного вы­полнения функция возвращает TRUE, иначе - FALSE.

Структура TEXTMETRIC содержит полную информацию о шрифте, выбранном в данный момент в контексте устройства и включает набор из 20 полей. Наиболее важными из них являются:

- tmHeight - общая высота букв.

- tmAveCharWidth - средняя ширина строчных букв, равна ширине латинской буквы "х".

 

Пример: фрагмент оконной функции, в котором осуществляется вывод строки текста в центре рабочей области окна:

case WM_LBUTTONDOWN:

{

char *str="Выводимая строка";

// Получение контекста устройства

HDC hdc= GetDC(hWnd);

// Получение размеров рабочей области окна

RECT r; GetClientRect(hWnd, &r);

// Получение информации о текущем шрифте

TEXTMETRIC tm; GetTextMetrics(hdc, &tm);

// Координаты X и Y для вывода строки в центре окна

int x=(r.right-tm.tmAveCharWidth*strlen(str))/2;

int y=(r.bottom-tm.tmHeight)/2;

// Цветом вывода символов выбран малиновый

SetTextColor(hdc, RGB( 255, 0, 255));

// Цветом фона выбран кремовый

SetBkColor(hdc, RGB(255, 251, 240));

// Вывод строки

TextOut(hdc, x, y, str, strlen(str));

// Освобождение контекста устройства

ReleaseDC(hWnd, hdc); return 0;

}

 

Настройка параметров шрифта

В контекст устройства по умолчанию выбирают системный шрифт (system font). Для создания логического шрифта необходимо вызвать функцию:

HFONT CreateFontIndirect(const LOGFONT* lplf);

Она возвращает дескриптор созданного шрифта. В качестве аргумента вызова функции CreateFontIndirect() передают указатель на структуру типа LOGFONT:

typedef struct {   

LONG lfHeight;

LONG lfWidth;

LONG lfOrientation;

.... // Другие поля структуры

TCHAR lfFaceName[LF_FACESIZE]; } LOGFONT;

Назначение полей этой структуры:

- lfHeight - высота шрифта в логических единицах. При lfHeight=0 создается шрифт с высотой символов по
умолчанию: lfHeight=12.

- lfWidth - ширина символов в логических единицах. Если указано ну­левое значение, используют ширину по умолчанию.

- lfOrientation – задает угол наклона (в десятых долях градуса) между осью Х и линией символа.

lfFaceName - строка с именем шрифта. Длина этой строки не должна превышать 32 символа.

Для выбора шрифта hfont в контекст устройства hdc вызывают функцию:

HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);

где hgdiobj – дескриптор объекта GDI, который выбирается для контекста устройства hdc. В данном случае это hfont – шрифт, полученный с помощью функции CreateFontIndirect().

Функция SelectObject() возвращает дескриптор объекта GDI, который заменяется новым объектом.

Когда в шрифте hfont отпадет необходимость, его следует уда­лить при помощи функции:

BOOL DeleteObject(HGDIOBJ hObject);

где hObject – дескриптор удаляемого объекта GDI.

Предварительно необходимо выбрать в контекст устройства предыдущий шрифт.

 

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

LRESULT CALLBACK WndProc( HWND hWnd, UINT msg,

WPARAM wParam, LPARAM lParam)

{   

 char szFont[]="Строка выводимого текста";

 static int cyClient;

 RECT Rect;

 switch (msg)

 { 

case WM_CREATE:   

// Получение размера раб. обл. окна по высоте

{ GetClientRect(hWnd, &Rect);

cyClient=Rect.bottom; return 0;}

case WM_SIZE:   

// Получение нового cyClient при изм. размера окна

{cyClient=HIWORD(lParam); return 0;}

case WM_PAINT:

{   

PAINTSTRUCT ps;

HDC hdc=BeginPaint(hWnd, &ps);

static LOGFONT lf;

lf.lfHeight=20; lf.lfWeight=FW_BOLD;

strcpy(lf.lfFaceName, "Times New Roman"); 

// Вывод строки 10 раз в нижн. лев. углу окна

for(int i=0; i<10; i++)

{  

lf.lfOrientation=i*100;

HFONT hNewFont=CreateFontIndirect(&lf);

HFONT hOldFont=(HFONT) SelectObject(hdc, hNewFont);

SetTextColor(hdc, RGB(i*15, i*20, i*25));

SetBkColor(hdc, RGB(255-i*15,255-i*20,255-i*25));

TextOut(hdc, 0, cyClient-(i+1)*30, szFont, strlen(szFont));

SelectObject(hdc, hOldFont);

DeleteObject(hNewFont);

}

EndPaint(hWnd, &ps); return 0;

}

case WM_DESTROY:

{PostQuitMessage(0); return 0;}

 }

 return DefWindowProc(hwnd, msg, wParam, lParam);

}

 

Тема: Рисование с помощью функций GDI

При рисовании в окне с помощью функций GDI используются следующие объекты, входящие в контекст устройства: перья (Pen), кисти (Brush).

Приложение при использовании этих объектов должно выполнить следующее:

· Создать объект GDI.

· Выбрать объект GDI в контекст устройства и сохранить “старый” объект с помощью функции SelectObject().

· Вызвать одну или несколько функций рисования GDI.

· Восстановить в контексте устройства “старый” объект GDI с помощью функции SelectObject().

· Разрушить объект GDI с помощью функции DeleteObject().

Перья

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

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

HPEN CreatePen(int fnPenStyle,int nWidth,COLORREF crColor);

Параметр fnPenStyle определяет стиль пера и принимает одно из сле­дующих значений:

Значение Стиль линии пера
PS_SOLID Сплошная
PS_DASH Штриховая
PS_DOT Пунктирная
PS_DASHDOT Штрихпунктирная, одна точка на одну черточку
PS_DASHDOTDOT Штрихпунктирная, две точки на одну черточку
PS_NULL Невидимая

Параметр nWidth задает ширину пера. В зависимости от режима ото­бражения ширина может быть указана в пикселях, долях дюйма или до­лях миллиметра. Ширина прерывистых линий может быть равна только единице. Параметр crColor задает цвет пера.

В случае успешного выполнения функция CreatePen возвращает де­скриптор созданного пера, иначе - NULL.

 

Пример создания пера (сплошная зеленая линия):

HDC hdc=GetDC(hWnd); // Получение контекста устройства

// Создание пера и выбор его в контекст устройства

HPEN hPen=CreatePen(PS_SOLID, 1, RGB(0,255,0));

HPEN hOldPen=(HPEN) SelectObject(hdc, hPen);

// Рисование в окне с помощью пера

. . .

// Восстановление старого пера и удаление созданного пера

SelectObject(hdc, hOldPen);

DeleteObject(hPen);

// Освобождение контекста устройства

ReleaseDC(hWnd, hdc); 

 

Кисти

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

Для создания различных кистей используются следующие функции:

· Для создания кисть сплошной заливки (Solid Brush) используется функция CreateSolidBrush().

· В приложении можно выбрать одну из семи преопределенных кистей (Stock Brush) с помощью функции GetStockObject();

· Приложение может создать одну из шести заштрихованных кистей (Hatch Brush) функцией CreateHatchBrush().

· Кисть, имеющую свой стиль заполнения (Pattern Brush), можно создать из битового изображения функцией CreatePatternBrush().

Функция CreateSolidBrush() создает кисть сплошной заливки цвета crColor:

HBRUSH CreateSolidBrush( COLORREF crColor);

В случае ус­пешного выполнения она возвращает дескриптор созданной кисти, ина­че - NULL.

Пример создания красной сплошной кисти:

HDC hdc=GetDC(hWnd); // Получение контекста устройства

// Создание кисти и выбор ее в контекст устройства

HBRUSH hRedBrush=CreateSolidBrush(RGB(255, 0, 0));

HBRUSH hOldBrush=(HBRUSH) SelectObject(hdc, hRedBrush);

// Рисование в окне с закрашиванием кистью

...

// Восстановление старой кисти и удаление созданной

SelectObject(hdc, hOldBrush);

DeleteObject(hRedBrush);

// Освобождение контекста устройства

ReleaseDC(hWnd, hdc); 

 

Рисование геометрических фигур

Функции рисования точки:

- SetPixel() устанавливает заданный цвет в точке с указанными координатами.

- GetPixel() определяет цвет точки с указанными координатами.

 

Функции рисования линий:

- LineTo() рисует прямую линию из текущей позиции.

- GetCurrentPositionEx() определяет текущую позицию пера.

- Polyline() рисует ломаную линию.

 

Функции рисования замкнутых фигур:

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

- Rectangle() рисует прямоугольник.

- RoundRect() рисует прямоугольник с закругленными углами.

- FillRect() закрашивает прямоугольную область окна заданной кистью.

- FrameRect() рисует прямоугольную рамку.

- Ellipse() используется для рисования эллипса.

- Chord() рисует сегмент эллипса.

- Pie() используется для рисования сектора эллипса.

- Polygon() рисует многоугольник.

 

Дополнительный материал по теме: Рисование с помощью функций GDI

 

Рисование геометрических фигур

Функции рисования точки

Функция SetPixel () устанавливает заданный цвет в точке с указанными координатами:

COLORREF SetPixel( HDC hdc, int x, int y, COLORREF crColor);

Параметры х и у определяют координаты точки, цвет кото­рой будет изменен. Параметр crColor задает цвет окраски точки. В случае успешного выполнения функция возвращает установленное значение цвета.

Функция GetPixel () определяет цвет точки с указанными координатами:

COLORREF GetPixel( HDC hdc, int x, int у);

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

 

Функции рисования линий

Функция LineTo () используется для рисования прямой линии:

BOOL LineTo( HDC hdc, int x, int у);

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

Функция GetCurrentPositionEx () используется для определения текущей позиции пера:

BOOL GetCurrentPositionEx( HDC hdc, LPPOINT lpPoint);

Параметр lpPoint указывает на структуру типа POINT, в которую бу­дут записаны логические координаты текущей позиции. В случае ус­пешного выполнения функция возвращает ненулевое значение.

Функция Polyline () предназначена для рисования ломаных линий:

BOOL Polyline(HDC hdc, CONST POINT *lppt, int cPoints);

Она соединяет прямыми линиями точки, координаты которых указаны в массиве структур типа POINT. Параметр lppt указывает на массив структур POINT. cPoints равен количеству точек в массиве и должен быть больше 1. В случае успешного выполнения функция возвращает ненулевое значение. Функция Polyline() игнорирует текущую позицию. Прямые рисуют от точки первого элемента массива к точке второго элемента и т. д. Если ломаная ли­ния не замкнута, ее последняя точка не рисуется.

 

Функции рисования замкнутых фигур

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

Функция Rectangle () предназначена для рисования прямоугольника:

BOOL Rectangle( HDC hdc, int l, int t, int r, int b);

Параметры l, t, r и b определяют логические координаты соответст­венно левого, верхнего, правого и нижнего краев прямоугольника.

Функция RoundRect () рисует прямоугольник с закругленными углами:

BOOL RoundRect( HDC hdc, int l, int t, int r, int b, int w, int h);

Первые 5 параметров этой функции совпадают с параметрами функ­ции Rectangle. А параметры w и h задают соответственно ширину и вы­соту эллипса, дуги которого закругляют углы прямоугольника.

Функция FillRect () закрашивает прямоугольную область окна заданной кистью:

int FillRect( HDC hdc, CONST RECT *lprc, HBRUSH hbr);

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

Например: FillRect( hdc, &rect, (HBRUSH)(COLOR_WINDOW+1));

Правая и нижняя границы прямоугольника не закрашиваются.

Функция FrameRect () рисует прямоугольную рамку:

int FrameRect( HDC hdc, CONST RECT *lprc, HBRUSH hbr);

Параметры этой функции подобны параметрам функции FillRect. Функция FrameRect кистью hbr рисует рамку вокруг заданного прямо­угольника. Ширина пера, используемого для рисования рамки, всегда равна одной логической единице.

Функция Ellipse () используется для рисования эллипса:

BOOL Ellipse( HDC hdc, int l, int t, int r, int b);

Параметры функции Ellipse() идентичны первым пяти параметрам функции Rectangle.

Функция Chord () рисует сегмент эллипса:

BOOL Chord(HDC hdc, int l, int t, int r, int b, int x0, int y0, int x, int у);

Первые 5 параметров этой функции совпадают с параметрами функ­ции Ellipse(). Функция Chord() соединяет хордой точки начала и конца дуги эллипса и закрашивает выделенный таким образом сегмент текущей кистью.

Начало дуги эллипса определяется пересе­чением эллипса с воображаемой прямой линией, проведенной из центра эллипса (хс, ус) в точку (х0, у0). Конец дуги определяется аналогично - как пересечение эллипса с воображаемой прямой линией, проведенной из центра эллипса в точку (х, у). Дуга рисуется от начальной точки к ко­нечной, в направлении против хода часовой стрелки. Если начальная и конечная точки дуги совпадают, то рисуется полный эллипс.

Функция Pie () используется для рисования сектора эллипса:

BOOL Pie(HDC hdc, int l, int t, int r, int b, int x0, int y0, int x, int у);

Параметры этой функции аналогичны параметрам функции Chord(). В отличие от функции Chord(), функция Pie() соединяет точки начала и конца дуги с центром эллипса и закрашивает выделенный таким обра­зом сектор текущей кистью.

Функция Polygon () рисует многоугольник:

BOOL Polygon(HDC hdc, CONST POINT *lpPoints, int nCount);

Параметр lpPoints указывает на массив структур POINT, в котором нахо­дятся координаты вершин многоугольника. Параметр nCount равен размеру этого массива. В массиве каждая вершина должна быть указана только один раз. Функция Polygon автоматически соединяет первую и последнюю вер­шины многоугольника.

 

 

Тема: Обработка сообщений клавиатуры

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

При нажатии и отпускании клавиши происходит следующее:

· Драйвер клавиатуры передает информацию о нажатии клавиш в Windows.

· Windows сохраняет эту информацию (в виде сообщений) в системной очереди сообщений.

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

· Затем программа отправляет сообщения соответствующей оконной процедуре (с помощью функции DispatchMessage()).

 

Понятие фокуса клавиатуры

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

Окно, имеющее фокус клавиатуры – это либо активное окно, либо дочернее окно активного окна. Наиболее часто дочерними окнами являются кнопки, переключатели и другие элементы управления, которые обычно присутствуют в окне диалога.

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

- функция GetFocus() позволяет получить дескриптор окна, которое в данный момент имеет фокус клавиатуры:

HWND GetFocus(VOID);

- функция SetFocus() передает фокус клавиатуры окну hWnd и возвращает дескриптор окна, ранее имевшего фокус клавиатуры:

HWND SetFocus(HWND hWnd);

 

Категории клавиатурных сообщений

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

1. Клавиатура представляет собой набор клавиш. Нажатие на любую клавишу является одним аппаратным событием; отпускание этой же клавиши является другим аппаратным событием.

2. Клавиатура также является устройством ввода, генерирующим отображаемые символы. Одна и та же клавиша, например <A>, в зависимости от состояния клавиш <Ctrl>, <Alt>, <Shift> и <CapsLock>, может стать источником нескольких символов.

Некоторые клавиши не генерируют символов. Это такие клавиши, как клавиши переключения, функциональные клавиши, клавиши управления курсором и специальные клавиши, такие как <Insert> и <Delete>. Для таких клавиш Windows вырабатывает только аппаратные сообщения.

 

Аппаратные сообщения

При нажатии клавиши Windows помещает в очередь сообщений окна, имеющего фокус ввода сообщение WM_KEYDOWN или WM_SYSKEYDOWN. Когда клавиша отпускается, в очередь сообщений помещается сообщение WM_KEYUP или WM_SYSKEYUP.

Системные аппаратные сообщения WM_SYSKEYDOWN и WM_SYSKEYUP обычно вырабатываются при нажатии клавиш в сочетании с клавишей <Alt>. Эти сообщения используются Windows для вызова опций меню программы или системного меню, или используются для системных функций, таких как смена активного приложения (<Alt+Tab>) и др.

Программы обычно игнорируют сообщения WM_SYSKEYDOWN и WM_SYSKEYUP и передают их в  Windows  через функцию DefWindowProc().

При необходимости обработки системных аппаратных сообщений клавиатуры в программе следует после обработки этих сообщений передать их в DefWindowProc(), чтобы Windows могла их использовать в обычных целях:

case WM_SYSKEYDOWN: // или WM_SYSKEYUP

… // Обработка сообщения WM_SYSKEYDOWN

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

Несистемные аппаратные сообщения WM_KEYDOWN и WM_KEYUP обычно вырабатываются для клавиш, которые нажимаются и отпускаются без участия клавиши <Alt>. Приложение может использовать или не использовать эти сообщения клавиатуры. Сама Windows их проигнорирует.

Для всех аппаратных сообщений клавиатуры:

- параметр lParam, передаваемый в оконную функцию, состоит из шести полей, таких как: счетчик повторений (число нажатий клавиши), скан-код OEM (Original Equipment Manufacturer) (код клавиши, генерируемый аппаратурой компьютера) и др.

- параметр wParam содержит код виртуальной клавиши (virtual key code), идентифицирующий нажатую или отпущенную клавишу. Этот код не зависит от аппаратной реализации клавиатуры. Коды виртуальных клавиш имеют символьные обозначения, определенные в заголовочных файлах Windows, и имеют префикс VK_.

 

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

case WM_KEYDOWN:

{ int nVirtKey = (int) wParam; // виртуальный код клавиши

switch(nVirtKey)

{

// нажатие клавиши Space (пробел)

case VK_SPACE:

MessageBox(hWnd,“Нажата клавиша <Space>”, 

“<Space>”,MB_OK);

break;

// нажатие клавиши F1

case VK_F1:

MessageBox(hWnd,“ Нажата клавиша < F1>”,

“<F1>”,MB_OK);

break;

}

}

 

Символьные сообщения

Типичный цикл обработки сообщений в главной функции приложения WinMain() имеет вид:

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

{

TranslateMessage(&msg);

DispatchMesage(&msg);

}

Здесь функция TranslateMessage() преобразует аппаратные сообщения клавиатуры в символьные сообщения. Если этим сообщением является WM_KEYDOWN (WM_SYSKEYDOWN) и, если нажатие клавиши генерирует символ, тогда TranslateMessage() помещает символьное сообщение в очередь сообщений.

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

Существует четыре вида символьных сообщений: несистемные – WM_CHAR, WM_DEADCHAR, системные – WM_SYSCHAR, WM_SYSDEADCHAR.

В большинстве случаев программы для Windows могут игнорировать все сообщения за исключением WM_CHAR.

Параметр lParam, передаваемый в оконную процедуру как часть символьного сообщения, является таким же, как и в случае аппаратного сообщения клавиатуры. Параметр wParam – это код символа в таблице ASCII.

Если Windows-приложению необходимо обрабатывать вводимые с клавиатуры символы, то ему необходимо реагировать на сообщение WM_CHAR.

Типичный код обработки сообщения WM_CHAR в оконной функции имеет следующий вид:

case WM_CHAR:

{

 // Получение ASCII-кода символа

 CHAR chCharCode = (CHAR) wParam;

switch(chCharCode)

{

case ‘A’: // Введен прописной символ A

. . . // Обработка нажатия клавиши 'A'

break;

case ‘a’: // Введен строчный символ а

. . . // Обработка нажатия клавиши 'а'

break;

default: // введены другие символы

. . . // Обработка нажатия других клавиш

break;

}

}

 

 


Тема: Работа с таймерами в Windows

 

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

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

Возможные случаи применения таймеров в Windows:

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

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

· Завершение демонстрационных версий программ – некоторые демонстрационные версии программ рассчитаны на свое завершение через какое-либо заданное время после запуска. Таймер сигнализирует таким приложениям, когда их время истекает.

· Задание темпа изменения – графические объекты в играх или окна с информацией в обучающих программах могут нуждаться в задании установленного темпа изменения.

Сообщения от таймера

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

Для остановки потока сообщений от таймера приложение должно вызвать функцию KillTimer(). Вызов KillTimer() очищает очередь сообщений от всех необработанных сообщений WM_TIMER.

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

Варианты использования таймера

Таймер можно использовать одним из трех способов, в зависимости от параметров функции SetTimer().

Первый способ

При этом способе Windows посылает сообщения WM_TIMER требуемой оконной процедуре приложения. Вызов функции SetTimer() в этом случае имеет такой вид:

     SetTimer(hWnd, iTimerID, dwTimer, NULL);Параметры функции:

· hWnd – дескриптор того окна, чья оконная процедура будет получать сообщения WM_TIMER.

· iTimerID - идентификатор таймера, целое число, значение которого должно быть отлично от нуля. Можно задавать номера произвольно, начиная с 1.

· dwTimer – это 32-разрядное беззнаковое целое, которое задает интервал в миллисекундах.

· NULL – неиспользуемый в этом способе параметр.

Поток сообщений WM_TIMER можно в любое время остановить (даже во время обработки сообщения WM_TIMER), вызвав функцию:

     KillTimer(hWnd, iTimerID);

Вторым параметром здесь является тот же идентификатор таймера, который использовался при вызове функции SetTimer().

Примечание. Приложение должно перед завершением работы уничтожить все активные таймеры.

Когда оконная процедура получает сообщение WM_TIMER, wParam равен значению идентификатора таймера, а lParam равен 0.

Если приложению необходимо несколько таймеров, для каждого из них необходимо использовать свой идентификатор, например:

#define TIMER_SEC 1

#define TIMER_MIN 2

...

SetTimer(hWnd, TIMER_SEC, 1000, NULL);

SetTimer(hWnd, TIMER_MIN, 60000, NULL);

Значение параметра wParam позволяет различать передаваемые в оконную процедуру сообщения WM_TIMER.

Код для обработки сообщения WM_TIMER при нескольких таймерах для одного окна следующий:

case WM_TIMER:

{ UINT wTimerID = wParam;

switch(wTimerID)

{

// действия происходят один раз в секунду

case TIMER_SEC:

. . .

break;

// действия происходят один раз в минуту

case TIMER_MIN:

. . .

break;

}

}; return 0;

Примечание. Для того чтобы установить новое время срабатывания для существующего таймера, следует уничтожить таймер функций KillTimer() и снова установить его функцией SetTimer().

Второй способ

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

Функция, которая будет получать эти таймерные сообщения, называется функцией обратного вызова (Call-back). Эта функция приложения, которую вызывает непосредственно Windows. Приложение сообщает Windows адрес этой функции, а позже Windows вызывает ее.

Как и оконная процедура, функция обратного вызова должна определяться как CALLBACK, поскольку Windows вызывает ее вне кодового пространства программы. Параметры функции обратного вызова и ее возвращаемое значение зависят от назначения функции обратного вызова.

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

Если для таймерной функции обратного вызова выбрано имя TimerProc, тогда эта функция должна иметь следующее определение (она будет обрабатывать только сообщения WM_TIMER):

void CALLBACK TimerProc(HWND hWnd, UINT iMsg, UINT iTimerID, DWORD dwTime){     // обработка сообщений WM_TIMER     . . .}Параметры функции:

· hWnd – дескриптор окна, задаваемый при вызове функции SetTimer.

· iMsg всегда будет равен WM_TIMER, т.к.  Windows будет посылать функции TimerProc() только сообщения WM_TIMER.

· iTimerID – это идентификатор таймера.

· dwTime – системное время.

При использовании функции обратного вызова для обработки сообщений WM_TIMER (второй способ использования таймера), четвертый параметр функции SetTimer() заменяется адресом функции обратного вызова:

   SetTimer(hWnd, 1, 1000, (TIMERPROC) TimerProc);

Третий способ

Третий способ установки таймера напоминает второй, за исключением того, что параметр hWnd функции SetTimer() устанавливается NULL, а второй параметр (идентификатор таймера) игнорируется. Функция возвращает ID таймера (возвращаемое функцией значение будет равно NULL, если таймер недоступен):

UINT iTimerID;

iTimerID = SetTimer(NULL, 0, 1000, (TIMERPROC) TimerProc);

Первый параметр функции KillTimer() при удалении установленного таймера также должен быть равен NULL. Идентификатор таймера должен быть равен значению, возвращаемому функцией SetTimer():

   KillTimer(NULL, iTimerID);

Такой метод установки таймера используется относительно редко. Он удобен, если в программе в разное время делается много вызовов функции SetTimer(), и при этом не запоминаются те таймерные идентификаторы, которые уже использовались.

 


Тема: Ресурсы приложения и их использование

 

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

Файлы ресурсов (.rc) являются текстовыми файлами (их можно создать как специальным редактором ресурсов, так и текстовым редактором) и компилируются компилятором ресурсов. Полученный в результате двоичный файл (.res) компонуется с остальными частями приложения, образуя исполняемый exe-файл, содержащий программный код и информацию о ресурсах.

Ресурсы также могут включаться в отдельную динамически связываемую библиотеку - DLL (файл .dll). В этом случае при изменении файла ресурсов не требуется перекомпилировать всё приложение, а нужно только заменить DLL.

 

Структура файла ресурсов

Файл ресурсов представляет собой набор директив препроцессора и операторов описания ресурсов:

#include "resource.h"

#include "windows.h"

…. // другие директивы препроцессора

оператор описания ресурса1

….

оператор описания ресурсаN

 

Операторы описания ресурсов могут быть двух видов: однострочные и многострочные.

Однострочные операторы определяют следующие типы ресурсов: пиктограммы (ICON), курсоры (CURSOR), растровые изображения (BITMAP), шрифты (FONT), язык ресурсов (LANGUGE).

Однострочный оператор имеет следующий вид:

Идентификатор Тип_ресурса [Характеристика_загрузки] "Имя_файла_ресурса"

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

Для ресурсов типа BITMAP, CURSOR, FONT и ICON также может указываться характеристика загрузки DISCARDABLE, указывающая, что ресурс может быть удален из памяти, если он больше не требуется, например:

MyBitmap BITMAP DISCARDABLE “mybitmap.bmp”

  

Многострочные операторы определяют следующие типы ресурсов: таблицы строк (STRINGTABLE), меню (MENU), таблицы акселераторов (ACCELERATORS), диалоговые окна (DIALOG), пользовательские данные (RCDATA) и ресурсы информации о версии.

Форма записи многострочного оператора следующая:

Идентификатор Тип_ресурса [Необязательные_параметры]

[Необязательные_инструкции]

BEGIN

[Инструкции]

END

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

 

Определение и использование различных типов ресурсов

Пиктограммы

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

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

Для включения пиктограммы в файл описания ресурсов используется оператор ICON, например:

MyIcon ICON "iconfile.ico"

Функция LoadIcon() используется в приложениях для получения дескриптора пиктограммы:

HICON LoadIcon(HINSTANCE hInst, LPCTSTR lpszIcon);

Параметры функции:

· hInst - дескриптор экземпляра приложения.

· lpszIcon - идентификатор пиктограммы из описания ресурсов, заданный в виде указателя на строку.

Если первый параметр функции LoadIcon() установлен в NULL, то это означает, что данная пиктограмма является преодопределенной (с префиксом IDI_). Предопределенные пиктограммы описаны в заголовочном файле windows.h:

//загрузка предопределенной пиктограммы для приложения

LoadIcon(NULL, IDI_APPLICATION);

 

Способы загрузки пиктограмм, определенных в ресурсах приложения

1. Идентификатор ресурса пиктограммы в описании задан именем:

Описание ресурса: MyIcon ICON "iconfile.ico"

Текст программы: HICON hIcon=LoadIcon(hInst,”MyIcon”);

2. В качестве идентификатора ресурса используется число (16-разрядное беззнаковое WORD):

Описание ресурса: 125 ICON "iconfile.ico"

Текст программы:   

HICON hIcon=LoadIcon(hInst, MAKEINTRESOURCE(125));

Макрос MAKEINTRESOURCE() определен в заголовочных файлах Windows, он преобразует число в указатель, но со старшими разрядами, установленными в нуль.

 

Чтобы окно hWnd имело требуемую пиктограмму необходимо дескриптор, возвращаемый функцией LoadIcon(), присвоить полю пиктограммы структуры класса окна:

wndclass.hIcon=LoadIcon(hInst,”MyIcon”);

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

SetClassLong(hWnd, GCL_HICON, LoadIcon(hInst,”Icon_ID”));

где Icon_ID – идентификатор требуемой пиктограммы.

Замечания:

1. После того, как приложение загрузило пиктограмму, ее можно также нарисовать в любом месте экрана функцией DrawIcon().

2. Если загруженная с помощью функции LoadIcon() пиктограмма приложению больше не нужна, то можно освободить занимаемую ею память, вызвав функцию DestroyIcon().

 

Курсоры

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

Оператор для описания курсора в файле ресурсов имеет вид, аналогичный для пиктограммы, при этом указывается вид ресурса - CURSOR. Для получения дескриптора курсора используется функция LoadCursor():

Описание ресурса: MyCursor CURSOR "cursfile.cur"

Текст программы:   

HCURSOR hCursor=LoadCursor(hInst, ”MyCursor”);

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

wndclass.hCursor= LoadCursor(hInst, "MyCursor”);

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

SetClassLong(hWnd, GCL_HCURSOR, LoadCursor(hInst,

”Cursor_ID”));

где Cursor_ID – имя требуемого курсора.

Windows содержит несколько встроенных курсоров. Их идентификаторы описаны в файле windows.h и начинаются с префикса IDC_. Для загрузки встроенных курсоров в функцию LoadCursor() в качестве первого параметра передается NULL:

 LoadCursor(NULL, IDC_ARROW);

Замечания:

1. Для того чтобы выключить изображение курсора или вновь его включить, используют функцию ShowCursor().

2. Если курсор, загруженный с помощью функции LoadCursor(), приложению больше не нужен, то можно освободить занимаемую им память, вызвав функцию DestroyCursor().

 

Битовые изображения

Графические изображения широко используются для оформления внешнего вида окон приложения. В ресурсы приложения такие изображения включают в виде битового образа (ресурс типа BITMAP). Изображения создаются с помощью графических редакторов и записываются в файл с расширением имени .bmp.

Битовый образ включается в файл описания ресурсов в том же формате, что пиктограмма или курсор:

MyBmp BITMAP "bmpfile.bmp"

Для загрузки этого ресурса используется функция LoadBitmap(). Ее возвращаемым значением является дескриптор битового образа:

HBITMAP hBitmap=LoadBitmap(hInst, ”MyBmp”);

Битовые образы используются в следующих случаях:

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

Для создания кисти из изображения используется функция CreatePatternBrush(), в качестве параметра которой задается дескриптор битового образа hBitmap. Эта функция возвращает дескриптор кисти, который можно использовать при регистрации окна:

HBRUSH hBrush=CreatePatternBrush(hBitmap);

wndclass.hbrBackground=hBrush;

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

Перед завершением работы приложения созданная кисть должна быть уничтожена функцией DeleteObject().

2. Рисование на экране картинок . Битовые образы можно просто рисовать в рабочей области окна; можно использовать их в кнопках, определяемых пользователем; применять при работе с меню.

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

Пример вывода битового изображения в рабочую область окна. Выводится оно, начиная от точки с координатами (100, 100) с фактическими размерами:

HDC hDC=GetDC(hWnd); // Получение контекста у-ва

// Создание контекста, совместимого с контекстом окна

HDC BitmapDC=CreateCompatibleDC(hDC);

// Выбор объекта в контекст устройства

HBITMAP hOldBitmap=

     (HBITMAP)SelectObject(BitmapDC, hBitmap);

// Получение размеров изображения

int iHorSize=GetDeviceCaps(BitmapDC, HORZSIZE);

int iVerSize=GetDeviceCaps(BitmapDC, VERTSIZE);

// Вывод битового образа в окно

BitBlt(hDC,100,100,iHorSize,iVerSize,BitmapDC,0,0,SRCCOPY);

// Восстановление прежнего объекта

SelectObject(BitmapDC, hOldBitmap);

// Удаление созданного контекста

DeleteDC(BitmapDC);

ReleaseDC(hWnd,hDC); // Освобождение контекста у-ва

Символьные строки

Использование в качестве ресурсов символьных строк предназначено главным образом для облегчения перевода (локализации) приложения на другие языки.

Такой ресурс задается в виде таблицы строк с помощью  ключевого слова STRINGTABLE, за которым следуют несколько определений строк, заключенных между ключевыми словами BEGIN-END:

STRINGTABLE

BEGIN

     id1 “содержимое строки 1”

     id2 “содержимое строки 2”

     … // определения остальных строк

END

Идентификаторы строк id1, id2 . . ., которые предшествуют каждой строке, должны быть или числами, или идентификаторами макроопределений, которые задаются в заголовочном файле. В описании ресурсов может быть только одна таблица строк. Максимальный размер каждой строки – 255 символов.

Приложения ссылаются на эти строки по символьным идентификаторам.

Например:

// Определение идентификаторов строк в заголов. файле

# define IDS_HELLO 1

# define IDS_BYE 2

. . .

// Описание таблицы строк в файле ресурсов

STRINGTABLE

BEGIN

     IDS_HELLO “Hello”

     IDS_BYE   “Good bye”

END

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

char szBuffer[256];

LoadString(hInst, IDS_BYE, szBuffer, 255);

MessageBox(hWnd, szBuffer,”Text from stringtable”,MB_OK);

 

 

Тема: Создание и использование меню в приложениях

Меню представляет собой ресурс типа MENU. Структура меню определяется в описании ресурсов, каждому пункту меню присваивается уникальный идентификатор. Имя меню указывается в структуре класса окна при регистрации этого класса. Когда пользователь выбирает пункт меню, Windows посылает приложению сообщение WM_COMMAND, содержащий идентификатор этого пункта.

 

Типы меню

1. Главное меню окна (main menu) или меню верхнего уровня (top-level menu). Строка меню выводится непосредственно под строкой заголовка окна.

2. Всплывающее меню (popup menu) или подменю (submenu). Появляется при выборе элемента главного меню.

3. Плавающее (floating menu). Приложение может создать меню в любом месте экрана – независимое всплывающее меню.

4. Системное меню (system menu). В левой части заголовка главного окна приложения находится пиктограмма приложения, щелчок по которой приводит к появлению этого типа меню. Приложение может изменять системное меню, дополняя его новыми строками, удалять строки.

 

Свойства пунктов меню

Пункты всплывающих меню могут быть отмечены (checked), при этом слева от текста пункта меню ставится специальная метка. Эти метки указывают, какие опции программы выбраны из этого меню. Пункты главного меню не могут быть отмечены.

Пункты в главном и всплывающих меню могут быть разрешены (enabled, active), запрещены (disabled, inactive) или недоступны (grayed).

Пункты, помеченные как разрешенные или запрещенные, для пользователя выглядят одинаково, а недоступный пункт меню выводится в сером цвете.

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

 

Способы создания меню:

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

2. Динамическое создание меню в программе при помощи специальных функций Win32 API. Этот способ подходит для приложений, меняющих внешний вид меню, когда не получается создать подходящий шаблон заранее.

3. Подготовка шаблона меню непосредственно в оперативной памяти и создание меню на базе этого шаблона при помощи функции LoadMenuIndirect().

 

Создание меню с помощью шаблона (1-й способ)

Определение главного меню в файле ресурсов в форме шаблона меню с помощью редактора ресурсов имеет вид:

идентификатор_меню MENU

BEGIN

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

END

где идентификатор_меню может быть задан именем в виде текстовой строки или в виде макроконстанты, имеющей целое значение. Например:

MyMenu MENU

или

#define IDR_MENU1 100

. . .

IDR_MENU1 MENU

Внутри блока BEGIN-END описания главного меню можно использовать либо операторы MENUITEM, либо POPUP.

Оператор MENUITEM описывает отдельный пункт меню и имеет следующий формат:

MENUITEM текст_пункта, идентификатор [, атрибуты]

Формат оператора всплывающего меню POPUP следующий:

POPUP текст_пункта [, атрибуты]

BEGIN

. . . // список пунктов подменю

END

Атрибутами в операторах MENUITEM и POPUP, которые появляются в списке главного меню, являются следующие (атрибуты могут комбинироваться с помощью поразрядной операции ИЛИ):

· GRAYED - элемент меню отображается серым цветом и находится в недоступном состоянии. Данный элемент не генерирует сообщений WM_COMMAND.

· INACTIVE - элемент меню отображается в нормальном виде, но находится в неактивном состоянии. Данный элемент не генерирует сообщений WM_COMMAND.

· MENUBREAK - данный элемент меню, а также все последующие выводится в новой строке меню.

· HELP – данный элемент меню, а также все последующие появляются на экране, выровненные по правому краю.

Следующий за оператором POPUP блок BEGIN-END всплывающего меню определяет список пунктов этого подменю. При определении пунктов всплывающего меню допускаются три следующих оператора:

MENUITEM текст_пункта, идентификатор [, атрибуты]

или

MENUITEM SEPARATOR

или

POPUP текст_пункта [, атрибуты]

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

Атрибутами в инструкциях пунктов всплывающих меню являются следующие:

· CHECKED - при выводе пункт подменю отмечается галочкой.

· GRAYED – пункт подменю отображается серым цветом и находится в недоступном состоянии.

· INACTIVE - пункт подменю отображается в нормальном виде, но находится в неактивном состоянии.

· MENUBREAK - данный пункт подменю, а также все последующие выводится в новом столбце подменю.

· MENUBARBREAK - аналогично атрибуту MENUBREAK, но дополнительно новый столбец отделяется вертикальной линией.

Замечание. Если в строке текста элемента меню встречается символ &, то сам этот символ не выводится, а следующий за ним подчеркивается. Пользователь может выбрать этот элемент меню, нажав клавиши <Alt>+подчеркнутый символ.

 

Подключение меню к окну приложения

Это можно сделать тремя способами:

1. Подключение меню при регистрации класса окна.

В структуре класса окна полю lpszMenuName задается идентификатор меню:

WndClass.lpszMenuName=”MyMenu”;

или

WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU);

Тогда все окна, создаваемые на базе этого класса, будут иметь данное меню, если при создании их функцией CreateWindow() идентификатор меню указан как NULL.

2. Подключение меню при создании окна

Для подключения меню, отличного от указанного в классе окна, необходимо задать дескриптор нужного меню при создании окна функцией CreateWindow():

HMENU hMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU));

hWnd = CreateWindow( … , hMenu, hInst, NULL);

Таким образом, меню, указанное при вызове функции CreateWindow() перекрывает меню, заданное в классе.

3. Динамическое подключение меню

Можно также указать NULL для меню при регистрации класса окна и NULL для меню при вызове функции CreateWindow(), а затем присоединить загруженное меню к окну с помощью функции SetMenu():

HMENU hMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU));

. . .

SetMenu(hWnd, hMenu);

Данный способ позволяет динамически подключать и в любое время изменять меню окна.

 

Динамическое создание меню (2-й способ)

Приложение может не использовать файл описания ресурсов и с помощью функций Win32 API создать все меню в процессе работы приложения.

Для динамического создания меню используются следующие функции:

1. Функция CreateMenu() создает пустое меню верхнего уровня и возвращает его дескриптор:

HMENU CreateMenu(VOID);

2. Создание пустого всплывающего меню (подменю) производится функцией CreatePopupMenu(), которая возвращает дескриптор этого меню:

HMENU CreatePopupMenu(VOID);

Всплывающие меню сначала строятся отдельно, а затем их дескрипторы вставляются в меню верхнего уровня.

3. Добавление элементов в меню (в главное и всплывающие меню) производится с помощью функции AppendMenu():

BOOL AppendMenu(HMENU hMenu, UINT uFlags,

     UINT_PTR uIDNewItem, LPCTSTR lpNewItem);

Параметры функции:

hMenu – дескриптор меню; uFlags – флаг(и), описывающие тип и состояние нового пункта меню; uIDNewItem – идентификатор пункта меню или дескриптор подменю; lpNewItem – строка с названием пункта меню (подменю).

Параметр uFlags может задавать: тип пункта меню (MF_POPUP - подменю, MF_STRING - строка, MF_BITMAP - битовый образ, MF_SEPARATOR – разделитель) и(или) его состояние (MF_CHECKED, MF_UNCHECKED, MF_DISABLED, MF_ENABLED, MF_GRAYED). Несколько флагов могут объединяться поразрядной логической операцией ИЛИ (|).

4. Для подключения меню верхнего уровня к созданному ранее окну hWnd служит функция SetMenu(), а для отображения строки меню - функция DrawMenuBar():

SetMenu(hWnd, hMenu);

DrawMenuBar(hWnd);

5. С помощью функции DestroyMenu() приложение перед завершением работы должно удалить меню, созданное описанным выше способом:

DestroyMenu(hMenu);

 

Пример создания меню верхнего уровня, элементами которого являются два всплывающих меню (каждое содержит по два пункта) и один обычный элемент, с последующим его присоединением к уже созданному окну hWnd:

#dеfine ID_OPEN 40

#dеfine ID_ EXIT 41

#dеfine ID_COLOR 42

#dеfine ID_FONT 43

#dеfine ID_HELP 44

. . .

static HMENU hMainMenu, hMenuFile, hMenuSetup;

. . .

hMainMenu=CreateMenu();

// Создание первого всплывающего меню

hMenuFile=CreatePopupMenu();

AppendMenu(hMenuFile,MF_STRING,ID_OPEN,”Open file…”);

AppendMenu(hMenuFile,MF_SEPARATOR,0,NULL);

AppendMenu(hMenuFile,MF_STRING,ID_EXIT,”Exit”);

// Создание второго всплывающего меню

hMenuSetup=CreatePopupMenu();

AppendMenu(hMenuSetup,MF_STRING,ID_COLOR,”Choose color…”);

AppendMenu(hMenuSetup,MF_STRING,ID_FONT,”Choose font…”);

// Включение всплывающих меню в главное

AppendMenu(hMainMenu,MF_POPUP,(UINT)hMenuFile,”File”);

AppendMenu(hMainMenu,MF_POPUP,(UINT)hMenuSetup,”Setup”);

AppendMenu(hMainMenu,MF_STRING,ID_HELP,”Help”);

. . .

// Присоединение меню к окну и вывод его

SetMenu(hWnd,hMainMenu);

DrawMenuBar(hWnd);

. . .

 

Сообщения, поступающие от меню

Когда пользователь выбирает пункт любого меню, Windows посылает оконной функции несколько сообщений: WM_COMMAND, WM_INITMENU, WM_INITMENUPOPUP, WM_SYSCOMMAND. Большинство из этих сообщений обычно игнорируется программой и передается на обработку в функцию DefWindowProc().

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

 

Пример фрагмента оконной функции, в котором обрабатываются сообщения от обычных меню:

case WM_COMMAND:

{

UINT idItem= LOWORD(wParam);

switch(idItem)

{

case ID_ITEM1: . . . // Обработка 1-го пункта меню

      break;

case ID_ITEM2: . . . // Обработка 2-го пункта меню

      break;

case ID_ITEM3: . . . // Обработка 3-го пункта меню

      break;

}

}; return 0;

 

Плавающее (независимые всплывающие ) меню

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

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

Порядок создания плавающего меню следующий:

1. Сначала при помощи функции CreatePopupMenu() создается пустое всплывающее меню. Это меню заполняется обычным образом при помощи функции AppendMenu(), но затем оно не привязывается к главному меню приложения или какому-либо другому меню.

2. Вместо этого создается плавающее меню. Для этого идентификатор этого меню передается функции TrackPopupMenu(). Эта функция выводит на экран плавающее меню и создает свой собственный цикл обработки сообщений, завершающий работу после выбора строк. Функция TrackPopupMenu() не возвращает управление до тех пор, пока работа с меню не будет завершена либо выбором строки, либо отказом от выбора.

3. После выбора пункта плавающего меню (или отказа от выбора) само меню исчезает, а оконной процедуре окна, к которому присоединено это меню, посылается сообщение WM_COMMAND (аналогично сообщениям обычного оконного меню).

Синтаксис функции TrackPopupMenu() следующий:

BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, CONST RECT *prcRect);

Параметры функции:

1. hMenu - дескриптор отображаемого плавающего меню.

2. uFlags - комбинация флажков, которые задают функциональные па­раметры плавающего меню: способ размещения меню по го­ризонтали и вертикали относительно параметров х, y; кнопку мыши, которую просле­живает плавающее меню

3. х - координата по горизонтали от левого края окна.

4. у - координата по вертикали от верхнего края окна.

5. nReserved - зарезервированный параметр, должен быть всегда равен нулю.

6. hWnd - дескриптор уже существующего окна-владельца, которое по­лучит сообщения от меню. Сообщение WM_COMMAND окно полу­чит только после завершения работы функции TrackPopupMenu().

7. prcRect - указатель на прямоугольную область, находясь в пределах которой можно работать с меню. Если сделать щелчок мышью за пределами этого прямоугольника, плавающее меню исчезнет. Если prcRect=NULL, то эта область ограничена прямоугольной рамкой плавающего меню.

Пример фрагмента оконной функции окна hWnd, создающей плавающее меню по щелчку правой клавишей мыши в рабочей области окна и обрабатывающей сообщения от этого меню:

#define ID_ARROW 100

#define ID_CROSS 101

. . .

static HMENU hPopMenu;

. . .

case WM_CREATE:

// создание плавающего меню

{ hPopMenu=CreatePopupMenu();

AppenMenu(hPopMenu,MF_ENABLED|MF_STRING,ID_ARROW,

"IDC_ARROW");

AppendMenu(hPopMenu,MF_ENABLED|MF_STRING,ID_CROSS,

"IDC_CROSS");

}; return 0;

. . .

case WM_RBUTTONDOWN:

// отображение плавающего меню

{ RECT r;

GetWindowRect(hWnd, &r);

TrackPopupMenu(hPopMenu, TPM_CENTERALIGN| TPM_LEFTBUTTON, r.left+LOWORD(lParam), r.top+HIWORD(lParam), 0, hWnd, NULL);

}; return 0;

. . .

case WM_COMMAND:

// обработка сообщений плавающего меню

{ switch(LOWORD(wParam))

{

case ID_ARROW:  

. . . // операции по пункту меню "IDC_ARROW"

break;

case ID_CROSS:   

. . . // операции по пункту меню "IDC_CROSS"

break;

}

}; return 0;

. . .

case WM_DESTROY:

DestroyMenu(hPopMenu); // удаление плавающего меню

PostQuitMessage(0);

return 0;

. . .

 

Тема: Работа с диалоговыми панелями, стандартные диалоги

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

Для расположения элементов управления на поверхности диалоговой панели используется три способа:

1. Описание шаблона диалоговой панели создается в файле ресурсов при помощи любого текстового редактора.

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

3. Создание шаблона диалоговой панели в памяти во время работы приложения.

Для создания диалоговой панели необходимо выполнить следующие действия:

· Создать шаблон диалога.

· Описать функцию диалога (диалоговую процедуру).

· Вызвать функцию создания диалога.

Типы диалоговых панелей

В Windows имеется два типа диалоговых окон: модальные и немодальные.

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

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

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

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

 

Шаблон диалоговой панели

Оператор описания диалогового окна DIALOG, содержащийся в файле ресурсов приложения, определяет его размещение и внешний вид, а также список всех его элементов управления:

Имя_или_Идентификатор DIALOG x, y, w, h

// необязательные операторы, определяющие св-ва диалога

BEGIN

     // операторы, определяющие элементы управления

END

Параметры x, y задают координаты расположения окна, а w, h – ширину и высоту.

Необязательные операторы могут быть следующие:

· CAPTION указывает заголовок диалогового окна. По умолчанию диалоговое окно не имеет заголовка.

· STYLE определяет стиль диалогового окна.

· FONT определяет используемый в диалоговом окне шрифт. По умолчанию используется системный шрифт.

· MENU указывает ресурс меню, определяющий меню этого диалогового окна. При отсутствии этого оператора диалоговое окно будет создано без строки меню.

Операторы, определяющие элементы управления диалогового окна, заключенные между ключевыми словами BEGIN-END имеют вид:

тип_элемента_управления "text", id, x, y, w, h [, style]

Типы элементов управления:

· EDITTEXT определяет поле ввода.

· COMBOBOX определяет раскрывающийся список.

· LISTBOX используется для определения окна со списком.

· SCROLLBAR – применяется для полосы прокрутки.

· Статические элементы управления для вывода надписей могут иметь тип LTEXT, CTEXT, RTEXT или ICON.

· Кнопка определяется одним из следующих ключевых слов: PUSHBUTTON, CHECKBOX, RADIOBUTTON и др.

Другие параметры: "text" - заголовок элемента, id – его идентификатор.

 

Модальная диалоговая панель

 

Создание окна модальной диалоговой панели

Для отображения модальной диалоговой панели, внешний вид которой определяется шаблоном с идентификатором IDR_DIALOG1, а поведение диалоговой процедурой DlgProc, используется функция DialogBox:

int iCode=DialogBox(hInst,MAKEINTRESOURCE(IDR_DIALOG1), hWnd, DlgProc);

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

 

Диалоговая процедура модальной диалоговой панели

Диалоговая процедура обрабатывает сообщения, получаемые окном диалога. Большинство элементов управления посылают своему родительскому окну сообщения WM_COMMAND (кроме полосы прокрутки).

Для модального диалога диалоговая процедура DlgProc имеет следующий вид:

BOOL CALLBACK DlgProc(HWND hDlg,UINT message, WPARAM wParam,LPARAM lParam)

{

 switch(message)

 {

case WM_INITDIALOG:

{  // различные инициализации

. . .

return TRUE;

};

case WM_COMMAND:

{ switch(LOWORD(wParam))

{

case IDCANCEL:

// нажаты или ESC, или Ctrl+Break, или пункт

// меню IDCANCEL, или кнопка IDCANCEL

EndDialog(hDlg, IDCANCEL);

return TRUE;

case IDOK:

// нажата кнопка IDOK или пункт меню IDOK или

// нажата ENTER и при этом ни одна из кнопок не   

// находилась в фокусе

EndDialog(hDlg, IDOK);

return TRUE;

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

case ID. . . :

. . .

}

 }; break;

case WM_CLOSE: // закрытие окна при помощи системного меню

{     

PostMessage(hDlg, WM_COMMAND, IDCANCEL, 0L);

}; return TRUE;

 }

 return FALSE;

}

 

Немодальная диалоговая панель

 

Создание окна немодальной диалоговой панели

Для создания немодальной диалоговой панели, внешний вид которой определяется шаблоном с идентификатором IDR_DIALOG2, а поведение диалоговой процедурой DlgModalessProc, используется функция CreateDialog. Параметры этой функции те же, что и у функции DialogBox:

HWND hDlgModaless=NULL; // дескриптор окна диалога,

                              // глобальная переменная

. . .

hDlgModaless=CreateDialog(hInst, MAKEINTRESOURCE(

               IDR_DIALOG2), hWnd, DlgModalessProc);

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

 

Диалоговая процедура немодальной диалоговой панели

Простейшая диалоговая процедура DlgModalessProc для немодального диалога должна иметь следующий вид:

BOOL CALLBACK DlgModalessProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

switch(message)

{

case WM_INITDIALOG:

{ ... // различные инициализации

     return TRUE;

};

case WM_COMMAND:

{ switch(LOWORD(wParam)

     {

      case IDCANCEL: // если есть кнопка IDCANCEL

      CloseWindow(hDlg);

      break;

      // обработка сообщений от других элементов

      // управления

      ...

     }

}; break;

case WM_CLOSE: // закрытие через системное меню

{     

     DestroyWindow(hDlg); // не EndDialog !!!

     hDlgModaless=NULL;

}; return TRUE;

}

  return FALSE;

}

 

Особенности работы с немодальными окнами диалога

Работа с немодальными окнами диалога похожа на работу с модальными, но имеет несколько отличий:

1)  немодальные окна диалога похожи на временные (всплывающие) окна и обычно содержат строку заголовка и значок системного меню. Строка заголовка и системное меню дают пользователю возможность перемещать немодальное окно диалога по экрану как с помощью мыши, так и клавиатуры. Инструкция STYLE в шаблоне окна диалога для немодального окна должна выглядеть следующим образом:

STYLE WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_VISIBLE

2) если в инструкцию STYLE не включен стиль WS_VISIBLE, то после вызова функции CreateDialog необходимо вызвать функцию ShowWindow, так как иначе немодальное окно не появится на экране:

hDlgModaless=CreateDialog(…);

ShowWindow(hDlgModaless, SW_SHOW);

3) для закрытия немодального диалога следует в диалоговой процедуре использовать функцию DestroyWindow. После вызова функции DestroyWindow глобальная переменная hDlgModaless должна быть установлена в NULL:

case WM_CLOSE:

{        

DestroyWindow(hDlg);

hDlgModaless=NULL;

}; return TRUE;

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

Передача сообщений немодальным окнам диалогов

Для этого в программе необходимо выполнить следующие действия:

а) объявить глобальную переменную для хранения дескриптора созданного окна немодального диалога, например, hDlgModaless:

HWND hDlgModaless=NULL;

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

hDlgModaless=CreateDialog(…);

в) необходимо изменить цикл обработки сообщений, чтобы он выглядел так:

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

{

if(hDlgModaless==NULL || !IsDialogMessage(hDlgModaless,

&msg))

{

     TranslateMessage(&msg);

     DispatchMessage(&msg);

}

}

Если сообщение предназначено для немодального диалога, то функция IsDialogMessage отправляет его оконной процедуре окна диалога и возвращает TRUE (не 0); в противном случае она возвращает FALSE (0). Функции TranslateMessage и DispatchMessage будут вызываться только в том случае, если hDlgModaless равен NULL или если сообщение не для окна диалога.


Стандартные диалоговые панели

В Win32 реализован ряд часто употребляемых диалоговых окон. К ним относятся

· диалоговые окна открытия (“Open”) и сохранения (“Save As”) файлов,

· выбора цвета (“Color”) и шрифта (“Font”),

· печати (“Print”) и ее настройки (“Page Setup”),

· поиска (“Find”) и замены (“Replace”) текста.

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

#include <commdlg.h>

а также приведены в таблице

Имя диалога Вызываемая функция Используемая структура
Open GetOpenFileName OPENFILENAME
Save As GetSaveFileName OPENFILENAME
Color ChooseColor CHOOSECOLOR
Font ChooseFont CHOOSEFONT
Print PrintDlg PRINTDLG
Page Setup PageSetupDlg PAGESETUPDLG
Find FindText FINDREPLACE
Replace ReplaceText FINDREPLACE

 

Диалоговое окно “Open

Открывается при вызове функции GetOpenFileName. Единственным параметром функции является указатель на структуру OPENFILENAME. Если пользователь выбрал файл и нажал кнопку OK, функция возвращает значение TRUE. При этом по адресу в поле lpstrFile структуры OPENFILENAME запишется полный путь и имя выбранного файла. В противном случае функция возвращает FALSE.

Пример использования функции GetOpenFileName в оконной процедуре окна Wnd:OPENFILENAME ofn;       // Open dialog box structurechar szFileName[260]; // buffer for file nameHWND hWnd;           // owner window handler // Инициализация OPENFILENAMEZeroMemory(&ofn, sizeof(ofn));ofn.lStructSize = sizeof(ofn);ofn.hwndOwner = hWnd;ofn.lpstrFile = szFileName;ofn.lpstrFile[0] = '\0';ofn.nMaxFile = sizeof(szFileName);ofn.lpstrFilter = "Все\0*.*\0Текстовые\0*.TXT\0";ofn.nFilterIndex = 1;ofn.lpstrFileTitle = NULL;ofn.nMaxFileTitle = 0;ofn.lpstrInitialDir = NULL;ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; // Отображение диалогового окна Open

if (GetOpenFileName(&ofn)==TRUE)

{

// пользователь выбрал файл, полное имя которого

// хранится в szFileName

}

 

Диалоговое окно “ Color ”

Это диалоговое окно используется для выбора цвета из системной палитры или определения пользовательского цвета. Оно появляется при вызове функции ChooseColor. Начальное значение в этом диалоговом окне передается через указатель на структуру CHOOSECOLOR, поле rgbResult этой структуры содержит выбранный цвет.

Пример использования функции ChooseColor в оконной процедуре окна Wnd:

static COLORREF rgb_text, CustColors[16];

CHOOSECOLOR CC;

. . .

rgb_text=RGB(0,0,255);

for(int i=0; i<16; i++) CustColors[i]=0;

...

memset(&CC,0,sizeof(CHOOSECOLOR));

CC.lStructSize=sizeof(CHOOSECOLOR);

CC.hwndOwner=hWnd;

CC.hInstance=NULL;

CC.lpCustColors=CustColors;

CC.Flags=CC_RGBINIT|CC_FULLOPEN;

CC.rgbResult=rgb_text;

// Отображение диалогового окна Color

if(ChooseColor(&CC))

{

 // пользователь выбрал цвет,

 // информация о нем хранится в CC.rgbResult

 rgb_text=CC.rgbResult;

}

 

Тема: Работа с элементами управления в Windows -программах

Стандартные элементы управления являются дочерними окнами и имеют вид кнопок, флажков, окон редактирования, списков, комбинированных списков, строк текста и полос прокрутки.

 

Сообщения элементов управления родительскому окну

Если элемент управления изменяет свое состояние, то функция родительского окна получает сообщение WM_COMMAND. Вместе с сообщением оконная процедура получает и дополнительную информацию:

LOWORD(wParam) - идентификатор дочернего окна (тип UINT);

HIWORD(wParam) - код уведомления (тип UINT);

lParam - дескриптор дочернего окна (тип HWND).

· Идентификатор дочернего окна – это значение, передаваемое функции CreateWindow, когда создается рабочее окно.

· Дескриптор дочернего окна – это значение, которое Windows возвращает при вызове функции CreateWindow.

· Код уведомления – это дополнительный код, который дочернее окно использует для того, чтобы сообщить родительскому окну более точные сведения о сообщении.

Константы, идентифицирующие различные коды уведомления от элементов управления, определены в заголовочных файлах Windows и имеют следующие обозначения:

BN_CLICKED – нажата кнопка класса “button”,

EN_CHANGE - текст в окне редактирования класса “edit” изменился,

LBN_ DBLCLK - двойной щелчок левой клавишей мыши по строке списка класса “listbox”,

CBN_ DBLCLK - двойной щелчок левой клавишей мыши по строке списка класса “combobox”.

Пример фрагмента оконной процедуры родительского окна, в котором происходит обработка нажатия на дочернее окно-кнопку с идентификатором ID_button:

case WM_COMMAND:

{        

UINT idCtl=LOWORD(wParam); // идентификатор дочернего окна

UINT code=HIWORD(wParam); // код уведомления

HWND hChild=(HWND)lParam; // дескриптор дочернего окна

if(idCtl==ID_button && code==BN_CLICKED)

{

// кнопка была нажата

. . .  // действия, связанные с нажатием кнопки

CloseWindow(hWnd); // закрыть окно-родителя

}

}; return 0;

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

 

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

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

Передать можно как обычное оконное сообщение (с префиксом WM_), так и специфические для каждого типа элемента управления

Константы, идентифицирующие различные сообщения для дочерних окон управления, определены в заголовочных файлах Windows и имеют соответственно следующие префиксы: BM_ - “button”, EM_ - “edit”, LB_ - “listbox”, CB_ - “combobox”. Для работы с окнами класса “scrollbar” применяются специальные Set/Get-функции WinAPI.

Существует два способа передачи сообщений:

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

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

Предварительно необходимо получить дескриптор дочернего окна на основании его идентификатора с помощью функции GetDlgItem.

Пример сообщения диалогового окна hDlg дочернему окну редактирования класса “edit” c дескриптором hWndEdit об установке максимального количества вводимых символов (5 символов):

static UINT ID_edit=3;

static HWND hWndEdit;

. . .

HWND hWndEdit=GetDlgItem(hDlg, ID_edit);

. . .

SendMessage(hWndEdit,EM_LIMITTEXT,5,0L);

. . .

 

Функции для работы с элементами управления

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

· Для заполнения списка LISTBOX именами файлов, каталогов и дисковых устройств предназначена функция DlgDirList.

· Для списка COMBOBOX определена аналогичная функция DlgDirListComboBox.

· Для получения строки, связанной с элементом управления, можно использовать функцию GetDlgItemText.

· Функция GetDlgItemInt, получает от элемента управления текстовую строку и выполняет преобразование ее в целое число.

· Функция CheckRadioButton снимает контрольные метки со всех радио-кнопок RADIOBUTTONза исключением одной.

· Функция CheckDlgButton снимает или устанавливает контрольную метку для заданного флажка-переключателя CHECKBOX.

· Функция IsDlgButtonCkecked позволяет получить текущее состояние флажка переключателя CHECKBOX.

 

Примеры использования некоторых функций

1. Получение строки текста от окна редактирования с идентификатором ID_EDIT1 с запоминанием ее в буфере после нажатия кнопки с идентификатором IDOK.

static char szBuffer[80]; // буфер . . .case WM_COMMAND:  switch (LOWORD(wParam))  {   case IDOK:    {     GetDlgItemText(hwndDlg, ID_EDIT1, szBuffer, 80); . . . // другие действия, связанные с нажатием кнопки                   EndDialog(hwndDlg, wParam);     return TRUE;    }  . . . }

2. Заполнение окна listbox с идентификатором IDL_TEAMLIST списком имен игроков команды и получение номера из этого списка при выборе пользователя:

#define TEAMSIZE 5 . . .char *Name[]={"Alan","Colin","Pitcher","Cindy","Dave"};. . .BOOL CALBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)     {  int nItem, i;  HWND hwndList;  switch (message)  {   case WM_INITDIALOG:   {    hwndList = GetDlgItem(hDlg, IDL_TEAMLIST);    // Заполнение list box именами игроков    for (i = 0; i < TEAMSIZE; i++)    {     SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM) Name[i]);     SendMessage(hwndList, LB_SETITEMDATA, i, (LPARAM) i);    }    return FALSE;  }  case WM_COMMAND:   switch (LOWORD(wParam))   {    case IDL_TEAMLIST:     if (HIWORD(wParam)==LBN_SELCHANGE) {       hwndList=GetDlgItem(hDlg, IDL_SOFTBALL);       nItem=SendMessage(hwndList,LB_GETCURSEL,0,0);       i = SendMessage(hwndList,LB_GETITEMDATA,nItem,0);                            return TRUE;      }

. . .

}

 

3. Снятие контрольных меток со всех радио-кнопок диалоговой панели hDlg с идентификаторами от idFirst до idLast, за исключением радио-кнопки с идентификатором idCheck, которая, наоборот, включается:

     CheckRadioButton(hDlg, idFirst, idLast, idCheck);

4. Если в окне диалога hDlg создан элемент управления CHECKBOX с идентификатором idCheckbox, то снять или установить контрольную метку (iCheck – 0/1) можно следующим образом:

     CheckDlgButton(hDlg, idCheckbox, iCheck);

5. Получение состояния флажка в окне диалога в любой момент времени:

     int iCheck=IsDlgButtonCkecked(hDlg, idCheckbox);

 

 

Работа с различными элементами управления

 


Дата добавления: 2019-09-13; просмотров: 199; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!