2013-04-21 50 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