从HGDIOBJ转换为HBRUSH
Conversion from HGDIOBJ to HBRUSH
(这个问题是在使用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
GetStockObjecthttp://msdn.microsoft.com/en-us/library/dd144925(v=vs.85).aspx
WNDCLASSEXhttp://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);
谢谢你的帮助。
这是因为在C++中不允许从void*
进行隐式转换(与C不同)。
功能
HGDIOBJ GetStockObject(int fnObject);
返回定义为void*
:的HGDIOBJ
typedef void NEAR* HGDIOBJ;
您正在将其发送到HBRUSH,HBRUSH是指向struct
的typedef
指针
struct HBRUSH__;
typedef struct HBRUSH__ *HBRUSH;
(见windef.h
)
虽然这样的赋值在C中很好,但在C++中,您应该显式地强制转换:
wndclass.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
请参阅:void指针:C和C++之间的区别
编辑:
正如jensa在评论中指出的那样,文章"Windows数据类型"已经过时了。这是委婉的说法。我不记得具体是什么时候发生的,但STRICT Type Checking
已经默认启用了几十年。这篇文章可能写于上个世纪(20世纪)。
以下是10/7/2012
对yic81
的评论
这篇文章需要复习。上次审查是什么时候?15年前?语句typedef HANDLE HINSTANCE;完全不正确其他typedef句柄。其中绝大多数现在都是DECLARE_HANDLE()结构。请审阅并修复这篇文章。参见本KB83456http://support.microsoft.com/kb/83456(上次更新于1999年11月)更多详细信息
你也可以在这里了解更多关于STRICT
及其优点:STRICT类型检查
以下是它在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
默认情况下,我们使用第6行中的DECLARE_HANDLE
。带有NO_STRICT
——第9-10行。
在C++术语中,可以说GetStockObject
返回一个GDIBase*
,它需要转换为适当的派生类(例如,假定HBrushGDI
)。因此,你必须打字。
class GDIBase;
class HBrushGDI : GDIBase;
GDIBase* GetStockObject(int);
HBrushGDI* pBrush;
pBrush = static_cast<HBrushGDI*>GetStockObject(WHITE_BRUSH);
它与从GetProcAddress
返回的函数指针的类型转换相同。因此,将类型转换为适当的类型是安全的(假设您知道正确的类型)。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 从HGDIOBJ转换为HBRUSH