我的问题很简单,也不是很重要。
我开始学习编写Win32应用程序。当我从其他人那里阅读代码时,我经常看到他们将PAINTSTRUCT ps;
放在WndProc
中的switch语句之前。他们为什么不把这个问题放到WM_PAINT
?他们为ps
分配内存然后不使用它?
我总是看到PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);
。但我多次检查ps.hdc
的值,ps.hdc
和hdc
的值每次都相等。定义hdc
还有其他原因,而不仅仅是可读性还是编写更少的代码?
(对不起,如果我的英语不好而且问题不属于这个社区的水平)
答案 0 :(得分:5)
回答第1点:Win32 API是为C设计的(它已经很老了)将PAINTSTRUCT ps;
放在case
语句中需要放入case
的内容在大括号{}
内,因为C不允许内联声明。 C ++也可能在没有大括号的情况下在case
语句中声明变量时出现问题 - 在不调用构造函数的情况下调用析构函数。您会很快发现switch() case...
样式将难以维护,该功能将变得非常庞大且难以处理,并且与Intellisense等功能不相称。通常,您会看到开发人员使用地图将功能与特定消息相关联: -
WindowProc (args)
{
func_ptr = some_map.GetValue (message_type)
if func_ptr not null
call func_ptr
else
DefWindowProc (args)
}
对于第2点,如果出现错误,hdc
的值将为null
,并且使用hdc
代替ps.hdc
看起来更干净。此外,hdc
更容易传递给ps
以外的其他功能。但除此之外,文档没有说明为什么ps.hdc
与BeginPaint
的结果不同的原因。
答案 1 :(得分:2)
当我读取其他人的代码时,我经常看到他们把PAINTSTRUCT ps;在WndProc中的switch语句之前。为什么他们不把这个放入WM_PAINT?
几种可能性:
窗口程序可能不应该处理"消息,而是将它们分派给特定于消息的处理程序。因此,WndProc中的WM_PAINT情况应该调用一个单独的函数来执行绘制,而PAINTSTRUCT可以是该单独函数的本地函数。但我们正在冒险进入意见,所以我会把它留在那里。
我总是看到
PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);
。
我似乎记得有一个模糊的情况,返回的设备上下文句柄可能与PAINTSTRUCT中的不同,但可能非常罕见,在现代版本的Windows中可能不存在。
考虑返回的HDC是一种方便。如果您的绘画很简单并且不需要PAINTSTRUCT中的任何其他字段,那么这将为您提供一种简单的方法来引用设备上下文。
答案 2 :(得分:1)
它确实没有区别,并且每次调用窗口过程时,许多实现都将“分配”内存,无论变量是在函数的顶部声明还是在WM_PAINT
的情况下声明。开关。
BeginPaint不仅仅是返回ps.hdc
。
答案 3 :(得分:1)
我经常看到他们将
PAINTSTRUCT ps;
放在WndProc
中的switch语句之前。为什么他们不把这个问题放到WM_PAINT
?他们为ps分配内存然后不使用它?
这样做是不好的做法。最佳做法是调用单独的函数来执行绘制,并避免使用页面长的窗口过程。但是如果你必须在窗口过程中绘制,请使用尽可能局部的范围声明变量。
定义hdc还有其他原因,而不仅仅是可读性还是编写更少的代码?
这是一种便利。由于绘制函数一次又一次地引用设备上下文,因此将它存储在局部变量中很方便,因此使代码更简洁。是的,当BeginPaint
成功时,可以保证HDC
返回的BeginPaint
等于绘制结构中的HDC
。