(在使用g ++编译器的Win32API上下文中询问此问题).我很难理解为什么以下代码行不起作用
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass是WNDCLASSEX结构的一个实例,Windows API明确指出其成员hbrBackground的类型是HBRUSH.此外,HBRUSH只是HANDLE的typedef,而HANDLE又是void*的typedef.因此,HBRUSH应为void*类型.现在,GetStockObject函数的返回类型是HGDIOBJ,它也被命名为HANDLE,因此是void*.
Windows数据类型 http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
GetStockObject http://msdn.microsoft.com/en-us/library/dd144925(v=vs.85).aspx
WNDCLASSEX http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577(v=vs.85).aspx
为什么编译时会出现以下错误:
invalid conversion from 'HGDIOBJ {aka void*}' to 'HBRUSH' [-fpermissive]
如果我从GetStockObject显式地转换返回的值,它可以工作
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
感谢您的任何帮助.
这是因为void*在C++中不允许隐式转换(与C不同).
功能
HGDIOBJ GetStockObject(int fnObject);
返回HGDIOBJ定义为void*:
typedef void NEAR* HGDIOBJ;
你正在向它指向HBRUSH这是一个typedef指向struct
struct HBRUSH__;
typedef struct HBRUSH__ *HBRUSH;
(见windef.h)
虽然这样的赋值在C中工作正常,但在C++中你应该明确地转换:
wndclass.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
正如jensa在评论中指出的那样,文章Windows数据类型已经过时了.这是温和的.我不记得它究竟发生了什么,但是STRICT Type Checking几十年来默认启用了.这篇文章可能写于上个世纪(20世纪).
下面是评论的报价yic81从10/7/2012
本文需要审核.什么时候上次审核?15年前?声明typedef HANDLE HINSTANCE; 完全不正确,就像许多其他typedef HANDLEs一样.其中绝大多数现在是DECLARE_HANDLE()结构.请查看并修复此文章.有关详细信息,请参阅此KB83456 http://support.microsoft.com/kb/83456(最后更新于1999年11月)
您还可以STRICT在此处了解更多有关它的优点:STRICT Type Checking
以下是它的样子windef.h:
DECLARE_HANDLE(HBRUSH);
以下某处DECLARE_HANDLE定义为:
#ifdef STRICT
typedef void *HANDLE;
#if 0 && (_MSC_VER > 1000)
#define DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name
#else
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
#endif
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
默认情况下,我们使用DECLARE_HANDLE第6行.使用NO_STRICT- 第9-10行.
| 归档时间: | 
 | 
| 查看次数: | 2242 次 | 
| 最近记录: |