我与一位程序员进行了一次小小的辩论.他在代码中使用了以下习语:
HWND hWnd = SomeFunctionWhichReturnsAWindow();
if(hWnd != NULL && hWnd != INVALID_HANDLE_VALUE)
{
// All good
}
else
{
// Error
}
Run Code Online (Sandbox Code Playgroud)
我告诉他,在我看来,这是一种错误的方法,因为HWND类型与INVALID_HANDLE_VALUE定义无关,但他确信这是一个好的代码,因为有效的句柄永远不会相等INVALID_HANDLE_VALUE,而且它的情绪是"比抱歉更安全".
那么,这是一个可以接受和正确的成语吗?
Dav*_*nan 16
比较HWND反对是错误的INVALID_HANDLE_VALUE.虽然,在实践中,这不是一个会伤害你的错误.
HWND由CreateWindowEx无效保留的唯一值是NULL.现在,它恰好是一个INVALID_HANDLE_VALUE不能有效的HWND实现细节,但这只是实现细节.能产生窗口句柄功能,CreateWindowEx,使用NULL以指示失败.这就是你需要知道的全部.
如果您希望与您的同事赢得您的论点,我建议您查看内部SomeFunctionWhichReturnsAWindow并找出调用哪个Win32 API来生成HWND.然后查阅文档.这将显示您NULL保留的无效值.
为了清楚起见,您绝对应该更改代码以NULL单独测试.
Rem*_*eau 11
INVALID_HANDLE_VALUE定义为-1.无效HWND定义为0.没有API会HWND(-1)在失败时返回,因此检查INVALID_HANDLE_VALUE是没有意义的,它永远不会发生.
但是,有些API接受保留的非零HWND值作为输入,因此不能用作有效的HWND返回值:
如果hWnd为NULL,则(Peek/Get)Message检索属于当前线程的任何窗口的消息,以及当前线程的消息队列中hwnd值为NULL的任何消息(请参阅MSG结构).因此,如果hWnd为NULL,则处理窗口消息和线程消息.
如果hWnd为-1,则(Peek/Get)消息仅检索当前线程的hwnd值为NULL的消息队列上的消息,即PostMessage发布的线程消息(当hWnd参数为NULL时)或PostThreadMessage.
所以HWND(0)和之间存在逻辑差异HWND(-1).事实上,由于存在这种差异,有效HWND将永远不会为-1,因为消息循环永远无法为其检索消息.
还有SetWindowPos()一些保留值:
hWndInsertAfter [in,optional]
类型:HWND窗口的句柄,位于Z顺序中定位窗口之前.此参数必须是窗口句柄或以下值之一.
HWND_BOTTOM
(HWND)1
将窗口置于Z顺序的底部.如果hWnd参数标识最顶层窗口,则窗口将失去其最顶层状态,并放置在所有其他窗口的底部.HWND_NOTOPMOST
(HWND)-2
将窗口置于所有非最顶层窗口(即所有最顶层窗口后面)的上方.如果窗口已经是非最顶层窗口,则此标志无效.HWND_TOP
(HWND)0
将窗口置于Z顺序的顶部.HWND_TOPMOST
(HWND)-1
将窗口置于所有非最顶层窗口的上方.即使停用窗口,窗口也会保持最高位置.