The Pianist
The Pianist

Reputation: 556

How to draw a line in a static control?

I want to draw a line in a static control:

case WM_CREATE:
    {
        hgraph=CreateWindow(WC_STATIC,NULL,WS_CHILD|WS_VISIBLE|SS_CENTER,20,20,660,80,hWnd,NULL,NULL,NULL);
        SendMessage(hgraph,WM_SETTEXT,NULL,(LPARAM) "My Static");
        break;
    }
    case WM_PAINT:
    {

        hdc=GetDC(hgraph);
        hp=CreatePen(0 ,5,RGB(0,100,0));
        SelectObject(hdc,hp); 
        MoveToEx(hdc, 0, 0, 0);
        LineTo(hdc, 100, 100);
        ReleaseDC(hgraph, hdc);
    }

    break;

but it goes under the static control: enter image description here

Upvotes: 2

Views: 3798

Answers (2)

RizonBarns
RizonBarns

Reputation: 621

Hei bro! Don't forget to add DefWindowProc in the Static Procedure. Sometime you cannot paint your controls without DefWindowProc function.

Example:

LRESULT CALLBACK StaticProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
        case WM_PAINT:
            // Do paint here.
            break;
    }
    return DefWindowProc(hWnd, Msg, wParam, lParam); // Call Default Window Procedure.
}

Upvotes: 1

aps2012
aps2012

Reputation: 1612

When drawing to any child window, you need to do your drawing within the WM_PAINT of the child window procedure, not within the WM_PAINT of the parent window as you are doing.

For system controls (e.g. statics), you need to subclass the window, which means that you need to replace the system-defined window procedure with your own. Once you have installed your own window procedure into the system control, you can catch the WM_PAINT event on the system control to do your painting.

The complete procedure is as follows:

  1. Define your Replacement Window Procedure for the Static Control.

    We also must define a variable that we can use to store the original system Window Procedure for the control, which we must call at some point to allow the control to be drawn as normal.

    static WNDPROC pFnPrevFunc;
    
    static LRESULT CALLBACK ProcessStaticMessages(HWND hWindow,
                                                  UINT uMessage,
                                                  WPARAM wParam,
                                                  LPARAM lParam)
    {
        /*
         * call the original system handler so the control
         * gets painted as normal.
         */
        (*pFnPrevFunc)(hWindow, uMessage, wParam, lParam);
    
        /*
         * perform our custom operations on this control in
         * addition to system operations.
         */
        switch (uMessage)
        {
            ...
    
            case WM_PAINT:
                /*
                 * static control has just been painted by system.
                 */
                hDC = GetDC(hWindow);
    
                /* draw your lines on the static control */
    
                ReleaseDC(hWindow, hDC);
                return TRUE;
        }
    
        return TRUE;
    }
    
  2. Create your static control window.

    hWndStatic = CreateWindow(WC_STATIC, (LPSTR) NULL, WS_CHILD|... );
    
  3. Subclass your static control window (install your window procedure)

    pFnPrevFunc = SetWindowLongPtr(hWndStatic,
                                   GWLP_WNDPROC,
                                   (LONG_PTR) ProcessStaticMessages);
    

If this works correctly, then you should receive WM_PAINT messages inside your private message processing function for the static, and your drawing should occur correctly.

Upvotes: 3

Related Questions