在64位程序中调用SetWindowLong指定窗口处理过程失效问题排查(附C++编译器数据模型)

news2024/9/19 17:04:53

C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html
       将32位程序升级到64位后,遇到了使用API函数SetWindowLong设置窗口窗口处理过程WindowProc失效的问题,需要替换成SetWindowLongPtr,能同时兼容32位和64程序。下面讲一下这个小问题的分析解决过程。

      有如下一段代码:

// 创建消息接收窗口
m_hRecvMsgWnd = ::CreateWindowEx( 0, _T("Static"), _T("MsgReciever"), WS_DISABLED
                                , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
                                CW_USEDEFAULT, NULL, NULL, 0, 0 );

if (m_hRecvMsgWnd != NULL )
{
    m_wndprocOld = reinterpret_cast<WNDPROC>( GetWindowLong(m_hRecvMsgWnd, GWL_WNDPROC) );
    SetWindowLong(m_hRecvMsgWnd, GWL_WNDPROC, reinterpret_cast<int>(WndProc) );
} 
else
{
    m_wndprocOld = NULL;
}

代码中创建了一个掩藏的窗口,该窗口用于接收其他代码抛过来的消息。因为业务需要,我们需要在代码中拦截该窗口的消息,于是调用API函数SetWindowLong重新给窗口指定新的窗口消息处理函数,然后我们在新的窗口处理函数中拦截窗口消息,如下所示:

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    // 拦截发给窗口的消息
    if (uMsg == CMainLogic::SYS_INNERMSG_COMING )
    {
                // ...
    }

    return 0;
}

上述代码在x64下编译时会报错:

即找不到GWL_WNDPROC宏的定义,这个就奇怪了,明明在Win32下编译是没问题的,
于是go到GWL_WNDPROC宏的定义处:

GWL_WNDPROC宏的定义在x64下被取消了,定义了新的宏GWLP_WNDPROC(多了一个P),其实GWLP_WNDPROC和GWL_WNDPROC宏的值是一模一样的,所以不管是32位还是64位,直接使用GWLP_WNDPROC就好了!于是将代码修改成:

m_wndprocOld = reinterpret_cast<WNDPROC>( GetWindowLongPtr(m_hRecvMsgWnd, GWLP_WNDPROC) );

这段代码在Win32下编译运行是正常的,但拿到x64下编译后运行就出问题了,好像失效了,在新的窗口消息处理函数中拦截不到消息

        于是以“SetWindowLong msdn”为关键字去搜索,找到MSDN上对API函数SetWindowLong的说明:

msdn上明确说了,为了兼容32位和64位程序,应使用SetWindowLongPtr函数。言下之意,SetWindowLong在x64下是有问题的,应该使用SetWindowLongPtr

       于是直接将上述代码中的GetWindowLong替换成GetWindowLongPtr、将SetWindowLong替换成SetWindowLongPtr。同时,在调用SetWindowLongPtr时,将第三个参数换成LONG_PTR。为什么要换成LONG_PTR呢?可以go到SetWindowLongPtr的定义处查看该函数的参数类型,如下所示:

也可以go到LONG_PTR定义处:

在64位下,LONG_PTR被定义为64位整型__int64,这和64位环境是一致的。


       在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:(该精品技术专栏的订阅量已达到430多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)

C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2: 

C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战经验为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对C++相关知识点进行详细地展开与剖析!专栏涉及了C/C++开发领域多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!

专栏3: 

VC++常用功能开发汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585

专栏将10多年C++开发实践中常用的功能,以高质量的代码展现出来,并对相关功能的实现细节进行了详细的说明。这些常用的代码,其质量与稳定性是有保证的,可以直接拿过去使用,可以有效地解决C++软件开发过程中遇到的问题。


       下面给出常见的int、long和Pointer指针在常见的编译器模型下的长度说明

大家可以参考一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1702825.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

进程信号(2)

一、信号的处理 进程对应信号的处理的一般步骤就是&#xff1a;先去遍历pending位图&#xff0c;找到比特位为1的位置对应的信号&#xff0c;然后再去检测block位图对应位置的比特位是否为1。若不为1&#xff0c;就hander表的对应位置去调用信号的处理动作函数&#xff0c;若为…

ESP32C3驱动SPI NAND

最近收到了一片国产工业级SD NAND&#xff0c;可以替代SD卡&#xff0c;容量大&#xff0c;贴片封装&#xff0c;非常适合做飞控"黑匣子"。 不用写驱动程序自带坏块管理的NAND Flash&#xff08;贴片式TF卡&#xff09;&#xff0c;尺寸小巧&#xff0c;简单易用&…

深入理解Kubernetes的调度核心思想

一、引言 Kubernetes&#xff08;简称K8s&#xff09;是一个开源的容器编排系统&#xff0c;用于自动化部署、扩展和管理容器化应用程序。在Kubernetes集群中&#xff0c;调度器是一个核心组件&#xff0c;它负责将Pod&#xff08;Kubernetes中的最小部署单元&#xff09;分配…

网络协议——FTP(简介、搭建FTP服务端)

一、简介 1、什么是FTP&#xff1f; FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09; TCP/IP 协议组的协议之一。常用20&#xff08;数据&#xff09;、21&#xff08;命令&#xff09;端口作为通讯端口。&#xff08;22为SSH端口&#xff09;F…

一口气看完es(上)

此系列博客分为上中下3篇&#xff1a;上篇是关于es的概念和对数据的增删改操作&#xff0c;中篇是对数据的查询、对搜索结果进行处理操作&#xff0c;下篇是介绍怎么在Java代码中调用和操作es。 基本概念 1、es是什么&#xff1f;有什么作用&#xff1f; es全名是elasticsea…

诚心分享!主食冻干横向对比:希喂、爱立方、K9等谁最值得入手?

主食冻干到底有必要喂吗&#xff1f;七年铲龄铲屎官告诉你&#xff0c;是真的很有必要喂&#xff01; 这些年随着宠物经济的发展、科学养宠的普及&#xff0c;现在养猫不仅局限在让猫吃饱就行&#xff0c;更多人开始关注到猫的饮食健康。大量的实际喂养案例证明了&#xff0c;传…

【Linux】centos7下载安装Python3.10,下载安装openssl1.1.1

目录 centos7下载安装Python&#xff08;版本3.10.14&#xff09; &#xff08;1&#xff09;网页下载python压缩包&#xff0c;并解压缩 &#xff08;2&#xff09;编译安装 Python在make altinstall时&#xff0c;报错及解决 &#xff08;3&#xff09;将安装目录和可执…

Python脚本启动应用并输入账号或密码

一、简介 如果每天要启动某个软件还要输入账号密码登录的需求的话&#xff0c;可以参考本文章&#xff1b; 二、Python环境 环境&#xff1a;Python3.11 已经在Windows电脑中配置Python环境变量&#xff0c;且配置了pipd的环境变量&#xff1b; 三、安装模块 安装所需要的…

【Linux学习】进程间通信 (2) —— 信号

下面是有关进程通信中信号的相关介绍&#xff0c;希望对你有所帮助&#xff01; 小海编程心语录-CSDN博客 目录 1. 信号 1.1 概念 1.2 信号的产生 1.3 信号的处理方式 2. 函数 2.1 kill() 函数 2.2 signal()函数 2.3 sigaction()函数 2.4 sigprocmask()函数 …

自定义函数python:深入解析与实操

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;函数的命名与规范 二、函数命名&#xff1a;遵循规范&#xff0c;易于…

Python计算回归拟合各项指标

0、各项回归指标简介 Relative Root Mean Squared Error&#xff08;RRMSE&#xff09;&#xff1a;The RRMSE normalizes the Root Mean Squared Error (RMSE) by the mean of observations. It goes from 0 to infinity. The lower the better the prediction performance.T…

“AI黏土人”一夜爆火,图像生成类应用应该如何长期留住用户?

文章目录 最近大火的“AI黏土人”&#xff0c;一股浓浓的《小羊肖恩》风。 凭借这这种搞怪的风格&#xff0c;“AI黏土人”等图像生成类应用凭借其创新技术和市场需求迅速崛起并获得巨大关注。然而&#xff0c;要保持用户黏性并确保长期发展&#xff0c;这些应用需要采取一系列…

Spring常用注解(超全面)

官网&#xff1a;核心技术SPRINGDOC.CN 提供 Spring 官方文档的翻译服务&#xff0c;可以方便您快速阅读中文版官方文档。https://springdoc.cn/spring/core.html#beans-standard-annotations 1&#xff0c;包扫描组件标注注解 Component&#xff1a;泛指各种组件 Controller、…

第53期|GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

Leecode热题100---46:全排列(递归)

题目&#xff1a; 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 思路&#xff1a; 元素交换函数递归&#xff1a; 通过交换元素来实现全排列。即对于[x, nums.size()]中的元素&#xff0c;for循环遍历每个元素分别成…

streamlit 学习

表情网站 https://getemoji.com/ 官网&#xff1a; https://streamlit.io/ 文档 https://docs.streamlit.io/develop/api-reference/chat/st.chat_message 安装&#xff1a; pip install streamlit启动 以下的python 文件指写streamlit 程序的脚步。 1、先切换目录到Pyth…

回溯算法之简单组合

哦吼&#xff01;今天结束了二叉树&#xff0c;开始回溯算法 其实也需要用到迭代&#xff0c;哈哈哈哈&#xff0c;但是这个暴力穷举真的好爽。 先记一下回溯算法的基本框架吧 老规矩&#xff1a; 还是有结束条件 但是后面就不太一样了 这里就是for循环&#xff0c;循环n…

2024年中国金融行业网络安全案例集

随着科技的飞速发展,金融行业与信息技术的融合日益加深,网络安全已成为金融行业发展的生命线。金融行业作为国家经济的核心支柱&#xff0c;正在面临着日益复杂严峻的网络安全挑战。因此&#xff0c;深入研究和探讨金融行业的网络安全问题&#xff0c;不仅关乎金融行业的稳健运…

聚数力 以数兴 | 与“闽”同行,共话数字未来

闽江之畔&#xff0c;数智腾飞。5月24日&#xff0c;第七届数字中国建设峰会在海峡国际会展中心盛大举办。本届展会的主题是“释放数据要素价值&#xff0c;发展新质生产力”&#xff0c;由国家发展改革委、国家数据局、福建省人民政府等单位共同主办&#xff0c;福州市人民政府…

【电路笔记】-状态可变滤波器

状态可变滤波器 文章目录 状态可变滤波器1、概述2、**状态可变滤波器电路**3、状态可变滤波器示例4、陷波滤波器设计5、总结状态可变滤波器是一种多反馈滤波器电路,可以从同一单个有源滤波器设计中同时产生所有三种滤波器响应:低通、高通和带通。 1、概述 状态可变滤波器使用…