为何CDialog::DoModal返回INT_PTR而非旧SDK中的int?
这是个非常务实的问题!微软把CDialog::DoModal()的返回类型从int调整为INT_PTR,本质是为了适配64位平台的底层逻辑和API设计的通用性,咱们可以从几个核心角度理解:
对齐底层Win32 SDK的类型设计
MFC本质是Win32 API的封装,而原生Win32对话框函数(比如DialogBoxParam())的返回值在64位系统下定义为INT_PTR。这个类型是自适应宽度的:32位编译时等价于int,64位时等价于__int64。
为什么底层要这么设计?因为Win32对话框的返回值不局限于IDOK/IDCANCEL这类小整数——某些场景下开发者可能会返回指针值(比如从对话框返回一个动态创建的对象地址),如果用32位的int接收,在64位系统下会直接截断高位地址,导致内存访问错误。MFC作为上层封装,必须和底层API的类型保持一致,避免这种隐性的兼容性问题。64位迁移的API统一性要求
在64位平台普及的过程中,微软对整个Windows API体系做了类型标准化:把所有可能涉及指针或宽整数返回的API,都统一替换成INT_PTR/LONG_PTR这类自适应类型。这样开发者不需要为32/64位写大量条件编译代码,代码的可移植性更强。DoModal()的调整正是这个统一策略的一部分,和SendMessage()返回LRESULT(本质是INT_PTR)的逻辑完全一致。覆盖更广泛的使用场景
你提到IDOK/IDCANCEL用64位确实没必要,但API设计必须考虑通用性。有些自定义对话框可能会返回超出32位int范围的自定义值,或者如前面所说的指针类型。微软调整返回类型是为了让API能支持所有合法的使用场景,而不是只覆盖最常见的按钮返回值。
至于你提到的代码适配方案,把int替换为INT_PTR确实是最规范的做法——这也是微软官方推荐的64位迁移方案。另外你也可以用auto自动推导类型:
auto answer = someDialog.DoModal();
这种写法更简洁,也能自动适配32/64位的类型差异,不过如果需要明确类型语义,INT_PTR会更清晰。
内容的提问来源于stack exchange,提问作者Jabberwocky

