some help please :)

Started by
4 comments, last by Drew_Benton 19 years ago
Hello again. sorry for all the dumb questions but hey im learning well here is a little background on what i am doing. i am trying to familiarize myself with windows api. so I made a class called line that makes a line at a specified location with a specified thickness. you can access the variables to change the size and location. so I am making a bacic win32 app with a half second timer. every time WM_TIMER comes around I want to change the values of my line objects members randomly and then draw it to the hdc. For some reason It is not working from within the message loop. here are the source files. lines.h

#include <math.h>

class Line
{
      private:
              HWND Hwnd;
                
      public:
             double sx,sy,ex,ey,T;
      Line(HWND, double, double, double, double, double, bool);

      int draw(HWND);
};
      
Line::Line(HWND lHwnd, double lsx, double lsy, double lex, double ley, double lT, bool drw) :
                sx(lsx), sy(lsy), ex(lex), ey(ley), T(lT), Hwnd(lHwnd)
                {
                if(drw)
                     draw(Hwnd);
                }

                
int Line::draw(HWND Hwnd)
{
   bool virt = false;
   int start[] = {(int) sx, (int) sy};
   int end[] = {(int) ex, (int) ey};
   
   if (start[1] == end [1])
   virt = true;
   
   double hT = (T / 2);
   
   HDC hDC;
   //PAINTSTRUCT ps;
   hDC = GetDC(Line::Hwnd);
   MoveToEx(hDC, end[0], end[1], NULL);
   LineTo(hDC, start[0], start[1]);
   
   
   
   for(int c = 0; c < hT; c++)
   {
      //if(T > 1)
      //{

        start[0]--;
        start[1]++;
        end[0]--;
        end[1]++;
        
        MoveToEx(hDC, end[0], end[1], NULL);
        LineTo(hDC, start[0], start[1]);
      //}
    }
        start[0] = (int) sx;
        start[1] = (int) sy;
        end[0] = (int) ex;
        end[1] = (int) ey;
       
     for(int c = 0; c < hT; c++)
   {
      //if(T > 1)
      //{

        start[0]++;
        start[1]--;
        end[0]++;
        end[1]--;
        MoveToEx(hDC, end[0], end[1], NULL);
      LineTo(hDC, start[0], start[1]);
      //}
  
   }
   ReleaseDC(Hwnd,hDC);
   return 0;
}





I have cut all of the window creation code out for your viewing pleasure. main.cpp



LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        Line dude(hwnd, 0, 0, 544, 375, 20, false);
//if i uncomment the next commented section of code it will work fine.
            /* dude.sx = (double) (rand() % 375 + 1);
             dude.sy = (double) (rand() % 544 + 1);
             dude.ex = (double) (rand() % 375 + 1);
             dude.sy = (double) (rand() % 544 + 1);
             dude.draw(hwnd);
             RECT txtrct;
             txtrct.bottom = 375;
             txtrct.top = 0;
             txtrct.left = 0;
             txtrct.right = 544;
             HDC hDC;
             hDC = GetDC(hwnd);
             HBRUSH brush;
             brush = (HBRUSH)SelectObject(hDC, GetStockObject(WHITE_BRUSH));
             FillRect(hDC, &txtrct, brush);
             ReleaseDC(hwnd, hDC);*/
             
    switch (message)                  /* handle the messages */
    {
           
        case WM_CREATE:
             SetTimer(hwnd, 1, 500, NULL);
             srand(time(0));
             
             break;
        case WM_TIMER:

// this does not produce any lines when i run it. :(            
              //Line dude(hwnd, 0, 0, 544, 375, 20, false);
             dude.sx = (double) (rand() % 544 + 1);
             dude.sy = (double) (rand() % 375 + 1);
             dude.ex = (double) (rand() % 544 + 1);
             dude.sy = (double) (rand() % 375 + 1);
             dude.draw(hwnd);
             
             
             break;
        case WM_PAINT:
             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;
}





so there it is can anyone catch any errors in the code? thanks EDIT: I know my file structure is messed up, Ill try fixing that real quick.
These tears..leave scars...as they run down my face.
Advertisement
You again! [grin] Well here is the MSDN reference for using timers. That code looks like it will work, but try this - set a breakpoint on the WM_TIMER code and see if it is ever reached when you debug. If it is reached, then that means your code is flawed. If it is not reached, then that means your timer was not created successfully.

SO you will set a break point on the line:

dude.sx = (double) (rand() % 544 + 1);

Or if you do not know how to use that debugging junk, you can just add in an abort(); before that line. If it aborts, then your timer is fine and your code is broken, if it does not abort, then your timer is broken.
well the timer works, so the code must be broken somewhare but I cant see how.

If I perform the exact same operations outside of the message loop then it works fine. if I copy and paste the following code (which works anyware else in the program) into the WM_TIMER CASE. it wont work.

dude.sx = (double) (rand() % 544 + 1);
dude.sy = (double) (rand() % 375 + 1);
dude.ex = (double) (rand() % 544 + 1);
dude.sy = (double) (rand() % 375 + 1);
dude.draw(hwnd);
NOTE: the dude object is created right before the switch statement for messages within winproc.

but if I make a MessageBox in the WM_TIMER case it will pop up a box every half second.

hmmm
These tears..leave scars...as they run down my face.
Ok how about this. Rather than trying to draw every timer even, you always draw and only modify the position in the timer. Example:
case WM_TIMER:{   dude.sx = (double) (rand() % 544 + 1);   dude.sy = (double) (rand() % 375 + 1);   dude.ex = (double) (rand() % 544 + 1);   dude.sy = (double) (rand() % 375 + 1);} break;


Now though your code can't possibly work. I am not familar with all of Win32, but I am sure you are not supposed to be doing what you are in the WindowProcedure function. What you should try is this as well. Move Line dude(hwnd, 0, 0, 544, 375, 20, false); to the main loop area. After you creat your window, then you can set the hwnd of this Line. If you do not have a default construtor, you will need to make one. Then you need to make a Create function so you can do this:
Line g_dude; // global variable...// After window creation so you know the hwndg_dude.Create( hwnd, 0, 0, 544, 375, 20, false );


Then make the changed to the WM_TIMER above. Now you will need to figure out where to make the dude.draw(hwnd); call. Right now you are just calling it once every timer, so that may be the cause. Try moving it to the top of the function and see if that works.

See if you can get that to work. We can then go from there.
Well I have made some progress. but It turns out that the WM_TIMER message stops coming once the window is created.

This is getting frustrating.

Is there a better way to do this than with windows timers and messages?
These tears..leave scars...as they run down my face.
Can you explain exactly what you are trying to do? Like for this project. Then I can give you some reccomendations. Working with Win32 is not easy, so hang in there!

This topic is closed to new replies.

Advertisement