我刚开始学习C ++并学习winapi,我正在做Forgers Win32 API教程。
这是我的代码:
//MyControl.h
#pragma once
#include <windows.h>
#include "resource.h"
BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL BrushExists(HBRUSH hBrush);
-------------------------------------------------------
//MyControl.cpp
#include "MyControl.h"
HBRUSH g_hbrBackground = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
return (int)DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, (DLGPROC)DlgProc);
}
BOOL BrushExists(HBRUSH hBrush) // I added this to better understand what is happening
{
if (hBrush)
return TRUE;
else
return FALSE;
}
BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
{
g_hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
//... Other code skipped copy pasting ...
}
break;
case WM_COMMAND:
//... Other code skipped copy pasting ...
break;
case WM_CTLCOLORDLG:
return (LONG_PTR)g_hbrBackground; // Where casting happens
// return BrushExists(g_hbrBackground); // Tried this to understand things
break;
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(255, 255, 255));
SetBkMode(hdcStatic, TRANSPARENT);
return (LONG_PTR)g_hbrBackground; // Where casting happens
// return BrushExists(g_hbrBackground); // Tried this to understand things
}
break;
//... Other code skipped copy pasting ...
}
代码编译并发出警告:C4244: 'return': conversion from 'LONG_PTR' to 'BOOL', possible loss of data
投射工作,对话框按预期颜色正确: Black colored dialog.
我的问题:当HBRUSH从返回BOOL的函数(DLGPROC)返回为LONG_PTR时,后台会发生什么?我从阅读C ++的假设是,如果LONG_PTR非零,则返回的BOOL为TRUE,如果LONG_PTR为零,则返回的BOOL为FALSE。为了检查这一点,我创建了函数BOOL BrushExists(HBRUSH hBrush);// See code
。使用此函数检查HBRUSH并返回TRUE,编译时没有警告并且运行没有错误。但是对话框的颜色不会发生:
Black color missing.
所以我的假设是错误的。 {000}似乎将LONG_PTR
评估为数字而不是BOOL
。有人可以向我解释这是怎么回事吗?
答案 0 :(得分:3)
请注意,它是BOOL
而不是bool
。使用Windows SDK,BOOL
是int
的typedef,可以存储32位值 - 它不是一个只能存储true
或{{}的简单布尔值1}}。
这基本上是API中的一个kludge。在32位Windows中,刷柄处于32位值,即使它很丑陋且可能令人困惑,它也是安全的#34;返回一个刷子手柄强制转换为false
(你必须强制转换它,因为BOOL
被定义为返回)。
一旦Windows获得64位支持,这种情况显然是不可接受的 - 在这个例子中,刷柄(指针)的大小是64位 - 将它们转换为32位类型是不安全的
因此,DialogProc
的定义已更改为返回DialogProc
而不是INT_PTR
。这个类型定义为x86中的32位和x64中的64位。您使用的示例代码显然是在此更改之前,但所有新代码都应使用BOOL
的正确定义作为返回DialogProc
。
答案 1 :(得分:0)
int
只是LONG_PTR
typedef&#39; d。long int
可以是__int64
或#ifdef _WIN64
typedef __int64 LONG_PTR;
#else
typedef long LONG_PTR;
#endif
- 取决于所选择的平台。来自标题:
BOOL
您似乎将项目构建为x64编译器,因此LONG_PTR
到int
(基本上是int64
到int
)会向您发出警告。
请注意,{C <1}和long
在Visual C ++ / Windows上基本相同。