Click here to Skip to main content
15,881,248 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
See more:
Warning: super noob alert so bear with me. :D

I've only just begun learning the Win32 API and started using the GDI, etc and already I'm having some difficulty understanding.

This is my code:
#include <windows.h>

char ClassName[] = "myWindowClass";
HBRUSH hOrange = CreateSolidBrush(RGB(255,180,0));
HBRUSH hRed = CreateSolidBrush(RGB(255,0,0));
HBRUSH hYellow = CreateSolidBrush(RGB(255,255,0));

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam,LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE previnstance, LPSTR lpcmdline, int ncmdshow)
{
    WNDCLASSEX wc;     
    MSG msg;

    wc.cbSize = sizeof(WNDCLASSEX);                     
    wc.style = 0;                                       
    wc.lpfnWndProc = WndProc;                           
    wc.cbClsExtra = 0;                                  
    wc.cbWndExtra = 0;                                  
    wc.hInstance = hInstance;                           
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);         
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);           
    wc.hbrBackground = hYellow;        
    wc.lpszMenuName = NULL;                             
    wc.lpszClassName = ClassName;                      
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);      

    if (RegisterClassEx(&wc) == 0)                  
    {
        MessageBox(NULL,                                
                   "Windows class failed to register",  
                   "Error",                             
                   MB_ICONEXCLAMATION | MB_OK);         
        return 0;
    }

    HWND MainWindow;             
    MainWindow = CreateWindowEx( 
        WS_EX_CLIENTEDGE,        
        ClassName,              
        "Rectangles",            
        WS_OVERLAPPEDWINDOW,    
        CW_USEDEFAULT,          
        CW_USEDEFAULT,          
        320,                     
        540,                     
        NULL,                    
        NULL,                    
        hInstance,               
        NULL);                   

    if (MainWindow == NULL)
    {
        MessageBox(NULL,
                   "Failed to create window";,
                   "Error",
                   MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(MainWindow, ncmdshow);
    UpdateWindow(MainWindow);

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


LRESULT CALLBACK WndProc(HWND hwnd,     
                         UINT msg,       
                         WPARAM wParam,
                         LPARAM lParam)
{
    RECT secondbackground;
    RECT titlebox;
    HDC hdc;

    switch(msg)                          
    {
    case WM_PAINT:
        hdc = GetDC(hwnd);
        SetRect(&secondbackground, 3, 3, 297, 495);
        FillRect(hdc, &secondbackground, hOrange);
        SetRect(&titlebox, 20, 20, 278,45);
        FillRect(hdc,&titlebox, hYellow);
        ReleaseDC(hwnd, hdc);
        break;
    case WM_CLOSE:                       
        DestroyWindow(hwnd);             
        break;
    case WM_DESTROY:                    
        PostQuitMessage(0);             
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

My issue is that when i draw that second rectangle, i want to draw it on top of the first, so i figured it was just the order in which they were drawn, but clearly i'm mistaken cause when i run this, the second yellow rectangle is oddly strobing on the screen. If someone would like to enlighten me on the correct way to draw rectangles, i would greatly appreciate it. Btw, if there are any other little mistakes or anything, this is pretty much my first WinApi program, so any knowledge would be greatly appreciated. :)
Posted
Updated 26-Feb-11 21:43pm
v3
Comments
Hans Dietrich 27-Feb-11 3:39am    
Note that MSDN says: "For some common controls, the default WM_PAINT message processing checks the wParam parameter. If wParam is non-NULL, the control assumes that the value is an HDC and paints using that device context." The standard way to do this is by using code like this:

case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = (wParam != NULL) ? (HDC) wParam : ::BeginPaint(hWnd, &ps);
if (hdc == 0)
return 0;

[ do some drawing here]

if (wParam == NULL)
::EndPaint(hWnd, &ps);
return 0;

All correct. See this discussion for explanation on how to get rid of this effect called flickering: http://stackoverflow.com/questions/197948/reduce-flicker-with-gdi-and-c[^].

—SA
 
Share this answer
 
Comments
Espen Harlinn 27-Feb-11 5:42am    
Good link - my 5
Sergey Alexandrovich Kryukov 1-Mar-11 3:02am    
Thank you.
--SA
The hint of "Hans Dietrich" is right, because the call GetDC gets the window dc adjusted to screen coordinates. you can use them if you want to paint the non client area of the window (WM_NCPAINT). to paint within the client area you have to use BeginPaint and EndPaint. thats the clients update region is validated too. otherwise the update region is never cleared.
Regards.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900