目錄
- 指定ID
- 物件指標
- 建立物件
- 控制元件樣式
- 訊息映射
- 按鈕單擊
- 組合框選中
指定ID
在類中宣告并定義按鈕控制元件的起始ID,以控制元件的型別和功能對動態控制元件ID進行分組,每組最好定義一個自己的起始ID方便管理:
#define IDC_CONTROL_START 1000
#define IDC_BTN_START IDC_CONTROL_START+100
#define IDC_STA_START IDC_CONTROL_START+200
#define IDC_EIT_START IDC_CONTROL_START+300
#define IDC_CMB_START IDC_CONTROL_START+400
起始ID可以設定大一點,避免與表單內部的控制元件ID重復,上面定義了四種控制元件的起始ID,
物件指標
根據動態控制元件的生命周期,在對應的作用域里面定義控制元件物件的指標,一般會定義在頭檔案里保證控制元件和表單生命周期相同:
std::vector<CButton*>pBtn;
std::vector<CStatic*>pSta;
std::vector<CEdit*>pCet;
std::vector<CComboBox*>pCmb;
注:使用vector容器便于擴充控制元件數量,需添加頭檔案vector,
建立物件
在類的OnInitDialog()函式中動態創建按鈕:
int count = 3;
int width = 100;
int height = 50;
int space = 20;
pBtn.resize(count);
pSta.resize(count);
pCet.resize(count);
pCmb.resize(count);
int L, T, R, B;
CWnd* pWnd = this;
//可以使用其它控制元件作為父表單,但訊息處理會很麻煩
//pWnd = GetDlgItem(IDC_STATIC_GROUP);
DWORD dwStyle;
CRect rect;
for (size_t i = 0; i < count; i++)
{
L = 20 + i * (width + space);
T = 20 + 0 * (height + space);
dwStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_FLAT;
rect = CRect(L, T, L + width, T + height);
pBtn[i] = new CButton();
pBtn[i]->Create(_T("按鈕"), dwStyle, rect, pWnd, IDC_BTN_START + i);
T = 20 + 1 * (height + space);
dwStyle = WS_CHILD | WS_VISIBLE | SS_CENTER;
rect = CRect(L, T, L + width, T + height);
pSta[i] = new CStatic();
pSta[i]->Create(_T("文本"), dwStyle,rect, pWnd, IDC_CONTROL_START + 200);
T = 20 + 2 * (height + space);
dwStyle = ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER;
rect = CRect(L, T, L + width, T + height);
pCet[i] = new CEdit();
pCet[i]->Create(dwStyle,rect , pWnd, IDC_CONTROL_START + 300);
pCet[i]->SetWindowText(_T("編輯"));
//下拉框的高度必須設大一點,防止不能選中項
T = 20 + 3 * (height + space);
dwStyle = WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST | CBS_HASSTRINGS;
rect = CRect(L, T, L + width, T + height + 100);
pCmb[i] = new CComboBox();
pCmb[i]->Create(dwStyle, rect, pWnd, IDC_CONTROL_START + 400);
pCmb[i]->AddString(_T("1"));
pCmb[i]->AddString(_T("2"));
pCmb[i]->AddString(_T("3"));
}
上面的控制元件布局可以按自己的來,重要的是Create()函式,每個控制元件的Create()函式不一樣,以最底層CWnd類的Create()函式進行說明:
virtual BOOL Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd, UINT nID,
CCreateContext* pContext = NULL);
參考:https://learn.microsoft.com/zh-cn/cpp/mfc/reference/cwnd-class?view=msvc-170#create
- lpszClassName:指向以 null 結尾的字串的指標,該字串包含已注冊的系統視窗類的名稱;或者為預定義的系統視窗類的名稱,
- lpszWindowName:指向以 null 結尾的字串的指標,該字串包含視窗顯示名稱;否則為 NULL,表示沒有視窗顯示名稱,
- dwStyle:視窗樣式的按位組合 (OR), WS_POPUP 選項不是有效樣式,
- rect:視窗相對于父視窗左上角的大小和位置,
- pParentWnd:指向父視窗的指標,
- nID:視窗的 ID,
- pContext:指向 CCreateContext 結構的指標,該結構用于自定義應用程式的檔案視圖體系結構,
lpszClassName、lpszWindowName、pContext這三個引數不確定的情況下,可以傳入NULL,
其它控制元件的Create()函式參考 MFC 類 中的控制元件類
運行效果如下圖:

控制元件樣式
如果給定 WS_VISIBLE 樣式,Windows發送按鈕控制元件所需的所有資訊激活和顯示按鈕,還可以將以下 視窗樣式 應用于控制元件:
- 始終WS_CHILD
- 通常WS_VISIBLE
- 少見WS_DISABLED
- 對控制元件分組的WS_GROUP
- 包含控制元件的WS_TABSTOP 按tab鍵順序
每種控制元件還有自己的樣式,詳細內容見 MFC使用的樣式
訊息映射
一個MFC的訊息回應函式在程式中有以下三部分:
- 函式原型:頭檔案中在兩個AFX_MSG注釋宏之間是訊息回應函式原型的宣告,
- 函式實作:源檔案中的訊息回應函式的實作代碼,
- 關聯訊息和訊息回應函式的宏:在源檔案AFX_MSG_MAP注釋宏之間的訊息映射宏,用來關聯訊息和訊息回應函式,
關于訊息映射的更多內容參考 訊息映射(MFC),
按鈕單擊
可以使用常規方法,根據ID為按鈕系結單擊的訊息回應函式:
ON_BN_CLICKED(IDC_BTN_START + 0, &CMFCApplication1Dlg::OnBtnClik)
如果生成的按鈕比較多,一個個處理會很麻煩,需要使用批量系結,批量系結按鈕單擊訊息回應函式的步驟:
- 在對話框類的定義檔案(.h檔案)中宣告訊息回應函式OnBtnClick,
afx_msg void OnBtnClick(UINT uID);
注:OnBtnClick函式的引數nID代表回應函式對應按鈕控制元件的ID號,單個按鈕可不設引數,
- 在對話框類的函式實作檔案(.cpp檔案)中定義訊息映射ON_COMMAND_RANGE (多個按鈕),根據其輸入ID分辨具體回應那個按鈕,
ON_COMMAND_RANGE(IDC_BTN_START + 0, IDC_BTN_START + 3, &CMFCApplication1Dlg::OnBtnClik)
注:在函式實作檔案中的訊息映射部分(BEGIN_MESSAGE_MAP與END_MESSAGE_MAP之間)定義按鈕控制元件與其訊息回應函式之間的映射關系,
- 實作訊息回應函式OnBtnClick,在對話框類的函式實作檔案(.cpp檔案)中給出具體的按鈕訊息回應,
void CMFCApplication1Dlg::OnBtnClik(UINT uID)
{
int id = uID -IDC_BTN_START;
CString str;
str.Format("當前ID %d", id);
int result = MessageBox(str, TEXT("確認"), MB_YESNO);
}
組合框選中
使用ON_CBN_SELCHANGE訊息:
ON_CBN_SELCHANGE(IDC_CMB_START, &CMFCApplication1Dlg::OnSelComChange)
宣告訊息回應函式:
afx_msg void OnSelComChange();
實作訊息回應函式:
void CMFCApplication1Dlg::OnSelComChange()//選擇下拉框某一列的時候得到回應
{
for (size_t i = 0; i < pCmb.size(); i++)
{
if (pCmb[i]==GetFocus())
{
CString str(_T(""));//獲取當前下拉框的值
pCmb[i]->GetLBText(pCmb[i]->GetCurSel(), str);//獲取CComBox下拉框當前選中的值
MessageBox(str, TEXT("確認"), MB_OK);
}
}
}
疑問:明明對一個控制元件ID映射了訊息回應函式,但后面的組合框控制元件都能進入OnSelComChange() 函式,后面有時間再研究,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/536840.html
標籤:其他
上一篇:python中回圈值的處理
下一篇:Java 函式式編程「二」
