Winapi 向LRESULT/从LRESULT转换指针

Winapi 向LRESULT/从LRESULT转换指针,winapi,casting,lparam,Winapi,Casting,Lparam,我想确认一下这个windows编程习惯用法,我认为许多不同类型的“句柄”不仅作为LRESULT对象传递,而且还作为lParam和wParam对象传递,这是否正确 我猜想,只要我们知道LRESULT或lParam/wParam中的句柄类型是什么,我们就可以将其转换回它 比如说 case WM_CREATE: ... //create a window //lParam is the CREATESTRUCT for new window created here ....

我想确认一下这个windows编程习惯用法,我认为许多不同类型的“句柄”不仅作为LRESULT对象传递,而且还作为lParam和wParam对象传递,这是否正确

我猜想,只要我们知道LRESULT或lParam/wParam中的句柄类型是什么,我们就可以将其转换回它

比如说

case WM_CREATE:
   ...
   //create a window
   //lParam is the CREATESTRUCT for new window created here
   ....
   return lParam;
...
...
CREATESTRUCT cStruct = (CREATESTRUCT)SendMessage(hwnd, msg /*WM_CREATE*/);
cStrcut.cx;//this is the width of the new window?
对吗

这是“正确的”吗?有人能给我和StaticOverflow社区提供一篇关于这种技术/习惯用法的短文吗

问题: 我们应该只返回lParam(或者只返回wParam)值吗? 有什么应该知道的陷阱吗?
LRESULT和LPARAM都是LONG_PTR类型,是32位或64位整数。我不是一个经验丰富的C程序员,但看起来这些整数只是被用作“缓冲区”,程序员在使用前会将其转换为“真实”类型。。。听起来准确吗?

这种编程风格是“糟糕的”,因为在编译时无法知道什么是真正的东西。这就是说,由于WIN32 API是一个C API(而不是说C++),因此当人们想要使用相同的方法签名传递任何类型的结构时,没有什么其他的方法可以做

因此,API设计团队决定使用两个参数来处理这个问题。32位
LPRAM
和16位
WPARAM

在使用Win32 C API时,您只需确保正确阅读文档,并确保按照文档中所述的方式进行转换


所以要回答你的问题,你是正确的——但这只是因为你别无选择。在这里试图完成,MFC(C++程序员)出现了,但这并不被认为是一个好的面向对象的库——它更像是包装器。还有其他一些做得更好的(例如wxWidgets)。

首先,进入假设是错误的。WM_CREATE接收一个LPCREATESTRUCT转换,作为WndProc的LPARAM参数;它不会返回CREATESTRUCT表单SendMessage,这就引出了第二个无效假设:您从未发送WM_CREATE,窗口管理器会发送。你来处理它。编程风格本质上是通过文档进行抽象和细化。像LPRAM这样的东西在各种不同的窗口消息中扮演着许多角色,包括您可以定义的自定义窗口消息,但您无法通过阅读代码来“了解”它们。你需要医生,我放弃。如果没有代码块,我无法回复,而且什么都不起作用。[code][/code]也不是
也不是'code'/code',所以我不能准确地说。但是SendMessage将WindowProcedure放在堆栈上,并返回WindowProc作为LRESULT执行的操作。此外,您还可以使用SendMessage触发WM_CREATE消息或任何其他消息。你可能“不应该”,但你可以。此外,WM_CREATE可以很好地将CREATESRUCT返回给SendMessage(它将返回给您),您确实需要捕获消息并对其进行处理,但只要编译器可以强制转换为LRESULT,您就可以让它们返回您想要的w/e。可能没有人会以这种方式使用WM_CREATE,这可能就是为什么您怀疑它的正确性。我之所以选择它是因为它是每个windows程序员都熟悉的一条信息。当然,您也受文档的约束。API的某些部分“期望”来自某些消息的某些返回值。返回WM_CREATE消息的LPARAM可能会破坏API中可能期望WM_CREATE返回其他内容的部分,这将导致SEGFULT。我不知道,但将来我将避免在交流有效想法时使用糟糕的代码。@TraeBarlow:,它解释了如何在注释中格式化代码。我想知道为什么您不使用LRESULT和LPARAM void指针?这正是我过去使用它们的目的。我猜他们想要一个比空指针分配的w/e更大的“缓冲区”。我还猜测int32/64更标准化了。哦,顺便说一句。现在LPARAM和WPARAM都是32位或64位整数的typedef,但是WPARAMs是无符号的。@Trae因为远指针和近指针之间的差异,在编写16位窗口时必须区分它们。是的,LPARAM、WPARAM、LRESULT和其他数据类型随着时间的推移发生了变化。这就是你使用#定义的原因。就像Moo说的,它不再被认为是好的风格了,但它在20世纪80年代初非常活泼,仍然很好用。唯一的缺点是您必须阅读文档。但在20世纪80年代,你也可以期望程序员阅读文档。当时他们并没有堆栈溢出,所以这是一项艰苦的工作。@CodyGray,+1表示“当时并没有堆栈溢出”。)