如何在静态控件中画一条线?

时间:2012-06-22 15:47:35

标签: c windows winapi graphics

我想在静态控件中画一条线:

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;

但它受静态控制: enter image description here

2 个答案:

答案 0 :(得分:2)

当绘制到任何子窗口时,您需要在子窗口过程的WM_PAINT内进行绘制,而不是在父窗口的WM_PAINT范围内进行绘制。

对于系统控件(例如静态),您需要子类化窗口,这意味着您需要用自己的窗口替换系统定义的窗口过程。将自己的窗口过程安装到系统控件后,可以捕获系统控件上的WM_PAINT事件来进行绘制。

完整的程序如下:

  1. 定义静态控制的替换窗口过程。

    我们还必须定义一个变量,我们可以用它来存储控件的原始系统窗口过程,我们必须在某个时候调用它以允许控制正常绘制。

    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. 创建静态控制窗口。

    hWndStatic = CreateWindow(WC_STATIC, (LPSTR) NULL, WS_CHILD|... );
    
  3. 对静态控制窗口进行子类化(安装窗口过程)

    pFnPrevFunc = SetWindowLongPtr(hWndStatic,
                                   GWLP_WNDPROC,
                                   (LONG_PTR) ProcessStaticMessages);
    
  4. 如果这项工作正常,那么您应该收到静态的私人消息处理函数中的 内的WM_PAINT消息,并且您的绘图应该正确发生。

答案 1 :(得分:1)

嘿兄弟!不要忘记在静态过程中添加 DefWindowProc 。有时你不能在没有 DefWindowProc 功能的情况下绘制你的控件。

示例:

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.
}