简体   繁体   English

具有PROGRESS_CLASS的WM_PAINT

[英]WM_PAINT with PROGRESS_CLASS

I'm creating Win32 control: 我正在创建Win32控件:

m_progress = CreateWindowExW(0, PROGRESS_CLASSW, L"ProgressBar", WS_VISIBLE | WS_CHILD | WS_TABSTOP, 153, 339, 135, 33, m_window, (HMENU)0, m_instance, 0);
SendMessageW(m_progress, WM_SETFONT, (WPARAM)m_fontBold, TRUE);
SendMessageW(m_progress, PBM_SETRANGE, 0, MAKELPARAM(0, 100));

It's working, but I also want to draw text with percentage on it So I've subclassed progress control like this: 它正在工作,但是我也想在上面绘制带有百分比的文本,因此我将进度控制分为以下类:

m_progressPrevProc = (WNDPROC)SetWindowLongPtrW(m_progress, GWLP_WNDPROC, (LONG_PTR)ProgressMsgProcessor);
...
static LRESULT CALLBACK ProgressMsgProcessor(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    if (msg == WM_PAINT)
    {
        PAINTSTRUCT ps;
        RECT rc = { 5, 5, 135, 33 };
        //HDC hdc = BeginPaint(hwnd, &ps);
        //SelectObject(hdc, g_App.m_fontBold);
        //DrawTextA(hdc, "100 %", -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        //EndPaint(hwnd, &ps);
    }

    return CallWindowProcW((WNDPROC)PrevWndProcProzess, hwnd, msg, wparam, lparam);
}

But if uncomment atleast "HDC hdc = BeginPaint(hwnd, &ps);" 但是如果没有注释,至少“ HDC hdc = BeginPaint(hwnd,&ps);” then text appears, but default control absolutely disappears (like it's not drawn) How can I fix it to show default windows control with text on it, because I don't need to draw custom control, only add overlay text? 然后出现文本,但是默认控件完全消失(如未绘制)。如何修复它以显示带有文本的默认Windows控件,因为我不需要绘制自定义控件,只需添加覆盖文本? Thank you 谢谢

The problem here is that you cleared the update region with your BeginPaint and EndPaint calls, so the progress bar doesn't think it has to draw anything. 这里的问题是您使用BeginPaintEndPaint调用清除了更新区域,因此进度条认为它不必绘制任何内容。 It's a weakness of the way WM_PAINT works that you can't paint over an existing control in this way. WM_PAINT工作方式的一个缺点是您不能以这种方式在现有控件上绘制。 Instead, you have to do something like this: 相反,您必须执行以下操作:

static LRESULT CALLBACK ProgressMsgProcessor(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    if (msg == WM_PAINT)
    {
        // Paint the control first
        CallWindowProcW ((WNDPROC)PrevWndProcProzess, hwnd, msg, wparam, lparam);

        // Then draw over it
        HDC hDC = GetDC (hwnd);
        HFONT hOldFont = (HFONT) SelectObject(hDC, g_App.m_fontBold);

        // Draw your own stuff into hDC

        SelectObject (hDC, hOldFont);
        ReleaseDC (hwnd, hDC);
        return 0;
    }

    return CallWindowProcW ((WNDPROC)PrevWndProcProgress, hwnd, msg, wparam, lparam);
}

Other notes: 其他说明:

  • Your code as posted is drawing under the control, not over it (!). 您发布的代码是在控件下绘制的,而不是在它上面(!)。 My code fixes that. 我的代码解决了这个问题。
  • If you select and object into a DC, you should select the old one back in when you are done. 如果选择并反对DC,则应在完成后再选择旧的DC。 Again, my code shows how to do this. 同样,我的代码显示了如何执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM