
Практична робота №4
Тема: Вивчення функцій обробки натискання клавіш клавіатури.
Мета: Навчитись створювати і обробляти повідомлення з клавіатури засобами API.
Теоретичні відомості:
В Windows більшість дій виконуються мишею, тому на перший погляд застосування клавіатури обмежено введенням чисельних даних в поля введення. Але користувач часто використовує гарячі клавіші типу Ctrl+S, Ctrl+N і Shift+F12, а також в компютерних іграх, майже все повязано з клавіатурою.
Вікно Windows може працювати з клавіатурою. При натисканні будь-яких кнопок, вікно отримує від клавіатури повідомлення. В залежності від того, що треба зробити, це можуть бути повідомлення: WM_CHAR (робота з текстовими (символьними) кнопками), WM_KEYDOWN (натискання клавіш), WM_KEYUP (відпускання клавіш), наприклад при перетягуванні з Shft.
Усі клавіші мають свої коди. За допомогою конструкції switch/case можна відслідковувати натискання потрібних кнопок (наприклад, стрілок) і виконувати певні дії.
Ці коди можна побачити у довіднику з програмвання або самостійно написати програму, яка виводить на екран коди клавіш та їх комбінацій.
unsigned int key;
case WM_KEYDOWN:
key=wParam; //Отримання коду натиснутої клавіші
_itoa(key, szText, 10); //Перетворення його в рядок
hdc=GetDC(hWnd); //Отримання контексту малювання
TextOut(hdc, 10,10, szText, 2); //Виведення тексту на екран
break;
Ідентифікатори |
Коди клавіш |
Клавіша на клавіатурі |
VK_CANCEL |
03 |
<CTRL>+<BREAK> |
VK_BACK |
08 |
BACKSPACE |
VK_TAB |
09 |
TAB |
VK_CLEAR |
0C |
5 доп. клав |
VK_RETURN |
0xd |
ENTER |
VK_SHIFT |
10 |
SHIFT |
VK_CONTROL |
11 |
CTRL |
VK_MENU |
12 |
ALT |
VK_PAUSE |
13 |
PAUSE |
VK_CAPITAL |
14 |
CAPS LOCK |
VK_ESCAPE |
1B |
ESC |
VK_SPACE |
0x20 |
ПРОБЕЛ |
VK_PRIOR |
0x21 |
PAGE UP |
VK_NEXT |
0x22 |
PAGE DOWN |
VK_END |
0x23 |
END |
VK_HOME |
0x24 |
HOME |
VK_LEFT |
0x25 |
LEFT |
VK_UP |
0x26 |
UP |
VK_RIGHT |
0x27 |
RIGHT |
VK_DOWN |
0x28 |
DOWN |
VK_SNAPSHOT |
0x2a |
PRINT SCREEN |
VK_INSERT |
0x2d |
INSERT |
VK_DELETE |
0x2e |
DELETE |
|
0x30 |
A |
|
0x31 |
B |
|
… |
|
|
0x5a |
Z |
VK_NUMPAD0 |
0x60 |
<0> на дод. клав. |
VK_NUMPAD1 |
0x61 |
<1> на дод. клав. |
|
… |
|
VK_NUMPAD9 |
0x69 |
<9> |
VK_ADD |
0x6b |
<+> |
VK_MULTIPLAY |
0x6a |
<*> |
VK_SUBTRACT |
0x6d |
<-> |
VK_DIVIDE |
0x6f |
</> |
VK_F1 |
0x70 |
F1 |
VK_F2 |
0x71 |
F2 |
|
… |
|
VK_F12 |
0x7b |
F12 |
VK_NUMLOCK |
0x90 |
NUM LOCK |
VK_SCROLL |
0x91 |
SCROLL LOCK |
Лістинг програми:
//rp4_1.cpp
#include<windows.h>
#include<tchar.h>
const wchar_t szTitle[]=_T("ЗПЗС-114 Пр№4.1 Вариницький С.В.");
const wchar_t szProgName[]=_T("Пр№4.1");
wchar_t szText[]=_T("");
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
HWND hWnd; MSG lpMsg;
WNDCLASS w;
w.style = CS_HREDRAW|CS_VREDRAW;
w.lpfnWndProc = WndProc;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = hInstance;
w.hIcon = 0;
w.hCursor = 0;
w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
w.lpszMenuName = 0;
w.lpszClassName = szProgName;
if(!RegisterClass(&w)) {
MessageBox(NULL, _T("Can't register class"), _T("Error"), MB_OK); return 0;
}
hWnd = CreateWindow(szProgName, szTitle, WS_OVERLAPPEDWINDOW,100, 100, 300, 200, (HWND)NULL, (HMENU)NULL,(HINSTANCE)hInstance, (LPVOID) NULL);
if(!hWnd) {
MessageBox(NULL, _T("Can't create window"), _T("Error"), MB_OK); return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&lpMsg, hWnd, 0, 0)) {
TranslateMessage(&lpMsg);
DispatchMessage(&lpMsg);
}
return (lpMsg.wParam);
}
int i = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; PAINTSTRUCT ps;
switch(messg)
{
unsigned int key;
case WM_CHAR:
key=wParam;
wsprintfW(szText, _T("%c"), key);
hdc=GetDC(hWnd); //отримання контексту малювання
TextOut(hdc, i,10, szText, 1); //Виведення тексту на екран
i+=7;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, messg, wParam, lParam);
}
return 0;
}
Вікна результатів:
Лістинг програми:
//rp4_2.cpp
#include<windows.h>
#include<tchar.h>
const wchar_t szTitle[]=_T("ЗПЗС-114 Пр№4.2 Вариницький С.В.");
const wchar_t szProgName[]=_T("Пр№4.2");
wchar_t szText[]=_T("");
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
HWND hWnd; MSG lpMsg;
WNDCLASS w;
w.style = CS_HREDRAW|CS_VREDRAW;
w.lpfnWndProc = WndProc;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = hInstance;
w.hIcon = 0;
w.hCursor = 0;
w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
w.lpszMenuName = 0;
w.lpszClassName = szProgName;
if(!RegisterClass(&w)) {
MessageBox(NULL, _T("Can't register class"), _T("Error"), MB_OK); return 0;
}
hWnd = CreateWindow(szProgName, szTitle, WS_OVERLAPPEDWINDOW,100, 100, 300, 200, (HWND)NULL, (HMENU)NULL,(HINSTANCE)hInstance, (LPVOID) NULL);
if(!hWnd) {
MessageBox(NULL, _T("Can't create window"), _T("Error"), MB_OK); return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&lpMsg, hWnd, 0, 0)) {
TranslateMessage(&lpMsg);
DispatchMessage(&lpMsg);
}
return (lpMsg.wParam);
}
int i = 0, y = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; PAINTSTRUCT ps;
switch(messg)
{
unsigned int key;
case WM_CHAR:
key=wParam;
if (key != 0xd) {
wsprintfW(szText, _T("%c"), key);
hdc=GetDC(hWnd);
TextOut(hdc, i,y, szText, 1);
i+=7;
}
break;
case WM_KEYDOWN:
key=wParam;
switch(key) {
case VK_RETURN:
y+=15; i=0; return 0;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, messg, wParam, lParam);
}
return 0;
}
Вікна результатів:
Лістинг програми:
//rp4_3.cpp
#include<windows.h>
#include<tchar.h>
const wchar_t szTitle[]=_T("ЗПЗС-114 Пр№4.3 Вариницький С.В.");
const wchar_t szProgName[]=_T("Пр№4.3");
wchar_t szText[]=_T("");
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
HWND hWnd; MSG lpMsg;
WNDCLASS w;
w.style = CS_HREDRAW|CS_VREDRAW;
w.lpfnWndProc = WndProc;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = hInstance;
w.hIcon = 0;
w.hCursor = 0;
w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
w.lpszMenuName = 0;
w.lpszClassName = szProgName;
if(!RegisterClass(&w)) {
MessageBox(NULL, _T("Can't register class"), _T("Error"), MB_OK); return 0;
}
hWnd = CreateWindow(szProgName, szTitle, WS_OVERLAPPEDWINDOW,100, 100, 300, 200, (HWND)NULL, (HMENU)NULL,(HINSTANCE)hInstance, (LPVOID) NULL);
if(!hWnd) {
MessageBox(NULL, _T("Can't create window"), _T("Error"), MB_OK); return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&lpMsg, hWnd, 0, 0)) {
TranslateMessage(&lpMsg);
DispatchMessage(&lpMsg);
}
return (lpMsg.wParam);
}
int i = 0, y = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; PAINTSTRUCT ps;
switch(messg)
{
unsigned int key;
case WM_CHAR:
key=wParam;
if (key != 0x08) {
wsprintfW(szText, _T("%c"), key);
hdc=GetDC(hWnd);
TextOut(hdc, i,y, szText, 1);
i+=7;
}
break;
case WM_KEYDOWN:
key=wParam;
switch(key) {
case VK_BACK:
i-=7;hdc=GetDC(hWnd);SetTextColor(hdc, RGB(255,255,255));
TextOut(hdc, i,y, _T("M"), 1); SetTextColor(hdc, RGB(0,0,0));
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, messg, wParam, lParam);
}
return 0;
}
Вікна результатів:
Висновки: Я Навчився створювати і обробляти повідомлення з клавіатури засобами API.