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

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0