VS 学习笔记-MFC Appwizard原理

来源:互联网 发布:创建网络ftp平台 编辑:程序博客网 时间:2024/06/06 04:12

1.MFC:microsoft funcation class

2.新建一个MFC工程选择单文档-MFC标准类型的项目,产生出来直接编译就能产生一个窗口。所有的都是类,程序的入口Winmain在哪里呢?在VS安装目录下找到appmodul.cpp设置断点在_twWinMain处发现程序停止。所以新建的MFC程序会自动去调用这里的WinMain函数。

3.选择类视图可以看到:CTestView(窗口类),CTestDoc(文档类),CTesApp(应用程序类),CMainFrame(窗口类),CAboutDlg(窗口类).

打开CTestApp的构造函数:选择CTestApp。在左边框下方点击构造函数CTestApp()设置断点发现:程序先进入构造函数再进入WinMain函数。原因是因为在程序Test.cpp中定义了一个CTestApp类型的全局变量。因为全局变量在进入main之前就分配好了内存空间。



4.如何唯一的表示这个应用程序。在LESSON1中是通过WinMain中分配的实例号来唯一的表示应用程序。而这里是通过创建一个唯一的CTestApp全局对象来表示应用程序本身。用户编写的程序要实例化一个应用程序(全局变量)就必须要构造函数CTestApp(),构造这个子类时就要先构造基类CWinApp()。作为桥梁就使应用程序和微软提供的CWinApp和winmain联系了起来。


5.CWinApp:在appcore.cpp当中。创建一个CTestApp时,会调用基类的构造函数CWinApp(),这个构造函数中的this指针此时是指向派生类对象theApp的指针。因为这时调用的CWinApp()被看做是CTestApp的一部分。


6.AfxWinMain()在WINMAIN.cpp当中。Af:app framework,表示应用程序框架模型,使各个类有机的结合在一起。在主函数中调用initinstance结果会去调用子类的initinstance(),并且在这一部分实现窗口的注册创建,显示和更新。

AfxWinMain(){...CWinThread* pThread=AfxGetThread();CWinApp* pApp=AfxGetApp();//获得一个指向CWinApp的指针,实际上就是指向theApp。if (!pThread->InitInstance())//这里调用子类的InitInstance(){if (pThread->m_pMainWnd != NULL){TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");pThread->m_pMainWnd->DestroyWindow();}nReturnCode = pThread->ExitInstance();goto InitFailure;}nReturnCode = pThread->Run();//调用消息循环...}

CTestApp::InitInstance(){if(!ProcessShellCommand(cmdInfo))//这一部分创建注册窗口  return FALSE;m_pMainWnd->ShowWindow(SW_SHOW);//展示窗口m_pMainWnd->UpdateWindow();//更新窗口return TRUE;}



7.在MAIN函数中会调用注册窗口类函数。

注册窗口类wincore.cpp当中有函数AfxEndDeferGegisterClass.

MFC已经内部自己定义好了不同的窗口类,并不需要用户自己去定义。只需要用户去注册对应的窗口类。

if (fToRegister & AFX_WNDFRAMEORVIEW_REG){// SDI Frame or MDI Child windows or views - normal colorswndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);if (_AfxRegisterWithIcon(&wndcls, _afxWndFrameOrView, AFX_IDI_STD_FRAME))fRegisteredClasses |= AFX_WNDFRAMEORVIEW_REG;}

8.产生窗口

CMainFrame:框架窗口,整个应用程序的窗口。另外还有CView窗口。他们都是从CWnd派生出来的,所以都是窗口类。

正常情况下会在preCreateWindow这里才注册,但因为是是单文档MFC所以注册窗口类提前了。

调用CFramewnd中的Create函数,会进一步调用CWND的CreateEX函数。


用户可以修改CREATESTRUCT结构体调用PreCreateWindow,在创建窗口之前可以有机会去修改默认的窗口外观。


9.消息循环:主函数当中的RUN();

thrdcore.cpp当中有CWinThread::Run()

int CWinThread::Run(){ASSERT_VALID(this);_AFX_THREAD_STATE* pState = AfxGetThreadState();// for tracking the idle time stateBOOL bIdle = TRUE;LONG lIdleCount = 0;// acquire and dispatch messages until a WM_QUIT message is received.for (;;){...// phase2: pump messages while availabledo{// pump message, but quit on WM_QUITif (!PumpMessage())//Get Message, Translate Message, return ExitInstance();...} while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));}}

10.消息循环:主函数当中的RUN();

11.窗口与窗口类

窗口类都是从CWnd派生来的。窗口类其实只是一个句柄。窗口销毁并不代表窗口类销毁。

#include <windows.h>class CWnd{public:BOOL CreateEx(DWORD dwExStyle,//窗口的扩展风格LPCTSTR lpClassName,//指向注册类名的指针LPCTSTR lpWindowName,//指向窗口名称的指针DWORD dwStyle,//窗口风格int x,//窗口的水平位置int y,//窗口的垂直位置int nWidth,//窗口的宽度int nHeight,//窗口的高度HWND hWndParent,//父窗口的句柄HMENU hMenu,//菜单的句柄或是子窗口的标识符HINSTANCE hInstance,//应用程序实例的句柄LPVOID lpParam//指向窗口的创建数据            );BOOL ShowWindow(int nCmdShow);BOOL UpdateWindow();public:HWND m_hWnd;};BOOL CWnd::CreateEx(DWORD dwExStyle,//窗口的扩展风格LPCTSTR lpClassName,//指向注册类名的指针LPCTSTR lpWindowName,//指向窗口名称的指针DWORD dwStyle,//窗口风格int x,//窗口的水平位置int y,//窗口的垂直位置int nWidth,//窗口的宽度int nHeight,//窗口的高度HWND hWndParent,//父窗口的句柄HMENU hMenu,//菜单的句柄或是子窗口的标识符HINSTANCE hInstance,//应用程序实例的句柄LPVOID lpParam)//指向窗口的创建数据{  m_hWnd = ::CreateWindowEx(dwExStyle,lpClassName,lpWindowName,dwStyle,x,y,nWidth,                      nHeight,hWndParent,hMenu,hInstance,lpParam);  if(m_hWnd!=NULL)   return TRUE;  else  return FALSE;}BOOL CWnd::ShowWindow(int nCmdShow){ return::ShowWindow(m_hWnd,nCmdShow);}BOOL CWnd::UpdateWindow(){ return::UpdateWindow(m_hWnd);}int WINAPI WinMain(HINSTANCE hInstance,               HINSTANCE hPrevInstance,   LPSTR lpCmdLine,   int nCmdShow){WNDCLASS wndcls;wndcls.cbClsExtra=0;wndcls.cbWndExtra=0;...RegisterClass(&wndcls);CWnd wnd;wnd.CreateEx(...);wnd.ShowWindow(SW_SHOWNORMAL);wnd.UpdateWindow();...}


12.添加button:

在CMainFrame中添加一个新的成员:CButton m_btn;然后在On_Create()里产生副窗口。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CFrameWnd::OnCreate(lpCreateStruct) == -1)return -1;if (!m_wndStatusBar.Create(this)){TRACE0("未能创建状态栏\n");return -1;      // 未能创建}m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));m_btn.Create(TEXT("nino"),WS_CHILD|BS_DEFPUSHBUTTON,CRect(0,0,100,100),this,9);m_btn.ShowWindow(SW_SHOWNORMAL);return 0;}

如果要在CView里添加button,而CView里没有ON_Create成员函数(用来响应窗口创建消息的函数)。

在CView里右键选择类向导。在消息里选择WM_CREATE并且添加处理程序就在CView里添加了ON_Create函数。














0 0