I'm creating a Dialog using CreateDialog
.
in the dialog proc I do some drawing of text in 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;
...
Now the question is, am I doing it right with the font, meaning that, is this the correct way to get the font handle of a dialog using SendMessage(hDlg, WM_GETFONT, 0, 0)
and restoring it with SelectObject(dc, hfntPrev
)?
Do I need to restore old BkMode of bkmodePrev
using SetBkMode(dc, bkmodePrev);
? or will EndPaint
do that for me?
P.S: do I need to release the DC?
Am I doing it right with the font?
Yes.
Do I need to restore the old BkMode of bkmodeprev using
SetBkMode(dc, bkmodeprev)
, or willEndPaint
do that for me?
EndPaint
won't restore the background mix mode for you. But EndPaint
does destroy the device context so it doesn't need to be restored. However, in my view, best practise is to restore the background mix mode whenever you change it. Then if you extend the code in the future you won't be surprised. But that's really a preference. You may take a different stance.
Do I need to release the DC?
No, the call to EndPaint
suffices.
I would write this like so:
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);
Although, one might argue that it would be better to include some error checking.
As is pointed out in the comments you need to provide a return value for the WM_PAINT
message. From the docs:
If the dialog box procedure processes a message that requires a specific return value, the dialog box procedure should set the desired return value by calling SetWindowLong(hwndDlg, DWL_MSGRESULT, lResult) immediately before returning TRUE. Note that you must call SetWindowLong immediately before returning TRUE; doing so earlier may result in the DWL_MSGRESULT value being overwritten by a nested dialog box message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With