1. 程式人生 > >MFC 對話方塊與常用控制元件

MFC 對話方塊與常用控制元件

  1. 模態對話方塊建立方式
    【方法一】建立對話方塊類的物件,然後呼叫domodal
    CGuiDlg dlg;
    dlg.DoModal();
    會阻塞,可以區域性變數。因為會堵塞
    【方法二】
    CDialog dlg(IDD_GUI_DLG);
    dlg.DoModal();

2.非模態對話方塊 先建立,在顯示
在選單命令下 :
【方法一】
CDialog dlg;
dlg.Create(IDD_GUI_DLG);
dlg.ShowWindow(SW_SHOW);
會發現閃爍 是因為模態對話方塊會阻塞,而非模態不會,dlg是一個區域性變數,而選單有自己的更新機制,非模態的對話方塊被隱藏了,解決辦法
::::dlg設定為類的成員函式
【方法二】建立對話方塊類,然後顯示
CGuiDlg dlg;
dlg.Create(IDD_GUI_DLG);
dlg.ShowWindow(SW_SHOW);
【小結】
1.模態對話方塊可以區域性變數。因為會堵塞。
非模態對話方塊不能是區域性變數,因為不會堵塞,函式執行完畢就釋放啦。
2.Ctrl + D 可以檢視 控制元件的順序。點選數字可以改變順序

解決 vs2017問題 error MSB8008: 指定的平臺工具集(v120)未安裝或無效

專案屬性中 配置 中 平臺工具集 改成目前軟體的版本就可以啦

-------------控制元件------------------------
3. 單選框: 特殊的button按鈕,雙擊控制元件時,進入點選控制元件的處理函式,與CButton一樣的處理方式-
1) 屬性設定:順序排放 Ctrl+D 檢視
2) 同組第一個按鈕 Group 設定為 TRUE
3) 初始化單選框 CWnd::CheckRadioButton
4) 按鈕是否按下 CWnd::IsDlgButtonChecked
--------------------------摘抄------------------------------------
一、對話方塊
1)模態對話方塊
a) 資源檢視 -> Dialog -> 右擊 -> 插入 Dialog
b) 建立對話方塊物件 CDialog
c) 以模態方式執行 CDialog::DoModal
2)非模態對話方塊
a)資源檢視 -> Dialog -> 右擊 -> 插入 Dialog
b)建立對話方塊物件,需要在.h的地方宣告為成員變數 CDialog
c)建立對話方塊(在建構函式或OnCreate(),目的只建立一次) CDialog::Create
d)顯示視窗 CWnd::ShowWindow
3)自定義對話方塊類(重要)
a)資源檢視 -> Dialog -> 右擊 -> 插入 Dialog
b)點選對話方塊模板 -> 右擊 -> 新增類
c)多出來一個自定義的類, .h 類中有個列舉和對話方塊關聯 enum { IDD = IDD_DIALOG2 };

二、基於對話方塊(控制元件)程式設計
1)基於對話方塊應用程式框架
a)應用程式類:繼承於 CWinApp
InitInstance() : 程式的入口地址
b)對話方塊類:繼承於 CDialogEx
OnInitDialog() :對話方塊的初始化工作
DoDataExchange() : 控制元件和變數的關聯和交換

三、常用控制元件
1)靜態控制元件CStatic(Qt中的標籤QLabel)
顯示一些文字資訊 ,起標籤的作用
a) Caption: 修改顯示的內容
b) ID: XXX_STATIC,靜態ID,不響應任何訊息(事件)
c)如果想讓static相應訊息時
1… 修改ID
2…修改 屬性 notify 勾選

2)按鈕 CButton
a) Caption: 修改顯示的內容
b) 處理訊息 BN_CLICKED,使用者點選按鈕自動觸發:
1)屬性 -> 控制事件 -> 選擇所需事件
2)雙擊按鈕,自動生成訊息處理函式

3)逃跑按鈕(類似於Qt提升)
a)自定義按鈕類,繼承於 CButton
選擇類檢視最開始的資料夾 -> 右擊 -> 新增類 -> MFC -> MFC類
1)處理滑鼠移動訊息 WM_MOUSEMOVE
2)獲取父視窗指標 CWnd::GetParent
3)獲取父視窗客戶區域的範圍 CWnd::GetClientRect
4)獲取按鈕的範圍 CWnd::GetWindowRect
5)產生隨機座標 rand()%w
6)移動按鈕的位置 CWnd::MoveWindow
b)變數關聯
選中按鈕 -> 右擊 -> 新增變數 -> 變數型別: MyButton -> 變數:button
最終,button和我們所選中的按鈕關聯成功,操作button,相當於操作ui上的按鈕 (Qt的提升)
c)為按鈕設定點陣圖
1)按鈕屬性:Bitmap -> True
2)在對話方塊類中 OnInitDialog() 做如下處理
a)建立點陣圖模板
b)建立點陣圖物件 CBitmap
c)載入點陣圖資源 CBitmap::LoadBitmap
b)按鈕設定點陣圖 CButton::SetBitmap
c)獲取點陣圖大小 CBitmap::GetBitmap
c)重新設定按鈕大小(圖片和按鈕大小一致) CWnd::MoveWindow

4)編輯框CEdit
a)關聯類別:Value, Control
1)Value:標準普通資料型別 CString str;
關聯變數和控制元件資料的互動更新
a)把編輯區的內容更新到str中 UpdateData(TRUE); 獲取資料給變數
b)把str的內容更新到編輯區中 UpdateData(FALSE);初始化對化框

	2)Control:控制元件型別
		控制元件型別的物件即為ui上的控制元件
		
b)常用屬性設定
	1)Number -> True 只能輸入數字
	2)Password -> True 密碼模式
	3)Want return -> True 接收回車鍵,自動換行,只有在多行模式下,才能換行
	4)Multiline -> True 多行模式
	5)Auto VScroll -> True
	   Vertical Scroll -> True 當垂直方式字元太多,自動出現滾動條
	6)Read Only -> True 只讀
c)複製小案例
關聯 Control:控制元件型別,只能關聯一次
	1)獲取編輯區內容 CWnd::GetWindowText
	2)設定編輯區內容 CWnd::SetWindowText
	3)關閉對話方塊視窗
		CDialogEx::OnOK();
		CDialogEx::OnCancel();

5)單選框、複選框 (特殊的CButton, 沒有單選框, 複選框型別 )
a) 單選框
1) 屬性設定:順序排放 Ctrl+D 檢視
2) 同組第一個按鈕 Group 設定為 TRUE
3) 初始化單選框 CWnd::CheckRadioButton
4) 按鈕是否按下 CWnd::IsDlgButtonChecked

b) 複選框
	1) 常關聯變數 BOOL  UpdateData(TRUE), UpdateData(FALSE);
	2) 設定按鈕選擇狀態 CButton::SetCheck
	3) 獲取按鈕選擇狀態 CButton::GetCheck

6)列表框CListBox
a) 給列表框新增一個字串 CListBox::AddString
插入的結果順序是按照 英文字母 由上而下
CListBox::InsertString(int nIndex, LPCTSTR lpszItem );插入結果嚴格按照程式碼中寫的順序來 依賴nIndex這個值,為-1 時 新增到末尾
b) 選中列表列表框某一項,自動觸發事件:LBN_SELCHANGE
1)獲取當前選中項 CListBox::GetCurSel
2)獲取指定位置的內容 CListBox::GetText
c) 刪除指定位置的字串 CListBox::DeleteString 不用UpdateData(false)介面上的字串就被刪除了。
d) 在指定位置插入字串 CListBox::InsertString
e)設定選中行 CListBox::SetCurSel 設定預設選則項

7)組合框(下拉框)CComboBox
a) 獲取內容:CComboBox::GetLBText( int nIndex, LPTSTR lpszText )
其它介面和 CListBox 的用法幾乎一樣
b) 屬性設定
1) data: 設定內容,不同內容間同英文的分號“;”分隔 可以初始化
2) type : DropDown 可編輯 DropList 不可編輯
3)sort 排序 按照 字母順序

8)滾動條 CScrollBar: 只有一個事件處理,如果處理滑塊和兩端的按鈕,則處理父視窗的WM_HSCROLL訊息
a) 設定給定滾動條的最小和最大位置:CScrollBar::SetScrollRange
b) 獲取一個滾動框的當前位置: CScrollBar::GetScrollPos
c) 設定一個滾動框的當前位置:CScrollBar::SetScrollPos
d) 處理滾動條的事件,不是在滾動條控制元件本身處理,是在滾動條所屬的父視窗處理(對話方塊類)
處理訊號: WM_HSCROLL

	void CControlDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)   
	
	說明: 只有點選 滑塊時nPos 才有數值,如果想獲得當前位置,則用GetScrollPos獲得滑塊位置。 滾動條預設是不會變的
	
e)滾動條位置關係
	switch (nSBCode) //判斷滾動條的哪一部分
	{
	case SB_THUMBPOSITION: //滑塊位置
		break;
	case SB_LINELEFT: //向左的箭頭
		break;
	case SB_LINERIGHT: //向左的箭頭
		break;
	case SB_PAGELEFT: //箭頭和滑塊之間左邊
		break;
	case SB_PAGERIGHT: //箭頭和滑塊之間右邊
		break;
	default:
		break;
	}

9)微調(旋轉)按鈕 SpinControl 的使用
a)屬性設定
Auto Buddy -> True
Set buddy integer -> True
b)**微調(旋轉)**按鈕的順序比夥伴大1 (Ctrl + D 檢視),不能出現0.

在點選5時 會在 4上顯示
在點選5時 會在 4上顯示

點選2時,在1上有顯示

                                        點選2時,在1上有顯示

10)列表檢視控制元件 CListCtrl
a) 屬性設定 view -> Report (報表方式)
b) 常用介面 順序
1)設定列表風格 CListCtrl::SetExtendedStyle
LVS_EX_FULLROWSELECT:選擇整行
LVS_EX_GRIDLINES:網格方式
具體有哪些風格,可通過MSDN檢視

	2)獲取列表風格 CListCtrl::SetExtendedStyle
		具體有哪些風格,可通過MSDN檢視	
		
	3)插入某列 CListCtrl::InsertColumn
	
	4)字串格式化
		CString str;
		str.Format(_T("張三_%d"), i);
		
	5)插入新項後,才能設定子項內容
		a)插入新項(確定第幾行) CListCtrl::InsertItem
		b)設定子項內容(設定第幾列) CListCtrl::SetItemText	

【小結】先初始化InsertColumn 及SetExtendedStyle
再確定行 insertItem,
然後在修改行中列中內容SetItemText()

     //初始化 ::::
      CString str[] = { _T("家庭地址"),_T("電話"),_T("郵箱") };
	m_ctrList.InsertColumn(0,str[0], LVCFMT_LEFT,80,50);//如果只用m_ctrList.InsertColumn(0,str[0])則顯示不出來,必須設定風格
	m_ctrList.InsertColumn(1,str[1] , LVCFMT_LEFT, 80, 50);
	m_ctrList.InsertColumn(2, str[2], LVCFMT_LEFT, 80, 50);

11)樹檢視控制元件 CTreeCtrl
a) 常用屬性設定
has buttons -> true
has lines -> true
lines at root -> true
b) 寫程式碼流程
1) 載入自定義圖示
a) 獲取應用程式物件指標 AfxGetApp()
b) 載入自定義圖示 CWinApp::LoadIcon
2) 建立影象列表
a) .h 檔案類中定義圖形列表(CImageList)物件
b) 建立影象列表 CImageList::Create
c) 影象列表追加圖示 CImageList::Add
4) 設定圖形狀態列表 CTreeCtrl::SetImageList
5) 插入節點 CTreeCtrl::InsertItem
6) 設定預設選中項 CTreeCtrl::SelectItem

【程式程式碼】

//影象列表,程式完畢不能釋放 建立
	HICON hIc[3];
	//應用程式物件AfxGetApp(
	hIc[0] = AfxGetApp()->LoadIcon(IDI_ICON1);
	hIc[1] = AfxGetApp()->LoadIcon(IDI_ICON2);
	hIc[2] = AfxGetApp()->LoadIcon(IDI_ICON3);

	//給影象列表新增圖片
	//30 30 圖片的大小
	//3  3 有多少張寫多少
	m_image.Create(30,30, ILC_COLOR32,3,3);

	//圖片列表載入圖示
	for (int i = 0; i < 3; i++)
	{
		m_image.Add(hIc[i]);
	}
	//樹控制元件設定圖片列表
	m_treectrl.SetImageList(&m_image,TVSIL_NORMAL);

	//給樹建立節點
	//根節點 父節點 子節點
	//InsertItem(_T("根節點"), 0, 0, NULL);//文字,改變前圖示,改變後,是否有父節點
	HTREEITEM  root = m_treectrl.InsertItem(_T("根節點"),0,0,NULL);

	HTREEITEM father = m_treectrl.InsertItem(_T("父節點"), 1, 1, root);

	HTREEITEM son = m_treectrl.InsertItem(_T("父節點"), 2, 2, father);

	HTREEITEM  root2 = m_treectrl.InsertItem(_T("根節點"), 0, 0, NULL);

	HTREEITEM father2 = m_treectrl.InsertItem(_T("父節點"), 1, 1, root2);

	HTREEITEM son2 = m_treectrl.InsertItem(_T("父節點"), 2, 2, father2);

	//設定某個節點被選中
	m_treectrl.SelectItem(father);
	m_treectrl.SelectItem(son2);

執行結果
12) 標籤控制元件 CTabCtrl
1)在ui工具箱拖放 Tab Control
2)把 TabSheet.h和TabSheet.cpp 放在專案檔案同級目錄,並且新增到工程目錄中
3)給ui上 Tab Control 關聯Control型別(CTabSheet)
4)CTabSheet物件新增對話方塊
a) 資源檢視 -> Dialog -> 右擊 -> 插入 Dialog
b) 設定相應屬性:
Style -> Child (子視窗)
Border -> None (無邊框)
c) 自定義類:點選對話方塊模板 -> 右擊 -> 新增類
d) 主對話方塊類中, 定義自定義類物件
e) 主對話方塊類中 OnInitDialog() 做初始化工作
f)CTabSheet新增對話方塊 CTabSheet::AddPage()
tmp.AddPage(_T(“系統管理”), &t1, tab1);
tmp: 為CTabSheet物件
t1:需要新增對話方塊物件
tab1:對話方塊ID

	g)顯示視窗:CTabSheet::Show()
	【借用CTableSheet類來實現 Tab控制元件】
       //tab控制元件 新增對話方塊
	//對話方塊設定為子對話方塊,預設為單獨對話方塊,預設為父親
	//外觀   :sytle預設為popup 改為child  border 改為 none
	m_tab.AddPage(_T("測試"),&dlg1, IDD_DIALOG1);
	m_tab.AddPage(_T("實驗"), &dlg2, IDD_DIALOG2);
	//顯示控制元件
	m_tab.Show();
	//發現 對話方塊已經跑出了 主對話方塊,因為預設對話方塊為 彈出型  想要在裡面的話,則設定成 child模式