Re: [問題] MFC GetDlgItem的用法
: 但一直搞不清楚(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
10/09 11:41, 3F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):