- •ВВЕДЕНИЕ
- •1. ОБЩАЯ СТРУКТУРА ПРИЛОЖЕНИЯ WINDOWS
- •1.1. Главная функция WinMain()
- •1.2. Класс окна и его характеристики
- •1.3. Создание и показ окна
- •1.4. Обработка сообщений
- •1.5. Оконная функция
- •1.6. Сообщения Windows
- •1.7. Создание приложения с главным окном
- •1.7.1. Окна сообщений
- •1.7.2. Вывод текстовых строк
- •1.7.3. Атрибуты цвета и фона выводимого текста
- •1.7.4. Приложение с главным окном
- •2. МЕНЮ
- •2.1. Организация и виды меню
- •2.2. Приложение с главным окном и меню
- •3. ЭЛЕМЕНТЫ УПРАВЛЕНИЯ ОБЩЕГО ПОЛЬЗОВАНИЯ
- •3.1. Панель инструментов
- •3.1.1. Приложение с главным меню и панелью инструментов
- •3.2. Строка состояния
- •Библиографический список
Функция GetClientRect копирует параметры прямоуголь- ника, ограничивающего клиентскую часть окна, в структурную переменную типа RECT. Параметры даются относительно левого верхнего угла клиентской области окна, поэтому поля left и top всегда равны нулю, а поля right и bottom содержат ширину и высоту клиентской области в пикселях.
Метод форматирования задается параметром uFormat, кото- рый может быть задан, например, комбинацией следующих флагов:
DT_SINGLELINE | DT_CENTR | DT_VCENTR
где DT_SINGLELINE показывает, что текст будет выводиться в одну строку; DT_CENTR – текст будет выводиться по центру отно- сительно горизонтали прямоугольной области; DT_VCENTR – от-
носительно вертикали
1.7.3. Атрибуты цвета и фона выводимого текста
Цвет объектов задается 32-битным числом (тип COLORREF), например: 0x00bbggrr, где b – синяя, g – зеленая, r – красная составляющая цвета. Для создания цвета можно использовать мак-
рос RGB(R,G,B).
Для установки цвета текста (text color) применяется функция SetTextColor, прототип которой имеет вид
COLORREF SetTextColor(HDC hDc, COLORREF crColor);
Для установки цвета фона графического элемента (background color), т.е. цвета, который отображается под каж- дым символом, используется функция SetBkColor, имеющая следующий прототип:
COLORREF SetBkColor(HDC hDc, COLORREF crColor);
Для обеих функций первый параметр hDc – контекст устрой- ства, второй crColor – цвет текста или фона соответственно. Обе функции возвращают ссылку на предыдущий цвет.
Для установки режима смешивания фона (background mix mode) используется функция SetBkMode, прототип которой
int SetBkMode(HDC hDc, int uMode);
40
Второй параметр uMode функции может принимать следую- щие значения: OPAQUE – непрозрачный режим, т.е. цвет фона гра- фического элемента выводится поверх существующего фона окна; TRANSPARENT – прозрачный, т.е. цвет фона графического эле- мента игнорируется, а символ выводится на существующем фоне окна.
Если перечисленные выше функции не вызывались, то в кон-
тексте устройства будут использоваться по умолчанию следующие значения: цвет текста – черный, цвет фона графического элемента
– белый, режим смешивания фона – OPAQUE.
Эту программу можно использовать в качестве каркаса Windows-приложения с главным окном.
1.7.4. Приложение с главным окном
/*Операторы препроцессора*/
#define STRICT #include <windows.h> #include <windowsx.h>
/*Прототип оконной функции, используемый в программе*/
LRESULT WINAPI WndProc(HWND,UINT,WPARAM,LPARAM); /*Главная функция WinMain*/
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{
/* Произвольное имя класса */ char szClassName[]="qwerty";
// или LPCTSTR lpszClassName="qwerty"; /* Произвольный заголовок окна */ char szAppTitle[]="BGTU";
//или LPCTSTR lpszAppName="BGTU"; /*
Cтруктурная переменная wc типа WNDCLASSEX для задания характеристик окна
*/
WNDCLASSEX wc;
HWND hWnd; //дескриптор окна
/*
41
Структурная переменная Msg типа MSG для получения сообщений Windows
*/
MSG Msg;
/*Проверяем, было ли это приложение запущено ранее*/
if(hWnd=FindWindow(szClassName, NULL))
{
/*Поверяем, было ли это окно свернуто в пиктограмму */
if(IsIconic(hWnd)) ShowWindow(hWnd,SW_RESTORE);
/*Выдвигаем окно приложения на передний план*/ SetForegroundWindow(hWnd);
return FALSE;
}
/*Регистрируем класс главного окна*/ memset(&wc,0,sizeof(wc)); wc.cbSize=sizeof(WNDCLASSEX); /*Стандартная пиктограмма*/
wc.hIcon = (HICON)LoadImage(hInstance, IDI_APPLICATION, IMAGE_ICON,32,32,0); /*Стандартный курсор мыши*/ wc.hCursor=LoadCursor(NULL, IDC_ARROW); wc.style = CS_HREDRAW|CS_VREDRAW;
/*Определяем оконную процедуру для главного окна*/
wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance= hInstance;//дескриптор приложения wc.hIconSm=NULL;
/*Определяем кисть фона и ее цвет*/ wc.hbrBackground=(HBRUSH)GetStockObject(
WHITE_BRUSH); //или макрос-GetStockBrush(WHITE_BRUSH) //или (HBRUSH)(COLOR_APPWORKSPACE+1)
wc.lpszClassName=szClassName; if(!RegisterClassEx(&wc)) return FALSE; /*Создаем главное окно*/
hWnd=CreateWindowEx(WS_EX_WINDOWEDGE, szClassName, szAppTitle, WS_OVERLAPPEDWINDOW,
42
CW_USEDEFAULT,10,
CW_USEDEFAULT,100, HWND_DESKTOP, NULL,
hInstance,
NULL); if(!hWnd)return FALSE;
/*
Пересылаем содержимое сегментных регистров кода, данных и стека в переменные Reg1,Reg2 и Reg3
*/
char szTxt[80];
USHORT Reg1, Reg2, Reg3; __asm{
mov Reg1,CS mov Reg2,DS mov Reg3,SS
}
/*
Выводим окно сообщений со значениями сегментных регистров, смещения (адреса) главной функции и смещения (адреса) строки с именем класса
*/
wsprintf(szTxt,"CS=%X DS=%x SS=%X\nWinMain=%X\nszClassName=%X", Reg1, Reg2, Reg3, WinMain, szClassName);
MessageBox(hWnd, szTxt, "Регистры", MB_ICONINFORMATION);
/*Делаем главное окно видимым на экране*/ ShowWindow(hWnd,SW_SHOWNORMAL);
/*
Функция UpdateWindow() вызывает передачу сообщения WM_PAINT непосредственно оконной процедуре, а функция InvalidateRect() вызывает постановку сообщения WM_PAINT в очередь приложения, а там оно обрабатывается с самым низким приоритетом
*/
UpdateWindow(hWnd);
/*Цикл обработки сообщений*/ while(GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);
43
DispatchMessage(&Msg);
}
return Msg.wParam;//Код возврата
}
/*Оконная функция главного окна*/
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg, WPARAM wParam,LPARAM lParam)
{
HDC hDc; PAINTSTRUCT ps; RECT rect;
/*Строка текста для вывода в главное окно*/ LPCTSTR lpszTxt="Б Г Т У";
switch(msg)
{
/*Переход по значению кода сообщения(msg)*/ case WM_CREATE:
/*
Дескриптор экземпляра приложения (hInstance) можно определить, вызывая одну из следующих функций:
hInstance = GetModuleHandle(NULL); hInstance = GetClassLong(hWnd, GCL_HMODULE); */
//…
return TRUE; case WM_KEYDOWN:
/*Обрабатываем сообщение - нажатие клавиши*/ switch(wParam)
{
/*Клавиша Esc*/ case VK_ESCAPE: /*
Посылаем сообщение WM_CLOSE окну (hWnd), после того, как оконная процедура обработает это сообщение, система передаст управление инструкции, следующей за SendMessage */
SendMessage(hWnd,WM_CLOSE,0,0); break;
}
break;
44
case WM_COMMAND: //switch(wParam)
//{
//…
//}
break; case WM_PAINT:
/*Получаем контекст устройства*/ hDc=BeginPaint(hWnd,&ps);
/*
Определяем размеры клиентской области окна
*/
GetClientRect(hWnd,&rect);
/*
TRANSPARENT - в этом режиме вывода текста цвет фона графического элемента игнорируется, т.е. символ выводится на существующем фоне. */
SetBkMode(hDc,TRANSPARENT); DrawText(hDc,lpszTxt, -1,&rect,
DT_SINGLELINE|DT_CENTER|DT_VCENTER); /*Освобождаем контекст устройства*/ EndPaint(hWnd,&ps);
break;
case WM_CLOSE: /*
Сообщение появляется при щелчке на кнопке закрытия окна - здесь оно предназначено для вывода предупреждающего сообщения
*/
if(MessageBox(hWnd,"Вы уверены???","",
MB_YESNO | MB_ICONQUESTION)==IDYES) DestroyWindow(hWnd);
break;
case WM_SIZE: /*
Ширина width и высота height клиентской области окна в пикселях
*/
width=LOWORD(lParam);
height=HIWORD(lParam);
//…
break;
case WM_LBUTTONDOWN:
45
/*нажата клавиша Shift ?*/ if(wParam & MK_SHIFT)
{
MessageBox(hWnd, "Нажата клавиша\nShift", "Shift,Ctrl",MB_ICONINFORMATION);
}
break;
case WM_DESTROY: PostQuitMessage(0); /*
PostQuitMessage() выполняет только одно действие - ставит в очередь сообщение WM_QUIT. Параметр у этой функции - код возврата, который помещается в wParam
*/
break;
default:
/*Обработка прочих сообщений по умолчанию*/ return DefWindowProc(hWnd,msg,
wParam,lParam);
}
return 0L;
}
Результат работы программы представлен на рис. 2.
Рис. 2. Окно программы
46