日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入浅出MFC:动态创建控件

發布時間:2023/12/9 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入浅出MFC:动态创建控件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

——-先以CButton為例講解MFC中動態創建控件———
在對話框類中增加了以下3個成員變量:
CButton m_btn1;
CButton m_btn2;
CButton m_btn3;

在對話框的OnInitDialog函數中寫入了如下代碼動態創建控件

BOOL OnInitDialog {m_btn1.CreateEx(0, TEXT("BUTTON"), TEXT("Btn_1"), WS_CHILD | WS_VISIBLE, 10, 10, 100, 20,this->GetSafeHwnd(), (HMENU)IDC_BTN_DYN_BEG, 0);m_btn2.CreateEx(0, TEXT("BUTTON"), NULL, WS_CHILD | WS_VISIBLE, 10, 40, 100, 20,this->GetSafeHwnd(), (HMENU)IDC_BTN_DYN_BEG+1, 0);m_btn2.SetWindowText(TEXT("Btn_2"));m_btn3.Create(TEXT("Btn_3"), WS_CHILD | WS_VISIBLE, CRect(10, 70, 110, 90), this, IDC_BTN_DYN_BEG+4); }

我們現在來研究一下代碼的本質:
m_btn1.CreateEx與m_btn2.CreateEx實際上調用的CWnd::CreateEx
m_btn3.Create調用了CButton::Create
先來瞧瞧CButton::Create,其中調用了CWnd::Create

BOOL CButton::Create(LPCTSTR lpszCaption, DWORD dwStyle,const RECT& rect, CWnd* pParentWnd, UINT nID) {CWnd* pWnd = this;return pWnd->Create(_T("BUTTON"), lpszCaption, dwStyle, rect, pParentWnd, nID); }

CWnd::Create調用了CWnd::CreateEx

BOOL CWnd::Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,const RECT& rect,CWnd* pParentWnd, UINT nID,CCreateContext* pContext) {return CreateEx(0, lpszClassName, lpszWindowName,dwStyle | WS_CHILD,rect.left, rect.top,rect.right - rect.left, rect.bottom - rect.top,pParentWnd->GetSafeHwnd(), (HMENU)(UINT_PTR)nID, (LPVOID)pContext); }

研究CWnd::CreateEx才能看出本質

[wincore.cpp]

BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,int x, int y, int nWidth, int nHeight,HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam) {CREATESTRUCT cs;cs.dwExStyle = dwExStyle;cs.lpszClass = lpszClassName;cs.lpszName = lpszWindowName;cs.style = dwStyle;cs.x = x;cs.y = y;cs.cx = nWidth;cs.cy = nHeight;cs.hwndParent = hWndParent;cs.hMenu = nIDorHMenu;cs.hInstance = AfxGetInstanceHandle();cs.lpCreateParams = lpParam;if (!PreCreateWindow(cs)){PostNcDestroy();return FALSE;}AfxHookWindowCreate(this); //利用Hook進行了子類化HWND hWnd = ::AfxCtxCreateWindowEx(cs.dwExStyle, cs.lpszClass,cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);return TRUE; }

[wincore.cpp]

void AFXAPI AfxHookWindowCreate(CWnd* pWnd) {pThreadState->m_pWndInit == pWnd;if (pThreadState->m_hHookOldCbtFilter == NULL){pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT,_AfxCbtFilterHook, NULL, ::GetCurrentThreadId());}pThreadState->m_pWndInit = pWnd; }

[wincore.cpp]

LRESULT CALLBACK _AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam) {pWndInit->Attach(hWnd);pWndInit->PreSubclassWindow();WNDPROC *pOldWndProc = pWndInit->GetSuperWndProcAddr();WNDPROC afxWndProc = AfxGetAfxWndProc();//改寫了窗口過程函數為MFC通用的窗口過程函數也即子類化oldWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC,(DWORD_PTR)afxWndProc); if (oldWndProc != afxWndProc)*pOldWndProc = oldWndProc;pThreadState->m_pWndInit = NULL; }

所以動態創建控件全部都進行了子類化
以下列出了MFC中具體控件對應的窗口類名稱
(由于BUTTON按鈕對應了PUSHBUTTON&CHECKBOX&RADIOBOX等,按鈕樣式區分了創建按鈕的類型)
顯然:
Button———- CButton—— “BUTTON” — BS_PUSHBUTTON
Check Box——- CButton—— “BUTTON” — BS_AUTOCHECKBOX
Radio Button—- CButton—— “BUTTON” — BS_AUTORADIOBUTTON
Edit Control—- CEdit——– “EDIT”
Combo Box——- CComboBox—- “COMBOBOX”
List Box——– CListBox—– “SysListView32”

如果要動態創建Check Box,代碼如下

CButton m_btnChk; m_btnChk.CreateEx(0, TEXT("BUTTON"), NULL, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 10, 160, 100, 20,this->GetSafeHwnd(), (HMENU)1250, 0);

在CButton實例對象調用CreateEx時指定窗口類名為”EDIT”都可以,只不過創建的控件就是Edit Box了

m_btn1.CreateEx(0, TEXT("EDIT"), TEXT("Btn_1"), WS_CHILD | WS_VISIBLE, 10, 10, 100, 20,this->GetSafeHwnd(), (HMENU)IDC_BTN_DYN_BEG, 0);

總結

以上是生活随笔為你收集整理的深入浅出MFC:动态创建控件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。