Mierzenie czasu w WinAPI

0

Witam

Mam taki problem, otóż tworzę programik do rysowania i potrzebuję mierzyć czas rysowania: od naciśnięcia przycisku myszy do jego puszczenia.
Kombinuję z QueryPerformanceCounter, jednak nie działa mi taka sytuacja (skopiowałem tylko te główne linijki żeby pokazać o co mi chodzi :) ):

LARGE_INTEGER clockFrequency;
LARGE_INTEGER start_time;
LARGE_INTEGER end_time;
LARGE_INTEGER delta;

case WM_LBUTTONDOWN:
if (QueryPerformanceFrequency(&clockFrequency))
			QueryPerformanceCounter(&start_time);

case WM_MOUSEMOVE:
//tam rysuje się, wyświetlane jest na bieżąco położenie kursora itp.

case WM_LBUTTONUP:
QueryPerformanceCounter(&end_time);

delta.QuadPart = end_time.QuadPart - start_time.QuadPart;
deltaSeconds = ((float)delta.QuadPart) / clockFrequency.QuadPart;

sprintf_s(wynik, "czas: %.2f",deltaSeconds);
TextOut(hdc, 10, 100, wynik, strlen(wynik));

Zwraca mi za każdym razem '-1'. Dla testów przeniosłem i start i end w jedno miejsce, np do WM_LBUTTONUP, dałem start, Sleep(100) i end i wyświetliłem wynik to działało pięknie. Mógłby ktoś doradzić czy jest możliwość zrobienia takiego czegoś jak ja kombinuję?

0

Kod wygląda w porządku. Pokaż więcej, w jakiejś minimalnej całości dającej się skompilować. Coś innego musi być nie tak.

0

Załączę cały kod może:

 

#include <windows.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <math.h>
#include <CommCtrl.h>
//#include "funkcje.h"

struct wsp
{
	int x;
	int y;
	bool isin;
};

void prostokat_1(HDC hDC) //rysowanie prostokąta
{
	HPEN czerw, ziel, pudelko;
	czerw = CreatePen(PS_SOLID, 1, 0x0000FF);
	ziel = CreatePen(PS_SOLID, 1, 0x00FF00);
	MoveToEx(hDC, 400, 200, NULL);
	LineTo(hDC, 600, 200);
	pudelko = (HPEN)SelectObject(hDC, czerw);
	LineTo(hDC, 600, 250);
	SelectObject(hDC, pudelko);
	LineTo(hDC, 400, 250);
	SelectObject(hDC, ziel);
	LineTo(hDC, 400, 200);
	DeleteObject(ziel);
	DeleteObject(czerw);
};

void czysc(wsp tab[], int n) //czyszczenie tablicy
{
	int k = 0;
	for (k; k < n; k++)
	{
		tab[k].x = 0;
		tab[k].y = 0;
		tab[k].isin = 0;
	}
};

int sprawdz_p1(wsp tab[], int i) //sprawdzanie czy udało się pokonać tunel
{
	int k;
	int j;
	int licznik = 0;
	int roznica = 0;
	int wynik = 0;
	bool full;

	for (k = 0; k < i; k++)
	{
		full = 0;
		if (tab[k].x >= 398 && tab[k].x <= 402 && tab[k].y >= 200 && tab[k].y <= 250)
		{
			for (j = k; j < i; j++)
				if (tab[j].x >= 598 && tab[j].x <= 602 && tab[j].y >= 200 && tab[j].y <= 250)
				{
					full = 1;
					break;
				}
		}

		if (full == 1)
		{
			for (int l = k; l <= j; l++)
			{
				if (tab[l].y >= 200 && tab[l].y <= 250)
				{
					tab[l].isin = 1;
					licznik++;
				}
			}
			roznica = j - k;
			wynik = (licznik * 100) / roznica;
			break;
		}
	}

	return wynik;
}


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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT("Connect");
	HWND         hwnd;
	MSG          msg;
	WNDCLASS     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;
	
	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("Program requires Windows NT!"),
			szAppName, MB_ICONERROR);
		return 0;
	}

	hwnd = CreateWindow(szAppName, TEXT("Przechodzenie tunelu"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInstance, NULL);

	

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

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

	static int iCount, iPrevX, iPrevY;
	HDC hdc;
	PAINTSTRUCT ps;
	RECT rect;
	
	char wynik[100] = "";
	char dane[100] = "";
	char intro[100] = "";
	static int i = 0;
	static wsp tab[1000];
	int wyn;
	float deltaSeconds;

	LARGE_INTEGER clockFrequency;
	LARGE_INTEGER start_time;
	LARGE_INTEGER end_time;
	LARGE_INTEGER delta;

	switch (message)
	{
	case WM_LBUTTONDOWN:
		
		i = 0;
		iCount = 0;
		iPrevX = LOWORD(lParam);
		iPrevY = HIWORD(lParam);
		InvalidateRect(hwnd, &rect, TRUE);
		
		if (QueryPerformanceFrequency(&clockFrequency)) //w tym miejscu startuję mierzenie czasu
			QueryPerformanceCounter(&start_time);
		
		return 0;
	case WM_MOUSEMOVE:
		if (wParam & MK_LBUTTON)
		{
			hdc = GetDC(hwnd);
			MoveToEx(hdc, iPrevX, iPrevY, NULL);
			LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
			iPrevX = LOWORD(lParam);
			iPrevY = HIWORD(lParam);

			char info[100] = "";
			sprintf_s(info, "Mouse position");
			TextOut(hdc, 1000, 3, info, strlen(info));
			sprintf_s(info, "x: %i   y: %i  i: %i", iPrevX, iPrevY, i);
			TextOut(hdc, 1000, 20, info, strlen(info));
			
			tab[i].x = iPrevX;
			tab[i].y = iPrevY;
			i++;

			ReleaseDC(hwnd, hdc);
		}
		return 0;

	case WM_LBUTTONUP:
		QueryPerformanceCounter(&end_time); //tutaj kończę
		GetClientRect(hwnd, &rect);
		hdc = BeginPaint(hwnd, &ps);
		InvalidateRect(hwnd, NULL, FALSE);
		
		//QueryPerformanceCounter(&start_time);
		//Sleep(1000);
		
		
		delta.QuadPart = end_time.QuadPart - start_time.QuadPart;
		deltaSeconds = ((float)delta.QuadPart) / clockFrequency.QuadPart; //wyliczam wartość

		sprintf_s(wynik, "czas: %.2f",deltaSeconds);
		TextOut(hdc, 10, 100, wynik, strlen(wynik)); //wypisuję
		
		wyn = sprawdz_p1(tab, i - 1);
		if (wyn == 0)
		{
			sprintf_s(wynik, "Nie udało ci się pokonać tunelu, spróbuj jeszcze raz.");
			TextOut(hdc, 3, 40, wynik, strlen(wynik));
		}
		else
		{
			sprintf_s(wynik, "Skutecznosc: %i %%", wyn);
			TextOut(hdc, 3, 40, wynik, strlen(wynik));
		}
		czysc(tab, 1000);
		return 0;

	case WM_PAINT:
		GetClientRect(hwnd, &rect);
		hdc = BeginPaint(hwnd, &ps);
		sprintf_s(intro, "Pokonaj tunel, przechodząc najpierw przez zieloną, a kończąc za czerwoną linią");
		TextOut(hdc, 3, 3, intro, strlen(intro));
		prostokat_1(hdc);
		InvalidateRect(hwnd, &rect, FALSE);
		EndPaint(hwnd, &ps);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_ACTIVATE:
		GetClientRect(hwnd, &rect);
		hdc = BeginPaint(hwnd, &ps);
		InvalidateRect(hwnd, &rect, FALSE);
		EndPaint(hwnd, &ps);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);

}

1

Daję głowę, że zawartość zmiennych clockFrequency i start_time przepada tuż po wyjściu z obsługi WM_LBUTTONDOWN. Przerób je na satic.
clockFrequency wystarczy zainicjować raz.

0

Pomogło, śmiga, wielkie dzięki @sapero :D

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.