Обчислення координат курсору миші при переміщенні

Міністерство освіти і науки України

Житомирський державний технологічний університет

Лабораторна робота №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) ;

}

Висновок

Отже, при виконанні даної лабораторної роботи були здобуті навики обробки миші у вікні. В результаті, програма здатна виводити координати курсору миші при переміщенні, а також відображати відстань та швидкість з якою проходить курсор між двома обраними точками.