第一篇:MFC編程講稿(二)
一、打字功能
1.加入數(shù)據(jù)成員
選擇ClassView,雙擊CMyView,光標(biāo)直接停留在類CMyView的定義處。在類CMyView中加入如下部分: class CMyView : public CView { protected: // create from serialization only
CMyView();
DECLARE_DYNCREATE(CMyView)
// Attributes public:
CMyDoc* GetDocument();
// Operations public: //代碼編寫開始
POINT Caret;
//用于存放插入符當(dāng)前坐標(biāo)位置 //代碼編寫結(jié)束 // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyView)public: virtual void OnDraw(CDC* pDC);// overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);//}}AFX_VIRTUAL
// Implementation public: virtual ~CMyView();#ifdef _DEBUG virtual void AssertValid()const;virtual void Dump(CDumpContext& dc)const;#endif
protected:
// Generated message map functions protected: //{{AFX_MSG(CMyView)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);//}}AFX_MSG DECLARE_MESSAGE_MAP()};2.加入消息:WM_CREATE(1)在“查看”菜單中選擇“建立類向?qū)А保–lassWizard)命令,打開MFC ClassWizard窗口。
(2)選擇 Message Maps。(3)分別選擇:
Project: 打字
Class Name: CMyView Objects: CMyView Messges: WM_CREATE(4)單擊Add Function按鈕。
(5)單擊Edit Code按鈕。在OnCreate()函數(shù)體中加入以下部分。
int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct){ if(CView::OnCreate(lpCreateStruct)==-1)
return-1;//代碼編寫開始
TEXTMETRIC tm;
//聲明TEXTMETRIC結(jié)構(gòu)類型對象tm,用于存放字符信息。
CClientDC dc(this);
//生成應(yīng)用程序窗口設(shè)備情景對象
//調(diào)用CDC類成員函數(shù)GetTextMetrics()取得字符信息,并存入變量tm中。
dc.GetTextMetrics(&tm);//調(diào)用CWnd類成員函數(shù)CreateSolidCaret()創(chuàng)建黑色矩形條插入符,插入符寬度為tm.tmAveCharWidth/8,高度為tm.tmHeight。
CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);//設(shè)置插入符的初始位置
Caret.x=0;
} Caret.y=tm.tmHeight;SetCaretPos(Caret);//在初始位置顯示插入符 ShowCaret();//代碼編寫結(jié)束 return 0;3.加入鍵盤消息:WM_CHAR(1)在“查看”菜單中選擇“建立類向?qū)А保–lassWizard)命令,打開MFC ClassWizard窗口。
(2)選擇 Message Maps。(3)分別選擇:
Project: 打字
Class Name: CMyView Objects: CMyView Messges: WM_CHAR(4)單擊Add Function按鈕。
(5)單擊Edit Code按鈕。在OnChar()函數(shù)體中加入以下部分。
void CMyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags){
// TODO: Add your message handler code here and/or call default
//代碼編寫開始
SIZE size;
//存放字符的寬度和長度。
static UINT dy=Caret.y;
//聲明靜態(tài)變量dy,存放插入符Y軸坐標(biāo)。CString a;
//聲明CString類對象a,存放鍵盤檢索到的字符nChar。a=nChar;CClientDC dc(this);//生成應(yīng)用程序窗口設(shè)備情景對象
} CView::OnChar(nChar, nRepCnt, nFlags);for(UINT i=0;i } //代碼編寫結(jié)束 HideCaret(); //隱藏光標(biāo),使得顯示字符使插入符消失。switch(nChar){ case 'r': //將插入符移動到下一行的開頭 Caret.x=0;Caret.y+=Caret.y;break;default: } //將插入符移動到字符后面,并顯示出來。SetCaretPos(Caret);ShowCaret();dc.TextOut(Caret.x,Caret.y,a,1);//輸出字符 size=dc.GetTextExtent(a);//獲得字符大小 Caret.x+=size.cx;//將字符的寬度加入到插入符的當(dāng)前坐標(biāo)位置 二、繪圖功能 (一)生成Draw程序框架 (二)鼠標(biāo)繪圖 用鼠標(biāo)繪制圖形,一般分三個環(huán)節(jié): (1)確定繪圖位置:按下鼠標(biāo)左鍵,產(chǎn)生WM_LBUTTONDOWN消息(2)確定圖形顯示范圍:拖動鼠標(biāo),產(chǎn)生WM_MOUSEMOVE消息(3)完成圖形顯示:放開鼠標(biāo)左鍵,產(chǎn)生WM_LBUTTONUP消息 1.在視圖類CDrawView中加入數(shù)據(jù)成員 選擇ClassView視圖,雙擊CdrawView,光標(biāo)直接停留在類CdrawView的定義處。在類CdrawView的定義中加入如下代碼。 class CDrawView : public CView { //代碼開始編寫 protected: int m_Dragging; CPoint m_PointOld;CPoint m_PointOrigin;//代碼編寫結(jié)束 protected: // create from serialization only // Attributes public: // Operations CDrawView();DECLARE_DYNCREATE(CDrawView)CDrawDoc* GetDocument();public: // Overrides // Implementation public: virtual ~CDrawView();// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDrawView)public: virtual void OnDraw(CDC* pDC);// overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);//}}AFX_VIRTUAL #ifdef _DEBUG virtual void AssertValid()const;virtual void Dump(CDumpContext& dc)const;#endif protected: // Generated message map functions protected: //{{AFX_MSG(CDrawView)// NOTEthe ClassWizard will add and remove member functions here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSG DECLARE_MESSAGE_MAP()21 4.定義函數(shù)CdrawDoc::AddLine()選擇FileView,展開SourceFiles,雙擊DrawDoc.cpp,打開執(zhí)行文件DrawDoc.cpp,在其末尾,加入以下代碼。 //代碼編寫開始 // AddLine()生成新的Cline對象,并調(diào)用CObArray成員函數(shù)Add()向m_LineArray添加Cline對象指針。 void CDrawDoc::AddLine(int X1,int Y1,int X2,int Y2){ } //代碼編寫結(jié)束 CLine *pLine=new CLine(X1,Y1,X2,Y2);m_LineArray.Add(pLine);5.定義函數(shù)CdrawDoc::GetLine()選擇FileView,展開SourceFiles,雙擊DrawDoc.cpp,打開執(zhí)行文件DrawDoc.cpp,在其末尾,加入以下代碼。 //代碼編寫開始 // CObArray成員函數(shù)GetUpperBound()返回加入的最后一個指針的索引,即最大的有效索引,CObArray成員函數(shù)GetAt()返回對應(yīng)的CLine指針。如果索引號小于0或大于最大的有效索引號,GetLine()返回0;否則,返回對應(yīng)的CLine指針。 CLine *CDrawDoc::GetLine(int Index){ } //代碼編寫結(jié)束 if(Index<0||Index>m_LineArray.GetUpperBound())return 0;return(CLine *)m_LineArray.GetAt(Index);22 6.定義函數(shù)CdrawDoc::GetNumLines()選擇FileView,展開SourceFiles,雙擊DrawDoc.cpp,打開執(zhí)行文件DrawDoc.cpp,在其末尾,加入以下代碼。 //代碼編寫開始 // 通過調(diào)用CObArray成員函數(shù)GetSize(),GetNumLines()返回m_LineArray當(dāng)前存放的CLine指針的個數(shù)。 int CDrawDoc::GetNumLines(){ } //代碼編寫結(jié)束 return m_LineArray.GetSize();7.修改函數(shù)視圖類消息處理函數(shù)OnLButtonUp()調(diào)用GetDocument()和AddLine()來存放新直線。 回到Workspace,選擇ClassView,單擊CDrawView,展開CdrawView成員變量和成員函數(shù)。雙擊OnLButtonUp(),在函數(shù)OnLButtonUp()中定義后加入以下代碼。 void CDrawView::OnLButtonUp(UINT nFlags, CPoint point){ // TODO: Add your message handler code here and/or call default int b; CRect Rect(40,40,600,400);b=Rect.PtInRect(point);if(b)::SetCursor(m_HCross);else ::SetCursor(m_HArrow);if(m_Dragging&&b){ m_Dragging=0;CClientDC dc(this);dc.SetROP2(R2_NOT); dc.MoveTo(m_PointOrigin);dc.LineTo(m_PointOld);dc.MoveTo(m_PointOrigin);dc.LineTo(point);//代碼開始編寫 //調(diào)用函數(shù)GetDocument()取得文檔類的指針,并存入pDoc中。CDrawDoc * pDoc=GetDocument(); //通過指針pDoc調(diào)用加入的文檔類成員函數(shù)AddLine()向m_LineArray加入 Cline類直線對象。 pDoc->AddLine(m_PointOrigin.x,m_PointOrigin.y,point.x,point.y); // 當(dāng)一條新的直線繪制完成,視圖類OnLButtonUp(nFlags, point)函數(shù)通過上面的工作將新繪制的直線存入文檔類中。 } } CView::OnLButtonUp(nFlags, point);//代碼編寫結(jié)束 8.修改視圖類成員函數(shù)OnDraw()void CDrawView::OnDraw(CDC* pDC){ CDrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data here pDC->MoveTo(40,40); pDC->LineTo(600,40); pDC->LineTo(600,400); pDC->LineTo(40,400); pDC->LineTo(40,40); //代碼編寫結(jié)束 } 9.編譯、運行 //代碼開始編寫 int Index=pDoc->GetNumLines();while(Index--)pDoc->GetLine(Index)->Draw(pDC); (六)圖形的刪除 下面向Draw程序加入圖形的編輯功能。選擇“編輯/撤銷”菜單命令就可以刪除最近繪制的直線,選擇“編輯/全部刪除”菜單命令可以清除掉視圖窗口中所有的直線。 函數(shù)DeleteContents專門負(fù)責(zé)文檔數(shù)據(jù)的刪除工作,可以在文檔類中加入該函數(shù)刪除存放的直線。我們的目的是通過菜單命令答道編輯的功能,因此需要加入“編輯/撤銷”和 “編輯/全部刪除”菜單命令的消息處理函數(shù),在它們的消息處理函數(shù)中調(diào)用函數(shù)DeleteContents()。 1. 加入“編輯”菜單命令“全部刪除” (1)選擇ResourceView視圖,打開Menu項目下的IDR_MAINFRAME標(biāo)志符,在Edit菜單下面加入菜單命令 “全部刪除”。 ID標(biāo)志符為:ID_EDIT_CLEAR_ALL,Caption為:全部刪除(&A)tCtrl+A(2)雙擊Accelerator項目下面的IDR_MAINFRAME標(biāo)志符,打開快捷鍵編輯器。雙擊快捷鍵編輯框底部的空框,在ID文本框中輸入ID_EDIT_CLEAR_ALL,在Key文本框中輸入A,并選擇Ctrl。 2. 加入虛函數(shù)DeleteContents()25(1)在“查看”菜單中選擇“建立類向?qū)А保–lassWizard)命令,打開MFC ClassWizard窗口。 (2)選擇 Message Maps。(3)分別選擇: Project: Draw Class Name: CDrawDoc Objects: CDrawDoc Messges: DeleteContents(4)單擊Add Function按鈕。 (5)單擊Edit Code按鈕。在DeleteContents()函數(shù)體中加入以下部分。void CDrawDoc::DeleteContents(){ } 3. 加入ID_EDIT_CLEAR_ALL的COMMAND消息處理函數(shù)OnEditClearAll()(1)在“查看”菜單中選擇“建立類向?qū)А保–lassWizard)命令,打開MFC ClassWizard窗口。 (2)選擇 Message Maps。(3)分別選擇: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_CLEAR_ALL Messges: COMMAND // TODO: Add your specialized code here and/or call the base class //代碼編寫開始 int Index=m_LineArray.GetSize();while(Index--)delete m_LineArray.GetAt(Index);m_LineArray.RemoveAll();//代碼編寫結(jié)束 CDocument::DeleteContents();(4)單擊Add Function按鈕。 (5)單擊Edit Code按鈕。在OnEditClearAll()函數(shù)體中加入以下部分。void CDrawDoc::OnEditClearAll(){ // TODO: Add your command handler code here //代碼編寫開始 DeleteContents(); } 4. 加入ID_EDIT_CLEAR_ALL的UPDATE_COMMAND_UI消息處理函數(shù)(1)在“查看”菜單中選擇“建立類向?qū)А保–lassWizard)命令,打開MFC ClassWizard窗口。 (2)選擇 Message Maps。(3)分別選擇: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_CLEAR_ALL Messges: UPDATE_COMMAND_UI(4)單擊Add Function按鈕。 (5)單擊Edit Code按鈕。在OnUpdateEditClearAll()函數(shù)體中加入以下部分。void CDrawDoc::OnUpdateEditClearAll(CCmdUI* pCmdUI){ } 5. 加入ID_EDIT_UNDO的COMMAND消息處理函數(shù) UpdateAllViews(0);//代碼編寫結(jié)束 // TODO: Add your command update UI handler code here //代碼編寫開始 pCmdUI->Enable(m_LineArray.GetSize());//代碼編寫結(jié)束(1)在“查看”菜單中選擇“建立類向?qū)А保–lassWizard)命令,打開MFC ClassWizard窗口。 (2)選擇 Message Maps。(3)分別選擇: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_UNDO Messges: COMMAND(4)單擊Add Function按鈕。 (5)單擊Edit Code按鈕。在OnEditUndo()函數(shù)體中加入以下部分。void CDrawDoc::OnEditUndo(){ // TODO: Add your command handler code here //代碼編寫開始 int Index=m_LineArray.GetUpperBound(); } 6. 加入ID_EDIT_UNDO的UPDATE_COMMAND_UI消息處理函數(shù) (1)在“查看”菜單中選擇“建立類向?qū)А保–lassWizard)命令,打開MFC ClassWizard窗口。 (2)選擇 Message Maps。(3)分別選擇: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_UNDO if(Index>-1){ } UpdateAllViews(0);//代碼編寫結(jié)束 delete m_LineArray.GetAt(Index);m_LineArray.RemoveAt(Index);Messges: UPDATE_COMMAND_UI(4)單擊Add Function按鈕。 (5)單擊Edit Code按鈕。在OnUpdateEditUndo()函數(shù)體中加入以下部分。void CDrawDoc::OnUpdateEditUndo(CCmdUI* pCmdUI){ // TODO: Add your command update UI handler code here //代碼編寫開始 pCmdUI->Enable(m_LineArray.GetSize());//代碼編寫結(jié)束 } (七)圖形的存取 (八)滾動窗口 (九)分割窗口 (十)拖放與注冊 // 1、將C語言變量簡單重新定義 UINT、INT(32位,4字節(jié)) LONG、DWORD(32位,4字節(jié))WPARAM、LPARAM(32位,4字節(jié))SHORT、WORD(16位,2字節(jié))LONG、LRESULT BOOL(TRUE、FALSE)PINT PSTR、LPSTR、LPCSTR(字符串指針,只讀和可寫) // 2、H開頭,Windows句柄類型變量 HANDLE of Windows =>HWND HANDLE of Instance =>HINSTANCE HANDLE of Icon =>HICON //3結(jié)構(gòu)體類型 SIZE、POINT、RECT MFC所有封裝類一共有200多個,但是MFC的內(nèi)部技術(shù)不只是簡單地封裝。MFC內(nèi)部總共有六大關(guān)鍵技術(shù),構(gòu)架起了整個MFC開發(fā)平臺。 一、MFC的六大關(guān)鍵技術(shù)包括: a)MFC程序的初始化過程: b)消息映射機制; c)運行時類型識別(RTTI); d)動態(tài)創(chuàng)建; e)永久保存; f)消息傳遞; 六大關(guān)鍵技術(shù)的目的是為了提高開發(fā)效率,開發(fā)者只需要在局部做簡單的修改,即可處理大部分窗口事物。 二、SendMessage和PostMessage函數(shù)的功能: a)能夠向指定的窗口內(nèi)發(fā)送窗口消息,既可以是本進(jìn)程內(nèi)窗口也可以是其他進(jìn)程的; b)既可以發(fā)送系統(tǒng)內(nèi)部消息,消息編號的范圍是:1-WM_USER-1; 例如:WM_LBUTTONDONW,WM_MOUSEMOVE等; c)也可以發(fā)送非系統(tǒng)消息(開發(fā)者定義的消息),范圍是WM_USER-0x7FFF。 三、SendMessage和PostMessage兩個函數(shù)的區(qū)別是: a)SendMessage是阻塞型函數(shù),PostMessage是非阻塞型函數(shù): SendMessage用于調(diào)用指定窗口的內(nèi)部程序,直到窗口程序處理完成以后再返回: PostMessage是將一個消息寄送到一個窗口內(nèi)的消息隊列后就立即返回。b)兩個函數(shù)的返回值不同: LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM,lParam);BOOL PostMessage(HWND hWnd,UNIT Msg,WPARAM wParam,LPARAM,lParam);SendMessage的返回值依賴于消息處理函數(shù) c)跨線程或者跨進(jìn)程發(fā)送消息,推薦使用PostMessage函數(shù)。 一、更具主窗口類型,MFC軟件工程可以分為以下幾種構(gòu)架模型: 1、SDI(Single Document Interface):單文檔界面,一個主框架窗口下只能編輯一份文檔。例如:記事本和畫筆等。 2、MDI(Multiple Document Interface):多文檔界面,一個主框架窗口下可以同時編輯多份文檔。 例如:VC++6.0,Photoshop等軟件。 3、基于對話框的軟件模型:主窗口是通過資源管理器,在對話框模板內(nèi)擺放控件編輯而成的。 多數(shù)用于開發(fā)小規(guī)模軟件,例如:任務(wù)管理器。 4、其他自定義窗口做主窗口:主窗口既不是框架也不是對話框,而是直接開發(fā)通用窗口類CWind而成。 例如:輸入法窗口、QQ和360軟件等,有時這類軟件都可以使用框架和對話框模式來代替開發(fā)而成。 對話框常用消息映射函數(shù): 二、對話框初始化消息: 1、WM_CREATE:通用窗口初始化消息 窗口還未顯示出來,只有父窗口,子窗口還沒創(chuàng)建 2、WM_INITDIALOG:對話框窗口專用消息 子窗口已經(jīng)全部創(chuàng)建完成,可以調(diào)用和操作子窗口 三、對話框關(guān)閉過程消息: 1、WM_SYSCOMMAND:管理所有系統(tǒng)菜單和系統(tǒng)按鈕消息 包括通過最大化、最小化、移動、大小和關(guān)閉等 2、WM_CLOSE:是WM_SYSCOMMAND消息的一個專用關(guān)閉的分支 再次消息處理過程可以取消本次關(guān)閉任務(wù) 3、IDCANCEL按鈕消息:不但用于按鈕回調(diào)消息,也是系統(tǒng)按鈕關(guān)閉窗口的回調(diào) 執(zhí)行真正關(guān)閉對話框函數(shù)是EndDialog,在此消息處理過程可以取消本次關(guān)閉任務(wù) 4、WM_DESTROY:通用窗口銷毀消息 窗口已經(jīng)在屏幕中消失了,但是自身窗口和窗口內(nèi)的控件都還可以調(diào)用 在此消息處理過程可以取消本次關(guān)閉任務(wù) 四、非模式對話框: 1、在調(diào)用EndDialog函數(shù)關(guān)閉時,非模式對話框只是隱藏沒有真正關(guān)閉; 2、在調(diào)用DestroyWindow函數(shù)關(guān)閉時,只是隱藏沒有真正關(guān)閉; 3、DestroyWindow函數(shù)是通用摧毀窗口的函數(shù),適用于對話框、控件、框架和視圖等。 一個MFC軟件工程由至少一個CWind派生類和一個CWinApp派生類,因此這兩個類是MFC工程中最重要的兩個類。 一、CWind成員函數(shù):主要就是一個核心成員變量m_hWnd。 1、DestroyWindow:摧毀窗口。 2、Create和CreateEx:創(chuàng)建窗口,CreateEx創(chuàng)建時可以指定擴展風(fēng)格。 3、獲取窗口句柄: a)pWnd->m_hWnd:直接調(diào)用前最好判斷一下指針是否為空。b)operator HWND():自動類型轉(zhuǎn)換,將對象轉(zhuǎn)換為句柄。 c)GetSafeHwnd():可以避免的a方法,因為指針為空造成軟件崩潰。 4、由句柄轉(zhuǎn)化為CWnd對象: a)CWnd::FromHandle:生成一個臨時性窗口類指針 b)Attach和Detach:為一個CWnd對象嫁接和移除窗口句柄; c)SubclassWindow和UnsubclassWindow:子類化和反子類化; d)SubclassDlgItem:子類化指定ID對應(yīng)的控件窗口。 5、獲取和設(shè)置窗口信息: a)GetWindowText和SetWindowText:獲取和設(shè)置窗口的標(biāo)題文字。b)GetStyle和ModifyStyle:獲取和設(shè)置窗口的基礎(chǔ)風(fēng)格。c)GetExStyle和ModifyStyleEx:獲取和設(shè)置窗口的擴展風(fēng)格。 6、計時器: a)SetTimer: b)KillTimer: 7、窗口操作: a)ShowWindow: b)EnableWindow: c)MoveWindow: d)CenterWindow: 二、CWinApp類成員變量: 三、CWinApp類成員函數(shù): //匈牙利命名法: //變量: int long定義:int nSel;long nTel HANDLE hInst;CString szName,szPass;CString strAddr;LPCSTR pszName;DWORD dwID;//如果是成員變量,以“m_”開頭 //如果是全局變量,以“g_”開頭 MFC 對話框編程--總結(jié) 一、創(chuàng)建對話框?qū)ο?/p> 1.首先利用資源編輯器創(chuàng)建對話框資源,并針對該對話框資源定義一個對話框類:classCTestDlg :public CDialog 2.創(chuàng)建話話框?qū)ο?/p> 模態(tài)對話框的創(chuàng)建: 如: CTestDlgdlg; dlg.DoModal(); 非模態(tài)對話框創(chuàng)建: 如: CTestDlgdlg; dlg.Create(IDD_DIALOG, this); 但這樣是得不到一個正常顯示的非模態(tài)對話框的。因為模態(tài)與非模態(tài)對話框的實現(xiàn)方式并不相同,這里我們還要注意幾點。 非模態(tài)對話框創(chuàng)建完成后是隱藏著的,必須調(diào)用ShowWindow來進(jìn)行顯示。 對于模態(tài)對話框,當(dāng)執(zhí)行到DoModal 函數(shù)以創(chuàng)建對話框時,程序會暫停執(zhí)行,直至模態(tài)對話框關(guān)閉。所以創(chuàng)建模態(tài)對話框可以采用局部對象。 但是,對于非模態(tài)對話框,當(dāng)執(zhí)行Create函數(shù)時并不會暫停執(zhí)行,當(dāng)執(zhí)行到大括號“}后Dlg局部對象被銷毀生命周期結(jié)束,于是異常出現(xiàn)了。 解決方法有兩個: 一、在View類中定義一個CTestDlg 成員變量。 二、動態(tài)創(chuàng)建一個CTestDlg 變量,并重寫CTestDlg 類的 PostNcDestroy函數(shù),在該函數(shù)里銷毀對象 deletethis; 無論創(chuàng)建的是模態(tài)對話框,還是非模態(tài)對話框,當(dāng)我們單擊確定或取消按鈕后對話框都會消失。但這時低層的操作卻是不同的。 對于模態(tài)對話框,此時對話框?qū)ο蟮拇_是被銷毀了,但對于非模態(tài)對話框,這時只是隱藏起來不再顯示。這需要我們自己調(diào)用DestoryWindow函數(shù)來進(jìn)行銷毀工作。 這時我們必須重寫 CTestDlg 的 OnOK、OnCancel 兩個函數(shù)(這兩個是基類CDialog的虛函數(shù)),在這兩個函數(shù)內(nèi)調(diào)用DestroyWindow函數(shù),并注意不再調(diào)用基類CDialog相應(yīng)的函數(shù)。正確地創(chuàng)建非模態(tài)對話框的代碼如下: CTestDlg*pDlg = new CTestDlg; pDlg->Create(IDD_DIALOG, this); pDlg->ShowWindow(SW_SHOW); 同時,在CTestDlg 類的 PostNcDestroy函數(shù)中銷毀對象:deletethis; 二、動態(tài)創(chuàng)建按鈕 1.在對話框類CTestDlg 中定義一個 CButton 類對象,作為其成員變量。 2.在相應(yīng)的消息處理中,調(diào)用 CButton類的Create函數(shù)創(chuàng)建按鈕。 要注意兩點: 如果在調(diào)用CButton::Create創(chuàng)建按鈕時沒有指定WS_VISIBLE 風(fēng)格,那么隨后一定要調(diào)用這個按鈕對象的ShowWindow函數(shù),來將該按鈕顯示出來。 為防止該CButton關(guān)聯(lián)多個按鈕,這里需要進(jìn)行一些設(shè)置,如下: if(!m_btn.m_hwnd) { // CButton 對象m_btn 未關(guān)聯(lián)一個按鈕 m_btn.Create(....); } else { // CButton 對象m_btn 已關(guān)聯(lián)一個按鈕 其他操作...} 當(dāng)然,方法并不只這一種。但這是最漂亮的方法。 三、設(shè)置控件文本文字 1.下面列舉幾個用來設(shè)置控件文本文字的函數(shù): // 取得對話框中指定控件的窗口句柄。控件通過ID標(biāo)識來指定 CWnd*GetDlgItem(int nID)const; void CWnd::GetDlgItem(int nID, HWND* phWnd)const; // 取得窗口文本 intGetWindowText(LPTSTR lpszStringBuf, int nMaxCount)const; voidGetWindowText(CString& rString)const; // 設(shè)置窗口文本 voidSetWindowText(LPCTSTR lpszString); // 取得指定控件窗口文本。控件通過ID標(biāo)識來指定 intGetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount)const; intGetDlgItemText(int nID, CString& rString)const; // 設(shè)置指定控件窗口文本。控件通過ID標(biāo)識來指定 void SetDlgItemText(int nID, LPCTSTR lpszString); // 取得指定控件窗口文本,并轉(zhuǎn)化為UINT 類型返回。控件通過ID標(biāo)識來指定 UINT GetDlgItemInt(int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE)const;// 設(shè)置指定控件窗口文本,由UINT類型轉(zhuǎn)化為字符。控件通過ID標(biāo)識來指定 voidSetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE); 2.可以為對話框控件關(guān)聯(lián)一個變量,在CTestDlg 類的DoDataExchange來完成數(shù)據(jù)的更新與交換。這里我們需要重點說明 DoDataExChange 函數(shù): 首先引用MSDN的一段解釋吧:Called by the framework to exchange and validate dialog data。意指框架調(diào)用此函數(shù)來改寫與確認(rèn)對話框數(shù)據(jù)。 其實DoDataExChange函數(shù)主要是通過DDX_TEXT(....)或 DDX_CONTROL(....)來實現(xiàn)數(shù)據(jù)的實時關(guān)聯(lián)的。 我從我的MSDN中隨便拿來一個定義: void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, BYTE& value); 其實這個要關(guān)聯(lián)的話也很簡單,沒有那么復(fù)雜。如下: value = GetDlgItemInt(nIDC); SetDlgItemInt(nIDC, value); 而DoDataExchange 函數(shù)是在UpdateData函數(shù)內(nèi)部調(diào)用的。 該函數(shù)只有一個布爾型參數(shù),b31.org 它決定了數(shù)據(jù)傳送的方向: 調(diào)用UpdateData(TRUE),將數(shù)據(jù)從對話框的控件中傳送到對應(yīng)的數(shù)據(jù)成員中。 調(diào)用UpdateData(FALSE),則將數(shù)據(jù)從數(shù)據(jù)成員中傳送給對應(yīng)的控件。 UpdateData(FALSE)是將變量的值傳到控件.UpdateData(TRUE)是從控件中取值到關(guān)聯(lián)的變量 四、對話框伸縮功能的實現(xiàn) 只關(guān)聯(lián)到兩個函數(shù): // 取得指定窗口邊框折尺寸 void GetWindowRect(LPRECT lpRect)const; // 設(shè)置指定窗口(控件)的位置同尺寸 BOOL SetWindowPos(const CWnd* pWndInsertAfter, intx, inty, int cx, intcy, UINTnFlags); 五、逃跑按鈕的實現(xiàn) 1.創(chuàng)建一個基于對話框的MFC 程序,刪除原有的控件后,再添加兩個按鈕,更改兩按鈕名為”你能抓到我嗎?“ 2.打開類視圖,定義一個新類CNewButton,這個新類的基類為CButton。并為此類添加一個成員變量:CNewButton*m_pbtn; 3.打開資源視圖,分別為兩個按鈕創(chuàng)建兩個CNewButton類關(guān)聯(lián)變量:m_btn1, m_btn2; 4.在CXXXDlg中改寫其OnInitDialog函數(shù)。主要添加: m_btn1.m_pbtn = &m_btn2; m_btn2.m_pbtn = &m_btn1; 5.對于CNewButton 類,必定其OnMouseMove函數(shù)。主要添加: ShowWindow(SW_HIDE); m_pbtn->ShowWindow(SW_SHOW); 編譯,連接。OK 六、屬性頁、屬性表單與向?qū)У慕?/p> 1.創(chuàng)建屬性頁 打開資源編輯器,點擊Dialog 資源并在列出的選項中,選擇:IDD_PROPPAGE_LARGE。建立屬性頁資源。 之后,我們就可以其上添加其他控件來完善我們的屬性頁。關(guān)于屬性頁的完善操作我們在后面會談到。 屬性頁資源完善后,再為每一個屬性頁關(guān)聯(lián)一個類。 2.創(chuàng)建屬性表單 打開類視圖,添加新類CPropSheet,其基類為CPropertySheet。 之后再為其添加屬性頁類對象,并在其構(gòu)造函數(shù)中利用AddPage函數(shù)將屬性頁添加到表單上。 3.消息響應(yīng) 再主菜單的最后再增加一個菜單項,并為此菜單添加消息響應(yīng)函數(shù)。 在此響應(yīng)函數(shù)中創(chuàng)建屬性表單: CPropSheetpropSheet(TEXT(”屬性表單")); propSheet.DoModal(); 4.向?qū)У膭?chuàng)建 創(chuàng)建一個向?qū)ь愋偷膶υ捒颍瑧?yīng)該遵循創(chuàng)建一個標(biāo)準(zhǔn)屬性表單的步驟來實現(xiàn)。 但在調(diào)用屬性表單對象的DoModal函數(shù)之前,應(yīng)該先調(diào)用SetWizardMode函數(shù),來聲明建立的是一個作為向?qū)У膶傩员韱巍?/p> 所以,應(yīng)在DoModal函數(shù)之前添加如下代碼: propSheet.SetWizardMode(); 5.屬性頁的完善操作 首先我們要注意到屬性頁,澳門新濠天地官網(wǎng)66bb.org 在三個不同時期的關(guān)鍵性操作:當(dāng)屬性表單中的某屬性頁被選中,從而成為一個活動的頁面時,應(yīng)用程序框架就會調(diào)用OnSetActive函數(shù)。 OnSetActive 是其基類的一個虛函數(shù),我們可以重寫這個函數(shù)并在其中進(jìn)行一些操作。 假設(shè)當(dāng)前我們處于屬性表單中的某屬性頁,當(dāng)我們點擊下一步并將進(jìn)入下一個屬性頁時,應(yīng)用程序框架會調(diào)用OnWizardNext函數(shù)。 OnWizardNext 是其基類的一個虛函數(shù),我們可以重寫這個函數(shù)并在其中進(jìn)行一些操作。類似的還有OnWizardBack 同 OnWizardFinish函數(shù)。 當(dāng)一個屬性頁被創(chuàng)建時,會調(diào)用其OnInitDialog函數(shù)。 我們可以在這個函數(shù)里對屬性頁中的控件進(jìn)行一些操作。如為列表框或下拉框添加字符串等。 MFC編程實驗總結(jié)報告 知識總結(jié)+個人心得 2011年暑期MFC編程實驗報告 / 6 MFC編程實驗個人總結(jié)報告 一、MFC類、函數(shù)等知識小結(jié): 1、SetTimer(1, m_intLevel, NULL);在MFC程序中SetTimer被封裝在CWnd類中,調(diào)用就不用指定窗口句柄了于是SetTimer函數(shù)的原型變?yōu)椋?/p> UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPORT *lpfnTimer)(HWND,UINT ,YINT ,DWORD)) 當(dāng)使用SetTimer函數(shù)的時候,就會生成一個計時器。函數(shù)中nIDEvent指的是計時器的標(biāo)識,也就是名字。nElapse指的是時間間隔,也就是每隔多長時間觸發(fā)一次事件。第三個參數(shù)是一個回調(diào)函數(shù),在這個函數(shù)里,放入你想要做的事情的代碼,你可以將它設(shè)定為NULL,也就是使用系統(tǒng)默認(rèn)的回調(diào)函數(shù),系統(tǒng)默認(rèn)認(rèn)的是onTime函數(shù)。這個函數(shù)怎么生成的呢?你需要在需要計時器的類的生成onTime函數(shù):在ClassWizard里,選擇需要計時器的類,添加WM_TIME消息映射,就自動生成onTime函數(shù)了。然后在函數(shù)里添加代碼,讓代碼實現(xiàn)功能。每隔一段時間就會自動執(zhí)行一次。 例: SetTimer(1,1000,NULL); 1:計時器的名稱; 1000:時間間隔,單位是毫秒; NULL:使用onTime函數(shù)。 當(dāng)不需要計時器的時候調(diào)用KillTimer(nIDEvent); 例如:KillTimer(1); KillTimer(1); 2、typedef struct{};(1)struct{ int x;int y;}test1;好,定義了 結(jié)構(gòu) test1,test1.x 和 test1.y 可以在語句里用了。 (2)struct test {int x;int y;}test1;定義了結(jié)構(gòu) test1,test1.x 和 test1.y 可以在語句里用了。與(1)比,省寫 了 test (3)typedef struct test / 6 {int x;int y;}text1,text2; 此處時說了這種結(jié)構(gòu)體(類型)別名 叫 text1 或叫 text2,而不是定義了結(jié)構(gòu)體變量.真正在語句里用,還要寫: text1 test1;//定義結(jié)構(gòu)體變量 然后好用 test1.x test1.y 或?qū)?text2 test1;//定義結(jié)構(gòu)體變量 然后好用 test1.x test1.y 3、Invalidate();//讓客戶區(qū)無效,即時重新繪制客戶區(qū) void Invalidate(BOOL bErase = TRUE); 該函數(shù)的作用是使整個窗口客戶區(qū)無效。窗口的客戶區(qū)無效意味著需要重繪,例如,如果一個被其它窗口遮住的窗口變成了前臺窗口,那么原來被遮住的部分就是無效的,需要重繪。這時Windows會在應(yīng)用程序的消息隊列中放置WM_PAINT消息。MFC為窗口類提供了WM_PAINT的消息處理函數(shù)OnPaint,OnPaint負(fù)責(zé)重繪窗口。視圖類有一些例外,在視圖類的OnPaint函數(shù)中調(diào)用了OnDraw函數(shù),實際的重繪工作由OnDraw來完成。參數(shù)bErase為TRUE時,重繪區(qū)域內(nèi)的背景將被擦除,否則,背景將保持不變。 4、CDC::Rectangle(左上x,左上y,右下x,右下y);使用該函數(shù)畫一個矩形,可以用當(dāng)前的畫筆畫矩形輪廓,用當(dāng)前畫刷進(jìn)行填充。 函數(shù)原型:BOOL Rectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); hdc:設(shè)備環(huán)境句柄。 nLeftRect:指定矩形左上角的邏輯X坐標(biāo)。 nTopRect:指定矩形左上角的邏輯Y坐標(biāo)。 nRightRect:指定矩形右下角的邏輯X坐標(biāo)。 nBottomRect:指定矩形右下角的邏輯Y坐標(biāo)。 5、CBrush:: CBrush//畫刷類 eg:CBrush brushStick(RGB(127, 127, 127));四種構(gòu)造函數(shù): CBrush(); CBrush(COLORREF crColor); CBrush(int nIndex, COLORREF crColor); CBrush(CBitmap* pBitmap); / 6 參數(shù)說明: crColor指定畫刷的前景色(RGB方式)。如果畫刷是陰影線型的,則指定陰影線的顏色。 nIndex指定畫刷陰影線采用的風(fēng)格,取值如下: HS_BDIAGONAL45度的向下影線(從左到右) HS_CROSS水平和垂直方向以網(wǎng)格線作出陰影 HS_DIAGCROSS 45度的網(wǎng)格線陰影 HS_FDIAGONAL 45度的向上陰影線(從左到右) HS_HORIZONTAL 水平的陰影線 HS_VERTICAL 垂直的陰影線 pBitmap指向CBitmap對象的指針,該對象指定了畫刷要繪制的位圖。 構(gòu)造函數(shù)說明: 類CBrush一共有四個覆蓋的構(gòu)造函數(shù)。不帶參數(shù)的那個構(gòu)造函數(shù)構(gòu)造一個未初始化的CBrush對象,在使用該對象之前需要另外初始化。如果使用了不帶參數(shù)的那個構(gòu)造函數(shù),則必須用CreateSolidBrush、CreateHatchBrush、CreateBrushIndirect、CreatePatternBrush或CreateDIBPatternBrush來初始化返回的CBrush對象。如果使用了帶參數(shù)的構(gòu)造函數(shù),則不再需要初始化CBrush對象。帶參數(shù)的構(gòu)造函數(shù)在出錯時會產(chǎn)生一個異常,而不帶參數(shù)的構(gòu)造函數(shù)總是成功返回。只帶有一個參數(shù)COLORREF的構(gòu)造函數(shù)用指定的顏色構(gòu)造一個實線型的畫刷。顏色是一個RGB值,可以用WINDOWS.H中的宏RGB構(gòu)造出來。帶兩個參數(shù)的構(gòu)造函數(shù)構(gòu)造一個陰影線型的畫刷,參數(shù)nIndex指定了陰影線模式的指數(shù)(index)。參數(shù)crColor指定了畫刷的顏色。帶有一個CBitmap型參數(shù)的構(gòu)造函數(shù)構(gòu)造一個模式化的畫刷。參數(shù)指定一個位圖。該位圖應(yīng)該是已經(jīng)用CBitmap::CreateBitmap、CBitmap::CreateBitmapIndirect、CBitmap::LoadBitmap或CBitmap::CreateCompatiableBitmap建立或加載的位圖。填充模式下的位圖的最小尺寸為8像素×8像素。 6、MessageBox(“Game Over!”);MessageBox(NULL,“text”,“title”,BUTTON);參數(shù)title:string類型,指定消息對話框的標(biāo)題。text:指定消息對話框中顯示的消息,該參數(shù)可以是數(shù)值數(shù)據(jù)類型、字符串或boolean值。icon:Icon枚舉類型,可選項,指定要在該對話框左側(cè)顯示的圖標(biāo)。button:Button枚舉類型,可選項,指定顯示在該對話框底部的按鈕。default:數(shù)值型,可選項,指定作為缺省按鈕的按鈕編號,按鈕編號自左向右依次計數(shù),缺省值為1,如果該參數(shù)指定的編號超過了顯示的按鈕個數(shù),那么MessageBox()函數(shù)將使用缺省值返回值Integer。函數(shù)執(zhí)行成功時返回用戶選擇的按鈕編號(例如1、2、3等),發(fā)生錯誤時返回-1。如果任何參數(shù)的值為NULL,4 / 6 MessageBox()函數(shù)返回NULL。 函數(shù)原型:MessageBox.Show(Text,Title,MessageBoxButtons,MessageBoxIcon ,MessageBoxDefaultButtons) 參數(shù)說明: (1)Text:必選項,消息框的正文。(2)Title:可選項,消息框的標(biāo)題。 (3)MessageBoxButtons:可選項,消息框的按鈕設(shè)置,默認(rèn)只顯示【確定】按鈕。 OK――確定 OKCancel――確定和取消 AbortRetryIgnore――終止、重試和忽略 YesNoCancel――是、否和取消 YesNo――是和否 RetryCancel――重試和取消 (4)MessageBoxIcon:對話框中顯示的圖標(biāo)樣式,默認(rèn)不顯示任何圖標(biāo)。 Question――問號 Information、Asterisk――i號 Error、Stop、Hand――錯誤號 Warning、Exclamation――!號 None――不顯示任何圖標(biāo) (5)MessageBoxDefaultButtons:可選項,對話框中默認(rèn)選中的按鈕設(shè)置。 DefaultButton1――第1個button是默認(rèn)按鈕 DefaultButton2――第2個button是默認(rèn)按鈕 DefaultButton3――第3個button是默認(rèn)按鈕 7、Memcpy(拷貝目的地,拷貝對象,拷貝長度);包含在頭文件#include 函數(shù)原型: extern void *memcpy(void *destin, void *source, unsigned n);功能: 由source指向地址為起始地址的連續(xù)n個字節(jié)的數(shù)據(jù)復(fù)制到以destin指向地址為起始地址的空間內(nèi)。eg: int a=5,b=9;memcpy(a,b,sizeof(a));//將b按位拷給a;說明: 1.source和destin所指內(nèi)存區(qū)域不能重疊,函數(shù)返回指向destin的指針。 2.與strcpy相比,memcpy并不是遇到'
主站蜘蛛池模板:
又色又爽又黄又硬的视频免费观看|
粗大的内捧猛烈进出视频|
无码一区二区|
国产性色强伦免费视频|
2021久久国自产拍精品|
69堂人成无码免费视频果冻传媒|
欧美拍拍视频免费大全|
精品少妇爆乳无码av无码专区|
久久丫精品久久丫|
国产精品自在线拍国产手青青机版|
精品无码久久久久久尤物|
国产午夜精品久久久久免费视|
在线观看的av网站|
精品亚洲欧美视频在线观看|
人人妻人人爽人人做夜欢视频九色|
亚洲午夜爱爱香蕉片|
久久人人玩人妻潮喷内射人人|
好爽…又高潮了毛片免费看|
久久久久人妻精品一区三寸|
少妇极品熟妇人妻|
国产精品进线69影院|
久久国产精品久久喷水|
国产欧美另类精品久久久|
亚洲综合天天夜夜久久|
亚洲av乱码中文一区二区三区|
亚洲国产成人精品一区刚刚|
亚洲香蕉aⅴ视频在线播放|
无码人妻丰满熟妇bbbb|
无码av天堂一区二区三区|
亚洲av乱码一区二区三区按摩|
欧美激情一区二区三区|
久久婷婷五月综合97色直播|
亚洲国产天堂久久综合226114|
内射少妇一区27p|
群交射精白浆视频|
特黄aaaaaaa片免费视频|
波多野结衣办公室33分钟|
v一区无码内射国产|
5858s亚洲色大成网站www|
精品一二三区久久aaa片|
丁香五月亚洲综合深深爱|
第二篇:MFC編程學(xué)習(xí)心得
第三篇:MFC 對話框編程 -- 總結(jié)
第四篇:MFC編程實驗個人總結(jié)報告