我正在使用CreateDialog
创建一个Dialog。
在对话框proc中我在WM_PAINT
中做了一些文字绘制:
function DialogProc(hDlg: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
...
case Msg of
WM_PAINT:
begin
dc := BeginPaint(hDlg, ps);
bkmodePrev := SetBkMode(dc, TRANSPARENT);
hfnt := SendMessage(hDlg, WM_GETFONT, 0, 0);
hfntPrev := SelectObject(dc, hfnt);
DrawTextW(dc, 'Text', -1, R, DT_SINGLELINE or DT_CENTER or DT_VCENTER);
SelectObject(dc, hfntPrev);
// SetBkMode(dc, bkmodePrev); // do I need this?
EndPaint(hDlg, ps);
Result := True;
end;
end;
...
现在问题是,我是否正确使用字体,这意味着,这是使用SendMessage(hDlg, WM_GETFONT, 0, 0)
获取对话框的字体句柄并使用SelectObject(dc, hfntPrev
还原它的正确方法吗?
我是否需要使用bkmodePrev
恢复SetBkMode(dc, bkmodePrev);
的旧BkMode?或EndPaint
会为我做这件事吗?
答案 0 :(得分:5)
我用字体做得对吗?
是
我是否需要使用
SetBkMode(dc, bkmodeprev)
恢复bkmodeprev的旧BkMode,或EndPaint
为我做这个?
EndPaint
无法为您恢复背景混合模式。但EndPaint
会破坏设备上下文,因此不需要恢复。但是,在我看来,最佳做法是在您更改后恢复背景混合模式。然后,如果您将来扩展代码,您将不会感到惊讶。但这确实是一种偏好。你可以采取不同的立场。
我是否需要释放DC?
不,拨打EndPaint
就足够了。
我会这样写:
dc := BeginPaint(hDlg, ps);
bkmodeprev := SetBkMode(dc, TRANSPARENT);
hfnt := SendMessage(hDlg, WM_GETFONT, 0, 0);
hfntPrev := SelectObject(dc, hfnt);
DrawTextW(dc, 'Text', -1, R, DT_SINGLELINE or DT_CENTER or DT_VCENTER);
SelectObject(dc, hfntPrev);
SetBkMode(dc, bkmodeprev);
EndPaint(hDlg, ps);
尽管如此,有人可能会认为最好包含一些错误检查。
正如评论中指出的那样,您需要为WM_PAINT
消息提供返回值。来自docs:
如果对话框过程处理需要特定返回值的消息,则对话框过程应通过在返回TRUE之前立即调用SetWindowLong(hwndDlg,DWL_MSGRESULT,lResult)来设置所需的返回值。请注意,您必须在返回TRUE之前立即调用SetWindowLong;提前执行此操作可能会导致DWL_MSGRESULT值被嵌套的对话框消息覆盖。