Uhr Geht Falsch



  • Also ich will/habe mir eine Stopuhr programmiert.
    Diese Uhr soll/zeigt milisecunden, secunden und minuten an.
    Und das sobald man auf die Lehrtase trückt.
    Leider nicht ganz richtig.

    Der zuständige teil sieht so aus.

    switch(wParam)
    				{
    					case VK_SPACE:
    					{
    						isActive = !isActive;
    
    						if(isActive)
    						{
    							SetTimer(hWnd, TimerID, 1, NULL);
    						}
    						else
    						{
    							KillTimer(hWnd, TimerID);
    						}
    						return 0;
    					}
    

    isActive prüft ob die lehrtase gedrückt wurde.
    Standartmäßig so:
    bool isActive = false;

    jetzt sollte der Timer ja alle milisec eine nachricht schicken.
    Tut er aber nicht. Denn eine sec in meinem Programm entspricht nicht einer real sec.
    Woran kann das liegen?
    So sieht meine rechnung aus.

    case WM_TIMER:
    			{
    				if(iMSec < 1000)
    				{
    					iMSec++;
    				}
    				else if(iSec < 60)
    				{
    					iSec++;
    					if(iSec > 59)
    					{
    						iMin++;
    						iSec = 0;
    					}
    					iMSec = 0;
    				}
    				else
    				{
    				}
    				InvalidateRect(hWnd, NULL, TRUE);
    				return 0;	
    			}
    

    wenn ich SetTimer(hWnd, TimerID, 1, NULL); nehme und nur sec und min ausgeben lasse stimmt es wieder...



  • Windows hat eine Auflösung von maximal 10ms, wenn nicht mehr, und ist ausserdem kein Echtzeitsystem.



  • Naja aus erfahrung weiss ich,
    dass solche Programme nicht Praxisfähig sind,
    ein kleiner "Lag" durch z.B. den Virenscanner
    und das Programm "geht falsch"

    Versuch die Zeit vom System auszulesen,
    und die millisekunden dazuzuzählen, dann ist die Abweichung
    minimal...



  • Multimedia Timer haben ne Auflösung von 1 Sekunde, die eignen sich da für eher.

    Siehe:
    timeSetEvent()
    timeKillEvent()



  • Ich meine die Milisec sind eh unrelevant. Am ende sollen eh nur 30 sec runtergezählt werden. Die stopuhr sollte nur eine Übung sein in der ich gcuke wie ich das mit der zeit am besten umsetze. ich habe am ende ein kleines fenster in das man klicken soll.
    Klickt man rein zählt es die klicks. man hat 30 sec zeit so viel zu klicken wie möglich.

    Das problem zeit is auch eher klein. Wenn Milisec nicht gehen, is das net schlimm weil ich die eh nicht brauche.

    viel schlimmer ist was anderes.
    Und zwar werden die Klicks zwar gezählt aber nicht ausgegeben. Ausgeben werden die erst wenn man das fenster klein macht und dann wieder öfnet.
    hat einer ne ahnung woran das liegen kann?

    Hier mal mein script...

    #include <windows.h>
    
    int i = 0;
    const UINT sizeX = 300;
    const UINT sizeY = 300;
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch(message)
    	{
    
    		case WM_PAINT:
    		{
    			PAINTSTRUCT   ps;
    			HDC           hDC;
    			SIZE          size;
    			char sTime[30];
    			int iLength;
    
    			iLength = wsprintf(sTime, "Sie haben %i mal geklickt", i);
    
    			hDC = BeginPaint(hWnd, &ps);
    			{
    				GetTextExtentPoint32(hDC, sTime, iLength, &size);
    
    				TextOut(hDC, 100, 100, sTime, iLength);
    			}
    			EndPaint(hWnd, &ps);         
    			return 0;
    		}
    		case WM_LBUTTONDOWN:
    		{
    			i++;
    			SendMessage(hWnd, WM_PAINT, 0, 0);
    		}
    		break;
    		case WM_DESTROY:
    		{
    			PostQuitMessage(0);
    			return 0;
    		}
    	}
    	return DefWindowProc(hWnd, message, wParam, lParam);
    }
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
       HWND         hWnd;
       MSG          msg;
       WNDCLASS     wc;
    
       char         szAppName[] = "CountClick";
    
       wc.cbClsExtra          = 0;
       wc.cbWndExtra          = 0;
       wc.hbrBackground       = (HBRUSH)GetStockObject(WHITE_BRUSH);
       wc.hCursor             = LoadCursor(NULL, IDC_ARROW);
       wc.hIcon               = LoadIcon(NULL, IDI_APPLICATION);
       wc.hInstance           = hInstance;
       wc.lpfnWndProc         = WndProc;
       wc.lpszClassName       = szAppName;
       wc.lpszMenuName        = NULL;
       wc.style               = CS_HREDRAW | CS_VREDRAW;
    
       RegisterClass(&wc);
    
       hWnd = CreateWindow(  szAppName,
                             szAppName,
                             WS_SYSMENU,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             sizeX,
                             sizeY,
                             NULL,
                             NULL,
                             hInstance,
                             NULL);
    
       ShowWindow(hWnd, iCmdShow);
       UpdateWindow(hWnd);
    
       while (GetMessage(&msg, NULL, 0, 0))
       {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
       }
    
       return msg.wParam;
    }
    


  • statt SendMessage(hWnd, WM_PAINT, 0, 0); musst du InvalidateRect aufrufen...



  • 😮 Hätte ich auch selber merken können...
    InvalidateRect(hWnd, NULL, FALSE); hats getan.
    Funzt jetzt...

    THX



  • Ähm der Aufruf von:

    GetTextExtentPoint32(hDC, sTime, iLength, &size);
    

    Ist irgendwie überflüssig :p .



  • Wenn ich jezt noch die schrift größe ändern möchte bräuchte ich den doch oder?



  • Jo, wenn du ihn auch noch richtig benutzt, dann ja 😉 .



  • ja an der richtigen verwendung arbeite ich nich. 🙂
    Wenn ich da einfach ne Zahl rein setzte sacht er mir
    das eine convertierung von const int in struct HDC__ * nicht möglich ist.

    Mal sehen was google dazu sagt...

    EDIT:
    Ok. Ich versuche das ding grade für was ganz falsches zu benutzen...
    ich lasse es weg....



  • Sqwan schrieb:

    EDIT:
    Ok. Ich versuche das ding grade für was ganz falsches zu benutzen...
    ich lasse es weg....

    Also, wenn du mit sagst, was du erreichen willst, kann ich dir vllt helfen 😉 .



  • ich wollte die schriftgröße änder.



  • Sqwan schrieb:

    ich wollte die schriftgröße änder.

    Ahso 😉 . Das geht zum Beispiel so ( ➡ Setzt eine aktuellere (=schönere, wie ich finde 😉 ) Schriftart und ändert nur die Größe), ist aber nur der WM_PAINT-Handler:

    case WM_PAINT: {
                PAINTSTRUCT   ps;
                HDC           hDC;
                char sTime[30];
                int iLength;
    
                iLength = wsprintf(sTime, "Sie haben %i mal geklickt", i);
    
                hDC = BeginPaint(hWnd, &ps);
                {
                    LOGFONT lfData;
                    GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lfData);
                    lfData.lfHeight = 15;
                    // Hier kannst du weitere Dinge modifizieren, schau dir einfach mal die LOGFONT-Struktur an ;-)
                    // lfData. ... = ...;
                    HFONT hfOldFont = (HFONT)SelectObject(hDC, CreateFontIndirect(&lfData));
    
                    TextOut(hDC, 100, 100, sTime, iLength);
                    DeleteObject(SelectObject(hDC, hfOldFont);
                }
                EndPaint(hWnd, &ps);        
                } return (0);
    

    Wenn du mehr wissen willst, schau dir einfach die Docs du den Funktionen an oder google n bissl da findet sich ne Menge 😉 .


Anmelden zum Antworten