Jas*_*ion 0 c++ winapi controls drawing ownerdrawn
我有一个WIN32所有者绘制的静态控件,使用两个源图像(填充和未填充)绘制进度条.在初始抽奖中效果很好:
case WM_DRAWITEM:
{
DRAWITEMSTRUCT* draw = (DRAWITEMSTRUCT*)lparam;
// Manually draw the progress bar.
if( draw->hwndItem == hwndProgress )
{
// Progress bar is 526 pixels wide.
int left = progressPercent * 526 / 100;
// Paint sections of window with filled and unfilled bitmaps
// based on progress bar position.
HDC hdcMem = ::CreateCompatibleDC(draw->hDC);
::SelectObject(hdcMem, hBmpProgressFull);
::BitBlt(draw->hDC, 0, 0, left, 36, hdcMem, 0, 0, SRCCOPY);
::DeleteDC(hdcMem);
HDC hdcMem2 = ::CreateCompatibleDC(draw->hDC);
::SelectObject(hdcMem2, hBmpProgressEmpty);
::BitBlt(draw->hDC, left, 0, 526-left, 36, hdcMem2, left, 0, SRCCOPY);
::DeleteDC(hdcMem2);
return TRUE;
}
}
return 0;
Run Code Online (Sandbox Code Playgroud)
但是,我似乎无法正确地擦除和重绘.我已经尝试使用WM_PAINT和RedrawWindow的SendMessage,并且没有一个人工作得很好:
bool SetLoginProgressBar(float value)
{
if( hwndProgress != NULL )
{
progressPercent = (int)(value * 100.0);
//::RedrawWindow(hwndProgress, NULL, NULL, RDW_INVALIDATE|RDW_INTERNALPAINT);
::SendMessage(hwndProgress, WM_PAINT, NULL, NULL);
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
它不是使用新值重新绘制窗口,而是使用最初绘制的图像坐在那里并忽略其他绘图命令.它正确地绘制了初始值的进度,无论是0%,50%等,我可以验证我的WM_DRAWITEM消息处理程序代码是否被调用.
那么,在WIN32中告诉此控件擦除和重绘的正确方法是什么?
有可能我需要做一些像BeginPaint/EndPaint,或者删除我已经通过的DRAWITEMSTRUCT中的hDC吗?
在销毁DC之前,您没有从内存DC中取消选择位图.也许位图处于Windows不允许再次选择它们的状态,因此BitBlts失败.
PS RedrawWindow就是我在这种情况下使用的.InvalidateRect也可以,但仅当您的消息循环正在运行时.这导致了另一个观察:如果您正处于长时间运行的操作中,您可能无法返回到消息循环,并且您的应用程序将显示为挂起,包括对进度窗口的更新.
| 归档时间: |
|
| 查看次数: |
3561 次 |
| 最近记录: |