WM_PAINT 和 PROGRESS_CLASS
WM_PAINT with PROGRESS_CLASS
我正在创建 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));
可以用,但我还想在上面绘制带有百分比的文本
所以我像这样子类化了进度控制:
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);
}
但如果至少取消注释 "HDC hdc = BeginPaint(hwnd, &ps);" 则会出现文本,但默认控件完全消失(就像没有绘制一样)
我怎样才能修复它以显示带有文本的默认 windows 控件,因为我不需要绘制自定义控件,只需添加覆盖文本?
谢谢
这里的问题是您使用 BeginPaint
和 EndPaint
调用清除了更新区域,因此进度条认为它不需要绘制任何东西。 WM_PAINT
工作方式的一个弱点是您不能以这种方式覆盖现有控件。相反,你必须做这样的事情:
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);
}
其他说明:
- 您发布的代码是在控制下绘制的,而不是在它之上 (!)。我的代码解决了这个问题。
- 如果您 select 并反对 DC,完成后您应该 select 返回旧的。同样,我的代码展示了如何执行此操作。
我正在创建 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));
可以用,但我还想在上面绘制带有百分比的文本 所以我像这样子类化了进度控制:
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);
}
但如果至少取消注释 "HDC hdc = BeginPaint(hwnd, &ps);" 则会出现文本,但默认控件完全消失(就像没有绘制一样) 我怎样才能修复它以显示带有文本的默认 windows 控件,因为我不需要绘制自定义控件,只需添加覆盖文本? 谢谢
这里的问题是您使用 BeginPaint
和 EndPaint
调用清除了更新区域,因此进度条认为它不需要绘制任何东西。 WM_PAINT
工作方式的一个弱点是您不能以这种方式覆盖现有控件。相反,你必须做这样的事情:
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);
}
其他说明:
- 您发布的代码是在控制下绘制的,而不是在它之上 (!)。我的代码解决了这个问题。
- 如果您 select 并反对 DC,完成后您应该 select 返回旧的。同样,我的代码展示了如何执行此操作。