winapi - 了解 : conversion from long_ptr to bool possible loss of data

标签 winapi visual-c++ casting

我刚刚学习 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,BOOLint 的 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/

相关文章:

sql - 如何将 String 值转换(或强制转换)为 Integer 值?

c++ - 一个应用程序可以运行另一个应用程序的代码吗?

vba - 如何获取工作簿文件的 "Last Saved By"属性

c++ - 如何使用 C++ 正确检查注册表项是否存在?

c++ - 在早期 Windows 版本上运行时检查 Windows 10 功能是否存在

windows - 哪个是前瞻性名称,vc_redist.<arch>.exe 或 vcredist_<arch>.exe?

c++ - 值如何存储在 char 中

c++ - 引入参数化构造函数后显示 LNK 2019 未解析的外部符号的代码错误

python - 基数为 10 的 int 的无效文字 : ''

ios - 使用 'case let x = y as NSString 发生内存泄漏