![]() |
| | #1 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 430
| Wm_timer I get uninitialized local variable 'hdc' error. Code: #include <windows.h>
#include <winuser.h>
#define ID_TIMER1 1
#define ID_TIMER2 2
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void DrawRectangle (HWND) ;
void DrawEllipse (HWND,HDC) ;
void DrawPolygon (HWND hwnd,HDC hdc) ;
int cxClient, cyClient ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Screensaver") ;
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 = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("Beeper1 Timer Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
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)
{
HBRUSH hBrush ;
static BOOL fFlipFlop = FALSE ;
HDC hdc ;
PAINTSTRUCT ps ;
RECT rc ;
switch (message)
{
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_CREATE:
SetTimer (hwnd, ID_TIMER1, 2000, NULL) ;
SetTimer (hwnd, ID_TIMER2, 1000, NULL) ;
return 0 ;
case WM_TIMER :
switch (wParam)
{
case ID_TIMER1:
fFlipFlop = !fFlipFlop ;
InvalidateRect (hwnd, NULL, FALSE) ;
break ;
case ID_TIMER2:
DrawPolygon (hwnd, hdc);
break ;
}
return 0 ;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rc) ;
hBrush = CreateSolidBrush (RGB(0,0,0)) ;
FillRect (hdc, &rc, hBrush) ;
DrawPolygon (hwnd, hdc);
fFlipFlop ? DrawRectangle (hwnd) : DrawEllipse (hwnd,hdc) ;
EndPaint (hwnd, &ps) ;
DeleteObject (hBrush) ;
return 0 ;
case WM_DESTROY :
KillTimer (hwnd, 1) ;
KillTimer (hwnd, 2) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
void DrawRectangle (HWND hwnd)
{
HBRUSH hBrush ;
HDC hdc ;
RECT rect ;
if (cxClient == 0 || cyClient == 0)
return ;
SetRect (&rect, rand () % cxClient, rand () % cyClient, rand () % cxClient, rand () % cyClient) ;
hBrush = CreateSolidBrush ( RGB (rand () % 256, rand () % 256, rand () % 256)) ;
hdc = GetDC (hwnd) ;
FillRect (hdc, &rect, hBrush) ;
ReleaseDC (hwnd, hdc) ;
DeleteObject (hBrush) ;
}
void DrawEllipse (HWND hwnd,HDC hdc)
{
HBRUSH hbr = CreateSolidBrush (RGB (rand () % 256, rand () % 256, rand () % 256)) ;
HBRUSH hOld = (HBRUSH) SelectObject (hdc,hbr);
Ellipse (hdc, rand () % cxClient, rand () % cyClient, rand () % cxClient, rand () % cyClient) ;
SelectObject (hdc,hOld) ;
DeleteObject (hbr) ;
}
void DrawPolygon (HWND hwnd, HDC hdc)
{
static POINT points[7] = {{20, 50},{180, 50},{180, 20},{230, 70},
{180, 120},{180, 90},{20, 90}};
HBRUSH hbr = CreateSolidBrush (RGB (rand () % 256, rand () % 256, rand () % 256)) ;
HBRUSH hOld = (HBRUSH) SelectObject (hdc,hbr);
Polygon(hdc, points, 7);
SelectObject (hdc,hOld) ;
DeleteObject (hbr) ;
}
__________________ Using Code::Blocks,MingW with Windows. |
| Ducky is offline | |
| | #2 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| You probably don't want to draw the polygon in the WM_TIMER code itself, but in the WM_PAINT that comes from a InvalidateRect call. Alternatively, you could use a double buffering technique to draw the data off-screen, and then just use the VM_PAINT to copy your off-screen data onto the screen. The compiler is indeed correct, hdc is in this case not initilalized - you declare it at the top of the function, and the only time it is assigned is in WM_PAINT, when you do BeginPaint. Remember that local variables "disappear" when you leave the function, and are created anew when the function is called next time. WndProc is called when a message is received by your application - it is not "there all the time". -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #3 |
| Registered User Join Date: Mar 2005 Location: Mountaintop, Pa
Posts: 1,059
| Declare hdc as static. Code: LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HBRUSH hBrush ;
static BOOL fFlipFlop = FALSE ;
static HDC hdc ;
PAINTSTRUCT ps ;
RECT rc ;
|
| BobS0327 is offline | |
| | #4 |
| train spotter Join Date: Aug 2001 Location: near a computer
Posts: 3,448
| Things to consider.... Timer events fire every time period, not once. So you have one timer every second and another firing every 2 secs. (or very similar times) EndPaint() cleans up the HDC from BeginPaint. It may not be valid to draw to it later. Look at GetDC(NULL) and ReleaseDC. You are not clearing the background (FillRect() or similar) I would set the drawing flags in the timer and call for a paint (which would choose the correct shape to draw).
__________________ "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter." Friedrich Nietzsche "I spent a lot of my money on booze, birds and fast cars......the rest I squandered." George Best "If you are going through hell....keep going." Winston Churchill |
| novacain is offline | |
| | #5 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
-- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. | |
| matsp is offline | |
| | #6 | |
| Registered User Join Date: Dec 2007 Location: France
Posts: 430
| Thanks for the help everybody! Quote:
I found this tutorial already http://www.codeproject.com/KB/cpp/DoubleBuffering.aspx PS How could this be possible that the program compiles with 0 error 0 warning but won't execute. VC++ 2008
__________________ Using Code::Blocks,MingW with Windows. Last edited by Ducky; 09-06-2008 at 01:28 AM. | |
| Ducky is offline | |
| | #7 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
-- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. | |
| matsp is offline | |
| | #8 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 430
| Makes sense, thanks Matsp! I will try to understand the code.
__________________ Using Code::Blocks,MingW with Windows. |
| Ducky is offline | |
| | #9 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 430
| Well what i see in this program is that he calls functions in WM_TIMER and not in WM_PAINT. And you told me above not to call drawing function in WM_TIMER. He also put a TODO in WM_PAINT, so maybe i should put some code there? Code: case WM_TIMER:
{
//controls growth of the ellipse
if (growth > 50 || growth < 0)
addition *= -1;
growth += addition;
if(double_buffer == true)
Draw_With_Buffering();
else
Draw_Without_Buffering(hWnd);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Fügen Sie hier den Zeichnungscode hinzu...
EndPaint(hWnd, &ps);
break;
__________________ Using Code::Blocks,MingW with Windows. Last edited by Ducky; 09-06-2008 at 06:12 AM. |
| Ducky is offline | |
| | #10 | |
| Registered User Join Date: Mar 2005 Location: Mountaintop, Pa
Posts: 1,059
| Quote:
| |
| BobS0327 is offline | |
| | #11 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 430
| Thanks a million Bob, im very grateful for this. I managed to compile it with VC++ 6.0 but not with VC++ 2008 free version. It must have some limitations resource files i guess. Now i can play around with the program. Its much easier to learn that way for me.
__________________ Using Code::Blocks,MingW with Windows. |
| Ducky is offline | |
| | #12 |
| Algorithm Dissector Join Date: Dec 2005 Location: New Zealand
Posts: 2,727
| The thing to know is that you have to do things in a slightly roundabout way. When you get your WM_TIMER messaege you don't just paint. Instead you ask the system to tell you to paint, via InvalidateRect for example.
__________________ My homepage Advice: Take only as directed - If symptoms persist, please see your debugger |
| iMalc is offline | |
| | #13 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 430
| I would like to make this http://www.turboupload.com/files/get...dbuffering.zip (same as above) double buffering program to be displayed in full screen. I guess i should call GetClientRect (hWnd, &rect) ;. But the program is first being loaded in the buffer you dont have a client area. So i thought about to put GetClientRect (hWnd, &rect) ; in the void Bitmap_Operations::Copy_to_Screen(int which) function. But its not working either.
__________________ Using Code::Blocks,MingW with Windows. |
| Ducky is offline | |
| | #14 | |
| Registered User Join Date: Mar 2005 Location: Mountaintop, Pa
Posts: 1,059
| Quote:
EDIT: I've updated the code to handle resizing, mazimizing of the window. I don't want to do all your work for you. So, you'll have to figure out how to adjust the buffering to keep the ellipse totally in the client window. The new link Last edited by BobS0327; 09-19-2008 at 07:22 PM. | |
| BobS0327 is offline | |
| | #15 |
| Registered User Join Date: Dec 2007 Location: France
Posts: 430
| Thank you Bob, highly appreciated. I put myself to it...
__________________ Using Code::Blocks,MingW with Windows. |
| Ducky is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|