我刚刚学习 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':从'LONG_PTR'转换为'BOOL',可能丢失数据
转换工作正常并且对话框的颜色符合预期: Black colored dialog.
我的问题:当 HBRUSH 从返回 BOOL 的函数 (DLGPROC) 作为 LONG_PTR 返回时,后台会发生什么?我在阅读 C++ 时的假设是,如果 LONG_PTR 非零,则返回的 BOOL 为 TRUE,如果 LONG_PTR 为零,则返回的 BOOL 为 FALSE。为了检查这一点,我创建了函数 BOOL BrushExists(HBRUSH hBrush);//查看代码
。使用此函数检查 HBRUSH 并返回 TRUE,编译时不会出现警告,运行时也不会出现错误。但对话框的着色没有发生:
Black color missing.
所以我的假设是错误的。 LONG_PTR
似乎被 win32 API 评估为数字而不是 BOOL
。有人可以向我解释这是怎么发生的吗?
最佳答案
请注意,它是 BOOL
而不是bool
。使用 Windows SDK,BOOL
是 int
的 typedef ,它可以存储一个32位值 - 它不是一个只能存储true
的简单 bool 值或false
.
这基本上是 API 中的一个拼凑。在 32 位 Windows 中,画笔句柄适合 32 位值,尽管它很难看并且可能会造成混淆,但将画笔句柄强制转换为 BOOL
是“安全的” (并且您必须强制转换它,因为这就是 DialogProc
被定义为返回的内容)。
一旦 Windows 获得 64 位支持,这种情况显然是 Not Acceptable - 在此示例中,画笔句柄(即指针)的大小为 64 位 - 将它们转换为 32 位类型是不安全的。
因此,DialogProc
的定义改为返回INT_PTR
而不是BOOL
。在 x86 中它被类型定义为 32 位,在 x64 中被类型定义为 64 位。您使用的示例代码显然早于此更改,但所有新代码都应使用 DialogProc
的正确定义。返回 INT_PTR
.
关于winapi - 了解 : conversion from long_ptr to bool possible loss of data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37452607/