Visual C++程序設計 # 機試操作複習 (MFC機試)

  • 考試環境: VS2010 (適用於NCEPU)
  • 個人總結,禁止轉載
  • 猜測考試題型爲:單文檔裏嵌入對話框

編譯異常處理方法

如果確認代碼無誤,選擇重新生成解決方案,嘗試能不能解決問題

1 基於對話框的應用程序

基礎知識

  • 學會修改控件的ID
  • 學會拖拽控件
  • 學會修改Static Text\Button\對話框的標題(Caption)
  • 學會給控件添加Value型變量[ctrl+shift+x]
  • 學會設置Edit的只讀(readonly)
  • 學會添加Button的click事件 [雙擊Button]
  • 數據交換機制DDX/數據驗證機制DDV
  • 修改對話框內控件的Tab順序[Ctrl+D]
  • 關閉對話框
	this->OnOK();
	this->OnCancel();

或者修改ID爲IDOK, IDCANCEL

  • 彈出對話框
    前置操作:#include對話框的頭文件
CdialogPracticeDlg dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
	// TODO: 在此放置處理何時用
	//  “確定”來關閉對話框的代碼
}
else if (nResponse == IDCANCEL)
{
	// TODO: 在此放置處理何時用
	//  “取消”來關閉對話框的代碼
}

注意:這段代碼必須要會,如果記不住:在XXXX(工程名).cpp裏面的InitInstance函數有類似的代碼,可以仿寫

  • afxMessageBox
  • 添加處理程序(以及錯誤添加的刪除)
  • 新建對話框

    然後雙擊或者右鍵添加類
#include "TipDlg.h"

void CdialogPracticeDlg::OnBnClickedButtonCalc()
{
	CTipDlg dlg;
	INT_PTR nResponse = dlg.DoModal();
	if(nResponse == IDCANCEL)return;

	UpdateData(TRUE);
	m_dAns = m_dOp1 + m_dOp2;
	UpdateData(FALSE);
}
  • CString類的基本操作要會 文末拓展閱讀材料
    CString變爲int:int y = _ttoi(year);
  • 組合框(ComboBox)的基本使用和一些屬性
    data 寫數據


    droplist不能修改,只能選,dropdown可以改


    一般把sort關掉
    關聯變量:int 表示第幾個被選中(從0開始,記得設置sort爲false,-1表示默認不選中)
    m_nChoose是關聯的int變量,sort設置爲false,數據是+;-;*;/;
void CdialogPracticeDlg::OnBnClickedButtonCalc()
{	
	UpdateData(TRUE);
	if(m_nChoose == -1){
		AfxMessageBox(_T("please choosee an operator"));
		return;
	}
	switch(m_nChoose){
	case 0:
		m_dAns = m_dOp1 + m_dOp2;
		break;
	case 1:
		m_dAns = m_dOp1 - m_dOp2;
		break;
	case 2:
		m_dAns = m_dOp1 * m_dOp2;
		break;
	case 3:
		if( fabs(m_dOp2) < 1e-10 ){
			AfxMessageBox(_T("Error"));
			return;
		}
		m_dAns = m_dOp1 / m_dOp2;
		break;
	}
	UpdateData(FALSE);
}

給combo box關聯 control類型變量m_comboCalc
定位到:CXXXXXXXDlg::OnInitDialog(),在TODO後面添加代碼

m_comboCalc.AddString(_T(“+"));動態添加選項

動態添加:

for(int i=2000;i<=2020;i++){
	CString str;
	str.Format(_T("%d"),i);
	this->m_combo_year.AddString(str);
}

獲得當前選中的選項和文本

CString year;
int nChoose = this->m_combo_year.GetCurSel();
this->m_combo_year.GetLBText(nChoose,year);

修改選項:SetCurSel()
清空選項: ResetContent()
選項變化事件:CBN_SELCHANGE

如果是dropdown,怎麼獲得輸入框裏的文本?m_combo.GetWindowTextW()
拓展閱讀: https://blog.csdn.net/qq_33583069/article/details/106167719

  • 根據ID獲得控件變量的方法:
    CButton *p8 = ((CButton*)GetDlgItem(IDC_B8));
  • Radio Button 單選互斥的操作

    根據tab順序,直到新的group:true,否則後面的都互斥
    GetCheck()判斷是否選中,0未選中1選中
  • 設置Button不可用/可用
pButton->EnableWindow(FALSE);
pButton->EnableWindow(TRUE);

綜合案例:計算器

https://blog.csdn.net/qq_33583069/article/details/106183203

// CCalculatorDlg 消息處理程序

BOOL CCalculatorDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 將“關於...”菜單項添加到系統菜單中。

	// IDM_ABOUTBOX 必須在系統命令範圍內。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
	//  執行此操作
	SetIcon(m_hIcon, TRUE);			// 設置大圖標
	SetIcon(m_hIcon, FALSE);		// 設置小圖標

	// TODO: 在此添加額外的初始化代碼
	CButton* pRadioDec = (CButton*)GetDlgItem(IDC_RADIO_DEC);
	pRadioDec->SetCheck(TRUE);
	CButton *pCheck = (CButton*)GetDlgItem(IDC_CHECK);
	pCheck->SetCheck(TRUE);

	return TRUE;  // 除非將焦點設置到控件,否則返回 TRUE
}

void CCalculatorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向對話框添加最小化按鈕,則需要下面的代碼
//  來繪製該圖標。對於使用文檔/視圖模型的 MFC 應用程序,
//  這將由框架自動完成。

void CCalculatorDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用於繪製的設備上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使圖標在工作區矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 繪製圖標
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//當用戶拖動最小化窗口時系統調用此函數取得光標
//顯示。
HCURSOR CCalculatorDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CCalculatorDlg::OnBnClickedB0(){
	m_nValue = m_nValue*10;
	UpdateData(FALSE);
}

void CCalculatorDlg::OnBnClickedB1()
{
	m_nValue = m_nValue*10+1;
	UpdateData(FALSE);
}




void CCalculatorDlg::OnBnClickedB2()
{
	m_nValue = m_nValue*10+2;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedB3()
{
	m_nValue = m_nValue*10+3;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedB4()
{
	m_nValue = m_nValue*10+4;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedB5()
{
	m_nValue = m_nValue*10+5;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedB6()
{
	m_nValue = m_nValue*10+6;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedB7()
{
	m_nValue = m_nValue*10+7;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedB8()
{
	m_nValue = m_nValue*10+8;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedB9()
{
	m_nValue = m_nValue*10+9;
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedBtnAdd()
{
	UpdateData(TRUE);
	m_nOp1 = m_nValue;
	m_nValue = 0;
	op = '+';
}


void CCalculatorDlg::OnBnClickedBtnSub()
{
	UpdateData(TRUE);
	m_nOp1 = m_nValue;
	m_nValue = 0;
	op = '-';
}


void CCalculatorDlg::OnBnClickedBtnMul()
{
	UpdateData(TRUE);
	m_nOp1 = m_nValue;
	m_nValue = 0;
	op = '*';
}


void CCalculatorDlg::OnBnClickedBtnDiv()
{
	UpdateData(TRUE);
	m_nOp1 = m_nValue;
	m_nValue = 0;
	op = '/';
}


void CCalculatorDlg::OnBnClickedBtnClr()
{
	m_nValue = 0;
	op = 0;
	m_nOp1 = 0;
	m_nOp2 = 0;
	UpdateData(FALSE);
}

int octToDec(int x){
	int result = 0;
	int w = 1;
	while(x){
		if(x&1)result += w*(x%8);
		w *= 8;
		x /= 8;
	}
	return result;
}


void CCalculatorDlg::OnBnClickedBtnEqu()
{
	if(op == 0){
		AfxMessageBox(_T("No Operand"));
		return;
	}
	m_nOp2 = m_nValue;	
	
	CButton *pRadioOct = ((CButton*)GetDlgItem(IDC_RADIO_OCT));
	if(pRadioOct->GetCheck()==1){
		m_nOp1 = octToDec(m_nOp1);
		m_nOp2 = octToDec(m_nOp2);
	}
	switch(op){
	case '+':
		m_nValue = m_nOp1 + m_nOp2;
		break;
	case '-':
		m_nValue = m_nOp1 - m_nOp2;
		break;
	case '*':
		m_nValue = m_nOp1 * m_nOp2;
		break;
	case '/':
		if(m_nOp2 == 0){
			AfxMessageBox(_T("Error"));
			return;
		}
		m_nValue = m_nOp1 / m_nOp2;
		break;
	}
	if(pRadioOct->GetCheck()==1){
		char s8[30];
		itoa(m_nValue,s8,8);
		m_nValue = atoi(s8);
	}
	UpdateData(FALSE);
	m_nValue = 0;
	op = 0;
	m_nOp1 = 0;
	m_nOp2 = 0;
}




void CCalculatorDlg::OnBnClickedRadioDec()
{
	CButton *p8 = ((CButton*)GetDlgItem(IDC_B8));
	CButton *p9 = ((CButton*)GetDlgItem(IDC_B9));
	p8->EnableWindow(TRUE);
	p9->EnableWindow(TRUE);
	transform();
}




void CCalculatorDlg::transform(){
	UpdateData(TRUE);
	CButton *pRadioOct = ((CButton*)GetDlgItem(IDC_RADIO_OCT));
	if(pRadioOct->GetCheck() == 0) {
		m_nValue = octToDec(m_nValue);
	}
	else {
		char s8[30];
		itoa(m_nValue,s8,8);
		m_nValue = atoi(s8);
	}
	UpdateData(FALSE);
}


void CCalculatorDlg::OnBnClickedRadioOct()
{
	CButton *p8 = ((CButton*)GetDlgItem(IDC_B8));
	CButton *p9 = ((CButton*)GetDlgItem(IDC_B9));
	p8->EnableWindow(FALSE);
	p9->EnableWindow(FALSE);
	transform();
}


void CCalculatorDlg::OnBnClickedCheck()
{
	CButton *pRadioDec = (CButton*)GetDlgItem(IDC_RADIO_DEC);
	CButton *pRadioOct = (CButton*)GetDlgItem(IDC_RADIO_OCT);
	CButton *pCheck = (CButton*)GetDlgItem(IDC_CHECK);
	if(pCheck->GetCheck()==0){
		pRadioDec->EnableWindow(FALSE);
		pRadioOct->EnableWindow(FALSE);
	} else {
		pRadioDec->EnableWindow(TRUE);
		pRadioOct->EnableWindow(TRUE);
	}
}

綜合案例2 登錄對話框

考察點:重寫CEdit

https://blog.csdn.net/qq_33583069/article/details/106194453
如果只是限定Edit輸入數字的話

改成True就好
如果是限定用字母的話,需要自己重寫,這裏纔是本節重點(考點)

重點

基類選擇爲:CEdit

添加WM_CHAR消息

  • 旋鈕應該不考

  • 圖標 bitmap

HBITMAP hBmp=::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
m_Btn.SetBitmap(hBmp);

2 單文檔應用程序

  • 修改XXXView.cpp的OnDraw方法
void CSDIView::OnDraw(CDC* pDC)
{
	CSDIDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	// TODO: 在此處爲本機數據添加繪製代碼
	pDC->TextOut(50,50,_T("hello,單文檔"));
}
  • pDC->TextOut(50,50,_T("hello,單文檔"));

  • CreatePointFont()

    void CApp15View::OnDraw(CDC* pDC)
    {
        CApp15Doc* pDoc = GetDocument();
         ASSERT_VALID(pDoc);
         if (!pDoc)      return;
        CFont newFont;     // 新字體   
        CFont *pOldFont;   // 選擇新字體之前的字體
        newFont.CreatePointFont(180, _T("隸書")); // 創建一種新的字體  
        pOldFont=(CFont*)pDC->SelectObject(&newFont);
        // 在指定位置輸出文本   
        pDC->TextOut(40,10,_T("你好!"));   
        // 恢復以前的字體   
        pDC->SelectObject(pOldFont);   
        pDC->TextOut(50,50, _T("這是我的第一個單文檔應用程序!"));
    }
    
  • pDC->SetTextColor(RGB(255,0,0));SetBkColor()

  • 修改菜單,並添加處理事件

    • 設置字體菜單
    • CreateFontIndirect
    • LogFont
    • CFontDialog
    void CSDIDoc::OnFontMenu()
    {
    	CFontDialog dlg;
    	if(dlg.DoModal() == IDOK){
    		LOGFONT lf;
    		COLORREF color;
    		dlg.GetCurrentFont(&lf);
    		m_font.DeleteObject();
    		m_font.CreateFontIndirect(&lf);
    		m_color = dlg.GetColor();
    		UpdateAllViews(NULL);
    	}
    }
    

    在view內裏刷新的話是RedrawWindow()

    • 添加字體菜單(自定義)
      注意傳遞數據
    void CSDIDoc::OnAddText()
    {
    	CTextDlg dlg;
    	if(dlg.DoModal() == IDOK){
    		m_nX = dlg.m_nX;
    		m_nY = dlg.m_nY;
    		m_strText = dlg.m_strText;
    	}
    }
    
    • 鼠標消息響應
      • CPoint
    void CSDIView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	// TODO: 在此添加消息處理程序代碼和/或調用默認值
    	m_posText = point;
    	RedrawWindow();
    	CView::OnLButtonDown(nFlags, point);
    }
    
    • 捕獲和釋放鼠標
  • 修改ToolBar


    ID和菜單欄上的某個菜單項保持一致

  • 修改光標

    • WM_SETCURSOR
    BOOL CSDIView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
    {
    	// TODO: 在此添加消息處理程序代碼和/或調用默認值
    		CSDIDoc* pDoc = GetDocument();
    		if(pDoc->m_nCursorFlag == 1){
    			::SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR));
    			return TRUE;
    		} else {
    			::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
    			return TRUE;
    		}
    }
    
  • 修改標題
    方法一:

    方法二:資源->string table裏改mainframe

  • 改圖標(Icon) 應用程序左上角的那個

    改EXE圖標

  • 對象鏈表

前置條件: 自定義數據類(例如文本信息類,繼承自CObject)
https://blog.csdn.net/qq_33583069/article/details/106239080


注意這裏記錄的是LOGFONT

void CSDIDoc::OnAppendText()
{
	CFontDialog dlg;
	LOGFONT lf;
	COLORREF color;
	if(dlg.DoModal() == IDOK){
		dlg.GetCurrentFont(&lf);
		color = dlg.GetColor();
		CTextDlg tdlg;
		if(tdlg.DoModal() == IDOK){
			m_nX = tdlg.m_nX;
			m_nY = tdlg.m_nY;
			m_strText = tdlg.m_strText;
			CMyText* pText = new CMyText(m_strText,CPoint(m_nX,m_nY),lf,color);
			m_textList.AddTail(pText)
		}
	}
	UpdateAllViews(NULL);
}

把view裏ondraw的後面的代碼刪完,重寫。

  • POSITION
  • GetHeadPosition
  • GetNext
    !!!這裏必考!!!
void CSDIView::OnDraw(CDC* pDC)
{
	CSDIDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	// TODO: 在此處爲本機數據添加繪製代碼
	POSITION pos = pDoc->m_textList.GetHeadPosition();
	while(pos != NULL){
		CMyText* pText = (CMyText*)pDoc->m_textList.GetNext(pos);
		CFont font;
		font.CreateFontIndirect(&pText->m_textFont);
		CFont* pOld = pDC->SelectObject(&font);
		pDC->SetTextColor(pText->m_textColor);
		pDC->TextOut(pText->m_textPos.x,pText->m_textPos.y,pText->m_strText);
		pDC->SelectObject(pOld);
	}
}

刪除:

  • RemoveAll
void CSDIDoc::RemoveTextList()
{
	POSITION pos = m_textList.GetHeadPosition();
	while(pos != NULL)
	{
		CMyText* pText = (CMyText*)m_textList.GetNext(pos);
		delete pText;
	}  
	m_textList.RemoveAll();
}

爲CMainFrame類添加窗口關閉響應函數OnClose()

  • GetActiveDocument
void CMainFrame::OnClose()
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	CSDIDoc* pDoc = (CSDIDoc*)this->GetActiveDocument();
	pDoc->RemoveTextList();
	CFrameWndEx::OnClose();
}
  • 新建/打開文件的處理
    執行File|New命令時,將調用文檔類成員函數OnNewDocument(),該函數又要調用另一個成員函數DeleteContents()。另外執行File|Open命令時也會調用DeleteContents()函數。
    注意:選虛函數!!!
void CSDIDoc::DeleteContents()
{
	RemoveTextList();
	CDocument::DeleteContents();
}
  • 序列化
    https://blog.csdn.net/qq_33583069/article/details/106239080
    序列化這個不用記,在Doc裏有類似的代碼,直接複製然後修改就行
class CMyText:public CObject  
{
  DECLARE_SERIAL(CMyText)
  public:
   ……
      virtual void Serialize(CArchive &ar);
   ……
}
CArchive& operator<<(CArchive& ar, LOGFONT& logfont)
{
	ar.Write(&logfont, sizeof(logfont));
	return ar;
}
CArchive& operator>>(CArchive& ar, LOGFONT& logfont)
{
	ar.Read(&logfont, sizeof(logfont));
	return ar;
}
void CMyText::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar << m_strText << m_textPos << m_textFont << m_textColor;
	}
	else
	{
		ar >> m_strText >> m_textPos >> m_textFont >> m_textColor;
	}
}
void CSDIDoc::Serialize(CArchive& ar)
{
	m_textList.Serialize(ar);
	if (ar.IsStoring())
	{
		// TODO: 在此添加存儲代碼
	}
	else
	{
		// TODO: 在此添加加載代碼
	}
}

設置文檔修改標記

綜合案例 畫圖系統

https://blog.csdn.net/qq_33583069/article/details/106248164

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章