本文所述情况是我在写测试代码时发现和解决问题的过程,见以下这段测试代码,在DEV-C++用32位TDM-GCC编译可无错无警告通过;但用64位编译却出错了。

#include <windows.h>
#include <string>
using namespace std;LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {static int i=0;static HWND bHwnd[15],sHwnd;static HFONT hFont = CreateFont(30, 20, 0, 0, 700, FALSE, FALSE, FALSE, DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE,TEXT("仿宋") );switch(Message) {case WM_CREATE:for (auto b:bHwnd){b = CreateWindow("BUTTON", "", //先不设标题,可以创建后添加 WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_FLAT | BS_PUSHBUTTON, 70 + (i>=10 ? 360:(i>=5 ? 180:0)) ,110 + i*60 - (i>=10 ? 600:(i>=5 ? 300:0)) ,120, 50, hwnd,(HMENU)i,(HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);SendMessage(b, WM_SETTEXT, 0, (LPARAM)to_string(1+i++).c_str()); //添加标题 }sHwnd = CreateWindow( TEXT("STATIC"),NULL,WS_CHILD | WS_VISIBLE,70, 30, 480, 50, hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance,NULL);SendMessage(sHwnd, WM_SETFONT, (WPARAM)hFont, lParam);SetWindowLong(sHwnd, GWL_STYLE, GetWindowLong(sHwnd, GWL_STYLE)|SS_CENTER|SS_CENTERIMAGE);break;case WM_COMMAND: SetWindowText(sHwnd, to_string(LOWORD(wParam)+1).data());break;case WM_MOUSEMOVE:SetWindowText(sHwnd, to_string((int)GetFocus()).data());break; case WM_DESTROY: PostQuitMessage(0);break;default:return DefWindowProc(hwnd, Message, wParam, lParam);}return 0;
}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {WNDCLASSEX wc; HWND hwnd; MSG msg;memset(&wc,0,sizeof(wc));wc.cbSize       = sizeof(WNDCLASSEX);wc.lpfnWndProc    = WndProc;wc.hInstance     = hInstance;wc.hCursor         = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.lpszClassName = "WindowClass";wc.hIcon       = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm      = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) {MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);return 0;}hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL,NULL,hInstance,NULL);if(hwnd == NULL) {MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);return 0;}while(GetMessage(&msg, NULL, 0, 0) > 0) { if(!IsDialogMessage(hwnd, &msg)){  TranslateMessage(&msg); DispatchMessage(&msg);}}return msg.wParam;
}

错误在39行代码:SetWindowText(sHwnd, to_string((int)GetFocus()).data());

错误信息:[Error] cast from 'HWND' to 'int' loses precision [-fpermissive]

分析错误所在,先看SetWindowText()原型:

#define SetWindowText __MINGW_NAME_AW(SetWindowText)
​​​WINUSERAPI WINBOOL WINAPI SetWindowTextA(HWND hWnd,LPCSTR lpString);
WINUSERAPI WINBOOL WINAPI SetWindowTextW(HWND hWnd,LPCWSTR lpString);

再看LPCSTR、LPCWSTR:

typedef CONST CHAR *LPCSTR,*PCSTR;
typedef CONST WCHAR *LPCWSTR,*PCWSTR;
typedef LPCSTR PCTSTR,LPCTSTR,PCUTSTR,LPCUTSTR;
typedef LPCWSTR PCTSTR,LPCTSTR;

to_string((int)GetFocus()).data()中,.data()等价于.c_str()没问题,所以只剩下GetFocus()的返回值强制转int这个可能了。

GetFocus()原型:

WINUSERAPI HWND WINAPI GetFocus(VOID);

它的返回值是HWND,它是窗口句柄Handle of Window,相当于一个指向窗口的指针。

#ifndef WIN_INTERNAL
    DECLARE_HANDLE            (HWND);
    DECLARE_HANDLE            (HHOOK);
#ifdef WINABLE
    DECLARE_HANDLE            (HEVENT);
#endif
#endif
......

struct HWND__ { 
    int unused ;
};
typedef struct HWND__ *HWND;

估计问题在32位系统里HWND 和 int 是同字节的可以转换,但在64位系统中int的字节宽度就不够所以出错了。

马上写代码验证:

#include <iostream>
#include <windows.h>
using namespace std;BOOL IsWow64()
{   //此函数好像取决于编译器的是32-bit还是64-bit,而不是操作系统的位数typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);LPFN_ISWOW64PROCESS fnIsWow64Process;BOOL bIsWow64 = FALSE;fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle("kernel32"),"IsWow64Process");if (NULL != fnIsWow64Process)fnIsWow64Process(GetCurrentProcess(),&bIsWow64);return bIsWow64;
}int main(void)
{cout<<sizeof(HWND)<<endl;cout<<sizeof(int)<<endl;cout<<sizeof(long)<<endl;cout<<sizeof(long long)<<endl;cout<<IsWow64()<<endl;return 0;
}
/*
8
4
4
8
0 //或1,取决于编译器的是32-bit还是64-bit --------------------------------
Process exited after 0.8295 seconds with return value 0
请按任意键继续. . .
*/

把 SetWindowText(sHwnd, to_string((int)GetFocus()).data()) 中红字部分改为(long long)就通过编译了。

后来发现只要是8位字节的数据类型都行(__int64)、(intptr_t)、(uintptr_t)、(ptrdiff_t),甚至这些类型:(LPARAM)、(WPARAM)、(LRESULT)。

看它们在库函数中的定义:

#ifndef _INTPTR_T_DEFINED
#define _INTPTR_T_DEFINED
#ifndef __intptr_t_defined
#define __intptr_t_defined
#undef intptr_t
#ifdef _WIN64
__MINGW_EXTENSION typedef __int64 intptr_t;
#else
typedef int intptr_t;
#endif /* _WIN64 */
#endif /* __intptr_t_defined */
#endif /* _INTPTR_T_DEFINED */#ifndef _UINTPTR_T_DEFINED
#define _UINTPTR_T_DEFINED
#ifndef __uintptr_t_defined
#define __uintptr_t_defined
#undef uintptr_t
#ifdef _WIN64
__MINGW_EXTENSION typedef unsigned __int64 uintptr_t;
#else
typedef unsigned int uintptr_t;
#endif /* _WIN64 */
#endif /* __uintptr_t_defined */
#endif /* _UINTPTR_T_DEFINED */#ifndef _PTRDIFF_T_DEFINED
#define _PTRDIFF_T_DEFINED
#ifndef _PTRDIFF_T_
#define _PTRDIFF_T_
#undef ptrdiff_t
#ifdef _WIN64
__MINGW_EXTENSION typedef __int64 ptrdiff_t;
#else
typedef int ptrdiff_t;
#endif /* _WIN64 */
#endif /* _PTRDIFF_T_ */
#endif /* _PTRDIFF_T_DEFINED */
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;... ...#ifdef _WIN64__MINGW_EXTENSION typedef __int64 INT_PTR,*PINT_PTR;__MINGW_EXTENSION typedef unsigned __int64 UINT_PTR,*PUINT_PTR;__MINGW_EXTENSION typedef __int64 LONG_PTR,*PLONG_PTR;__MINGW_EXTENSION typedef unsigned __int64 ULONG_PTR,*PULONG_PTR;
#define __int3264 __int64
#elsetypedef int INT_PTR,*PINT_PTR;typedef unsigned int UINT_PTR,*PUINT_PTR;typedef long LONG_PTR,*PLONG_PTR;typedef unsigned long ULONG_PTR,*PULONG_PTR;
#define __int3264 int
#endif

果然这些数据在两类系统中就是int和__int64的不同而已,所以把39行代码改为以下几行,就不出错了。

         #ifdef _WIN64SetWindowText(sHwnd, to_string((__int64)GetFocus()).data());#elseSetWindowText(sHwnd, to_string((int)GetFocus()).data());#endif /* _WIN64 */

随后再次编译,第23行代码又出现警告:  [Warning] cast to pointer from integer of different size [-Wint-to-pointer-cast]

估计是差不多情形,把(HMENU)i 改成 (HMENU)(WPARAM)i,代码通过无警告无错误编译;并且用 (WPARAM) 强制转换相当于C++代为条件编译了 。

C++ Windows编程中WPARAM等数据类型在32位和64位系统中的差异相关推荐

  1. 【笔试题】C语言结构体中,不同的数据类型在32位和64位下所占字节的区别

    题目 如下C程序,在64位处理器上运行后sz的值是什么? struct st {int *p;int i;char a; }; int sz=sizeof(struct st); 答案 16 解析 考 ...

  2. 从编程角度看32位和64位

    ------------------------文章内容并非原创,看其他博主,有所收获,积累一二---------------------------------- 一)64位系统和32位有什么区别? ...

  3. C++中int、long和double的取值范围和最大值,以及32位和64位的差异解读

    前言 一般对于C/C++下int等基本数字类型,主要关注三个维度,长度.取值范围和最大值的宏定义.下面分三个维度说明下. 有三个影响因素: 语言规则限制:比如int是变长,long是定长,double ...

  4. 64位处理器_32位和64位的Windows 10和处理器(CPU)有什么区别

    当你下载Windows 10.Office或任何其他软件时,可能会注意到有32位和64位版本可用,这时你可能会想到一个问题,我需要哪个? 在本文中,你可以了解32位和64位Windows 10之间的区 ...

  5. 64位linux,sizeof(int),C中sizeof()的用法——32位和64位下的sizeof()

    机器平台:X86_64 处理器 操作系统:Red Hat 4.1.2-14 编译器: gcc version 4.1.2 20070626 Size of char is:               ...

  6. 64 大小_32位和64位Windows系统差别在哪里

    如何确定32位和64位系统? 计算机体系结构是32位还是64位取决于计算机内部的处理器(CPU).目前,大多数计算机处理器属于这两个类别之一. 64位处理器比对应的32位处理器指数级更强大,因为它们可 ...

  7. Windows系统的32位和64位系统区别

    第一,设计初衷不同 64位的操作系统原本的初衷就是为了满足视频剪辑.三维动画.特效渲染.机械设计.高速运算等生产使用和前沿科技,换句简明的话说就是:它们是高科技人员使用本行业特殊软件的运行平台.32位 ...

  8. 判断当前Windows XP操作系统是32位还是64位的方法

    昨天在调查怎样区分Windows XP32位和64位的问题,在网上找了一下,大家常用的有两种方法. 方法一.通过指针来判断. 在32位操作系统上指针长是4个字节,而在64位系统上指针为8个字节. 方法 ...

  9. 台式计算机32位和64位的区别,电脑操作系统中32位和64位到底有哪些区别?

    xp系统之后,开始有了Windows7.如果你经常关注,并且安装软件的话,会常常听到32位和64位,那么这到底是什么意思呢?它们有什么区别了? 1.一般我们说的32位和64位,是指三种情况. 一种是3 ...

最新文章

  1. vim的一些快捷键,备忘
  2. PXE BOOT INSTALL WINXP
  3. 034_CSS绝对定位
  4. tcp c++ bind 端口_计算机端口到底是什么?
  5. 邮件中链接审批被公司邮件服务器自动操作了,Exchange 2010 实现邮件审批功能...
  6. java基础知识讲解(一)数据类型和运算符
  7. jQuery选择器案例之——index.js
  8. php加速缓存器opcache,apc,xcache,eAccelerator
  9. webpack打包优化_如何提升 Webpack 打包速度
  10. ActiveMQ(一)——JMS、应用场景、关键对象、demo
  11. java 噪声信道模型_噪声信道模型zz
  12. 分享10套好看的简历模板 | 免费Word模板下载
  13. 基于Android平台的会议室管理系统详细设计说明书
  14. 我们比任何时候都更接近梦想
  15. 计算机arp 各命令,ARP命令参数详解
  16. 提高系统开发效率的“银弹”——X-series可视化大规模应用开发工具集
  17. 质量运营在美团点评智能支付业务测试中的初步实践
  18. 使用 MyBatis 的 Maven 插件生成代码
  19. 搭建SSH,SSZ架构需注意数据库的编码问题
  20. Ubuntu配置和使用cups打印服务器

热门文章

  1. Qt信号与槽的五种连接方式
  2. 虚拟机网络:Bridged(桥接模式)
  3. golang使用sort包排序
  4. 【stm8】 远程更新固件--stm8s007c8t6 IAP Bootloader
  5. Github使用教程图文详解
  6. c语言uart串口通讯,uart串口通信c语言实现
  7. uni-App 新闻资讯
  8. ASEMI肖特基二极管MBR20200FCT特征,MBR20200FCT应用
  9. java 重写快捷键_方法重写
  10. APP极光消息推送无法接收,部分手机设置