Re: [問題] MFC GetDlgItem的用法

看板C_and_CPP作者 (purpose)時間10年前 (2013/10/09 00:23), 編輯推噓2(201)
留言3則, 2人參與, 最新討論串2/2 (看更多)
: 但一直搞不清楚(CButton*)GetDlgItem(IDC_BUTTON)裡的(CButton*)是什麼意思(汗) 顯式型別轉換 (cast),前面推文有講了。 這個查 C++ 的書就有詳細說明。 : 我試著改寫成我所能理解的"指向物件的指標"形式: : CButton *a,*b; : b=a->GetDlgItem(IDC_BUTTON); : b->SetWindowText(_T("Default State")); : 結果當然是不行XD 在第二行定義b的地方出現錯誤: : IntelliSense: 型別 "CWnd *" 的值無法指派至型別 "CButton *" 的實體 : 但卻看不懂這個問題..... : 想請問各位熱心的板友, 小弟的邏輯出了什麼問題>_< 觀念不太正確。 GetDlgItem,顧名思義, 是從 Dialog (對話方塊) 取得其包含的物品。 你的 a 變數是一種 CButton 不是 Dialog,又怎可以執行 CWnd::GetDlgItem() 呢。 (對,語法上不禁止你這樣寫,這是 MFC 設計上的錯) 再來,a 單純是指標,該指標指向的東西你還沒 new 出來...請回去翻書看指標的章節。 ---- 最初,Windows 沒有 C++ 跟 MFC 搗亂時, 其視窗程式上的按鈕、對話方塊...等,都是用 HANDLE 變數存放,如 HWND。 所以當時 Win32 API 版本的 ::GetDlgItem(HWND hDlg, int nIDDlgItem) 在參數 1 要用 hDlg 傳 Dialog 的 HANDLE 值。 進入 MFC 時代後,變成這樣: CWnd* CWnd::GetDlgItem( int nID ) const; void CWnd::GetDlgItem( int nID, HWND* phWnd ) const; 其中第二版的實際程式碼為 *phWnd = ::GetDlgItem(this->m_hWnd, nID); 幾乎跟 API 版做一模一樣的事,最後都是得到 nID 控件的 HWND 值,沒什麼好說的。 但是第一版本會傳回一個 CWnd * 今天假設 nID 指的是一顆按鈕,你就要這樣顯式轉型: CButton *pBtn1 = (CButoon *) GetDlgItem(ID_MYBUTTON); 如此才能當成按鈕來操作。 ---- 在 MSDN 文件中,對 CWnd::GetDlgItem() 的回傳值會這樣敘述: The returned pointer may be temporary and should not be stored for later use. 這是因為 MFC 總是替程式自動維護一份對應表,把「HWND <-> MFC 物件位址」做紀錄。 比如把一顆按鈕的 HWND 值,傳給查詢函數 CWnd::FromHandle() 就能得到該按鈕 所對應的 MFC 物件位址,也就是 CButton * 值。 實務上因為 MFC 物件的型態很多,所以物件位址的資料型態會使用 CWnd *, 需要時再自己 downcast 就好。 若某個 HWND 從未跟任何 MFC 物件綁定過,則 MFC 會產生暫時的物件出來跟這個 HWND 做映射,但這種映射是為了解決 GetDlgItem 需求而產生的,所以 過段時間就可能被清除,到時候暫時物件也會被砍掉。(pointer may be temporary) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 124.8.131.216

10/09 00:56, , 1F
推 詳細解說
10/09 00:56, 1F

10/09 11:40, , 2F
謝謝前輩詳盡的解說! 發現我之前沒碰過型別轉換
10/09 11:40, 2F

10/09 11:41, , 3F
我會先去研究一下cast 再來研讀這篇 謝謝!!
10/09 11:41, 3F
文章代碼(AID): #1IL35xis (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1IL35xis (C_and_CPP)