CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Apr 2009
    Posts
    1,355

    [RESOLVED] win32 - why SetTimer isn't working?

    i even tryied debug the code. but without sucess
    heres my message loop:
    Code:
    WPARAM MessageLoop()
    {
        MSG msgEvents;
        while(GetMessage(&msgEvents, NULL, 0, 0) > 0)
        {
            if (!IsDialogMessage(FormActivated, &msgEvents))
            {
               TranslateMessage(&msgEvents);
               DispatchMessage(&msgEvents);
            }
        }
        return msgEvents.wParam;
    }
    the FormActivated is a global variabel for the message loop.
    heres how i create the form:
    Code:
    void setParent(HWND parent=GetDesktopWindow())
            {
                if (hwnd==NULL)
                {
                    WNDCLASSEX FormClass;
                    char classname[20]="Form";
                    sprintf(classname,"%s",strCaption.c_str());
                    HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
    
                    FormClass.cbSize        = sizeof(WNDCLASSEX);
                    FormClass.style         = CS_HREDRAW | CS_VREDRAW;
                    FormClass.lpfnWndProc   = WndProcForm;
                    FormClass.cbClsExtra    = 0;
                    FormClass.cbWndExtra    = 0;
                    FormClass.hInstance     = mod;
                    FormClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
                    FormClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
                    FormClass.hbrBackground = (HBRUSH)((COLOR_WINDOW)+1);
                    FormClass.lpszMenuName  = NULL;
                    FormClass.lpszClassName = classname;
                    FormClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
                    // register the new window class
                    RegisterClassEx(&FormClass);
    
                    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, classname, strCaption.c_str(),WS_OVERLAPPEDWINDOW | WS_TABSTOP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
                                      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, parent, NULL, mod, this);
    
                    if (hwnd == NULL)
                        MessageBox(NULL, "Can't create the control", "error", MB_OK);
                }
                else
                {
                    SetParent(hwnd,parent);
                }
    
                ShowWindow(hwnd, SW_NORMAL);
                InvalidateRect(hwnd,NULL,true);//i add these line for fix that
                UpdateWindow(hwnd);
                clrBackColor =GetDCBrushColor(GetDC(hwnd));
                clrTextColor = GetTextColor(GetDC(hwnd));
            }
    heres the window form procedure:
    Code:
    static LRESULT CALLBACK WndProcForm(HWND HandleWindow, UINT msg, WPARAM wParam, LPARAM lParam)
            {
                static POINT PreviousLocation, Location;
                static bool Tracking = false;
                static MouseButtons MBButtons;
                static bool blControl = false;
                static bool blShift = false;
                static bool blResize = false;
                static int KeyDownCount=0;
                static int keyboard[256];
                static int xPos = 0;
                static int yPos = 0;
                static UINT_PTR timerid=0;
                static UINT_PTR KeyBoardTimer=0;
                static UINT_PTR JoystickTimer=1;
                static bool blnDrag = false;
                static bool KeyPressed=false;
                static HMENU menuhandle=NULL;
                HDC hdcimage = CreateCompatibleDC(NULL);
                HBITMAP hbitmap=NULL;
    
                //UINT JoystickCount =0;
    
                form *inst = (form *)GetWindowLongPtr(HandleWindow, GWLP_USERDATA);
    
    
                if(inst!=NULL && inst->Create!=NULL )
                {
                    static bool i=true;
                     if(i==true)
                     {
                        i=false;
                         RECT a;
                        GetWindowRect(inst ->hwnd,&a);
                        inst -> Create(a.left, a.top);
                     }
                }
    
    
                //Working with messages
                switch(msg)
                {
                    case WM_NCCREATE:
                    {
                        CREATESTRUCT *p = (CREATESTRUCT *)lParam;
                        inst = (form *)p->lpCreateParams;
                        SetWindowLongPtr(HandleWindow, GWLP_USERDATA, (LONG_PTR)inst);
                        inst->hwnd = HandleWindow;
                    }
                    break;
    
                    case WM_ACTIVATE:
                    {
                        if (wParam==WA_INACTIVE)
                        {
                            FormActivated = NULL;
                        }
                        else
                        {
                            FormActivated = inst->hwnd;
                        }
    
                        return 0;
                    }
                    break;
    
                    case WM_CREATE:
                    {
                        if(WindowMain == NULL || WindowMain ==GetDesktopWindow())
                        {
                             WindowMain = HandleWindow;
                        }
                        if(SetTimer(inst->hwnd,JoystickTimer,150,NULL)==NULL)
                            SetWindowText(inst->hwnd,"error");
                        SetTimer(inst->hwnd,KeyBoardTimer,150,NULL);
                        //SetWindowText(inst->hwnd, to_string(GetLastError()).c_str());
                        SendMessage((HWND)lParam , WM_CREATE, wParam, lParam);
                    }
                    break;
                   
                   
                    case WM_TIMER:
                    {
    
                        if (wParam == timerid)//for mouse stoped and it's working normaly
                        {
                            PreviousLocation = Location;
                            GetCursorPos(&Location);
                            if ((Location.x == PreviousLocation.x) && (Location.y == PreviousLocation.y))
                            {
                                KillTimer(inst->hwnd, timerid);
                                inst->MouseStoped();
                            }
                        }
                        else if(wParam==KeyBoardTimer)
                        {
                            SetWindowText(inst->hwnd, to_string(GetLastError()).c_str());
                            static bool KeyDown=false;
                            static int RepeatKeyDown;
                            int key[256];
    
                            GetKeyBoardKeyState(key);
                            static int key2[256];
                            if(key[AnyKey]==1 && KeyDown==false)
                            {
                                KeyDown=true;
                                RepeatKeyDown++;
                                GetKeyBoardKeyState(key2);
                                inst->SysKeyDown(key,RepeatKeyDown);
                            }
                            else if(key[AnyKey]==0 && KeyDown==true)
                            {
                                KeyDown=false;
                                inst->SysKeyUp(key2,RepeatKeyDown);
                                RepeatKeyDown=0;
                            }
                        }
                        else if(wParam==JoystickTimer)
                        {
                            JOYINFOEX  b;
                            b.dwSize=sizeof(JOYINFOEX );
                            b.dwFlags=JOY_RETURNALL;
    
                            //cicle all possible joysticks
                            for (int i=0; i<16; i++)
                            {
                                int direction=0;
                                if(joyGetPosEx(i,&b)!= JOYERR_NOERROR) //if theres any error then continue to next joystick
                                {
                                    if(i==0)
                                        inst->Joystick(-1, -1,-1);
                                    else
                                        inst->Joystick(0, -1,-1);
                                    break;
                                }
    
                                long h =b.dwButtons;
    
                                //testing the directions
                                //will be 8 directions(inclued diagonals)
    
    
                                if (b.dwXpos == 0 && b.dwYpos ==65535)
                                {
                                    direction=5;
                                }
                                else if (b.dwXpos == 65535 && b.dwYpos ==0)
                                {
                                    direction=6;
                                }
                                else if (b.dwXpos == 65535 && b.dwYpos ==65535)
                                {
                                    direction=7;
                                }
                                else if(b.dwXpos == 0 && b.dwYpos ==65535)
                                {
                                    direction=8;
                                }
    
                                else if (b.dwXpos == 0)
                                {
                                    direction=1;
                                }
                                else if (b.dwXpos == 65535)
                                {
                                    direction=2;
                                }
                                else if (b.dwYpos == 0)
                                {
                                    direction=3;
                                }
                                else if (b.dwYpos == 65535)
                                {
                                    direction=4;
                                }
                                inst->Joystick(i, direction,h);
                            }
                        }
                    }
                    break;
                    case WM_SHOWWINDOW:
                    {
                        if(inst->blnVisible==true)
                        {
                            inst->Show();
                        }
                        else
                        {
                            inst->Hide();
                        }
                    }
                    break;
                    case WM_KILLFOCUS:
                    {
                        inst->KillFocus();
                    }
                    break;
                    case WM_SETFOCUS:
                    {
                        inst->GetFocus();
                    }
                    break;
                    case WM_EXITSIZEMOVE:
                    {
    
                        xPos = GET_X_LPARAM(lParam);
                        yPos = GET_Y_LPARAM(lParam);
    
                        if(blResize == true)
                        {
                            inst->ResizeStoped();
                        }
                        else
                        {
                            inst->Stoped(xPos,yPos);
                        }
                    }
                    break;
                    case WM_MOUSEWHEEL:
                    {
                        xPos = GET_X_LPARAM(lParam);
                        yPos = GET_Y_LPARAM(lParam);
                        int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
                        inst->MouseWhell(zDelta,MBButtons, blControl, blShift, xPos, yPos);
                    }
                    break;
                    case WM_LBUTTONDBLCLK:
                    case WM_RBUTTONDBLCLK:
                    case WM_MBUTTONDBLCLK:
                    case WM_XBUTTONDBLCLK:
                    {
                        SetFocus(inst->hwnd);
    
                        xPos = GET_X_LPARAM(lParam);
                        yPos = GET_Y_LPARAM(lParam);
    
                        blControl = ((wParam & MK_CONTROL) == MK_CONTROL);
                        blShift = ((wParam & MK_SHIFT) == MK_SHIFT);
    
                        if((wParam & MK_LBUTTON) != false)
                            MBButtons = Left;
                        else if (wParam & MK_RBUTTON)
                            MBButtons = Right;
                        else if (wParam & MK_MBUTTON)
                            MBButtons = Middle;
                        else if (wParam & MK_XBUTTON1)
                            MBButtons = X1;
                        else if (wParam & MK_XBUTTON2)
                            MBButtons = X2;
                        inst->MouseDoubleClick(MBButtons, blControl, blShift, xPos, yPos);
                    }
                    break;
                    case WM_KEYDOWN:
                    {
                        KeyDownCount++;
                        GetKeyBoardKeyState(keyboard);
    
                        inst->KeyDown(keyboard,KeyDownCount);
                        if(KeyPressed==false)
                        {
                            KeyPressed=true;
                            inst->KeyPress();
                        }
                        return 0;
                    }
                    break;
                    case WM_KEYUP:
                    {
                        int a=TableMenuShortCuts.size();
    
                        for(int i=0; i<a;i++ )
                        {
                            if(keyboard[(int)TableMenuShortCuts[i].key]==true &&(keyboard[VK_CONTROL]==TableMenuShortCuts[i].control)&&(keyboard[VK_SHIFT]==TableMenuShortCuts[i].shift) &&(keyboard[VK_MENU]==TableMenuShortCuts[i].alt))
                            {
                                Menu *mMenu = (Menu *)TableMenuShortCuts[i].MenuPointer;
                                if (mMenu!=NULL)
                                {
                                    mMenu->Click();
                                }
                            }
    
                        }
                        KeyPressed=false;
                        inst->KeyUp(keyboard,KeyDownCount);
                        return 0;
                    }
                    break;
                    case WM_CLOSE:
                    {
                        inst->Close();
                        DestroyWindow(inst->hwnd);
                    }
                    break;
                    case WM_DESTROY:
                    {
                        DeleteObject(hbitmap);
                        DeleteDC(hdcimage);
                        joyReleaseCapture(JOYSTICKID1);
                        KillTimer(inst->hwnd, JoystickTimer);
                        KillTimer(inst->hwnd,KeyBoardTimer);
                        KillTimer(inst->hwnd,timerid);
                        --FormCount;
                        if(FormCount == 0)
                            End();
                    }
                    break;
                }
                return DefWindowProc(HandleWindow, msg, wParam, lParam);
            }
    why the WM_TIMER isn't executed?
    i use the GetLastError() and i get 0 or even 6(handle invalide).
    sorry, i came here on last result... but i don't understand why isn't executed
    another strange thing: when i minizate the form, the timer is executed. i know these, because, when i restaure the form, the image is changed.
    yesterday was working... today isn't. i'm very confused

  2. #2
    Join Date
    Apr 2011
    Posts
    22

    Re: win32 - why SetTimer isn't working?

    SetTimer(inst->hwnd,KeyBoardTimer,150,NULL); : you set KeyBoardTimer = 0 so that is bad.

    I don't think the HWND in WM_CREATE is valid yet so try the HandleWindow from WndProcForm: SetTimer(HandleWindow,JoystickTimer,150,NULL);

    I hope that helps, I really only know Win32 C++ so it's hard for me to read your code.

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: win32 - why SetTimer isn't working?

    For SetTimer(), the IDEvent parameter should be non-zero. See https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

    You have timerid = 0 and KeyBoardTimer = 0 and you have if... tests for both of these in your WM_TIMER message code with timerid test first??

    I would suggest having variables whose value doesn't change as const.

    Code:
    //static UINT_PTR timerid=0;    ?????????
    const UINT_PTR KeyBoardTimer=2;
    const UINT_PTR JoystickTimer=1;
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - why SetTimer isn't working?

    Quote Originally Posted by Cambalinho View Post
    why the WM_TIMER isn't executed?
    i use the GetLastError() and i get 0 or even 6(handle invalide).
    sorry, i came here on last result... but i don't understand why isn't executed
    another strange thing: when i minizate the form, the timer is executed. i know these, because, when i restaure the form, the image is changed.
    yesterday was working... today isn't. i'm very confused
    You really need to learn debugging your code. Do you really think that debugging it "virtually" from screen could be done better than in debug session? You did not provide something able to compile, like a minimalistic project replicating your issue, so the verdict is: you did something wrong. Maybe "yesterday", or maybe even before the yesterday.
    Best regards,
    Igor

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - why SetTimer isn't working?

    Code:
                        SendMessage((HWND)lParam , WM_CREATE, wParam, lParam);
    You need to immediately quit this habit of sending messages that are not your responsibility. WM_CREATE is a system message which is sent by Windows as the result of CreateWindowXxx call. If you need to do something on window creation, you should send/post a custom message instead of hijacking well-known system message.
    Last edited by Igor Vartanov; February 17th, 2015 at 11:35 AM.
    Best regards,
    Igor

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: win32 - why SetTimer isn't working?

    Igor is quite correct.This makes no sense.
    Code:
    SendMessage((HWND)lParam , WM_CREATE, wParam, lParam);
    In a WM_CREATE message, lParam is a pointer to a CREATESTRUCT. So you are casting a pointer to a struct to a HWND and then trying to send a WM_CREATE message to the window with this lParam HWND value - which is an invalid window handle!!!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Apr 2009
    Posts
    1,355

    Re: win32 - why SetTimer isn't working?

    after several test's i found the problem:
    Code:
    case WM_PAINT:
    {
         return 0;
    }
    so: how these code can afect the timer?

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: win32 - why SetTimer isn't working?

    Quote Originally Posted by Cambalinho View Post
    after several test's i found the problem:
    Code:
    case WM_PAINT:
    {
         return 0;
    }
    so: how these code can afect the timer?
    I don't see this code snippet in your OP.
    Define the "affection" of this code to your timer problem.
    Why don't you provide any drawing here?
    Victor Nijegorodov

  9. #9
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - why SetTimer isn't working?

    Who might know how many other odd things you do in your other code? All this time, per my understanding, you're trying to compose some framework without having consistent knowledge, neither in C++ nor in Win32 API. I salute to your courage, but at the same time feel a real pain looking at your struggling to break through an open door.

    The art of programming consists of a big number of little, or not so little, skills like knowing programming languages, APIs, architecture, algorithms, debugging, modelling, etc. You have no choice but to learn how to put all the things together.

    The advice I always give in a situation like this: put your current task aside, step back and overview the picture. Identify your weaknesses and start eliminating those. In a consistent manner, day by day. Don't try to save on tedious learning exercises. Make your tasks be observable and affordable, don't try to jump over your head. Gain skills and good habits first, then strengthen your power. Learn to test and re-test yourself. Learn to depend on nobody but yourself. Learn to ask questions that woul lead to problem solving, not just re-asking.
    Last edited by Igor Vartanov; February 21st, 2015 at 04:15 AM.
    Best regards,
    Igor

  10. #10
    Join Date
    Apr 2009
    Posts
    1,355

    Re: win32 - why SetTimer isn't working?

    Quote Originally Posted by VictorN View Post
    I don't see this code snippet in your OP.
    Define the "affection" of this code to your timer problem.
    Why don't you provide any drawing here?
    the timer isn't executed with that code. i was changing from WM_PAINT to WM_DRAWITEM messages, that's why.
    but i agree with Igor, like allways, he have right
    but sometimes i don't understand some strange effects. true: 'i'm eating a big sandwich with a little mouth'. but i never give up
    i have learned several experience, like:
    1 - code order can change all things;
    2 - saving the code on other files(like these situaction).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured