Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在windows对话框中使用字体和SetBkMode绘制文本_C++_Delphi_Winapi_Dialog - Fatal编程技术网

C++ 在windows对话框中使用字体和SetBkMode绘制文本

C++ 在windows对话框中使用字体和SetBkMode绘制文本,c++,delphi,winapi,dialog,C++,Delphi,Winapi,Dialog,我正在使用创建一个对话框 在对话框过程中,我在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, TRANSPAR

我正在使用创建一个对话框

在对话框过程中,我在
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;
...
现在的问题是,我使用字体是否正确,也就是说,使用
sendmages(hDlg,WM_GETFONT,0,0)
并使用
SelectObject(dc,hfntPrev
)恢复对话框的字体句柄,这是正确的方法吗? 我是否需要使用
SetBkMode(dc,bkmodePrev)恢复
bkmodePrev
的旧BkMode模式?或者
EndPaint
会为我这样做吗

我需要释放DC吗

我的字体做得对吗

我是否需要使用
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
消息提供返回值。从:

如果对话框过程处理需要特定返回值的消息,则对话框过程应在返回TRUE之前立即调用SetWindowLong(hwndDlg、DWL_MSGRESULT、lResult)来设置所需的返回值。请注意,在返回TRUE之前必须立即调用SetWindowLong;在此之前执行此操作可能会导致DWL_MSGRESULT值被嵌套对话框消息覆盖


EndPaint将破坏设备上下文,导致下一轮背景模式默认为(不透明)。无需恢复,只有“类”和“专用”DC保留状态。由于他正在对话框中处理
WM_PAINT
,他需要
SetWindowLongPtr(hDlg,DWLP_MSGRESYLT,(LONG_PTR)0)
EndPaint
调用之后。只有这样他才能返回
TRUE
或者可能是我弄错了?@SertacAkyuz,所以我不需要恢复
bkmodePrev
?@SertacAkyuz,恢复
BkMode
会有什么不良影响吗?或者我应该忽略它而不恢复它,让它由
EndPaint
?@David,在这种情况下,我应该调用
SetWindowLongPtr(hDlg,DWLP_MSGRESYLT,(LONG_PTR)0)像往常提到的学习新闻一样?