2013-04-21 54 views
2

我正在寻找关于这个windows编程习语的确认,我是否正确地认为许多不同类型的“句柄”不仅仅是作为LRESULT对象传递的,还包括lParam和wParam对象?指向LRESULT的指针

我在猜测,只要我们知道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程序员,但是看起来这些整数只是被用作“缓冲区”,后来程序员在使用之前将它们转换为“真实”类型......声音准确吗?

+1

对于初学者来说,入门假设是错误的。 WM_CREATE *接收* LPCREATESTRUCT **强制转换为WndProc的LPARAM参数;它不会*返回* CREATESTRUCT形式的SendMessage,这会将我们带入第二个无效假设:您从不*发送WM_CREATE,窗口管理器会这样做。你*处理*它。编程风格基本上是通过文档细化来抽象化的。像LPARAM这样的东西在各种不同的窗口消息中都有许多*角色,包括你可以定义的自定义窗口消息,但是你不能通过阅读代码来“认识”它们。你需要文档。 – WhozCraig 2013-04-21 07:59:34

+0

我放弃了。没有代码块我就不能回复,没有任何工作。 [代码] [/代码] 也不 也不 '代码' '/代码' 所以不能精确。 但SendMessage将WindowProcedure放置在堆栈上,并返回WindowProc作为LRESULT所做的操作。 – 2013-04-21 08:37:28

+0

另外,你可以使用SendMessage来发送WM_CREATE消息或任何其他消息。你可能“不应该”,但你可以。 此外,WM_CREATE很好,可以返回一个CREATESRUCT到SendMessage(它将返回给你),你是正确的,你必须捕获消息并处理它们,但是你可以让它们返回你想要的长度因为编译器可以投射到LRESULT。 没有人会以这种方式使用WM_CREATE,这可能是为什么你怀疑它是正确的。我只在这个例子中选择它,因为它是每个Windows程序员都熟悉的消息。 – 2013-04-21 08:58:11

回答

2

这种编程风格是“坏”的,因为没有办法知道究竟是什么在编译时。也就是说,由于WIN32 API是一个C API(而不是C++),当人们想使用相同的方法签名传递任何类型的结构时,没有什么可做的了。

因此,API设计团队决定有两个参数来处理这个问题。一个32位的LPARAM和一个16位的WPARAM

使用Win32 C API时,您只需确保您正确阅读文档,并确保您正确地转换文档所说的就是这样。

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

+0

+1毫不奇怪,我同意这个答案。 – WhozCraig 2013-04-21 08:00:19

+0

我想知道你为什么不制作LRESULT和LPARAM void指针?这正是我过去使用它们的原因。 我猜他们想要一个比void指针分配的更大的“缓冲区”。我也猜测int32/64是更加标准化的。 – 2013-04-21 08:10:46

+0

哦,顺便说一句。现在,LPARAM和WPARAM都是32位或64位整数的类型定义,但是WPARAM是无符号的。 – 2013-04-21 08:40:56