Обчислення координат курсору миші при переміщенні
Міністерство освіти і науки України
Житомирський державний технологічний університет
Лабораторна робота №6
з курсу «Системне програмування»
на тему: «Миша»
м. Житомир
2011 р.
Зміст
Завдання 3
Хід роботи 4
1. Виведення координат миші у вікні. 4
2. Відстань між двома точками у вікні. 4
Програмний код 5
Висновок 10
Завдання
1. Вивести координати миші у вікні
2. Знайти відстань між двома точками у вікні
3. Знайти швидкість руху миші на проміжку
Хід роботи
Для виконання цієї лабораторної роботи, було опрацьовано теоретичний матеріал поданий в додатках до лабораторної роботи.
1. Виведення координат миші у вікні
Для того щоб визначити координати миші, необхідно обробити повідомлення WM_MOUSEMOVE, яке приходить кожний раз, коли виконується рух миші при активному вікні, в рамках вікна. Параметрами цього повідомлення є координати миші.
Обробляючи це повідомлення, ми формуємо текстовий рядок наступним чином:
X = LOWORD(lParam);
Y = HIWORD(lParam);
wsprintf(str, “ X = %d Y = %d “, x,y );
2. Відстань між двома точками у вікні
Необхідно зафіксувати дві точки. Нехай це будуть точки в яких користувач натисне ліву а потім праву кнопку миші.
Коли виконується натискання лівої або правої кнопки миші, ми отримуємо повідомлення:
WM_LBUTTONDOWN або WM_RBUTTONDOWN
Разом з цими повідомленнями передаються координати миші.
X = LOWORD(lParam);
Y = HIWORD(lParam);
Це координати в яких було виконане натискання.
Нехай ліва кнопка миші була натиснута в координатах (X1,Y1) а права в координатах (X2,Y2). Відстань між двома точками отримуємо за виразом:
S = sqrt( ( X2 - X1 ) * ( X2 - X1 ) + ( Y2 - Y1 ) * ( Y2 - Y1 ) );
Для визначення швидкості руху миші потрібно знати час руху на проміжку.
Для визначення часу, потрібно зафіксувати час при натисканні лівої кнопки миші, а потім час при натисканні правої кнопки миші.
T1 = clock(); // цей рядок пишемо в обробник повідомлення WM_LBUTTONDOWN
…
T2 = clock(); // цей рядок пишемо в обробник WM_RBUTTONDOWN
DT = T2 – T1;
Speed = S / DT
Тепер залишається тільки вивести значення в вікно.
Для виведення отриманих текстових рядків можна використати функцію TextOut(). Вона вигідна тим, що дозволяє виводити в визначені координати вікна. координата курсор миша переміщення
Виведення отриманих рядків необхідно робити тільки в обробці повідомлення WM_PAINT. Воно приходить тоді, коти операційна система вважає, що інформація в нашому вікні застаріла.
Якщо, нам потрібно згенерувати повідомлення WM_PAINT, то викликаємо функцію InvalidateRect(), яка повідомляє ОС про те що якась частина нашого вікна (або все вікно) застаріло. Виклик цієї функції ми робимо кожний раз, коли необхідно перемалювати вікно.
Програмний код
#include <windows.h>
#include <math.h>
#include <time.h>
#include <tchar.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int cX, cY, sX,sY;
double speed;
double T1 = 0, T2 = 0;
double S = 0;
int wayOnTable;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = _T("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;
RegisterClassEx (&wndclass) ;
hwnd = CreateWindow (szAppName, // window class name
_T("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
RECT rectInv;
int x, y;
rectInv.top = 0;
rectInv.left = 0;
rectInv.right = 400;
rectInv.bottom = 60;
switch (iMsg)
{
case WM_CREATE :
return 0 ;
case WM_MOUSEMOVE:
cX = LOWORD(lParam);
cY = HIWORD(lParam);
InvalidateRect(hwnd, &rectInv, true);
return 0;
case WM_LBUTTONDOWN:
sX = LOWORD(lParam);
sY = HIWORD(lParam);
T1 = clock();
S = 0;
speed = 0;
wayOnTable = 0;
return 0;
case WM_RBUTTONDOWN:
x = LOWORD(lParam);
y = HIWORD(lParam);
S = sqrt((double)(( x - sX ) * ( x - sX ) + ( y - sY ) * ( y - sY)));
T2 = clock();
speed = (S / max(0.01, (T2 - T1))/ CLOCKS_PER_SEC);
wayOnTable = S / 25 ;
InvalidateRect(hwnd, &rectInv, true);
return 0;
case WM_PAINT :
TCHAR str[40];
TCHAR way[45];
TCHAR way2[45];
_stprintf(str, _T(" X = %d Y = %d "), cX, cY );
_stprintf(way, _T("Миша пройшла %d пікселів зі шв. %lf"), (int)S, speed);
_stprintf(way2, _T("Миша пройшла %d мм по столу"), wayOnTable);
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
TextOut(hdc, 5, 5, str, _tcslen(str));
TextOut(hdc, 5, 25, way, _tcslen(way));
TextOut(hdc, 5, 45, way2, _tcslen(way2));
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
Висновок
Отже, при виконанні даної лабораторної роботи були здобуті навики обробки миші у вікні. В результаті, програма здатна виводити координати курсору миші при переміщенні, а також відображати відстань та швидкість з якою проходить курсор між двома обраними точками.