Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsia_3_slaydy_2012.doc
Скачиваний:
6
Добавлен:
18.08.2019
Размер:
376.32 Кб
Скачать

11) Код функции обработки пароля приведён в листинге:

void OnChld(HWND hWnd,UINT message,int Length,LPARAM lParam)

{

if(strcmp(PassWord,TruePassWord)||Length)

MessageBox(hWnd, "Надо вспомнить правильный пароль","Скажи \"Пароль\"",0);

else MessageBox(hWnd, "Пароль принят","",0);

}

На основе сравнения строк и проверки длины введенного пароля функция принимает решение о приеме пароля и отображает соответствующее сообщение при помощи функции MessageBox().

12) При изменении размеров родительского окна в дочернее поступает сообщение WM_PAINT, по которому в переменной R формируются размеры родительского окна и при помощи функции MoveWindow(hWndC, R.left, R.bottom-iHeight, R.right, R.bottom-iHeight, 1) дочернему окну выделяется нижняя часть родительского окна.

15) Создание дочернего окна с дескриптором Chld оформлено отдельной функцией.

BOOL CreateChild(HWND hWnd)

{static WNDCLASS wc;

if(Chld) //Стандартный для WINDOWS прием - чтобы не думать, о

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

DestroyWindow(Chld);

UnregisterClass("ReadStr",GetModuleHandle(NULL));

// Раз было окно, значит был и класс

// Если класс не убрать, получится ошибка при новой регистрации

}

wc.hInstance = GetModuleHandle(NULL);

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

wc.lpfnWndProc = ChldWndProc;

wc.lpszClassName = "ReadStr";

if (!RegisterClass(&wc)) return 0;

Chld=0;

Chld=CreateWindowEx (WS_EX_CLIENTEDGE, "ReadStr",

"Значения ", WS_CHILD|WS_VISIBLE, 30,30,60,60,

hWnd, HMENU(NumC),GetModuleHandle(NULL), NULL);

SetFocus(Chld);

return (int)Chld;

}

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

Пример №1: Создания главного окна с дочерним окном для ввода пароля.

#include "stdafx.h"

#include "resource.h"

#define MAX_LOADSTRING 100

// Global Variables:

HINSTANCE hInst; // current instance

TCHAR szTitle[MAX_LOADSTRING]; // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text

static TCHAR PassWord[7]; //введенный пользователем пароль

static TCHAR TruePassWord[]=_T("Password"); //Правильный пароль

static HWND Chld;

static WORD i;

static TCHAR *Str=NULL;

static int sMax;

int wHeight=30; //Высота дочернего окна

static TCHAR Sym[80];

// Foward declarations of functions included in this code module:

ATOM MyRegisterClass(HINSTANCE hInstance);

BOOL InitInstance(HINSTANCE, int);

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

BOOL CreateChild(HWND hWnd);

void InitStr(HWND hWnd,TCHAR *s,int Max,TCHAR Sy);

void OnChld(HWND hWnd,UINT message,int Length,LPARAM lParam);

LRESULT APIENTRY ChldWndProc (HWND UkOkn,UINT message, WPARAM wParam,LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

UNREFERENCED_PARAMETER(hPrevInstance);

UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: Place code here.

MSG msg;

HACCEL hAccelTable;

// Initialize global strings

LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

LoadString(hInstance, IDC_CHILD_WINDOW, szWindowClass, MAX_LOADSTRING);

MyRegisterClass(hInstance);

// Perform application initialization:

if (!InitInstance (hInstance, nCmdShow))

{

return FALSE;

}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CHILD_WINDOW);

// Main message loop:

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

{

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

return msg.wParam;

}

LRESULT APIENTRY ChldWndProc(HWND hWndC,UINT message,WPARAM wParam,LPARAM lParam)

{ RECT R;

switch (message)

{

case WM_CHAR:

if (LOWORD(wParam)==VK_RETURN || i>=20)

{

Str[i]=0;

PostMessage(GetParent(hWndC),WM_COMMAND,MAKELONG(NumC, i-sMax),0);

i=0;

DestroyWindow(hWndC);

UnregisterClass(_T("ReadStr"),GetModuleHandle(NULL));

}

else

{

if(++i<=sMax)

Str[i-1]=(char )LOWORD(wParam);

InvalidateRect(hWndC,NULL,1);

}

break;

case WM_PAINT:

{PAINTSTRUCT ps;

GetClientRect(GetParent(hWndC),&R);

MoveWindow(hWndC,R.left,R.top,R.right,R.top+wHeight,1);

BeginPaint(hWndC,&ps);

SetBkMode(ps.hdc, TRANSPARENT);

TextOut(ps.hdc,0,0,_T("Введите пароль: "),14);

TextOut(ps.hdc,17*8,0,Sym,i);

EndPaint(hWndC,&ps);

}

return 0;

default:

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

}

return 0;

}

ATOM MyRegisterClass(HINSTANCE hInstance)

{

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;

wcex.lpfnWndProc = (WNDPROC)WndProc;

wcex.cbClsExtra = 0;

wcex.cbWndExtra = 0;

wcex.hInstance = hInstance;

wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_CHILD_WINDOW);

wcex.hCursor = LoadCursor(NULL, IDC_ARROW);

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

wcex.lpszMenuName = (LPCWSTR)IDC_CHILD_WINDOW;

wcex.lpszClassName = szWindowClass;

wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

return RegisterClassEx(&wcex);

}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

400, 300, 500, 500, NULL, NULL, hInstance, NULL);

if (!hWnd)

{

return FALSE;

}

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

return TRUE;

}

void OnChld(HWND hWnd,UINT message,int Length,LPARAM lParam)

{

if(_tcscmp(PassWord,TruePassWord)||Length)

MessageBox(hWnd, _T("Надо вспомнить правильный пароль"),_T("Скажи \"Пароль\""),0);

else MessageBox(hWnd, _T(" Пароль принят"),_T(""),0);

}

BOOL CreateChild(HWND hWnd)

{static WNDCLASS wc;

if(Chld) //Стандартный для WINDOWS прием - чтобы не думать, о действих при

{ //попытке нового ввода до завершения

DestroyWindow(Chld); // предыдущего.

UnregisterClass(_T("ReadStr"),GetModuleHandle(NULL));

// Раз было окно, значит,был и класс

// Если класс не убрать, получится ошибка при новой регистрации

}

wc.hInstance = GetModuleHandle(NULL);

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

wc.lpfnWndProc = ChldWndProc;

wc.lpszClassName = _T("ReadStr");

if (!RegisterClass(&wc)) return 0;

Chld=0;

Chld=CreateWindowEx

( WS_EX_CLIENTEDGE, _T("ReadStr"), _T(" Значения "),

WS_CHILD|WS_VISIBLE ,

30,30,60,60,

hWnd, HMENU(NumC),GetModuleHandle(NULL), NULL);

SetFocus(Chld);

return (int)Chld;

}

void InitStr(HWND hWnd,TCHAR *s,int Max,TCHAR Sy)

{

Str=s;

sMax=Max;

int j;

for (j=0; j<21;j++)Sym[j]=Sy;

Sym[j]=0;

CreateChild(hWnd);

}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

int wmId, wmEvent;

TCHAR szHello[MAX_LOADSTRING];

LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

switch (message)

{

case WM_COMMAND:

wmId = LOWORD(wParam);

wmEvent = HIWORD(wParam);

// Parse the menu selections:

switch (wmId)

{

case IDM_EXIT:

DestroyWindow(hWnd);

break;

case NumC:

OnChld(hWnd,message,HIWORD(wParam),lParam); // Обработка пароля

break;

default:

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

}

break;

case WM_LBUTTONDOWN:

InitStr(hWnd,PassWord,8,_T('*'));

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

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

}

return 0;

}

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

Шаг 1)

Для поиска приложения используется функция FindWindow:

HWND hwnd= FindWindow(szMainClass,szTitle);

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

Если работает экземпляр другого приложения с окном класса с таким же именем szMainClass и заголовком szTitle, то данная функция вернёт дескриптор окна другого приложения иначе переходим к шагу 5.

Шаг 2)

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

MessageBox(hwnd,”Можно запускать только одну копию приложения!!!\n\n

Перемещаю на передний план первый экземпляр”,

szTitle,MB_OK);

Шаг 3)

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]