MFC 学习笔记

一.MFC编程基础:

概述:

常用头文件:

MFC控制台程序:

MFC库程序:

规则库可以被各种程序所调用,扩展库只能被MFC程序调用。

MFC窗口程序:

示例:

MFC库中类的简介:

具体详细细节可以参考离线文档

第一个MFC程序:

1.创建一个win32程序

2.设置使用MFC

3.添加类

  1. #include <afxwin.h>
  2. class CMyFrameWnd : public CFrameWnd{
  3. };
  4. class CMyWinApp : public CWinApp{
  5. public:
  6. CMyWinApp()
  7. {
  8. }
  9. virtual BOOL InitInstance(){//此函数内部的this为&theApp
  10. CMyFrameWnd* pFrame = new CMyFrameWnd;
  11. pFrame->Create(NULL, "MFCBase");
  12. this->m_pMainWnd = pFrame;
  13. pFrame->ShowWindow(SW_SHOW);
  14. pFrame->UpdateWindow();
  15. return TRUE;
  16. }
  17. };
  18. CMyWinApp theApp;//爆破点

4.效果:

MFC程序启动:

  1. AFX_MODULE_STATE aaa;//当前程序模块状态信息
  2. AFX_MODULE_THREAD_STATE bbb; //当前程序线程状态信息
  3. CWinApp::CWinApp()//构造全局对象CMyWinApp theApp
  4. {
  5. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  6. //获取全局变量&aaa
  7. AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
  8. //获取全局变量&bbb
  9. pThreadState->m_pCurrentWinThread = this;//将&theApp保存到bbb的一个成员中
  10. AfxGetThread()
  11. {
  12. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//获取&bbb
  13. CWinThread* pThread = pState->m_pCurrentWinThread;
  14. return pThread;//返回的为&theApp
  15. }
  16. pModuleState->m_pCurrentWinApp = this;//将&theApp保存到aaa的一个成员中
  17. AfxGetApp()
  18. {
  19. return AfxGetModuleState()->m_pCurrentWinApp//返回&theApp
  20. }
  21. }

通过将断点打在InitInstance()这个方法,在调用堆栈里可以看到MFC里封装的WinMain方法。

  1. WinMain(...)//程序流程是不是theApp对象指导向哪走
  2. {
  3. AfxWinMain(...)
  4. {
  5. CWinThread* pThread = AfxGetThread();
  6. CWinApp* pApp = AfxGetApp();//这两代码都是获取&theApp
  7. pApp->InitApplication();//利用theApp对象调用应用程序类成员虚函数 初始化
  8. pThread->InitInstance();//利用theApp对象调用应用程序类成员虚函数 创建并显示窗口
  9. pThread->Run()//利用theApp对象调用应用程序类成员虚函数 消息循环
  10. {
  11. for (;;)
  12. {
  13. while(没有消息时)
  14. OnIdle(..);//利用theApp对象调用应用程序类成员虚函数 空闲处理
  15. do{
  16. if(GetMessage抓到WM_QUIT)
  17. return ExitInstance();
  18. //程序结束前,利用theApp对象调用应用程序类成员虚函数 善后处理。
  19. }while(...)
  20. }
  21. }
  22. }
  23. }

二.MFC窗口和消息:

钩子简介:

  1. #include <afxwin.h>
  2. class CMyFrameWnd : public CFrameWnd{
  3. public:
  4. virtual LRESULT WindowProc( UINT msgID, WPARAM wParam, LPARAM );
  5. };
  6. LRESULT CMyFrameWnd::WindowProc( UINT msgID, WPARAM wParam, LPARAM lParam ){
  7. //此函数内部的this为pFrame
  8. switch( msgID ){
  9. case WM_CREATE:
  10. AfxMessageBox( "WM_CREATE消息被处理" );
  11. break;
  12. case WM_PAINT:
  13. {
  14. PAINTSTRUCT ps = { 0 };
  15. HDC hdc = ::BeginPaint( this->m_hWnd, &ps );
  16. ::TextOut( hdc, 100, 100, "hello", 5 );
  17. ::EndPaint( m_hWnd, &ps );
  18. }
  19. break;
  20. }
  21. return CFrameWnd::WindowProc(msgID, wParam, lParam);
  22. }
  23. class CMyWinApp : public CWinApp{
  24. public:
  25. virtual BOOL InitInstance( );
  26. };
  27. CMyWinApp theApp;//爆破点
  28. BOOL CMyWinApp::InitInstance( ){
  29. CMyFrameWnd* pFrame = new CMyFrameWnd;
  30. pFrame->Create(NULL, "MFCCreate");
  31. m_pMainWnd = pFrame;
  32. pFrame->ShowWindow( SW_SHOW );
  33. pFrame->UpdateWindow( );
  34. return TRUE;
  35. }
MFC窗口创建过程:

  1. CMyFrameWnd* pFrame = new CMyFrameWnd;
  2. pFrame->Create(NULL, "MFCCreate")//函数内部this为pFrame(自己new框架类对象地址)
  3. {
  4. //加载菜单
  5. CreateEx(..., NULL,...)//函数内部this为pFrame
  6. {
  7. CREATESTRUCT cs;
  8. ....
  9. cs.lpszClass = NULL;//下面将更改
  10. ...
  11. cs.hInstance = AfxGetInstanceHandle(); //MFC里获取winMain的第一个参数
  12. PreCreateWindow(cs)
  13. {
  14. AfxDeferRegisterClass(...)
  15. {
  16. //注册窗口类
  17. WNDCLASS wndcls;
  18. ...
  19. wndcls.lpfnWndProc = DefWindowProc;//消息处理存在问题,下面将进行修改
  20. ...
  21. _AfxRegisterWithIcon(&wndcls, "AfxFrameOrView100sd"..)
  22. {
  23. &wndcls->lpszClassName = "AfxFrameOrView100sd";
  24. ::RegisterClass(&wndcls) //在这里执行窗口注册
  25. }
  26. }
  27. cs.lpszClass = _afxWndFrameOrView; //"AfxFrameOrView100sd"
  28. }
  29. AfxHookWindowCreate(pFrame)
  30. {
  31. _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
  32. //获取全局变量&ccc(当前程序线程信息)
  33. ::SetWindowsHookEx(WH_CBT,_AfxCbtFilterHook,...);
  34. //利用Win32的API函数,埋下一个类型为WH_CBT的钩子
  35. pThreadState->m_pWndInit = pFrame;
  36. //将自己new的框架类对象pFrame保存到全局变量ccc的一个成员中。
  37. }
  38. ::CreateWindowEx(...);//此函数一旦执行成功,立即转到钩子处理函数。
  39. }
  40. }
  41. 钩子处理函数
  42. _AfxCbtFilterHook(.wParam.)
  43. {
  44. _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();//获取&ccc
  45. CWnd* pWndInit = pThreadState->m_pWndInit;//获取pFrame===pWndInit
  46. HWND hWnd = (HWND)wParam;//刚刚创建成功的框架窗口句柄
  47. pWndInit->Attach(hWnd)//函数内部this为pFrame,参数为窗口句柄
  48. {
  49. CHandleMap* pMap = afxMapHWND(TRUE)
  50. {
  51. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//获取&bbb
  52. pState->m_pmapHWND = new CHandleMap(..);
  53. //new了一个映射类对象,并将对象地址保存到bbb的一个成员中
  54. return pState->m_pmapHWND;
  55. //返回映射类对象地址
  56. }
  57. pMap->SetPermanent(m_hWnd = hWnd, pFrame)//函数内部this为pMap
  58. {
  59. m_permanentMap[hWnd] = pFrame;
  60. }
  61. }
  62. (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC,AfxWndProc);
  63. //将窗口处理函数更改为AfxWndProc(才是真正的窗口处理函数)
  64. }
处理消息:

  1. //以WM_CREATE消息为例,捎带想着点WM_PAINT消息
  2. AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  3. {
  4. CWnd* pWnd = CWnd::FromHandlePermanent(hWnd)
  5. {
  6. CHandleMap* pMap = afxMapHWND()
  7. {
  8. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//获取&bbb
  9. return pState->m_pmapHWND;//返回就是之前保存在bbb中的映射类对象地址
  10. }
  11. pWnd = pMap->LookupPermanent(hWnd)//函数内部this为pMap
  12. {
  13. return m_permanentMap[hWnd];//返回的为pFrame
  14. }
  15. }
  16. AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam)//参数pWnd===pFrame
  17. {
  18. pWnd->WindowProc(nMsg, wParam, lParam);//回到自己的代码
  19. }
  20. }
消息映射机制:

在不重写WindowProc虚函数的大前提下,仍然可以处理消息。

具体实现:

  1. #include <afxwin.h>
  2. class CMyFrameWnd : public CFrameWnd{
  3. DECLARE_MESSAGE_MAP()
  4. protected:
  5. static const AFX_MSGMAP* PASCAL GetThisMessageMap();
  6. virtual const AFX_MSGMAP* GetMessageMap() const;
  7. public:
  8. LRESULT OnCreate( WPARAM wParam, LPARAM lParam );
  9. };
  10. BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
  11. ON_MESSAGE( WM_CREATE, OnCreate )
  12. END_MESSAGE_MAP()
  13. LRESULT CMyFrameWnd::OnCreate( WPARAM wParam, LPARAM lParam ){
  14. AfxMessageBox( "WM_CREATE" );
  15. return 0;
  16. }
  17. class CMyWinApp : public CWinApp{
  18. public:
  19. virtual BOOL InitInstance( );
  20. };
  21. CMyWinApp theApp;//爆破点
  22. BOOL CMyWinApp::InitInstance( ){
  23. CMyFrameWnd* pFrame = new CMyFrameWnd;
  24. pFrame->Create(NULL, "MFCCreate");
  25. m_pMainWnd = pFrame;
  26. pFrame->ShowWindow( SW_SHOW );
  27. pFrame->UpdateWindow( );
  28. return TRUE;
  29. }

将这几个宏替换:

  1. #include <afxwin.h>
  2. class CMyFrameWnd : public CFrameWnd{
  3. // DECLARE_MESSAGE_MAP()
  4. protected:
  5. static const AFX_MSGMAP* PASCAL GetThisMessageMap();
  6. virtual const AFX_MSGMAP* GetMessageMap() const;
  7. public:
  8. LRESULT OnCreate( WPARAM wParam, LPARAM lParam );
  9. };
  10. //BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
  11. // ON_MESSAGE( WM_CREATE, OnCreate )
  12. //END_MESSAGE_MAP()
  13. const AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const
  14. {
  15. return GetThisMessageMap();
  16. }
  17. const AFX_MSGMAP* PASCAL CMyFrameWnd::GetThisMessageMap()
  18. {
  19. static const AFX_MSGMAP_ENTRY _messageEntries[] =
  20. {
  21. { WM_CREATE, 0, 0, 0, AfxSig_lwl, (AFX_PMSG)(AFX_PMSGW)
  22. (static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > (&OnCreate)) },
  23. {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
  24. };
  25. static const AFX_MSGMAP messageMap = { &CFrameWnd::GetThisMessageMap, &_messageEntries[0] };
  26. return &messageMap;
  27. }
  28. LRESULT CMyFrameWnd::OnCreate( WPARAM wParam, LPARAM lParam ){
  29. AfxMessageBox( "WM_CREATE" );
  30. return 0;
  31. }
  32. class CMyWinApp : public CWinApp{
  33. public:
  34. virtual BOOL InitInstance( );
  35. };
  36. CMyWinApp theApp;//爆破点
  37. BOOL CMyWinApp::InitInstance( ){
  38. CMyFrameWnd* pFrame = new CMyFrameWnd;
  39. pFrame->Create(NULL, "MFCCreate");
  40. m_pMainWnd = pFrame;
  41. pFrame->ShowWindow( SW_SHOW );
  42. pFrame->UpdateWindow( );
  43. return TRUE;
  44. }

AFX_MSGMAP_ENTRY结构体的解释:

AFX_MSGMAP结构体的解释:

展开各部分作用介绍:

创建窗口的原理:

代码:

  1. //以WM_CREATE消息为例,捎带想着点WM_PAINT,WM_COMMAND(到了CWnd::OnWndMsg函数路线不一样)
  2. AfxWndProc(...)
  3. {
  4. CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
  5. //获取和hWnd绑定在一起的框架类对象地址(pFrame===pWnd)
  6. AfxCallWndProc(pWnd...)//参数pWnd===pFrame
  7. {
  8. pWnd->WindowProc(...)//函数内部this为pFrame===pWnd *************
  9. {
  10. OnWndMsg(...)//函数内部this为pFrame===pWnd
  11. {
  12. const AFX_MSGMAP* pMessageMap = GetMessageMap();
  13. //获取本类宏站开的静态变量的地址(链表头结点)
  14. const AFX_MSGMAP_ENTRY* lpEntry;
  15. for (; pMessageMap->pfnGetBaseMap != NULL;//此for就是在遍历链表
  16. pMessageMap = (*pMessageMap->pfnGetBaseMap)())
  17. {
  18. lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,message, 0, 0));
  19. //如果找到返回找到的数组元素的地址,如果没找到返回NULL
  20. if(lpEntry != NULL )
  21. {
  22. goto LDispatch;
  23. }
  24. }
  25. LDispatch:
  26. lpEntry->pfn; //CMyFrameWnd::OnCreate
  27. 调用CMyFrameWnd::OnCreate函数完成消息的处理
  28. }
  29. }
  30. }
  31. }

三.MFC消息:

消息的分类:

示例:

  1. #include <afxwin.h>
  2. #define WM_MYMESSAGE WM_USER+1001
  3. class CMyFrameWnd : public CFrameWnd{
  4. DECLARE_MESSAGE_MAP()
  5. public:
  6. int OnCreate( LPCREATESTRUCT pcs);
  7. void OnPaint( );
  8. void OnMouseMove( UINT nKey, CPoint pt );
  9. LRESULT OnMyMessage( WPARAM wParam, LPARAM lParam );
  10. int m_x;
  11. int m_y;
  12. };
  13. BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
  14. ON_WM_CREATE()
  15. ON_WM_PAINT()
  16. ON_WM_MOUSEMOVE()
  17. ON_MESSAGE( WM_MYMESSAGE, OnMyMessage)
  18. END_MESSAGE_MAP()
  19. LRESULT CMyFrameWnd::OnMyMessage( WPARAM wParam, LPARAM lParam ){
  20. CString str;
  21. str.Format( "wParam=%d,lParam=%d", wParam, lParam );
  22. AfxMessageBox( str );
  23. return 0;
  24. }
  25. void CMyFrameWnd::OnMouseMove( UINT nKey, CPoint pt){
  26. m_x = pt.x;
  27. m_y = pt.y;
  28. ::InvalidateRect( this->m_hWnd, NULL, TRUE );
  29. }
  30. void CMyFrameWnd::OnPaint( ){
  31. PAINTSTRUCT ps = { 0 };
  32. HDC hdc = ::BeginPaint( this->m_hWnd, &ps );
  33. ::TextOut( hdc, m_x, m_y, "hello", 5);
  34. ::EndPaint( m_hWnd, &ps );
  35. }
  36. int CMyFrameWnd::OnCreate( LPCREATESTRUCT pcs ){
  37. AfxMessageBox("WM_CREATE消息被处理");
  38. ::PostMessage( this->m_hWnd, WM_MYMESSAGE, 1, 2 );
  39. return CFrameWnd::OnCreate( pcs );
  40. }
  41. class CMyWinApp : public CWinApp{
  42. public:
  43. virtual BOOL InitInstance( );
  44. };
  45. CMyWinApp theApp;//爆破点
  46. BOOL CMyWinApp::InitInstance( ){
  47. CMyFrameWnd* pFrame = new CMyFrameWnd;
  48. pFrame->Create(NULL, "MFCCreate");
  49. m_pMainWnd = pFrame;
  50. pFrame->ShowWindow( SW_SHOW );
  51. pFrame->UpdateWindow( );
  52. return TRUE;
  53. }
MFC菜单:

菜单的使用:

方法一:

方法二:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyFrameWnd : public CFrameWnd{
  4. DECLARE_MESSAGE_MAP( )
  5. public:
  6. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  7. afx_msg void OnNew( );
  8. public:
  9. CMenu menu;
  10. };
  11. BEGIN_MESSAGE_MAP( CMyFrameWnd, CFrameWnd )
  12. ON_COMMAND( ID_NEW, OnNew )
  13. ON_WM_CREATE( )
  14. END_MESSAGE_MAP( )
  15. void CMyFrameWnd::OnNew( ){
  16. AfxMessageBox( "框架类处理了新建菜单项被点击" );
  17. }
  18. int CMyFrameWnd::OnCreate( LPCREATESTRUCT pcs ){
  19. //调用api(win32)的loadmenu方法拿到句柄,将菜单句柄和menu对象建立一对一的关系。
  20. menu.LoadMenu( IDR_MENU1 );
  21. // this->SetMenu( &menu );
  22. ::SetMenu( this->m_hWnd, menu.m_hMenu);
  23. return CFrameWnd::OnCreate( pcs );
  24. }
  25. class CMyWinApp : public CWinApp{
  26. DECLARE_MESSAGE_MAP()
  27. public:
  28. virtual BOOL InitInstance( );
  29. afx_msg void OnNew( );
  30. };
  31. BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
  32. ON_COMMAND( ID_NEW , OnNew )
  33. END_MESSAGE_MAP( )
  34. void CMyWinApp::OnNew( ){
  35. AfxMessageBox( "应用程序类处理了新建被点击" );
  36. }
  37. BOOL CMyWinApp::InitInstance( ){
  38. CMyFrameWnd* pFrame = new CMyFrameWnd;
  39. pFrame->Create(NULL, "MFCCreate");
  40. m_pMainWnd = pFrame;
  41. pFrame->ShowWindow( SW_SHOW );
  42. pFrame->UpdateWindow( );
  43. return TRUE;
  44. }
  45. CMyWinApp theApp;

菜单项没有对应的消息处理,就会默认灰显。

命令消息处理顺序:

(仅针对command消息类,其他类只有框架类处理一条路径)

框架类 ——> 应用程序处理类

设置菜单项状态:

设置右键菜单(上下文菜单):

代码:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyFrameWnd : public CFrameWnd{
  4. DECLARE_MESSAGE_MAP( )
  5. public:
  6. //afx_msg 占位符 标识这个方法是处理消息的
  7. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  8. afx_msg void OnNew( );
  9. afx_msg void OnInitMenuPopup( CMenu *pPopup, UINT nPos, BOOL i );
  10. afx_msg void OnContextMenu( CWnd* pWnd, CPoint pt );
  11. public:
  12. CMenu menu;
  13. };
  14. BEGIN_MESSAGE_MAP( CMyFrameWnd, CFrameWnd )
  15. // ON_COMMAND( ID_NEW, OnNew )
  16. ON_WM_CREATE( )
  17. ON_WM_INITMENUPOPUP()
  18. ON_WM_CONTEXTMENU( )
  19. END_MESSAGE_MAP( )
  20. void CMyFrameWnd::OnContextMenu( CWnd* pWnd, CPoint pt ){
  21. //获取整个大菜单顶层为0的子菜单
  22. // HMENU hPopup = ::GetSubMenu(menu.m_hMenu,0);
  23. // ::TrackPopupMenu( hPopup, TPM_LEFTALIGN|TPM_TOPALIGN, pt.x, pt.y,
  24. // 0, this->m_hWnd, NULL );
  25. CMenu* pPopup = menu.GetSubMenu(0);
  26. pPopup->TrackPopupMenu( TPM_LEFTALIGN|TPM_TOPALIGN, pt.x, pt.y, this );
  27. }
  28. void CMyFrameWnd::OnInitMenuPopup( CMenu* pPopup, UINT nPos, BOOL i){
  29. // pPopup->CheckMenuItem( ID_NEW, MF_CHECKED );
  30. ::CheckMenuItem( pPopup->m_hMenu, ID_NEW, MF_CHECKED );
  31. }
  32. class CMyWinApp : public CWinApp{
  33. public:
  34. virtual BOOL InitInstance( );
  35. };
  36. BOOL CMyWinApp::InitInstance( ){
  37. CMyFrameWnd* pFrame = new CMyFrameWnd;
  38. pFrame->Create(NULL, "MFCCreate");
  39. m_pMainWnd = pFrame;
  40. pFrame->ShowWindow( SW_SHOW );
  41. pFrame->UpdateWindow( );
  42. return TRUE;
  43. }
  44. CMyWinApp theApp;

效果:

四.MFC工具栏以及两大机制:

工具栏:

相关类:

工具栏的使用:

代码:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. #include <afxext.h>
  4. class CMyFrameWnd : public CFrameWnd{
  5. DECLARE_MESSAGE_MAP( )
  6. public:
  7. afx_msg void OnNew( );
  8. afx_msg void OnSet( );
  9. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  10. public:
  11. CToolBar toolbar;
  12. };
  13. BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd )
  14. ON_COMMAND( ID_SET, OnSet)
  15. ON_COMMAND( ID_NEW, OnNew )
  16. ON_WM_CREATE()
  17. END_MESSAGE_MAP()
  18. void CMyFrameWnd::OnSet( ){
  19. AfxMessageBox( "绿色工具按钮被点击" );
  20. }
  21. int CMyFrameWnd::OnCreate( LPCREATESTRUCT pcs ){
  22. toolbar.CreateEx( this, TBSTYLE_FLAT, WS_CHILD|WS_VISIBLE|CBRS_ALIGN_TOP|CBRS_GRIPPER);
  23. toolbar.LoadToolBar( IDR_TOOLBAR1 );
  24. //想停哪儿
  25. toolbar.EnableDocking( CBRS_ALIGN_ANY );
  26. //允许停哪儿
  27. this->EnableDocking( CBRS_ALIGN_ANY );
  28. //临时停哪儿
  29. this->DockControlBar( &toolbar, AFX_IDW_DOCKBAR_BOTTOM );
  30. return CFrameWnd::OnCreate( pcs );
  31. }
  32. void CMyFrameWnd::OnNew(){
  33. AfxMessageBox( "新建菜单项被点击" );
  34. }
  35. class CMyWinApp : public CWinApp{
  36. public:
  37. virtual BOOL InitInstance( );
  38. };
  39. BOOL CMyWinApp::InitInstance(){
  40. CMyFrameWnd* pFrame = new CMyFrameWnd;
  41. pFrame->Create( NULL, "MFCToolBar", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault,
  42. NULL, (CHAR*)IDR_MENU1);
  43. m_pMainWnd = pFrame;
  44. pFrame->ShowWindow( SW_SHOW );
  45. pFrame->UpdateWindow( );
  46. return TRUE;
  47. }
  48. CMyWinApp theApp;
运行时类信息机制:

在程序运行过程中可以获知对象的类的相关信息(例如:对象是否属于某个类)

使用:

代码:

  1. #include <afxwin.h>
  2. #include <iostream>
  3. using namespace std;
  4. class CAnimal : public CObject{
  5. DECLARE_DYNAMIC( CAnimal )
  6. };
  7. IMPLEMENT_DYNAMIC( CAnimal, CObject )
  8. class CDog : public CAnimal{
  9. // DECLARE_DYNAMIC( CDog )
  10. public:
  11. static const CRuntimeClass classCDog;
  12. virtual CRuntimeClass* GetRuntimeClass() const;
  13. };
  14. //IMPLEMENT_DYNAMIC( CDog, CAnimal )
  15. //IMPLEMENT_RUNTIMECLASS(CDog, CAnimal, 0xFFFF, NULL, NULL)
  16. AFX_COMDAT const CRuntimeClass CDog::classCDog = {
  17. "CDog",
  18. sizeof(class CDog),
  19. 0xFFFF,
  20. NULL,
  21. // RUNTIME_CLASS(CAnimal),
  22. ((CRuntimeClass*)(&CAnimal::classCAnimal)),
  23. NULL,
  24. NULL
  25. };
  26. CRuntimeClass* CDog::GetRuntimeClass() const
  27. {
  28. // return RUNTIME_CLASS(CDog);
  29. return ((CRuntimeClass*)(&CDog::classCDog));
  30. }
  31. int main(){
  32. CDog yellowdog;
  33. if( yellowdog.IsKindOf( RUNTIME_CLASS(CWnd) ) ){
  34. cout << "yellowdog is CWnd" << endl;
  35. }else{
  36. cout << "yellowdog isnot CWnd" << endl;
  37. }
  38. return 0;
  39. }

CRuntimeClass的数据结构:

宏展开各部分:

执行过程:

关注这个宏 RUNTIME_CLASS(CDog)

伪代码:

  1. yellowdog.IsKindOf( RUNTIME_CLASS(CDog))//函数内部this为&yellowdog,参数为链表头
  2. {
  3. CRuntimeClass* pClassThis = GetRuntimeClass();
  4. //利用&yellowdog调用宏展开虚函数,获取链表头结点
  5. return pClassThis->IsDerivedFrom(RUNTIME_CLASS(CDog))
  6. //函数内部this为链表头,参数也为链表头
  7. {
  8. const CRuntimeClass* pClassThis = this;//获取链表头
  9. while (pClassThis != NULL)
  10. {
  11. if (pClassThis == RUNTIME_CLASS(CDog))
  12. return TRUE;
  13. pClassThis = pClassThis->m_pBaseClass;
  14. }
  15. return FALSE;
  16. }
  17. }
动态创建机制:

在不知道类名的情况下,将类的对象创建出来。

使用:

  1. #include <afxwin.h>
  2. #include <iostream>
  3. using namespace std;
  4. class CAnimal : public CObject{
  5. DECLARE_DYNAMIC( CAnimal )
  6. };
  7. IMPLEMENT_DYNAMIC( CAnimal, CObject )
  8. class CDog : public CAnimal{
  9. // DECLARE_DYNCREATE( CDog )
  10. public:
  11. static const CRuntimeClass classCDog;
  12. virtual CRuntimeClass* GetRuntimeClass() const;
  13. static CObject* PASCAL CreateObject();
  14. };
  15. //IMPLEMENT_DYNCREATE( CDog, CAnimal )
  16. CObject* PASCAL CDog::CreateObject()
  17. {
  18. return new CDog;
  19. }
  20. AFX_COMDAT const CRuntimeClass CDog::classCDog = {
  21. "CDog",
  22. sizeof(class CDog),
  23. 0xFFFF,
  24. CDog::CreateObject,
  25. RUNTIME_CLASS(CAnimal),
  26. NULL,
  27. NULL
  28. };
  29. CRuntimeClass* CDog::GetRuntimeClass() const
  30. {
  31. return RUNTIME_CLASS(CDog);
  32. }
  33. int main(){
  34. CObject* pob = RUNTIME_CLASS(CDog)->CreateObject( );//对象加工厂
  35. if( pob ){
  36. cout << pob << endl;
  37. }else{
  38. cout << "对象创建失败" << endl;
  39. }
  40. return 0;
  41. }

与运行时类信息机制区别:

代码:

  1. RUNTIME_CLASS(CDog)->CreateObject()//函数内部this为本类(CDog)的静态变量地址(链表头
  2. {
  3. CObject* pObject = (*m_pfnCreateObject)() //CDog::CreateObject
  4. {
  5. return new CDog;
  6. }
  7. return pObject;
  8. }

五.MFC视图和文档

视图窗口:

提供了一个用于显示数据的窗口

相关类:

CView及其子类,父类为CWnd类,封装了关于视图窗口的各种操作,以及和文档类的数据交互。

使用:

命令消息处理顺序:

视图类 -> 框架类 ->应用程序类

对象关系图:

代码:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyView : public CView{
  4. DECLARE_MESSAGE_MAP( )
  5. public:
  6. void OnDraw(CDC* pDC);
  7. afx_msg void OnPaint( );
  8. afx_msg void OnNew( );
  9. };
  10. BEGIN_MESSAGE_MAP( CMyView, CView )
  11. // ON_COMMAND( ID_NEW, OnNew )
  12. // ON_WM_PAINT()
  13. END_MESSAGE_MAP()
  14. void CMyView::OnNew( ){
  15. AfxMessageBox( "视图类处理了WM_COMMAND消息" );
  16. }
  17. void CMyView::OnPaint( ){
  18. PAINTSTRUCT ps = { 0 };
  19. HDC hdc = ::BeginPaint( this->m_hWnd, &ps );
  20. ::TextOut( hdc, 200, 200, "CMyView::OnPaint", strlen("CMyView::OnPaint") );
  21. ::EndPaint( this->m_hWnd, &ps );
  22. }
  23. void CMyView::OnDraw( CDC* pDC ){
  24. pDC->TextOut( 100, 100, "CMyView::OnDraw" );
  25. }
  26. class CMyFrameWnd : public CFrameWnd{
  27. DECLARE_MESSAGE_MAP()
  28. public:
  29. afx_msg void OnPaint( );
  30. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  31. afx_msg void OnNew( );
  32. };
  33. BEGIN_MESSAGE_MAP( CMyFrameWnd, CFrameWnd )
  34. ON_WM_PAINT( )
  35. // ON_COMMAND( ID_NEW, OnNew )
  36. ON_WM_CREATE( )
  37. END_MESSAGE_MAP( )
  38. void CMyFrameWnd::OnNew( ){
  39. AfxMessageBox( "框架类处理了WM_COMMAND消息" );
  40. }
  41. int CMyFrameWnd::OnCreate( LPCREATESTRUCT pcs ){
  42. CMyView* pView = new CMyView;
  43. pView->Create( NULL, "MFCView", WS_CHILD|WS_VISIBLE|WS_BORDER, CRect(0,0,200,200), this,
  44. AFX_IDW_PANE_FIRST );
  45. this->m_pViewActive = pView; //视图类对象地址
  46. return CFrameWnd::OnCreate( pcs );
  47. }
  48. void CMyFrameWnd::OnPaint( ){
  49. PAINTSTRUCT ps = { 0 };
  50. HDC hdc = ::BeginPaint( this->m_hWnd, &ps );
  51. ::TextOut( hdc, 100, 100, "我是框架窗口客户区", strlen("我是框架窗口客户区"));
  52. ::EndPaint( this->m_hWnd, &ps );
  53. }
  54. class CMyWinApp : public CWinApp{
  55. DECLARE_MESSAGE_MAP( )
  56. public:
  57. virtual BOOL InitInstance( );
  58. afx_msg void OnNew( );
  59. };
  60. BEGIN_MESSAGE_MAP(CMyWinApp,CWinApp)
  61. ON_COMMAND( ID_NEW, OnNew )
  62. END_MESSAGE_MAP( )
  63. void CMyWinApp::OnNew( ){
  64. AfxMessageBox( "应用程序类处理了WM_COMMAND消息" );
  65. }
  66. BOOL CMyWinApp::InitInstance( ){
  67. CMyFrameWnd* pFrame = new CMyFrameWnd;
  68. pFrame->Create( NULL, "MFCView", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault,
  69. NULL, (CHAR*)IDR_MENU1);
  70. this->m_pMainWnd = pFrame;
  71. pFrame->ShowWindow( SW_SHOW );
  72. pFrame->UpdateWindow( );
  73. return TRUE;
  74. }
  75. CMyWinApp theApp;
文档类:

程序的创建过程:

代码:

  1. CMyFrameWnd* pFrame = new CMyFrameWnd;
  2. CMyDoc* pDoc = new CMyDoc;
  3. CCreateContext cct;
  4. cct.m_pCurrentDoc = pDoc;//文档类对象地址
  5. cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);//&CMyView::classCMyView
  6. pFrame->LoadFrame(... &cct)//函数内部this为pFrame
  7. {
  8. Create(...,&cct)//函数内部this为pFrame
  9. {
  10. CreateEx(...&cct)//函数内部this为pFrame
  11. {
  12. CREATESTRUCT cs;
  13. ....
  14. cs.lpCreateParams = &cct;
  15. ::CreateWindowEx(...,&cct);//创建主框架窗口
  16. }
  17. }
  18. }
  19. //处理框架窗口的WM_CREATE消息
  20. CFrameWnd::OnCreate( pcs )//函数内部this为pFrame,参数可以获取::CreateWindowEx的12个参数
  21. {
  22. CCreateContext* pContext = (CCreateContext*)pcs->lpCreateParams;//获取&cct
  23. OnCreateHelper(pcs, pContext)//函数内部this为pFrame,pContext===&cct
  24. {
  25. OnCreateClient(pcs, pContext)//函数内部this为pFrame,pContext===&cct
  26. {
  27. CreateView(pContext..)//函数内部this为pFrame,pContext===&cct
  28. {
  29. CWnd* pView = pContext->m_pNewViewClass->CreateObject();
  30. //动态创建视图类对象,并返回对象地址
  31. pView->Create(..,pContext)//函数内部this为pView,pContext===&cct
  32. {
  33. CreateEx(..,pContext//函数内部this为pView,pContext===&cct
  34. {
  35. CREATESTRUCT cs;
  36. ....
  37. cs.lpCreateParams = pContext;//pContext===&cct
  38. ::CreateWindowEx(...,pContext);//创建视图窗口
  39. }
  40. }
  41. }
  42. }
  43. }
  44. }
  45. //处理视图窗口的WM_CREATE消息
  46. CView::OnCreate( pcs )//函数内部this为pView,参数可以获取::CreateWindowEx函数的12个参数
  47. {
  48. CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;//获取&cct
  49. pContext->m_pCurrentDoc->AddView(pView)//函数内部this为pDoc,参数为视图类对象地址
  50. {
  51. m_viewList.AddTail(pView);//文档类对象用一个链表成员变量,保存视图类对象地址
  52. pView->m_pDocument = this;//视图类对象用一个普通成员变量,保存文档类对象地址
  53. }
  54. }

对象关系图:

窗口切分:

代码:

  1. #include <afxwin.h>
  2. #include <afxext.h>
  3. #include "resource.h"
  4. class CMyDoc : public CDocument{
  5. };
  6. class CMyView : public CView{
  7. DECLARE_DYNCREATE( CMyView ) //动态创建机制
  8. DECLARE_MESSAGE_MAP( )
  9. public:
  10. virtual void OnDraw(CDC* pDC);
  11. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  12. };
  13. IMPLEMENT_DYNCREATE( CMyView, CView )
  14. BEGIN_MESSAGE_MAP( CMyView, CView)
  15. ON_WM_CREATE( )
  16. END_MESSAGE_MAP()
  17. int CMyView::OnCreate( LPCREATESTRUCT pcs ){
  18. return CView::OnCreate( pcs ); //将文档类对象和视图类对象建立关联关系。
  19. }
  20. void CMyView::OnDraw( CDC* pDC ){
  21. pDC->TextOut( 100, 100, "我是视图窗口" );
  22. }
  23. class CMyFrameWnd : public CFrameWnd{
  24. DECLARE_MESSAGE_MAP( )
  25. public:
  26. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  27. afx_msg void OnPaint( );
  28. virtual BOOL OnCreateClient( LPCREATESTRUCT pcs, CCreateContext* pContext);
  29. CSplitterWnd split;//不规则框架窗口
  30. };
  31. BEGIN_MESSAGE_MAP( CMyFrameWnd, CFrameWnd )
  32. ON_WM_PAINT( )
  33. ON_WM_CREATE( )
  34. END_MESSAGE_MAP( )
  35. BOOL CMyFrameWnd::OnCreateClient( LPCREATESTRUCT pcs, CCreateContext* pContext ){
  36. //创建两个视图窗口
  37. split.CreateStatic( this, 1, 2 );//创建倒日型框架
  38. split.CreateView( 0, 0, RUNTIME_CLASS(CMyView), CSize(100,100), pContext );
  39. split.CreateView( 0, 1, pContext->m_pNewViewClass, CSize(100,100), pContext );
  40. return TRUE;
  41. }
  42. void CMyFrameWnd::OnPaint( ){
  43. PAINTSTRUCT ps = { 0 };
  44. HDC hdc = ::BeginPaint( this->m_hWnd, &ps );
  45. ::TextOut( hdc, 200, 200, "我是框架窗口客户区", strlen("我是框架窗口客户区"));
  46. ::EndPaint( this->m_hWnd, &ps );
  47. }
  48. int CMyFrameWnd::OnCreate( LPCREATESTRUCT pcs ){
  49. return CFrameWnd::OnCreate( pcs );//动态创建视图类对象,并创建视图窗口
  50. }
  51. class CMyWinApp : public CWinApp{
  52. public:
  53. virtual BOOL InitInstance( );
  54. };
  55. BOOL CMyWinApp::InitInstance( ){
  56. CMyFrameWnd* pFrame = new CMyFrameWnd;
  57. CMyDoc* pDoc = new CMyDoc;
  58. CCreateContext cct;
  59. cct.m_pCurrentDoc = pDoc;//文档类对象地址
  60. cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);//&CMyView::classCMyView
  61. pFrame->LoadFrame( IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
  62. m_pMainWnd = pFrame;
  63. pFrame->ShowWindow( SW_SHOW );
  64. pFrame->UpdateWindow( );
  65. return TRUE;
  66. }
  67. CMyWinApp theApp;

命令消息处理顺序:

代码:

  1. //WM_COMMAND消息的路线
  2. OnCommand(wParam, lParam)//函数内部this为pFrame
  3. {
  4. CWnd::OnCommand(..)//函数内部this为pFrame
  5. {
  6. OnCmdMsg(...)//函数内部this为pFrame *****CFrameWnd::OnCmdMsg 起点
  7. {
  8. CView* pView = GetActiveView()//函数内部this为pFrame
  9. {
  10. return this->m_pViewActive;//活动视图窗口对象地址
  11. }对象
  12. pView->OnCmdMsg(..) ===>终点 CCmdTarget::OnCmdMsg 此函数内部thispView
  13. m_pDocument->OnCmdMsg(.)==>终点CCmdTarget::OnCmdMsg 此函数内部this为文档类对象
  14. CWnd::OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部thispFrame
  15. CWinApp* pApp = AfxGetApp();//获取&theApp
  16. pApp->OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部this为&theApp
  17. }
  18. }
  19. }

文档类和视图类关系:

代码:

  1. #include <afxwin.h>
  2. #include <afxext.h>
  3. #include "resource.h"
  4. class CMyDoc : public CDocument{
  5. DECLARE_MESSAGE_MAP( )
  6. public:
  7. afx_msg void OnNew( );
  8. CString str;
  9. };
  10. BEGIN_MESSAGE_MAP( CMyDoc, CDocument )
  11. ON_COMMAND( ID_NEW, OnNew )
  12. END_MESSAGE_MAP( )
  13. void CMyDoc::OnNew( ){
  14. this->str = "hello world"; //接受到的数据。
  15. // this->UpdateAllViews( NULL );//刷新和这个文档类对象(this)关联的所有视图窗口
  16. //this->m_viewList;
  17. POSITION pos = this->GetFirstViewPosition(); //GetFirstXXXPosition
  18. CView* pView = this->GetNextView(pos); //GetNextXXX
  19. this->UpdateAllViews( pView );//刷新和这个文档类对象(this)关联的除了pView指向的视图窗口
  20. }
  21. class CMyView : public CView{
  22. DECLARE_DYNCREATE( CMyView ) //动态创建机制
  23. DECLARE_MESSAGE_MAP( )
  24. public:
  25. virtual void OnDraw(CDC* pDC);
  26. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  27. afx_msg void OnNew( );
  28. };
  29. IMPLEMENT_DYNCREATE( CMyView, CView )
  30. BEGIN_MESSAGE_MAP( CMyView, CView)
  31. // ON_COMMAND( ID_NEW, OnNew )
  32. ON_WM_CREATE( )
  33. END_MESSAGE_MAP()
  34. void CMyView::OnNew( ){
  35. AfxMessageBox( "视图类处理的WM_COMMAND消息" );
  36. }
  37. int CMyView::OnCreate( LPCREATESTRUCT pcs ){
  38. return CView::OnCreate( pcs ); //将文档类对象和视图类对象建立关联关系。
  39. }
  40. void CMyView::OnDraw( CDC* pDC ){
  41. // CMyDoc* pDoc = (CMyDoc*)this->m_pDocument;
  42. CMyDoc* pDoc = (CMyDoc*)this->GetDocument( );
  43. pDC->TextOut( 100, 100, pDoc->str );
  44. }
  45. class CMyFrameWnd : public CFrameWnd{
  46. DECLARE_MESSAGE_MAP( )
  47. public:
  48. afx_msg int OnCreate( LPCREATESTRUCT pcs );
  49. afx_msg void OnPaint( );
  50. virtual BOOL OnCreateClient( LPCREATESTRUCT pcs, CCreateContext* pContext);
  51. CSplitterWnd split;//不规则框架窗口
  52. afx_msg void OnNew( );
  53. };
  54. BEGIN_MESSAGE_MAP( CMyFrameWnd, CFrameWnd )
  55. // ON_COMMAND( ID_NEW, OnNew)
  56. ON_WM_PAINT( )
  57. ON_WM_CREATE( )
  58. END_MESSAGE_MAP( )
  59. void CMyFrameWnd::OnNew( ){
  60. AfxMessageBox( "框架类处理了新建被点击" );
  61. }
  62. BOOL CMyFrameWnd::OnCreateClient( LPCREATESTRUCT pcs, CCreateContext* pContext ){
  63. //创建两个视图窗口
  64. split.CreateStatic( this, 1, 2 );
  65. split.CreateView( 0, 0, RUNTIME_CLASS(CMyView), CSize(100,100), pContext );
  66. split.CreateView( 0, 1, pContext->m_pNewViewClass, CSize(100,100), pContext );
  67. m_pViewActive = (CView*)split.GetPane(0,0);
  68. return TRUE;
  69. }
  70. void CMyFrameWnd::OnPaint( ){
  71. PAINTSTRUCT ps = { 0 };
  72. HDC hdc = ::BeginPaint( this->m_hWnd, &ps );
  73. ::TextOut( hdc, 200, 200, "我是框架窗口客户区", strlen("我是框架窗口客户区"));
  74. ::EndPaint( this->m_hWnd, &ps );
  75. }
  76. int CMyFrameWnd::OnCreate( LPCREATESTRUCT pcs ){
  77. return CFrameWnd::OnCreate( pcs );//动态创建视图类对象,并创建视图窗口
  78. }
  79. class CMyWinApp : public CWinApp{
  80. DECLARE_MESSAGE_MAP( )
  81. public:
  82. virtual BOOL InitInstance( );
  83. afx_msg void OnNew( );
  84. };
  85. BEGIN_MESSAGE_MAP( CMyWinApp, CWinApp )
  86. // ON_COMMAND( ID_NEW, OnNew )
  87. END_MESSAGE_MAP( )
  88. void CMyWinApp::OnNew( ){
  89. AfxMessageBox( "应用程序类处理了WM_COMMAND消息" );
  90. }
  91. BOOL CMyWinApp::InitInstance( ){
  92. CMyFrameWnd* pFrame = new CMyFrameWnd;
  93. CMyDoc* pDoc = new CMyDoc;
  94. CCreateContext cct;
  95. cct.m_pCurrentDoc = pDoc;//文档类对象地址
  96. cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);//&CMyView::classCMyView
  97. pFrame->LoadFrame( IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
  98. m_pMainWnd = pFrame;
  99. pFrame->ShowWindow( SW_SHOW );
  100. pFrame->UpdateWindow( );
  101. return TRUE;
  102. }
  103. CMyWinApp theApp;

六.MFC架构程序

单文档视图架构:

单文档视图架构特点:

只能管理一个文档(只有一个文档类对象)

单文档视图架构使用:

实现:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyDoc : public CDocument{
  4. DECLARE_DYNCREATE( CMyDoc )
  5. };
  6. IMPLEMENT_DYNCREATE( CMyDoc, CDocument )
  7. class CMyView : public CView{
  8. DECLARE_DYNCREATE( CMyView )
  9. public:
  10. virtual void OnDraw( CDC* pDC );
  11. };
  12. IMPLEMENT_DYNCREATE( CMyView, CView )
  13. void CMyView::OnDraw( CDC* pDC ){
  14. pDC->TextOut( 100, 100, "我是视图窗口" );
  15. }
  16. class CMyFrameWnd : public CFrameWnd{
  17. DECLARE_DYNCREATE( CMyFrameWnd )
  18. };
  19. IMPLEMENT_DYNCREATE( CMyFrameWnd, CFrameWnd )
  20. class CMyWinApp : public CWinApp{
  21. public:
  22. virtual BOOL InitInstance( );
  23. };
  24. BOOL CMyWinApp::InitInstance( ){
  25. CSingleDocTemplate* pTemplate = new CSingleDocTemplate( IDR_MENU1,
  26. RUNTIME_CLASS(CMyDoc),
  27. RUNTIME_CLASS(CMyFrameWnd),
  28. RUNTIME_CLASS(CMyView) );
  29. AddDocTemplate( pTemplate );
  30. OnFileNew( );
  31. m_pMainWnd->ShowWindow( SW_SHOW );
  32. m_pMainWnd->UpdateWindow( );
  33. return TRUE;
  34. }
  35. CMyWinApp theApp;

执行过程:

伪代码:

  1. OnFileNew( )//函数内部this为&theApp
  2. {
  3. m_pDocManager->OnFileNew()//函数内部this为文档管理类对象地址
  4. {
  5. CDocTemplate* pTemplate = m_templateList.GetHead();//取出单文档模板类对象地址
  6. pTemplate->OpenDocumentFile()//函数内部this为单文档模板类对象地址
  7. {
  8. OpenDocumentFile(..)//函数内部this为单文档模板类对象地址
  9. {
  10. pDocument = CreateNewDocument()//函数内部this为单文档模板类对象地址
  11. {
  12. CDocument* pDocument = m_pDocClass->CreateObject();
  13. //动态创建文档类对象,并返回对象地址
  14. AddDocument(pDocument)//函数内部this为单文档模板类对象地址
  15. {
  16. m_pOnlyDoc = pDocument;
  17. }
  18. }
  19. pFrame = CreateNewFrame(pDocument..)//函数内部this为单文档模板类对象地址
  20. {
  21. CCreateContext context;
  22. ...
  23. context.m_pCurrentDoc = pDocument;//文档类对象地址
  24. context.m_pNewViewClass = m_pViewClass;//RUNTIME_CLASS(CMyView)
  25. CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
  26. //动态创建框架类对象,并返回对象地址
  27. pFrame->LoadFrame(...., &context);//创建框架窗口
  28. //后续过程看前一天的伪代码
  29. }
  30. }
  31. }
  32. }
  33. }

关于类向导的使用:

类向导可以帮助我们在已有的框架创建基础上再进一步帮我们生成代码。

选择: 位置 ->类向导

再这个里面可以选择要添加的项目,添加到的文件,添加的内容,框架会帮我们生成规范化的内容,我们只需要实现具体细节。

多文档视图架构:

特点:

可以管理多个文档 (可以有多个文档类对象)

多文档视图架构使用:

执行过程:

代码:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyDoc : public CDocument{
  4. DECLARE_DYNCREATE( CMyDoc )
  5. };
  6. IMPLEMENT_DYNCREATE( CMyDoc, CDocument )
  7. class CMyView : public CView{
  8. DECLARE_DYNCREATE( CMyView )
  9. public:
  10. virtual void OnDraw( CDC* pDC );
  11. };
  12. IMPLEMENT_DYNCREATE( CMyView, CView )
  13. void CMyView::OnDraw( CDC* pDC ){
  14. pDC->TextOut( 100, 100, "我是视图窗口" );
  15. }
  16. class CMyChild : public CMDIChildWnd{
  17. DECLARE_DYNCREATE( CMyChild )
  18. };
  19. IMPLEMENT_DYNCREATE( CMyChild, CMDIChildWnd )
  20. class CMyFrameWnd : public CMDIFrameWnd{ //自己造主框架窗口类的对象
  21. };
  22. class CMyWinApp : public CWinApp{//自己造应用程序类的对象
  23. public:
  24. virtual BOOL InitInstance( );
  25. };
  26. BOOL CMyWinApp::InitInstance( ){
  27. CMyFrameWnd* pFrame = new CMyFrameWnd;
  28. pFrame->LoadFrame( IDR_MENU1 );
  29. m_pMainWnd = pFrame;
  30. pFrame->ShowWindow( SW_SHOW );
  31. pFrame->UpdateWindow( );
  32. CMultiDocTemplate* pTemplate = new CMultiDocTemplate( IDR_MENU2,
  33. RUNTIME_CLASS(CMyDoc),
  34. RUNTIME_CLASS(CMyChild),
  35. RUNTIME_CLASS(CMyView));
  36. AddDocTemplate( pTemplate );
  37. OnFileNew( );//创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
  38. OnFileNew( );//创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
  39. OnFileNew( );//创建文档类对象,创建子框架类对象,创建子框架窗口,创建视图类对象,创建视图窗口,文档类对象和视图类对象关联
  40. return TRUE;
  41. }
  42. CMyWinApp theApp;
MFC绘图:

绘图相关类:

伪代码:

  1. 绘图相关的
  2. ***********************************************
  3. CPaintDC dc(pView) === CPaintDC::CPaintDC(...)//函数内部this为&dc
  4. {
  5. Attach(::BeginPaint(pView->m_hWnd, &m_ps))//函数内部this为&dc
  6. {
  7. m_hDC = hDC;//将BeginPaint获取的绘图设备句柄 保存到dc对象的一个成员变量中
  8. SetAttribDC(m_hDC)//函数内部this为&dc
  9. {
  10. m_hAttribDC = m_hDC;//dc对象的另一个成员变量也保存了绘图设备句柄
  11. }
  12. }
  13. }
  14. CPen pen(PS_SOLID, 2, RGB(255,0,0)) === CPen::CPen(PS_SOLID, 2, RGB(255,0,0))
  15. //函数内部this &pen
  16. {
  17. Attach(::CreatePen(PS_SOLID, 2, RGB(255,0,0)))//函数内部this &pen
  18. {
  19. m_hObject = hObject;//将::CreatePen获取的画笔句柄,保存到pen对象的一个成员变量中
  20. }
  21. }

view类:


  1. // MFCDrawView.cpp : implementation of the CMFCDrawView class
  2. //
  3. #include "stdafx.h"
  4. // SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
  5. // and search filter handlers and allows sharing of document code with that project.
  6. #ifndef SHARED_HANDLERS
  7. #include "MFCDraw.h"
  8. #endif
  9. #include "MFCDrawDoc.h"
  10. #include "MFCDrawView.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #endif
  14. // CMFCDrawView
  15. IMPLEMENT_DYNCREATE(CMFCDrawView, CView)
  16. BEGIN_MESSAGE_MAP(CMFCDrawView, CView)
  17. // Standard printing commands
  18. ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
  19. ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
  20. ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
  21. ON_WM_PAINT()
  22. ON_COMMAND(ID_CLIENT, &CMFCDrawView::OnClient)
  23. ON_COMMAND(ID_PEN, &CMFCDrawView::OnPen)
  24. ON_COMMAND(ID_BRUSH, &CMFCDrawView::OnBrush)
  25. ON_COMMAND(ID_FONT, &CMFCDrawView::OnFont)
  26. ON_COMMAND(ID_BMP, &CMFCDrawView::OnBmp)
  27. END_MESSAGE_MAP()
  28. // CMFCDrawView construction/destruction
  29. CMFCDrawView::CMFCDrawView()
  30. {
  31. // TODO: add construction code here
  32. }
  33. CMFCDrawView::~CMFCDrawView()
  34. {
  35. }
  36. BOOL CMFCDrawView::PreCreateWindow(CREATESTRUCT& cs)
  37. {
  38. // TODO: Modify the Window class or styles here by modifying
  39. // the CREATESTRUCT cs
  40. return CView::PreCreateWindow(cs);
  41. }
  42. // CMFCDrawView drawing
  43. void CMFCDrawView::OnDraw(CDC* /*pDC*/)
  44. {
  45. CMFCDrawDoc* pDoc = GetDocument();
  46. ASSERT_VALID(pDoc);
  47. if (!pDoc)
  48. return;
  49. // TODO: add draw code for native data here
  50. }
  51. // CMFCDrawView printing
  52. BOOL CMFCDrawView::OnPreparePrinting(CPrintInfo* pInfo)
  53. {
  54. // default preparation
  55. return DoPreparePrinting(pInfo);
  56. }
  57. void CMFCDrawView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  58. {
  59. // TODO: add extra initialization before printing
  60. }
  61. void CMFCDrawView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  62. {
  63. // TODO: add cleanup after printing
  64. }
  65. // CMFCDrawView diagnostics
  66. #ifdef _DEBUG
  67. void CMFCDrawView::AssertValid() const
  68. {
  69. CView::AssertValid();
  70. }
  71. void CMFCDrawView::Dump(CDumpContext& dc) const
  72. {
  73. CView::Dump(dc);
  74. }
  75. CMFCDrawDoc* CMFCDrawView::GetDocument() const // non-debug version is inline
  76. {
  77. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCDrawDoc)));
  78. return (CMFCDrawDoc*)m_pDocument;
  79. }
  80. #endif //_DEBUG
  81. // CMFCDrawView message handlers
  82. void CMFCDrawView::OnPaint()
  83. {
  84. CPaintDC dc(this); //::BeginPaint
  85. // dc.Rectangle( 100, 100, 300, 300 );//::Rectangle(...)
  86. // ::Rectangle( dc.m_hDC, 100, 100, 300, 300 );
  87. }
  88. void CMFCDrawView::OnClient()
  89. {
  90. CClientDC dc(this);
  91. dc.Ellipse( 300, 300, 500, 500 );
  92. }
  93. void CMFCDrawView::OnPen()
  94. {
  95. CClientDC dc( this );
  96. CPen pen(PS_SOLID, 2, RGB(255,0,0));
  97. // CPen* oldpen = dc.SelectObject( &pen );
  98. HGDIOBJ nOldPen = ::SelectObject( dc.m_hDC, pen.m_hObject );
  99. // dc.Rectangle( 100, 100, 300, 300 );
  100. ::Rectangle( dc.m_hDC, 100, 100, 300, 300 );
  101. // dc.SelectObject( oldpen );
  102. ::SelectObject( dc.m_hDC, nOldPen );
  103. // pen.DeleteObject( );
  104. ::DeleteObject( pen.m_hObject );
  105. }
  106. void CMFCDrawView::OnBrush()
  107. {
  108. CClientDC dc(this);
  109. CBrush brush(RGB(0,255,0));
  110. CBrush* oldbrush = dc.SelectObject( &brush );
  111. dc.Rectangle( 100, 100, 300, 300 );
  112. dc.SelectObject( oldbrush );
  113. brush.DeleteObject( );
  114. }
  115. void CMFCDrawView::OnFont()
  116. {
  117. CClientDC dc( this );
  118. CFont font;
  119. font.CreatePointFont(300, "黑体");//::CreateFont(..............)
  120. CFont* oldfont = dc.SelectObject( &font );
  121. dc.TextOut( 100, 100, "hello");
  122. dc.SelectObject( oldfont );
  123. font.DeleteObject();
  124. }
  125. void CMFCDrawView::OnBmp()
  126. {
  127. //添加位图资源(操作资源无需写代码)
  128. //创建一个和当前DC,相匹配的内存DC
  129. CClientDC dc( this );
  130. CDC memdc;
  131. memdc.CreateCompatibleDC( &dc ); //::CreateCompatibleDC
  132. //将位图的数据送给内存DC
  133. CBitmap bmp;
  134. bmp.LoadBitmap( IDB_BITMAP1 ); //::LoadBitmap
  135. CBitmap* oldbmp = memdc.SelectObject( &bmp );//::SelectObject
  136. //成像
  137. dc.BitBlt( 100, 100, 48, 48, &memdc, 0, 0, SRCCOPY );//::BitBlt
  138. //将位图数据要回来
  139. memdc.SelectObject( oldbmp );//::SelectObject
  140. //销毁位图
  141. bmp.DeleteObject( );//::DeleteObject
  142. //销毁内存DC
  143. memdc.DeleteDC( );//::DeleteDC
  144. }

七、序列化机制:

文件序列化与反序列化:

文件操作相关类:

代码 :

  1. #include <afxwin.h>
  2. #include <iostream>
  3. using namespace std;
  4. void File( ){
  5. CFile file;
  6. file.Open( "E:/MFC/Day07/file.txt", CFile::modeCreate|CFile::modeReadWrite );
  7. char str[] = "hello file";
  8. file.Write( str, strlen(str) );
  9. file.SeekToBegin( );
  10. char buf[256] = { 0 };
  11. long nLen = file.Read( buf, 255 );
  12. cout << buf << ' ' << nLen << endl;
  13. file.Close( );
  14. }
  15. int main(){
  16. File( );
  17. return 0;
  18. }

序列化机制使用:

反序列化机制使用:

代码:

  1. #include <afxwin.h>
  2. #include <iostream>
  3. using namespace std;
  4. void Store( ){//序列化(存储、写)数据
  5. CFile file;
  6. file.Open( "E:/MFC/Day07/serial.txt", CFile::modeCreate | CFile::modeWrite );
  7. CArchive ar(&file, CArchive::store, 4096);//归档类对象,维护缓冲区。
  8. long age = 18;
  9. ar << age;//将18保存当前指向的位置,并向后移动当前指向,相应字节数。
  10. float score = 88.5;
  11. ar << score;//将88.5保存当前指向的位置,并向后移动当前指向,相应字节数。
  12. CString name = "zhangsan";
  13. ar << name;
  14. ar.Close( );
  15. file.Close( );
  16. }
  17. void Load( ){//反序列化(加载/读)
  18. CFile file;
  19. file.Open( "E:/MFC/day07/serial.txt", CFile::modeRead );
  20. CArchive ar( &file, CArchive::load, 4096 );//维护一个buff,大小4096字节
  21. long age;
  22. ar >> age;//当反序列化第一个数据时候,内部将文件中所有数据读入ar维护的buff中
  23. float score;
  24. ar >> score;//当反序列化后续数据时候,不需要到硬盘文件中读取,直接到ar维护的buff中读取
  25. CString name;
  26. ar >> name;//当反序列化后续数据时候,不需要到硬盘文件中读取,直接到ar维护的buff中读取
  27. ar.Close( );
  28. file.Close( );
  29. cout << age << ' ' << score << ' ' << name << endl;
  30. }
  31. int main(){
  32. Store( );
  33. Load( );
  34. return 0;
  35. }

执行过程:

序列化过程:

伪代码:

  1. class CArchive{
  2. enum Mode { store = 0, load = 1…};
  3. BOOL m_nMode; //访问方式
  4. int m_nBufSize; //buff的大小
  5. CFile* m_pFile; //操作的文件对象
  6. BYTE* m_lpBufCur; //当前指向
  7. BYTE* m_lpBufMax; //终止指向
  8. BYTE* m_lpBufStart; //开始指向
  9. ….
  10. }
  11. CFile file;
  12. file.Open( "E:/MFC/Day07/serial.txt", CFile::modeCreate | CFile::modeWrite );
  13. CArchive ar(&file, CArchive::store, 4096) === CArchive::CArchive(&file0 4096)
  14. {
  15. m_nMode = CArchive::store; // 0
  16. m_pFile = &file;//“E:/....serial.txt”
  17. m_nBufSize = 4096;
  18. m_lpBufStart = new BYTE[m_nBufSize];
  19. m_lpBufMax = m_lpBufStart + 4096;
  20. m_lpBufCur = m_lpBufStart;
  21. }
  22. long age = 18;
  23. ar << age === CArchive::operator<<(age)//函数内部this为&ar
  24. {
  25. if (m_lpBufCur + sizeof(LONG) > m_lpBufMax)
  26. {
  27. Flush();
  28. }
  29. *m_lpBufCur = age;
  30. m_lpBufCur += sizeof(LONG);
  31. }
  32. float score = 88.5;
  33. ar << score === CArchive::operator<<(score)//函数内部this为&ar
  34. {
  35. if (m_lpBufCur + sizeof(float) > m_lpBufMax)
  36. {
  37. Flush();
  38. }
  39. *m_lpBufCur = score;//88.5
  40. m_lpBufCur += sizeof(float);
  41. }
  42. CString name = "zhangsan";
  43. ar << name === CArchive::operator<<(name)//函数内部this为&ar
  44. {
  45. AfxWriteStringLength(ar, 8 )
  46. {
  47. ar<<(unsigned char)nLength;//8
  48. }
  49. Write(name, 8)//函数内部this为&ar
  50. {
  51. memcpy_s(m_lpBufCur, (size_t)(m_lpBufMax - m_lpBufCur), name, 8);
  52. m_lpBufCur += 8;
  53. }
  54. }
  55. ar.Close( )//函数内部this为&ar
  56. {
  57. Flush()//函数内部this为&ar
  58. {
  59. &file->Write(m_lpBufStart, ULONG(m_lpBufCur - m_lpBufStart));
  60. m_lpBufCur = m_lpBufStart;//重置当前指向
  61. }
  62. }
  63. m_lpBufCur
  64. 18 88.5 8 zhangsan|
  65. |--------------------------------------------------------------------|
  66. | |
  67. m_lpBufStart m_lpBufMax

反序列化:

序列化类对象:

就是序列化类对象的各个成员变量

序列化类对象的使用:

伪代码:

  1. CFile file;
  2. file.Open("E:/MFC/Day08/serial.txt", CFile::modeCreate|CFile::modeWrite);
  3. CArchive ar(&file, CArchive::store, 4096);//归档类对象,维护缓冲区。
  4. CMyDoc data(18, 88.5, "zhangsan");
  5. ar << &data === operator<<(ar, const &data)
  6. {
  7. ar.WriteObject(&data)//函数内部this为&ar
  8. {
  9. CRuntimeClass* pClassRef = &data->GetRuntimeClass();//文档类静态变量
  10. WriteClass(pClassRef);//将类的相关信息(类名/类大小/类版本)存入ar维护的buff中
  11. (&data)->Serialize(ar)//函数内部this为&data
  12. {
  13. ar << this->m_age << this->m_score << this->m_name; //序列化基本类型变量
  14. }
  15. }
  16. }
  17. CFile file;
  18. file.Open( "E:/MFC/day08/serial.txt", CFile::modeRead );
  19. CArchive ar( &file, CArchive::load, 4096 );//维护一个buff,大小4096字节
  20. CMyDoc* pdata = NULL;//????????????
  21. ar >> pdata === operator>>(ar, pdata)
  22. {
  23. pdata = ar.ReadObject(RUNTIME_CLASS(CMyDoc))//函数内部this为&ar
  24. {
  25. CRuntimeClass* pClassRef = ReadClass(RUNTIME_CLASS(CMyDoc),...);
  26. //从文件读取 类的相关信息,和 RUNTIME_CLASS(CMyDoc)中信息进行比对,
  27. //如果相同返回RUNTIME_CLASS(CMyDoc),如果不同返回NULL
  28. CObject*pOb = RUNTIME_CLASS(CMyDoc)->CreateObject();
  29. //动态创建CMyDoc类的对象,并返回对象地址
  30. pOb->Serialize(ar)//函数内部this为刚刚创建的CMyDoc类对象(pOb)
  31. {
  32. ar >> m_age >> m_score >> m_name;//反序列化基本类型变量
  33. }
  34. return pOb;
  35. }
  36. }

代码:

  1. #include <afxwin.h>
  2. #include <iostream>
  3. using namespace std;
  4. class CMyDoc : public CDocument{
  5. // DECLARE_SERIAL( CMyDoc )
  6. _DECLARE_DYNCREATE(CMyDoc) //动态创建机制的声明宏
  7. AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, CMyDoc* &pOb);//操作符重载函数
  8. public:
  9. CMyDoc(int age=0, float score=0.0, CString name=""):m_age(age),m_score(score),m_name(name){}
  10. int m_age;
  11. float m_score;
  12. CString m_name;
  13. virtual void Serialize( CArchive& ar );
  14. };
  15. IMPLEMENT_SERIAL( CMyDoc, CDocument, 1 )
  16. /*
  17. 动态创建机制实现宏站出来的东西
  18. CArchive& AFXAPI operator>>(CArchive& ar, CMyDoc* &pOb)
  19. {
  20. pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(CMyDoc));
  21. return ar;
  22. }
  23. */
  24. void CMyDoc::Serialize( CArchive& ar ){
  25. if( ar.IsStoring() ){
  26. ar << this->m_age << this->m_score << this->m_name; //序列化基本类型变量
  27. }else{
  28. ar >> m_age >> m_score >> m_name;//反序列化基本类型变量
  29. }
  30. }
  31. void Store( ){//序列化(存储、写)数据
  32. CFile file;
  33. file.Open("E:/MFC/Day08/serial.txt", CFile::modeCreate|CFile::modeWrite);
  34. CArchive ar(&file, CArchive::store, 4096);//归档类对象,维护缓冲区。
  35. CMyDoc data(18, 88.5, "zhangsan");
  36. ar << &data; //序列化对象,就是将对象的各个成员变量序列化。
  37. ar.Close( );
  38. file.Close( );
  39. }
  40. void Load( ){//反序列化(加载/读)
  41. CFile file;
  42. file.Open( "E:/MFC/day08/serial.txt", CFile::modeRead );
  43. CArchive ar( &file, CArchive::load, 4096 );//维护一个buff,大小4096字节
  44. CMyDoc* pdata = NULL;
  45. ar >> pdata;
  46. ar.Close( );
  47. file.Close( );
  48. cout << pdata->m_age << ' ' << pdata->m_score << ' ' << pdata->m_name << endl;
  49. }
  50. int main(){
  51. Store( );
  52. Load( );
  53. return 0;
  54. }

八.对话框机制

win32创建无模式对话框:
  1. #include <windows.h>
  2. #include "resource.h"
  3. HINSTANCE g_hInstance = 0;
  4. INT CALLBACK DlgProc( HWND hwndlg, UINT msgID, WPARAM wParam, LPARAM lParam ){
  5. switch( msgID ){
  6. case WM_DESTROY:
  7. MessageBox( NULL, "我要死了", "Infor", MB_OK );
  8. break;
  9. case WM_SYSCOMMAND:
  10. if( wParam == SC_CLOSE ){
  11. HWND hWnd = GetParent( hwndlg );
  12. EnableWindow( hWnd ,TRUE );
  13. DestroyWindow( hwndlg );//销毁无模式对话框, 切忌不能EndDialog
  14. // EndDialog( hwndlg, 1001 );//只能隐藏无模式对话框, 可以销毁模式对话框
  15. }
  16. break;
  17. }
  18. return FALSE;//对话框的消息交给真正对话框窗口处理函数处理。
  19. }
  20. void OnNoModel( HWND hWnd ){
  21. EnableWindow( hWnd, FALSE );
  22. // HWND hDlg = CreateDialog( g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc );//直接创建
  23. HRSRC hRs = FindResource( g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG );
  24. HGLOBAL hGl = LoadResource( g_hInstance, hRs );
  25. LPCDLGTEMPLATE pTemplate = (LPCDLGTEMPLATE)LockResource( hGl );
  26. HWND hDlg = CreateDialogIndirect( g_hInstance, pTemplate, hWnd, DlgProc );
  27. ShowWindow( hDlg, SW_SHOW );
  28. }
  29. void OnCommand( HWND hWnd, WPARAM wParam ){
  30. switch(LOWORD(wParam)){
  31. case ID_NOMODEL:
  32. OnNoModel( hWnd );
  33. break;
  34. }
  35. }
  36. //窗口处理函数( 自定义,处理消息)
  37. LRESULT CALLBACK WndProc( HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam ){
  38. switch(msgID){
  39. case WM_COMMAND:
  40. OnCommand( hWnd, wParam );
  41. break;
  42. case WM_DESTROY:
  43. PostQuitMessage( 0 );
  44. break;
  45. }
  46. return DefWindowProc( hWnd, msgID, wParam, lParam );
  47. }
  48. //入口函数
  49. int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow){
  50. g_hInstance = hIns;
  51. //注册窗口类
  52. WNDCLASS wc = { 0 };
  53. wc.cbClsExtra = 0;
  54. wc.cbWndExtra = 0;
  55. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  56. wc.hCursor = NULL;
  57. wc.hIcon = NULL;
  58. wc.hInstance = hIns;
  59. wc.lpfnWndProc = WndProc;
  60. wc.lpszClassName = "Main";
  61. wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);//(CHAR*)IDR_MENU1;
  62. wc.style = CS_HREDRAW | CS_VREDRAW;
  63. RegisterClass( &wc );//将以上所有赋值全部写入操作系统。
  64. //在内存创建窗口
  65. HWND hWnd = CreateWindowEx( 0, "Main", "window", WS_OVERLAPPEDWINDOW,
  66. 100, 100, 500, 500, NULL, NULL, hIns, NULL );
  67. //显示窗口
  68. ShowWindow( hWnd, SW_SHOW );
  69. UpdateWindow( hWnd );
  70. //消息循环
  71. MSG nMsg = { 0 };
  72. while( GetMessage(&nMsg,NULL,0,0) ){
  73. TranslateMessage( &nMsg );
  74. DispatchMessage( &nMsg );//将消息交给窗口处理函数来处理。
  75. }
  76. return 0;
  77. }
MFC对话框:

分类:模式对话框(假)、无模式对话框

参与架构的类: CDialog、CWinApp

无模式对话框:

执行过程:

伪代码:

  1. AFX_MODULE_STATE aaa;//当前程序模块状态信息
  2. AFX_MODULE_THREAD_STATE bbb; //当前程序线程状态信息
  3. CWinApp::CWinApp()//构造全局对象CMyWinApp theApp
  4. {
  5. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  6. //获取全局变量&aaa
  7. AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
  8. //获取全局变量&bbb
  9. pThreadState->m_pCurrentWinThread = this;//将&theApp保存到bbb的一个成员中
  10. AfxGetThread()
  11. {
  12. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//获取&bbb
  13. CWinThread* pThread = pState->m_pCurrentWinThread;
  14. return pThread;//返回的为&theApp
  15. }
  16. pModuleState->m_pCurrentWinApp = this;//将&theApp保存到aaa的一个成员中
  17. AfxGetApp()
  18. {
  19. return AfxGetModuleState()->m_pCurrentWinApp//返回&theApp
  20. }
  21. }
  22. 进入入口函数
  23. WinMain(...)
  24. {
  25. AfxWinMain(..)
  26. {
  27. CWinThread* pThread = AfxGetThread();
  28. CWinApp* pApp = AfxGetApp();//获取&theApp
  29. pApp->InitApplication();//利用theApp调用应用程序类的成员 虚函数(初始化)
  30. pThread->InitInstance()//利用theApp调用应用程序类的成员 虚函数(创建并显示无模式对话框)
  31. {
  32. CMyDlg* pdlg = new CMyDlg;
  33. pdlg->Create( IDD_DIALOG1 )//函数内部this为pdlg(自己new的对话框类对象地址)
  34. {
  35. CDialog::Create(MAKEINTRESOURCE(IDD_DIALOG1), ..)//函数内部this为pdlg
  36. {
  37. HRSRC hResource = ::FindResource(hInst, lpszTemplateName, RT_DIALOG);
  38. HGLOBAL hTemplate = LoadResource(hInst, hResource);
  39. //以上两行代码,查找并加载对话框资源
  40. CreateIndirect(MAKEINTRESOURCE(IDD_DIALOG1), ...)
  41. {
  42. LPCDLGTEMPLATE lpDialogTemplate = LockResource(hDialogTemplate);
  43. CreateIndirect(lpDialogTemplate..)
  44. {
  45. CreateDlgIndirect(...)
  46. {
  47. ::CreateDialogIndirect(...);//以间接方式创建无模式对话框
  48. }
  49. }
  50. }
  51. }
  52. }
  53. }
  54. pThread->Run()//函数内部this为&theApp
  55. {
  56. CWinThread::Run()//函数内部this为&theApp
  57. {
  58. for (;;)
  59. {
  60. while(没有消息时)
  61. {
  62. OnIdle(..);//空闲处理(虚函数)
  63. }
  64. do
  65. {
  66. if(::GetMessage抓到WM_QUIT消息)
  67. return ExitInstance(..);//善后处理(虚函数)
  68. }while(...)
  69. }
  70. }
  71. }
  72. }
  73. }
  74. ******************************
  75. 父类,处理点击OK按钮发出的WM_COMMAND消息
  76. ******************************
  77. CDialog::OnOK()
  78. {
  79. EndDialog(IDOK)
  80. {
  81. ::EndDialog(m_hWnd, nResult);//只能将无模式对话框隐藏
  82. }
  83. }

代码:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyDlg : public CDialog{
  4. DECLARE_MESSAGE_MAP()
  5. public:
  6. void OnZjwOK();
  7. void OnZjwCancel( );
  8. };
  9. BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
  10. ON_COMMAND( IDOK, OnZjwOK )
  11. ON_COMMAND( IDCANCEL, OnZjwCancel )
  12. END_MESSAGE_MAP()
  13. void CMyDlg::OnZjwCancel( ){
  14. // CDialog::OnCancel( );
  15. this->DestroyWindow( );
  16. }
  17. void CMyDlg::OnZjwOK(){
  18. // CDialog::OnOK();//只能将无模式对话框隐藏,并没有销毁。
  19. ::DestroyWindow( this->m_hWnd );
  20. }
  21. class CMyWinApp : public CWinApp{
  22. public:
  23. virtual BOOL InitInstance( );
  24. };
  25. BOOL CMyWinApp::InitInstance( ){
  26. CMyDlg* pdlg = new CMyDlg;
  27. pdlg->Create( IDD_DIALOG1 );
  28. m_pMainWnd = pdlg;
  29. pdlg->ShowWindow( SW_SHOW );
  30. return TRUE;
  31. }
  32. CMyWinApp theApp;

模式对话框:

执行过程:

伪代码:

  1. AFX_MODULE_STATE aaa;//当前程序模块状态信息
  2. AFX_MODULE_THREAD_STATE bbb; //当前程序线程状态信息
  3. CWinApp::CWinApp()//构造全局对象CMyWinApp theApp
  4. {
  5. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  6. //获取全局变量&aaa
  7. AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
  8. //获取全局变量&bbb
  9. pThreadState->m_pCurrentWinThread = this;//将&theApp保存到bbb的一个成员中
  10. AfxGetThread()
  11. {
  12. AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//获取&bbb
  13. CWinThread* pThread = pState->m_pCurrentWinThread;
  14. return pThread;//返回的为&theApp
  15. }
  16. pModuleState->m_pCurrentWinApp = this;//将&theApp保存到aaa的一个成员中
  17. AfxGetApp()
  18. {
  19. return AfxGetModuleState()->m_pCurrentWinApp//返回&theApp
  20. }
  21. }
  22. 进入入口函数
  23. WinMain(...)
  24. {
  25. AfxWinMain(..)
  26. {
  27. CWinThread* pThread = AfxGetThread();
  28. CWinApp* pApp = AfxGetApp();//获取&theApp
  29. pApp->InitApplication();//利用theApp调用应用程序类的成员 虚函数(初始化)
  30. pThread->InitInstance()
  31. {
  32. CMyDlg dlg===CDialog(IDD)//函数内部this为&dlg
  33. {
  34. m_lpszTemplateName=MAKEINTRESOURCE(IDD)//将对话框资源ID保存dlg的一个成员中
  35. }
  36. m_pMainWnd = &dlg;
  37. dlg.DoModal( )//函数内部this为&dlg
  38. {
  39. HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
  40. hDialogTemplate = LoadResource(hInst, hResource);
  41. lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);
  42. //以上三行代码,查找加载并锁定对话框资源
  43. HWND hWndParent = PreModal();//获取父窗口的句柄
  44. ::EnableWindow(hWndParent, FALSE);//将父窗口设置为不可用状态
  45. CreateDlgIndirect(...);//间接方式创建无模式对话框
  46. RunModalLoop(...)//函数内部this为&dlg
  47. {
  48. for (;;) //消息循环
  49. {
  50. while(没有消息){ 空闲处理 }
  51. do{
  52. 消息循环的相关函数;
  53. if (!ContinueModal())//函数内部this为&dlg(m_nFlags(24/8) & 0x0010)
  54. goto ExitModal;
  55. }while(....);
  56. }
  57. ExitModal
  58. return m_nModalResult;
  59. }
  60. }
  61. ::EnableWindow(hWndParent, TRUE);//将父窗口设置为可用
  62. DestroyWindow();//销毁无模式对话框
  63. return m_nModalResult;//????dlg的一个成员变量
  64. }
  65. }
  66. }
  67. 01000
  68. 10000
  69. --------
  70. 00000
  71. ******************************
  72. 父类,处理点击OK按钮发出的WM_COMMAND消息
  73. ******************************
  74. CDialog::OnOK()//函数内部this为&dlg
  75. {
  76. EndDialog(IDOK) //参数为1
  77. {
  78. EndModalLoop(IDOK)//函数内部this为&dlg
  79. {
  80. m_nModalResult = IDOK; // 1
  81. m_nFlags = 8;
  82. }
  83. ::EndDialog(m_hWnd, nResult);//只能将无模式对话框隐藏
  84. }
  85. }
  86. CDialog::OnCancel()//函数内部this为&dlg
  87. {
  88. EndDialog(IDCANCEL) //参数为2
  89. {
  90. EndModalLoop(IDCANCEL)//函数内部this为&dlg
  91. {
  92. m_nModalResult = IDCANCEL; // 1
  93. m_nFlags = 8;
  94. }
  95. ::EndDialog(m_hWnd, nResult);//只能将无模式对话框隐藏
  96. }
  97. }

代码:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyDlg : public CDialog{
  4. public:
  5. DECLARE_MESSAGE_MAP( )
  6. enum{IDD=IDD_DIALOG1};
  7. public:
  8. afx_msg void OnOK();
  9. CMyDlg() : CDialog(IDD){
  10. }
  11. };
  12. BEGIN_MESSAGE_MAP( CMyDlg, CDialog )
  13. ON_COMMAND( IDOK, OnOK )
  14. END_MESSAGE_MAP( )
  15. void CMyDlg::OnOK( ){
  16. CDialog::OnOK();
  17. }
  18. class CMyWinApp : public CWinApp{
  19. public:
  20. virtual BOOL InitInstance( );
  21. };
  22. BOOL CMyWinApp::InitInstance( ){
  23. CMyDlg dlg;//栈空间
  24. m_pMainWnd = &dlg;
  25. int nRet = dlg.DoModal( );
  26. return FALSE;//不再执行MFC库中安排的Run函数
  27. }
  28. CMyWinApp theApp;

九.MFC控件

对象和控件绑定:

绑定的作用:

与数据类型对象绑定:

与控件类型对象绑定:

控件消息处理:

代码:

  1. #include <afxwin.h>
  2. #include "resource.h"
  3. class CMyDlg : public CDialog{
  4. public:
  5. DECLARE_MESSAGE_MAP( )
  6. enum{IDD=IDD_DIALOG1};
  7. public:
  8. afx_msg void OnOK();
  9. afx_msg void OnBtn1();
  10. afx_msg void OnBtn2();
  11. afx_msg void OnDblClk( );
  12. CMyDlg() : CDialog(IDD){
  13. }
  14. public:
  15. CString m_strEdit;//数据类型对象
  16. CEdit m_ctrlEdit;//控件类型对象
  17. virtual void DoDataExchange( CDataExchange* pDX );
  18. };
  19. BEGIN_MESSAGE_MAP( CMyDlg, CDialog )
  20. ON_BN_CLICKED( IDC_BUTTON1, OnBtn1 )
  21. ON_BN_CLICKED( IDC_BUTTON2, OnBtn2 )
  22. /* { WM_COMMAND, (WORD)BN_CLICKED, (WORD)IDC_BUTTON2, (WORD)IDC_BUTTON2, AfxSigCmd_v,
  23. (static_cast< AFX_PMSG > (OnBtn1)) },*/
  24. ON_BN_CLICKED( IDOK, OnOK)
  25. ON_BN_DOUBLECLICKED( IDC_BUTTON2, OnDblClk)
  26. /* { WM_COMMAND, (WORD)BN_DOUBLECLICKED, (WORD)IDC_BUTTON2, (WORD)IDC_BUTTON2, AfxSigCmd_v,
  27. (static_cast< AFX_PMSG > (OnDblClk)) },*/
  28. END_MESSAGE_MAP( )
  29. void CMyDlg::OnDblClk( ){
  30. AfxMessageBox( "双击了按钮" );
  31. }
  32. void CMyDlg::OnBtn1(){//控件--》数据对象
  33. UpdateData( TRUE );
  34. AfxMessageBox( m_strEdit );
  35. }
  36. void CMyDlg::OnBtn2(){//数据对象--》控件
  37. m_strEdit = "hello world";
  38. UpdateData( FALSE );
  39. }
  40. void CMyDlg::DoDataExchange( CDataExchange* pDX ){
  41. DDX_Text( pDX, IDC_EDIT1, m_strEdit );//调用一系列DDX_xxx函数(类向导自动添加)
  42. DDX_Control( pDX, IDC_EDIT1, m_ctrlEdit );
  43. }
  44. void CMyDlg::OnOK( ){
  45. m_ctrlEdit.MoveWindow(0, 0, 200, 200);
  46. // CDialog::OnOK();
  47. }
  48. class CMyWinApp : public CWinApp{
  49. public:
  50. virtual BOOL InitInstance( );
  51. };
  52. BOOL CMyWinApp::InitInstance( ){
  53. CMyDlg dlg;//栈空间
  54. m_pMainWnd = &dlg;
  55. int nRet = dlg.DoModal( );
  56. return FALSE;//不再执行MFC库中安排的Run函数
  57. }
  58. CMyWinApp theApp;
基本控件:

控件介绍 :

下压式按钮:

编辑框:

复选框按钮:

单选框按钮:

分组框按钮:

文本静态框:

图像静态框:

代码:


  1. // MFCCtrl2Dlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MFCCtrl2.h"
  5. #include "MFCCtrl2Dlg.h"
  6. #include "afxdialogex.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. // CMFCCtrl2Dlg dialog
  11. CMFCCtrl2Dlg::CMFCCtrl2Dlg(CWnd* pParent /*=NULL*/)
  12. : CDialogEx(CMFCCtrl2Dlg::IDD, pParent)
  13. {
  14. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  15. }
  16. void CMFCCtrl2Dlg::DoDataExchange(CDataExchange* pDX)
  17. {
  18. CDialogEx::DoDataExchange(pDX);
  19. DDX_Control(pDX, IDC_CHECK1, m_check);
  20. DDX_Control(pDX, IDC_BUTTON1, m_btn);
  21. DDX_Control(pDX, IDC_RADIO1, m_r1);
  22. DDX_Control(pDX, IDC_RADIO2, m_r2);
  23. DDX_Control(pDX, IDC_GROUP, m_group);
  24. DDX_Control(pDX, IDC_ST, m_st);
  25. DDX_Control(pDX, IDC_PS, m_ps);
  26. }
  27. BEGIN_MESSAGE_MAP(CMFCCtrl2Dlg, CDialogEx)
  28. ON_WM_PAINT()
  29. ON_WM_QUERYDRAGICON()
  30. ON_BN_CLICKED(IDC_BUTTON1, &CMFCCtrl2Dlg::OnClickedButton1)
  31. ON_BN_CLICKED(IDC_CHECK1, &CMFCCtrl2Dlg::OnClickedCheck1)
  32. ON_BN_CLICKED(IDC_RADIO1, &CMFCCtrl2Dlg::OnClickedRadio1)
  33. ON_BN_CLICKED(IDC_RADIO2, &CMFCCtrl2Dlg::OnClickedRadio2)
  34. END_MESSAGE_MAP()
  35. // CMFCCtrl2Dlg message handlers
  36. BOOL CMFCCtrl2Dlg::OnInitDialog()
  37. {
  38. CDialogEx::OnInitDialog();
  39. // Set the icon for this dialog. The framework does this automatically
  40. // when the application's main window is not a dialog
  41. SetIcon(m_hIcon, TRUE); // Set big icon
  42. SetIcon(m_hIcon, FALSE); // Set small icon
  43. // TODO: Add extra initialization here
  44. m_check.SetCheck( TRUE );
  45. m_r1.SetCheck( TRUE );
  46. return TRUE; // return TRUE unless you set the focus to a control
  47. }
  48. // If you add a minimize button to your dialog, you will need the code below
  49. // to draw the icon. For MFC applications using the document/view model,
  50. // this is automatically done for you by the framework.
  51. void CMFCCtrl2Dlg::OnPaint()
  52. {
  53. if (IsIconic())
  54. {
  55. CPaintDC dc(this); // device context for painting
  56. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  57. // Center icon in client rectangle
  58. int cxIcon = GetSystemMetrics(SM_CXICON);
  59. int cyIcon = GetSystemMetrics(SM_CYICON);
  60. CRect rect;
  61. GetClientRect(&rect);
  62. int x = (rect.Width() - cxIcon + 1) / 2;
  63. int y = (rect.Height() - cyIcon + 1) / 2;
  64. // Draw the icon
  65. dc.DrawIcon(x, y, m_hIcon);
  66. }
  67. else
  68. {
  69. CDialogEx::OnPaint();
  70. }
  71. }
  72. // The system calls this function to obtain the cursor to display while the user drags
  73. // the minimized window.
  74. HCURSOR CMFCCtrl2Dlg::OnQueryDragIcon()
  75. {
  76. return static_cast<HCURSOR>(m_hIcon);
  77. }
  78. void CMFCCtrl2Dlg::OnClickedButton1()
  79. {
  80. /*
  81. if( m_check.GetCheck() )
  82. m_check.SetCheck( FALSE );
  83. else
  84. m_check.SetCheck( TRUE );*/
  85. m_check.SetCheck( !m_check.GetCheck() );
  86. m_st.SetWindowText( "hello" );
  87. m_ps.SetBitmap( ::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP2)));
  88. }
  89. void CMFCCtrl2Dlg::OnClickedCheck1()
  90. {
  91. int nState = m_check.GetCheck( );
  92. CString sState;
  93. sState.Format( "%d", nState );
  94. m_btn.SetWindowText( sState );
  95. }
  96. void CMFCCtrl2Dlg::OnClickedRadio1()//男
  97. {
  98. m_r1.SetCheck( TRUE );
  99. m_r2.SetCheck( FALSE );
  100. }
  101. void CMFCCtrl2Dlg::OnClickedRadio2()//女
  102. {
  103. m_r2.SetCheck( TRUE );
  104. m_r1.SetCheck( FALSE );
  105. }

组件效果:

注意:有的组件的默认id为IDC_STATIC,需要修改id,才能在类向导里面找到。

组合框:

分类:简单式组合框/下拉式组合框/下拉列表式组合框

如何选择:

列表框:

代码:


  1. // MFCCtrl3Dlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MFCCtrl3.h"
  5. #include "MFCCtrl3Dlg.h"
  6. #include "afxdialogex.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. // CMFCCtrl3Dlg dialog
  11. CMFCCtrl3Dlg::CMFCCtrl3Dlg(CWnd* pParent /*=NULL*/)
  12. : CDialogEx(CMFCCtrl3Dlg::IDD, pParent)
  13. {
  14. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  15. }
  16. void CMFCCtrl3Dlg::DoDataExchange(CDataExchange* pDX)
  17. {
  18. CDialogEx::DoDataExchange(pDX);
  19. DDX_Control(pDX, IDC_DROPDOWN, m_dropdown);
  20. DDX_Control(pDX, IDC_DROPLIST, m_droplist);
  21. DDX_Control(pDX, IDC_SIMPLE, m_simple);
  22. }
  23. BEGIN_MESSAGE_MAP(CMFCCtrl3Dlg, CDialogEx)
  24. ON_WM_PAINT()
  25. ON_WM_QUERYDRAGICON()
  26. ON_BN_CLICKED(IDC_CLEAR, &CMFCCtrl3Dlg::OnBnClickedClear)
  27. ON_BN_CLICKED(IDC_DEL, &CMFCCtrl3Dlg::OnBnClickedDel)
  28. ON_BN_CLICKED(IDC_TEXT, &CMFCCtrl3Dlg::OnBnClickedText)
  29. ON_BN_CLICKED(IDC_DATA, &CMFCCtrl3Dlg::OnBnClickedData)
  30. ON_CBN_SELCHANGE(IDC_SIMPLE, &CMFCCtrl3Dlg::OnSelchangeSimple)
  31. ON_CBN_EDITCHANGE(IDC_SIMPLE, &CMFCCtrl3Dlg::OnEditchangeSimple)
  32. END_MESSAGE_MAP()
  33. // CMFCCtrl3Dlg message handlers
  34. BOOL CMFCCtrl3Dlg::OnInitDialog()
  35. {
  36. CDialogEx::OnInitDialog();
  37. // Set the icon for this dialog. The framework does this automatically
  38. // when the application's main window is not a dialog
  39. SetIcon(m_hIcon, TRUE); // Set big icon
  40. SetIcon(m_hIcon, FALSE); // Set small icon
  41. for( int i=0; i<100; i++ ){
  42. char szItem[256];
  43. sprintf(szItem, "Item%d", i);
  44. m_simple.AddString( szItem );//追加选项
  45. m_simple.SetItemData( i, 1000+i );
  46. m_dropdown.AddString( szItem );
  47. m_droplist.AddString( szItem );
  48. }
  49. m_simple.SetCurSel( 99 );
  50. m_dropdown.SetCurSel( 99 );
  51. m_droplist.SetCurSel( 99 );
  52. return TRUE; // return TRUE unless you set the focus to a control
  53. }
  54. // If you add a minimize button to your dialog, you will need the code below
  55. // to draw the icon. For MFC applications using the document/view model,
  56. // this is automatically done for you by the framework.
  57. void CMFCCtrl3Dlg::OnPaint()
  58. {
  59. if (IsIconic())
  60. {
  61. CPaintDC dc(this); // device context for painting
  62. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  63. // Center icon in client rectangle
  64. int cxIcon = GetSystemMetrics(SM_CXICON);
  65. int cyIcon = GetSystemMetrics(SM_CYICON);
  66. CRect rect;
  67. GetClientRect(&rect);
  68. int x = (rect.Width() - cxIcon + 1) / 2;
  69. int y = (rect.Height() - cyIcon + 1) / 2;
  70. // Draw the icon
  71. dc.DrawIcon(x, y, m_hIcon);
  72. }
  73. else
  74. {
  75. CDialogEx::OnPaint();
  76. }
  77. }
  78. // The system calls this function to obtain the cursor to display while the user drags
  79. // the minimized window.
  80. HCURSOR CMFCCtrl3Dlg::OnQueryDragIcon()
  81. {
  82. return static_cast<HCURSOR>(m_hIcon);
  83. }
  84. void CMFCCtrl3Dlg::OnBnClickedClear()
  85. {
  86. // TODO: Add your control notification handler code here
  87. m_simple.ResetContent( );
  88. m_dropdown.ResetContent( );
  89. m_droplist.ResetContent( );
  90. }
  91. void CMFCCtrl3Dlg::OnBnClickedDel()
  92. {
  93. m_simple.DeleteString( m_simple.GetCurSel() );
  94. m_dropdown.DeleteString( m_dropdown.GetCurSel() );
  95. m_droplist.DeleteString( m_droplist.GetCurSel() );
  96. }
  97. void CMFCCtrl3Dlg::OnBnClickedText()
  98. {
  99. //获取选项的文本内容
  100. CString str;
  101. m_simple.GetLBText( m_simple.GetCurSel(), str );
  102. AfxMessageBox( str );
  103. }
  104. void CMFCCtrl3Dlg::OnBnClickedData()
  105. {
  106. DWORD nData = m_simple.GetItemData( m_simple.GetCurSel() );
  107. CString strData;
  108. strData.Format( "附加数据:%d", nData );
  109. AfxMessageBox( strData );
  110. }
  111. void CMFCCtrl3Dlg::OnSelchangeSimple()
  112. {
  113. int nSel = m_simple.GetCurSel();
  114. m_dropdown.SetCurSel( nSel );
  115. m_droplist.SetCurSel( nSel );
  116. }
  117. void CMFCCtrl3Dlg::OnEditchangeSimple()
  118. {
  119. AfxMessageBox( "内容被修改" );
  120. }

滑块控件:

代码:


  1. // MFCCtrlDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MFCCtrl.h"
  5. #include "MFCCtrlDlg.h"
  6. #include "afxdialogex.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. // CMFCCtrlDlg dialog
  11. CMFCCtrlDlg::CMFCCtrlDlg(CWnd* pParent /*=NULL*/)
  12. : CDialogEx(CMFCCtrlDlg::IDD, pParent)
  13. {
  14. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  15. }
  16. void CMFCCtrlDlg::DoDataExchange(CDataExchange* pDX)
  17. {
  18. CDialogEx::DoDataExchange(pDX);
  19. DDX_Control(pDX, IDC_SLIDER1, m_slider);
  20. DDX_Control(pDX, IDC_PROGRESS1, m_pro);
  21. }
  22. BEGIN_MESSAGE_MAP(CMFCCtrlDlg, CDialogEx)
  23. ON_WM_PAINT()
  24. ON_WM_QUERYDRAGICON()
  25. ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, &CMFCCtrlDlg::OnCustomdrawSlider1)
  26. END_MESSAGE_MAP()
  27. // CMFCCtrlDlg message handlers
  28. BOOL CMFCCtrlDlg::OnInitDialog()
  29. {
  30. CDialogEx::OnInitDialog();
  31. // Set the icon for this dialog. The framework does this automatically
  32. // when the application's main window is not a dialog
  33. SetIcon(m_hIcon, TRUE); // Set big icon
  34. SetIcon(m_hIcon, FALSE); // Set small icon
  35. // TODO: Add extra initialization here
  36. m_slider.SetRange( 0, 100 );
  37. m_slider.SetPos( 50 );
  38. m_pro.SetRange( 0, 100 );
  39. m_pro.SetPos( 50 );
  40. return TRUE; // return TRUE unless you set the focus to a control
  41. }
  42. // If you add a minimize button to your dialog, you will need the code below
  43. // to draw the icon. For MFC applications using the document/view model,
  44. // this is automatically done for you by the framework.
  45. void CMFCCtrlDlg::OnPaint()
  46. {
  47. if (IsIconic())
  48. {
  49. CPaintDC dc(this); // device context for painting
  50. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  51. // Center icon in client rectangle
  52. int cxIcon = GetSystemMetrics(SM_CXICON);
  53. int cyIcon = GetSystemMetrics(SM_CYICON);
  54. CRect rect;
  55. GetClientRect(&rect);
  56. int x = (rect.Width() - cxIcon + 1) / 2;
  57. int y = (rect.Height() - cyIcon + 1) / 2;
  58. // Draw the icon
  59. dc.DrawIcon(x, y, m_hIcon);
  60. }
  61. else
  62. {
  63. CDialogEx::OnPaint();
  64. }
  65. }
  66. // The system calls this function to obtain the cursor to display while the user drags
  67. // the minimized window.
  68. HCURSOR CMFCCtrlDlg::OnQueryDragIcon()
  69. {
  70. return static_cast<HCURSOR>(m_hIcon);
  71. }
  72. void CMFCCtrlDlg::OnCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult)
  73. {
  74. LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
  75. int nPos = m_slider.GetPos( );
  76. CString strPos;
  77. strPos.Format( "滑块位置:%d", nPos );
  78. this->SetWindowText( strPos );
  79. m_pro.SetPos( nPos );
  80. *pResult = 0;
  81. }

进度条控件:

文件搜索类:

代码:

  1. #include "stdafx.h"
  2. #include "MFCFind.h"
  3. using namespace std;
  4. void Find( CString path ){
  5. CString strPath = path;
  6. strPath += "/*.*";
  7. CFileFind find;//文件搜索类对象
  8. BOOL goFind = find.FindFile( strPath ); //开启查找
  9. while( goFind ){
  10. goFind = find.FindNextFile( );//找到当前文件,将文件信息保存find对象的成员变量中
  11. CString filename = find.GetFileName( );
  12. CString filepath = find.GetFilePath();
  13. if( find.IsDirectory() && !find.IsDots() ){
  14. cout << "[" << filename << "]" << endl;
  15. Find( filepath );
  16. }else{
  17. cout << filename << endl;
  18. }
  19. }
  20. find.Close( );
  21. }
  22. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  23. {
  24. Find( "c:" );
  25. return 0;
  26. }

列表控件:

代码:


  1. // MFCListDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MFCList.h"
  5. #include "MFCListDlg.h"
  6. #include "afxdialogex.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. // CAboutDlg dialog used for App About
  11. class CAboutDlg : public CDialogEx
  12. {
  13. public:
  14. CAboutDlg();
  15. // Dialog Data
  16. enum { IDD = IDD_ABOUTBOX };
  17. protected:
  18. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  19. // Implementation
  20. protected:
  21. DECLARE_MESSAGE_MAP()
  22. };
  23. CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
  24. {
  25. }
  26. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  27. {
  28. CDialogEx::DoDataExchange(pDX);
  29. }
  30. BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
  31. END_MESSAGE_MAP()
  32. // CMFCListDlg dialog
  33. CMFCListDlg::CMFCListDlg(CWnd* pParent /*=NULL*/)
  34. : CDialogEx(CMFCListDlg::IDD, pParent)
  35. {
  36. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  37. }
  38. void CMFCListDlg::DoDataExchange(CDataExchange* pDX)
  39. {
  40. CDialogEx::DoDataExchange(pDX);
  41. DDX_Control(pDX, IDC_COMBO1, m_combox);
  42. DDX_Control(pDX, IDC_LIST1, m_list);
  43. }
  44. BEGIN_MESSAGE_MAP(CMFCListDlg, CDialogEx)
  45. ON_WM_SYSCOMMAND()
  46. ON_WM_PAINT()
  47. ON_WM_QUERYDRAGICON()
  48. ON_CBN_SELCHANGE(IDC_COMBO1, &CMFCListDlg::OnSelchangeCombo1)
  49. ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CMFCListDlg::OnDblclkList1)
  50. END_MESSAGE_MAP()
  51. // CMFCListDlg message handlers
  52. BOOL CMFCListDlg::OnInitDialog()
  53. {
  54. CDialogEx::OnInitDialog();
  55. // Add "About..." menu item to system menu.
  56. // IDM_ABOUTBOX must be in the system command range.
  57. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  58. ASSERT(IDM_ABOUTBOX < 0xF000);
  59. CMenu* pSysMenu = GetSystemMenu(FALSE);
  60. if (pSysMenu != NULL)
  61. {
  62. BOOL bNameValid;
  63. CString strAboutMenu;
  64. bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
  65. ASSERT(bNameValid);
  66. if (!strAboutMenu.IsEmpty())
  67. {
  68. pSysMenu->AppendMenu(MF_SEPARATOR);
  69. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  70. }
  71. }
  72. // Set the icon for this dialog. The framework does this automatically
  73. // when the application's main window is not a dialog
  74. SetIcon(m_hIcon, TRUE); // Set big icon
  75. SetIcon(m_hIcon, FALSE); // Set small icon
  76. // TODO: Add extra initialization here
  77. m_combox.AddString( "图标" );
  78. m_combox.AddString( "小图标" );
  79. m_combox.AddString( "列表" );
  80. m_combox.AddString( "报表" );
  81. m_combox.SetCurSel( 0 );
  82. m_list.InsertColumn( 0, "名称", LVCFMT_LEFT, 150 );
  83. m_list.InsertColumn( 1, "修改日期", LVCFMT_LEFT, 150 );
  84. m_list.InsertColumn( 2, "类型", LVCFMT_LEFT, 150 );
  85. m_list.InsertColumn( 3, "大小", LVCFMT_LEFT, 150 );
  86. m_list.SetExtendedStyle( LVS_EX_GRIDLINES );//经纬线
  87. CImageList* pImgLst = new CImageList;
  88. pImgLst->Create( IDB_BITMAP1, 24, 1, RGB(255,255,255) );
  89. m_list.SetImageList( pImgLst, LVSIL_NORMAL );//将图像链表应用在列表控件的图标风格中
  90. m_list.SetImageList( pImgLst, LVSIL_SMALL );//将图像链表应用在列表控件的其他风格中
  91. ShowFile("c:");
  92. /*//测试数据
  93. m_list.InsertItem( 0, "目录", 0 );
  94. m_list.SetItemText( 0, 1, "2100.5.7" );
  95. m_list.SetItemText( 0, 2, "Dir" );
  96. m_list.SetItemText( 0, 3, "3M" );
  97. m_list.InsertItem( 1, "文件", 1 );
  98. m_list.SetItemText( 1, 1, "2100.12.17" );
  99. m_list.SetItemText( 1, 2, "File" );
  100. m_list.SetItemText( 1, 3, "13K" );*/
  101. return TRUE; // return TRUE unless you set the focus to a control
  102. }
  103. void CMFCListDlg::ShowFile( CString path ){
  104. m_list.DeleteAllItems( );
  105. CString strPath = path;
  106. strPath += "/*.*";
  107. CFileFind find;//文件搜索类对象
  108. BOOL goFind = find.FindFile( strPath ); //开启查找
  109. int i = 0;
  110. while( goFind ){
  111. goFind = find.FindNextFile( );//找到当前文件,将文件信息保存find对象的成员变量中
  112. CString filename = find.GetFileName( );
  113. CString *filepath = new CString;
  114. *filepath = find.GetFilePath();
  115. if( find.IsDirectory() ){
  116. m_list.InsertItem( i, filename, 0 );
  117. m_list.SetItemData( i, (DWORD)filepath);
  118. }else{
  119. m_list.InsertItem( i, filename, 1 );
  120. }
  121. i++;
  122. }
  123. find.Close( );
  124. }
  125. void CMFCListDlg::OnSysCommand(UINT nID, LPARAM lParam)
  126. {
  127. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  128. {
  129. CAboutDlg dlgAbout;
  130. dlgAbout.DoModal();
  131. }
  132. else
  133. {
  134. CDialogEx::OnSysCommand(nID, lParam);
  135. }
  136. }
  137. // If you add a minimize button to your dialog, you will need the code below
  138. // to draw the icon. For MFC applications using the document/view model,
  139. // this is automatically done for you by the framework.
  140. void CMFCListDlg::OnPaint()
  141. {
  142. if (IsIconic())
  143. {
  144. CPaintDC dc(this); // device context for painting
  145. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  146. // Center icon in client rectangle
  147. int cxIcon = GetSystemMetrics(SM_CXICON);
  148. int cyIcon = GetSystemMetrics(SM_CYICON);
  149. CRect rect;
  150. GetClientRect(&rect);
  151. int x = (rect.Width() - cxIcon + 1) / 2;
  152. int y = (rect.Height() - cyIcon + 1) / 2;
  153. // Draw the icon
  154. dc.DrawIcon(x, y, m_hIcon);
  155. }
  156. else
  157. {
  158. CDialogEx::OnPaint();
  159. }
  160. }
  161. // The system calls this function to obtain the cursor to display while the user drags
  162. // the minimized window.
  163. HCURSOR CMFCListDlg::OnQueryDragIcon()
  164. {
  165. return static_cast<HCURSOR>(m_hIcon);
  166. }
  167. void CMFCListDlg::OnSelchangeCombo1()
  168. {
  169. switch( m_combox.GetCurSel() ){
  170. case 0://图标
  171. m_list.ModifyStyle( LVS_SMALLICON|LVS_LIST|LVS_REPORT, LVS_ICON );
  172. break;
  173. case 1://小图标
  174. m_list.ModifyStyle( LVS_ICON|LVS_LIST|LVS_REPORT, LVS_SMALLICON );
  175. break;
  176. case 2://列表
  177. m_list.ModifyStyle( LVS_ICON|LVS_SMALLICON|LVS_REPORT, LVS_LIST );
  178. break;
  179. case 3://报表
  180. m_list.ModifyStyle( LVS_ICON|LVS_LIST|LVS_SMALLICON, LVS_REPORT );
  181. break;
  182. }
  183. }
  184. void CMFCListDlg::OnDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
  185. {
  186. LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
  187. *pResult = 0;
  188. DWORD nData = m_list.GetItemData( pNMItemActivate->iItem );//双击选项
  189. CString* filepath = (CString*)nData;
  190. if( filepath != NULL )
  191. ShowFile( *filepath );
  192. }

树控件:

代码:


  1. // MFCTreeDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MFCTree.h"
  5. #include "MFCTreeDlg.h"
  6. #include "afxdialogex.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. // CMFCTreeDlg dialog
  11. CMFCTreeDlg::CMFCTreeDlg(CWnd* pParent /*=NULL*/)
  12. : CDialogEx(CMFCTreeDlg::IDD, pParent)
  13. {
  14. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  15. }
  16. void CMFCTreeDlg::DoDataExchange(CDataExchange* pDX)
  17. {
  18. CDialogEx::DoDataExchange(pDX);
  19. DDX_Control(pDX, IDC_TREE1, m_tree);
  20. }
  21. BEGIN_MESSAGE_MAP(CMFCTreeDlg, CDialogEx)
  22. ON_WM_PAINT()
  23. ON_WM_QUERYDRAGICON()
  24. ON_BN_CLICKED(IDC_DEL, &CMFCTreeDlg::OnBnClickedDel)
  25. ON_BN_CLICKED(IDC_TEXT, &CMFCTreeDlg::OnBnClickedText)
  26. END_MESSAGE_MAP()
  27. // CMFCTreeDlg message handlers
  28. BOOL CMFCTreeDlg::OnInitDialog()
  29. {
  30. CDialogEx::OnInitDialog();
  31. // Set the icon for this dialog. The framework does this automatically
  32. // when the application's main window is not a dialog
  33. SetIcon(m_hIcon, TRUE); // Set big icon
  34. SetIcon(m_hIcon, FALSE); // Set small icon
  35. // TODO: Add extra initialization here
  36. CImageList* pImgLst = new CImageList;
  37. pImgLst->Create( IDB_BITMAP1, 12, 1, RGB(255,255,255));
  38. m_tree.SetImageList( pImgLst, LVSIL_NORMAL );
  39. HTREEITEM nRoot = m_tree.InsertItem( "达内集团", 0, 1, NULL );
  40. m_tree.InsertItem( "中关村中心", 2, 3, nRoot );
  41. m_tree.InsertItem( "亚运村中心", 2, 3, nRoot );
  42. m_tree.InsertItem( "天坛中心", 2, 3, nRoot );
  43. m_tree.SetItemHeight( 50 );
  44. return TRUE; // return TRUE unless you set the focus to a control
  45. }
  46. // If you add a minimize button to your dialog, you will need the code below
  47. // to draw the icon. For MFC applications using the document/view model,
  48. // this is automatically done for you by the framework.
  49. void CMFCTreeDlg::OnPaint()
  50. {
  51. if (IsIconic())
  52. {
  53. CPaintDC dc(this); // device context for painting
  54. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  55. // Center icon in client rectangle
  56. int cxIcon = GetSystemMetrics(SM_CXICON);
  57. int cyIcon = GetSystemMetrics(SM_CYICON);
  58. CRect rect;
  59. GetClientRect(&rect);
  60. int x = (rect.Width() - cxIcon + 1) / 2;
  61. int y = (rect.Height() - cyIcon + 1) / 2;
  62. // Draw the icon
  63. dc.DrawIcon(x, y, m_hIcon);
  64. }
  65. else
  66. {
  67. CDialogEx::OnPaint();
  68. }
  69. }
  70. // The system calls this function to obtain the cursor to display while the user drags
  71. // the minimized window.
  72. HCURSOR CMFCTreeDlg::OnQueryDragIcon()
  73. {
  74. return static_cast<HCURSOR>(m_hIcon);
  75. }
  76. void CMFCTreeDlg::OnBnClickedDel()
  77. {
  78. m_tree.DeleteItem(m_tree.GetSelectedItem( ));
  79. }
  80. void CMFCTreeDlg::OnBnClickedText()
  81. {
  82. AfxMessageBox( m_tree.GetItemText( m_tree.GetSelectedItem() ) );
  83. }

MFC 学习笔记的更多相关文章

  1. MFC学习笔记1---准备工作

    什么是MFC MFC,全称Microsoft Foundation Classes,微软基础类库,顾名思义,是微软的攻城狮们将一些常用的基础的Windows API 函数用C++的形式封装成类,简化程 ...

  2. MFC学习笔记(一)

    个人对MFC技术一直都很感兴趣,因为能够做出漂亮绚丽的界面应该是一件十分有成就感的事情. 学习的参考课本为北京博彦科技发展有限责任公司翻译的Jeff Prosise著的<MFC Windows程 ...

  3. 【MFC学习笔记-作业7-小型画图软件】【】

    作业要求: 按下鼠标右键画圆. 按下鼠标左键移动曲线. 丝毫没有思路..网上教程又比这个程序复杂100倍... 好吧 总算找到一个合适的了... 转载至:http://blog.chinaunix.n ...

  4. MFC学习笔记2---简单计算器

    前言 学习了鸡啄米网页的前三部分后,我们就可以做一个小软件出来了,我选择先做一个计算器. 这是Win7系统自带的计算器: 为了提升成就感,我将计算器的大部分内容去除,于是就变成这样: 这样就只剩下了1 ...

  5. MFC学习笔记

    获取窗口句柄 FindWindow               根据窗口名获取 GetSafehWnd                取你程序所在窗口类的句柄 GetActiveWindow     ...

  6. 孙鑫MFC学习笔记13:文档

    1.CArchive类保存内存数据 2.CAchive类重载了>>与<<操作符,类似C++文件流 3.在OnNewDocument中通过SetTitle设置标题 4.字符串资源 ...

  7. 孙鑫MFC学习笔记12:文件读写

    1.指向常量的指针 2.指针常量 3.C语言对文件操作是在缓冲区,在缓冲区满或文件关闭时写入文件 读取相同 4.fflush刷新缓冲区,使缓冲区数据写入文件 5.fseek改变文件指针偏移量 6.st ...

  8. 孙鑫MFC学习笔记4:MFC画图

    1.画线方法 *1.捕获鼠标按下和弹起消息,获取两个点 *2.消息响应,画线 2.在CMainFrame类中的鼠标左键事件得不到响应的原因是CNameView覆盖了CMainFrame 3.注释宏 4 ...

  9. 孙鑫MFC学习笔记3:MFC程序运行过程

    1.MFC中WinMain函数的位置在APPMODUL.cpp APPMODUL.cpp中是_tWinMain,其实_tWinMain是一个宏#define _tWinMain WinMain 2.全 ...

随机推荐

  1. Semaphore-停车场

    模拟20辆车进停车场 停车场容纳总停车量5. 当一辆车进入停车场后,显示牌的剩余车位数响应的减1. 每有一辆车驶出停车场后,显示牌的剩余车位数响应的加1. 停车场剩余车位不足时,车辆只能在外面等待 p ...

  2. ARC125E - Snack (网络流)

    题面 有 N N N 种糖果, M M M 个小孩子,第 i i i 种糖果有 A i A_i Ai​ 个,第 i i i 个孩子不能有超过 B i B_i Bi​ 个同种类型的糖果,第 i i i ...

  3. 【IDEA】IDEA怎么汉化&汉化后怎么转回英文

    ① 英文转中文 1.点击左上角的File,然后选择Setting 2.达到Setting页面选择Plugins 3.在搜索框搜索chinese,选择中文语言包下载 4.找到下载插件,选择勾选上,然后o ...

  4. 从原理剖析带你理解Stream

    摘要:Stream是jdk1.8给我们提供的新特性 本文分享自华为云社区<深入理解Stream之原理剖析>,作者: 李哥技术 . Stream是jdk1.8给我们提供的新特性,主要就是允许 ...

  5. KingbaseESV8R6 垃圾回收原理以及如何预防膨胀

    背景 KingbaseESV8R6支持snapshot too old 那么实际工作中,经常看到表又膨胀了,那么我们讨论一下导致对象膨胀的常见原因有哪些呢? 未开启autovacuum 对于未开启au ...

  6. 不当使用 union all 导致的SQL解析时间过长的问题优化

    在帮助用户优化应用过程中,发现用户大量使用union all 导致SQL解析非常缓慢的问题.考虑到这个问题很有代表意义,我觉得很有必要对于问题进行总结. 一.用户例子 WITH company_use ...

  7. Go常见

    GO基础语法 方法或函数调用时,传入参数一般都是值复制,除非是map.slice.channel.指针类型是引用传递 短的变量声明(Short Variable Declarations),即自动推导 ...

  8. R语言-tidyr和dplyr

    一.安装和加载 1.安装并加载tidyr和dplyr包 install.packages("tidyr") library(tidyr) install.packages(&quo ...

  9. C语言001--hello world编译详解

    1.编写hello.c程序,并编译运行 book@100ask:~/linux/c01$ cat hello.c -n 1 #include <stdio.h> 2 3 int main( ...

  10. .NET 反向代理 YARP 通过编码方式配置域名转发

    前面介绍了 YARP 通过配置文件的方式配置代理转发(传送门),而众所周知,微软的一贯作风就是能通过配置文件做的事情,通过编码的方式也能实现!YARP 也不例外,废话不多说,直接上代码! 首先,参照官 ...