Win32 api - problém s časovačem – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Win32 api - problém s časovačem – C / C++ – Fórum – Programujte.comWin32 api - problém s časovačem – C / C++ – Fórum – Programujte.com

 

superbear
~ Anonymní uživatel
2 příspěvky
28. 9. 2012   #1
-
0
-

Zdravím,
mám následující problém.

Píšu program ve win32 api, kde mám jeden časovač, který se spustí po stisknutí jedné z kláves {w,s,a,d}. Jeho náplní je v daném intervalu pohybovat čtvercem v daném směru. Jeho barva je černá a pozadí modré, ovšem po určité době se oba štetce (ten, který vykresluje čtverec i ten, který ho zase ,,maže" na barvu pozadí) nějakým záhadným způsobem změní na bílou a čtverec za sebou tím pádem začne zanechávat dráhu. Zjistil jsem, že doba, za kterou se tohle stane není vždy stejná, čím větší je interval časovače, tím déle se čtverec vydrží vykreslovat normálně, takže to spíš vypadá, jako kdyby se v určitou chvíli zahltila paměť kontextu zařízení.

Ale vůbec nevím, co by to mohlo způsobovat, jestli nějaká chyba v kódu, nebo něco jiného...

Vývojové prostředí používám Dev C++.
Tady je celý zdrojový kód: 

#include <windows.h>



/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";



const int IDT_MOTION = 1;
const int IDT_CHANGE = 2;
int posX=600;
int posY=300;
int sizeCell=20;
int sizeMove=2;
int speed=1;
HDC hdc;
PAINTSTRUCT ps;
HPEN penDraw;
HPEN penBkg;
HBRUSH brushBkg;
HBRUSH brushDraw;
bool downDir = 0, upDir = 0, leftDir = 0, rightDir = 0;
int direction=0;
bool end = false;

void MoveSnake(HWND * adresa)
{
     
     
     
     
     hdc = GetDC(*adresa); 
     
     penBkg = CreatePen(PS_SOLID, 1, RGB(0,0,255));
     brushBkg = CreateSolidBrush(RGB(0,0,255));
     
     SelectObject(hdc, penBkg);
     SelectObject(hdc, brushBkg);
     
     Rectangle(hdc,posX,posY,posX+sizeCell,posY+sizeCell);
     
     if(rightDir == true)
     {
       posX += sizeMove;
     }
     if(leftDir == true)
     {
       posX -= sizeMove;
     }
     if(upDir == true)
     {
       posY -= sizeMove;
     }
     if(downDir == true)
     {
       posY += sizeMove;
     }
    
     
     penDraw = CreatePen(PS_SOLID, 1, RGB(0,0,0));
     brushDraw = CreateSolidBrush(RGB(0,0,0));
     
     SelectObject(hdc, penDraw);
     SelectObject(hdc, brushDraw);
     
     Rectangle(hdc,posX,posY,posX+sizeCell,posY+sizeCell);
     
     ReleaseDC(*adresa, hdc); 
}


int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    brushBkg = CreateSolidBrush(RGB(0,0,255));

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = brushBkg;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW| WS_MAXIMIZE, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, SW_SHOWMAXIMIZED);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
    
    
    
}


/*  This function is called by the Windows function DispatchMessage()  */




LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
           
      
        case WM_KEYDOWN:
             switch(wParam)
             {
                     case 0x44:
                          
                          rightDir = true;
                          downDir = false;       
                          leftDir = false;  
                          upDir = false;   
                          SetTimer( hwnd,IDT_MOTION,speed,(TIMERPROC)NULL ) ;
                          break;
                          
                     case 0x53:
                          
                          rightDir = false;
                          downDir = true;       
                          leftDir = false;  
                          upDir = false;  
                          SetTimer( hwnd,IDT_MOTION,speed,(TIMERPROC)NULL ) ; 
                          break;  
                     
                     case 0x41:
                          
                          rightDir = false;
                          downDir = false;       
                          leftDir = true;  
                          upDir = false;   
                          SetTimer( hwnd,IDT_MOTION,speed,(TIMERPROC)NULL ) ;
                          break;
                     
                     case 0x57:
                          
                          rightDir = false;
                          downDir = false;       
                          leftDir = false;  
                          upDir = true;  
                          SetTimer( hwnd,IDT_MOTION,speed,(TIMERPROC)NULL ) ;
                          break; 
                     case 0x20:
                          rightDir = false;
                          downDir = false;       
                          leftDir = false;  
                          upDir = false; 
                          KillTimer(hwnd,IDT_MOTION); 
                          break;          
             }
             
             break;   
           
        case WM_CREATE:
             SetTimer( hwnd,IDT_MOTION,speed,(TIMERPROC)NULL ) ;
             //SetTimer( hwnd,IDT_CHANGE,600,(TIMERPROC)NULL ) ;
             
             break;  
        
        case WM_TIMER:
            
             switch (wParam) 
             { 
                    
                    
              case IDT_MOTION:
                {  
                  
              
              
                  HWND * adresa = &hwnd;
                  MoveSnake(adresa);
                   
                   //KillTimer(hwnd, IDT_MOTION);
                  break;
                }
                
                
                
              case IDT_CHANGE:
                {
                 end = false;
                 //KillTimer(hwnd, IDT_MOTION);
                 switch(direction)
                 {   
                     
                          
                     case 1:
                          rightDir = true;
                          downDir = false;       
                          leftDir = false;  
                          upDir = false;   
                          break;
                          
                     case 2:
                          rightDir = false;
                          downDir = true;       
                          leftDir = false;  
                          upDir = false;   
                          break;  
                     
                     case 3:
                          rightDir = false;
                          downDir = false;       
                          leftDir = true;  
                          upDir = false;   
                          break;
                     
                     case 4:
                          rightDir = false;
                          downDir = false;       
                          leftDir = false;  
                          upDir = true;  
                          break;             
                 }
                        
                  if(direction == 4)
                  {
                   direction = 1;  
                   end = true;
                           
                  }
                  else
                  
                  {
                   direction++; 
                  }
                  break;
                  
                  //SetTimer(hwnd,IDT_MOTION,20,(TIMERPROC)NULL ) ;
                }
              
             
             break;
             }
        case WM_PAINT:
             {
             

             
             hdc = BeginPaint(hwnd, &ps);
             
             penDraw = CreatePen(PS_SOLID, 1, RGB(0,0,0));
             brushDraw = CreateSolidBrush(RGB(0,0,0));
     
             SelectObject(hdc, penDraw);
             SelectObject(hdc, brushDraw);
             
             Rectangle(hdc,posX,posY,posX+sizeCell,posY+sizeCell);
             
             
             EndPaint(hwnd, &ps);
             ReleaseDC(hwnd,hdc);
             break;
             }
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

Velmi bych ocenil jakoukoliv radu, díky!

Nahlásit jako SPAM
IP: 89.24.233.–
KIIV
~ Moderátor
+43
God of flame
28. 9. 2012   #2
-
0
-

Nebylo by jednodussi mit ty pera jako globalni promenne a nebo staticke promenne - ono to vytvaret furt dokola je docela draha zalezitost.

Jinak evidentne existuje i neco jako DeleteObject, kterymu se da podhodit handle pro pero.. Takze asi jen resource leak-- + ani nekontrolujes jestli create pen nevraci NULL (a kdyz neuvolnujes ...)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
superbear
~ Anonymní uživatel
2 příspěvky
28. 9. 2012   #3
-
0
-

Ve win32 api jsem začátečník, takže mi to nějak nedošlo, díky :-).

Nahlásit jako SPAM
IP: 89.24.233.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 36 hostů

Podobná vlákna

Win32 Api problém s oknami — založil nergaldiabolus

Problém s časovačem — založil paashi

Win32 API — založil survik1

Dialog ve Win32 API — založil david v.

Správy v Win32 API — založil Rišo Kakaš

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý