Avatar billede driis Nybegynder
13. december 2003 - 13:08 Der er 12 kommentarer og
1 løsning

SetTimer problem (Windows)

Jeg er ved at lave et rent Win32 program. I den forbindelse skal jeg bruge en timer. Jeg kalder SetTimer således:
SetTimer(hwnd,ID_TIMER,upd_interval,NULL);

Sådan som jeg læser dokumentationen, burde systemet nu poste WM_TIMER messages til mit vindue hver gang der er gået upd_interval millisekunder. Men det virker ikke. Hvad gør jeg galt ? (SetTimer returnerer værdien af ID_TIMER, som det også er beskrevet i dokumentationen).
Avatar billede soreno Praktikant
13. december 2003 - 13:13 #1
Måske det er hwnd der peger på et forkert vindue ?

Du kunne evt. teste ved at lave en metode som du kan bruge i sidste parameter.
Avatar billede driis Nybegynder
13. december 2003 - 13:30 #2
Det har jeg nu prøvet:
VOID CALLBACK TimerProc(HWND hwnd,UINT msg, UINT_PTR idEvent, DWORD dwTime)
{
    if ( idEvent == ID_TIMER )
        MessageBox(hwnd,"TEST",TITLE,0);
}

og begge af disse:
UINT_PTR tRet = SetTimer(NULL,ID_TIMER,upd_interval,TimerProc);
UINT_PTR tRet = SetTimer(hwnd,ID_TIMER,upd_interval,TimerProc);

Det fungerer heller ikke. upd_interval er 500 ms.
Avatar billede driis Nybegynder
13. december 2003 - 13:31 #3
.. Og jeg har et breakpoint ved indgangen til TimerProc, den bliver slet ikke kaldt.
Avatar billede soreno Praktikant
13. december 2003 - 13:40 #4
Der er et virkende eksempel her:
http://www.winprog.org/tutorial/animation.html

Måske du kunne kigge efter forskelligheder i forhold til din kode ?
Avatar billede soreno Praktikant
13. december 2003 - 13:45 #5
Hvad er returværdien af SetTimer(..) ?
Avatar billede driis Nybegynder
13. december 2003 - 13:46 #6
Den er værdien af ID_TIMER
Avatar billede soreno Praktikant
13. december 2003 - 13:56 #7
Dette eksempel virker fint:
#include <windows.h>

const int ID_TIMER = 123;

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    char *appName = "Win32Skabelon";
    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 = appName;

    if(!RegisterClass(&wndclass))
    {
        MessageBox(NULL, "This program requires Windows NT!", appName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindow(appName, // window class name
                        "The Hello Program", // window caption
                        WS_OVERLAPPEDWINDOW, // window style
                        CW_USEDEFAULT, // initial x position
                        CW_USEDEFAULT, // initial y position
                        320, // initial x size
                        200, // initial y size
                        NULL, // parent window handle
                        NULL, // window menu handle
                        hInstance, // program instance handle
                        NULL); // creation parameters   
   
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

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

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
   
    switch(message)
    {
        case WM_CREATE:
            SetTimer(hwnd, ID_TIMER, 1000 * 3, NULL);
            return 0;

        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);         
            GetClientRect(hwnd, &rect);
            DrawText(hdc, "Hello world", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint(hwnd, &ps);
            return 0;
         
        case WM_TIMER:
            MessageBox(NULL, "..in a bottle.", "Message..", MB_OK);
            return 0;
           
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
Avatar billede driis Nybegynder
13. december 2003 - 14:16 #8
Dit eksempel virker fint. Det gør eksemplet i tutorial'en på winprog.org også. Jeg kan ikke se hvorfor mit program ikke virker. Jeg har nu flyttet SetTimer kaldet ud i min WndProc under WM_CREATE, oprindeligt blev det kaldt i en klasses constructor. Men det virker heller ikke.
Avatar billede driis Nybegynder
13. december 2003 - 14:20 #9
Min WndProc ser sådan ud:

#include "winG.h"

// WndProc behandler alle vinduets messages.
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static Ball * ptrBall = 0;

    switch(msg)
    {
    // WM_CREATE sendes én gang, når vinduet vises på skærmen. Her kan vi lave initialisering.
    case WM_CREATE:
    {
        if ( ptrBall == 0 )
        {
            ptrBall = new Ball(hwnd,makePoint(0,0),makePoint(2,2) ,DEF_UPDATE_INTERVAL);   
            if ( ptrBall == 0 )
            {
                MessageBox(hwnd,ERR_CREATE,TITLE,MB_ICONSTOP);
                PostQuitMessage(0);
            }
           
        }
        SetTimer(hwnd,ID_TIMER,DEF_UPDATE_INTERVAL,NULL);
        break;
    }

       

    case WM_PAINT:
        ptrBall->draw();
        break;

    case WM_TIMER:
        if ( wParam == ID_TIMER )
            ptrBall->move();
        break;

    // WM_DESTROY = Vinduet lukkes.
    case WM_DESTROY:
        delete ptrBall;
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd,msg,wParam,lParam);
    }
   
    return 0;
}

// program entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    // initier window class
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style        = 0;
    wc.lpfnWndProc  = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance    = hInstance;
    wc.hIcon        = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAIN_ICON));
    wc.hCursor      = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = WINDOW_CLASS_NAME;
    wc.hIconSm      = (HICON)LoadImage(GetModuleHandle(NULL),
        MAKEINTRESOURCE(IDI_MAIN_ICON),IMAGE_ICON,16,16,0);


    // registrer window class i systemet.
    if(!RegisterClassEx(&wc))
    {
        MessageBox(0,ERR_CREATE,TITLE,MB_ICONSTOP);
        return 0;
    }
    // lav vinduet.
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        WINDOW_CLASS_NAME,
        TITLE,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 600, 400,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(hwnd,ERR_CREATE,TITLE,MB_ICONSTOP);
        return 0;
    }

    // vis vinduet på skærmen.
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // main message loop. DispatchMessage kalder WndProc.
    // GetMessage returnerer 0 når der afsluttes.
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return (int)Msg.wParam;
}
Avatar billede bertelbrander Novice
14. december 2003 - 01:04 #10
Problemet er måske din WM_PAINT!

Jeg kan ikke se hvad ptrBall->draw(); gør, men hvis ikke den kalder BeginPaint() og EndPaint() vil windows sende WM_PAINT igen og igen. WM_PAINT beskeder har højere prioritet en WM_TIMER, så WM_TIMER vil aldrig blive sendt.

Prøv at udkommentere håndtering af WM_PAINT, så DefWindowProc() bliver kaldt for WM_PAINT, og se så om ikke WM_TIMER kommer.
Avatar billede driis Nybegynder
15. december 2003 - 17:14 #11
Dér lå netop problemet, det havde jeg slet ikke tænkt på. Mange tak.
(hvis du vil have point, så læg et svar).
Avatar billede bertelbrander Novice
15. december 2003 - 19:57 #12
En ting man lærer af at programere windows app's er at fejlene kan ligge meget langt fra det symptom man ser.

Jeg forsøger at undgå point.
Avatar billede driis Nybegynder
15. december 2003 - 20:00 #13
Ja, det har jeg så konstateret ;-) Tak for hjælpen i hvert fald.
Jeg lukker spørgsmålet.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester