Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций Часть II.doc
Скачиваний:
14
Добавлен:
20.11.2018
Размер:
1.48 Mб
Скачать

П. 1.12 Примеры создания окон

Задача 1. Окно приложения стиля временного окна с кнопкой миними­зации и с фоном цвета рабочего стола Windows занимает весь экран. При попытке запуска второго экземпляра на передний план переместить окно первого экземпляра и завершить работу.

Анализ задания.

Для поиска других экземпляров приложения воспользуемся функци­ей FindWindow:

HWND hwnd=FindWindow(szMainClass,szTiUe);

Она возвращает дескриптор окна класса szMainClass с заголовком szTitle. Если такого окна нет, то это первый экземпляр приложения и де­скриптору hwnd присваивается NULL. Иначе, возвращается дескриптор найденного окна.

Внимание! Функция FindWindow проверяет только совпадение име­ни класса и заголовка. То есть, если работает экземпляр другого прило­жения с окном класса с таким же именем szMainClass и заголовком szTitle, то функция вернет дескриптор окна другого приложения.

Если "предыдущий экземпляр приложения" обнаружен, выводим со­общение:

MessageBox(hwnd,

"Можно запускать только одну копию приложения!!!"

"Перемещаю на передний план первый экземпляр", szTitle, MB_OK | MB_CONSTOP);

До перемещения окна на передний план проверяем состояние этого окна и, если оно свернуто, восстанавливаем его предыдущее состояние:

if (lslconic( hwnd)) ShowWindow( hwnd, SW_RESTORE);

Перемещаем окно первого экземпляра приложения на передний план:

SetForegroundWindow(hwnd);

Затем второй экземпляр приложения завершает работу.

Если предыдущий экземпляр приложения не найден, регистрируем класс окна:

if (!RC(WndProc,szMainClass,COLOR_DESKTOP)) return FALSE;

Для создания максимально распахнутого окна приложения определя­ем ширину и высоту экрана в пикселях:

Int w=GetSystemMetrics(SM_CXSCREEN);

int h=GetSystemMetrics(SM_CYSCREEN);

Создаем окно:

hwnd = CreateWindow(szMainClass, szTitle,

WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX | WS_VISIBLE, 0,0, w, h, 0,0, hinstance, NULL);

Далее активизируем цикл обработки и диспетчеризации сообщений:

while(GetMessage(&msg, 0,0,0)) DispatchMessage(&msg);

Любые действия над окном передают функции окна, которая ранее уже была рассмотрена.

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

HINSTANCE hInstance;

char szMainClass[ ] = "MainClass";

char szTitle[]= "Пример 1.2";

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevlnst,

LPSTR IpszCmdLine, int nCmdShow)

{

MSG msg;

hInstance=hInst;

HWND hwnd=FindWindow(szMainClass,szTitle);

if (hwnd) { MessageBox(hwnd,

"Можно запускать только одну копию приложения!!!"

"Перемещаю на передний план первый экземпляр", szTitle, MB_OK | MB_ICONSTOP);

if (IsIconic(hwnd))

ShowWindow(hwnd, SW_RESTORE);

SetForegroundWindow(hwnd);

return 0;

}

WNDCLASS wc;

wc.style=wc.cbClsExtra=wc.cbWndExtra=0;

wc.lpfnWndProc=Proc;

wc.hInstance = hInstance;

wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);

wc.lpszMenuName = (LPCTSTR)NULL;

wc.lpszClassName=szName;

if (RegisterClass(&wc) == 0) return FALSE;

int w=GetSystemMetrics(SM_CXSCREEN)-1; //Ширина

int h=GetSystemMetrics(SM_CYSCREEN)-1; //Высота

hwnd = CreateWindow(szMainClass, szTitle,

WS_POPUPWINDOW | WS_CAPTION |WS_MINIMIZEBOX | WS_VISIBLE,

0,0, w, h, 0,0, hInstance, NULL);

if (!hwnd) return FALSE;

while(GetMessage(&msg, 0,0,0)) DispatchMessage(&msg);

return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,

WPARAM wParam, LPARAM lParam)

{

switch (msg)

{ case WM_DESTROY: { PostQuitMessage(0); return 0; }}

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

}

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

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

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

left=LOWORD(IParam); //Координата левого края рабочей области top=HIWORD(IParam); //Координата верхнего края рабочей области

Таким образом, программа должна содержать обработку сообщения WM_MOVE.

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

cx=LOWORD(IParam); //Ширина рабочей области

cy=HIWORD(IParam); //Высота рабочей области

Тогда ширина временного окна определяется так:

cx=LOWORD(IParam)\2; //Ширина рабочей области

cy=HIWORD(IParam)\2; //Высота рабочей области

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

  1. Отобразить временное окно на экране функцией ShowWindow(pop,SW_SHOW).

При отжатии левой клавиши мыши поступает сообщение WM_LBUTTONUP. Здесь скрыть окно функцией ShowWindow(pop,SW_HIDE) и отменить режим монопольного использования мыши функцией ReleaseCapture.

Так как дескриптор временного окна, а также переменные left, top, cx, cy должны быть доступны в оконной функции, нужно описать их как глобальные. А так как необходимо, чтобы эти переменные сохраняли свои значения между вызовами оконной функции, нужно описать их с приставкой static:

static HWND pop;

static short left, top, cx,cy;

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK WndPop(HWND, UINT, WPARAM, LPARAM);

BOOL RC(WNDPROC, LPCTSTR, UINT);

char Name[]="Class";

char NamePop[]="Popup";

HINSTANCE hinst;

static HWND pop;

static short left, top, cx,cy;

int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE Prev,

LPSTR Line,

int Show)

{

MSG msg;

HWND hwnd;

hinst=hInstance;

if(!RC(WndProc,Name,COLOR_WINDOW)) return FALSE;

if(!RC(WndPop,NamePop,COLOR_BTNFACE)) return FALSE;

hwnd=CreateWindow(Name,"m a i n",

WS_OVERLAPPEDWINDOW|WS_VISIBLE,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

0, 0, hInstance, NULL);

if (!hwnd) return FALSE;

pop =CreateWindow(NamePop,"Мое окно",

WS_POPUPWINDOW,

left,top,cx,cy,

hwnd, 0, hinst, NULL);

if (!pop) return FALSE;

while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);

return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,

WPARAM wParam, LPARAM lParam)

{

switch (msg)

{ case WM_DESTROY : {PostQuitMessage(0); return (0);}

case WM_LBUTTONDOWN : {

SetCapture(hwnd);

ShowWindow(pop,SW_SHOW);

return 0; }

case WM_LBUTTONUP : {

ShowWindow(pop,SW_HIDE);

ReleaseCapture();

return 0;}

case WM_MOVE : {

left = LOWORD(lParam);

top = HIWORD (lParam); return 0;}

case WM_SIZE : {

cx = LOWORD(lParam)/2;

cy = HIWORD(lParam)/2; return 0;}

}

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

}

LRESULT CALLBACK WndPop(HWND hwnd, UINT msg,

WPARAM wParam, LPARAM lParam)

{

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

}

BOOL RC(WNDPROC WndProc, LPCTSTR Name, UINT brBackground)

{

WNDCLASS wc;

wc.style=wc.cbClsExtra=wc.cbWndExtra=0;

wc.lpfnWndProc=WndProc;

wc.hInstance=hinst;

wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);

wc.hCursor=LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground=(HBRUSH)( brBackground +1);

wc.lpszMenuName=NULL;

wc.lpszClassName=Name;

return (RegisterClass(&wc)!=0);}