本帖最后由 SummerGull 于 2022-4-4 22:59 编辑
SID单文档是如何创建的这里需要用到一个VS的插件叫做visual assist助手,因为VS的F12(转到定义)并不能准确的到达指定函数过程中下断点,助手的alt+g 就可以过去。 在InitInstance()下找到 单文档模板对象,并进入构造函数中下断点。 - CSingleDocTemplate* pDocTemplate;
- pDocTemplate = new CSingleDocTemplate(
- IDR_MAINFRAME,
- RUNTIME_CLASS(CMFCApplication8Doc),
- RUNTIME_CLASS(CMainFrame), // 主 SDI 框架窗口
- RUNTIME_CLASS(CMFCApplication8View));
复制代码参数1、菜单资源ID 参数2、文档类对象 参数3、主框架窗口 参数4、视图窗口对象 F5开始调试断点停留在21行代码,进入父类CDocTemplate()的构造函数 - CDocTemplate::CDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
- CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass)
- {
- m_nIDResource = nIDResource;
- m_pDocClass = pDocClass;
- m_pFrameClass = pFrameClass;
- m_pViewClass = pViewClass;
- m_bAutoDelete = TRUE; // usually allocated on the heap
- LoadTemplate();
- }
复制代码关键代码段当前this指针为*pDocTemplate 接着执行下面代码: AddDocTemplate(pDocTemplate); - void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)
- {
- if (m_pDocManager == NULL)
- m_pDocManager = new CDocManager;
- //m_pDocManager是 theApp的一个成员变量
- m_pDocManager->AddDocTemplate(pTemplate);
- }
复制代码- void CDocManager::AddDocTemplate(CDocTemplate* pTemplate)
- {
- pTemplate->LoadTemplate();
- m_templateList.AddTail(pTemplate);
- //这里的this指针是m_pDocManager
- }
复制代码以上代码总结一下做了什么事情: * pDocTemplate-> m_pOnlyDoc = NULL; m_nIDResource = nIDResource; m_pDocClass = pDocClass; m_pFrameClass = pFrameClass; m_pViewClass = pViewClass; m_bAutoDelete = TRUE; theApp-> m_pDocManager->AddDocTemplate(pTemplate);//就是上面的* pDocTemplate ->m_templateList.AddTail(pTemplate); 代码:ProcessShellCommand(cmdInfo)执行 - 以上代码总结一下做了什么事情:
- * pDocTemplate->
- m_pOnlyDoc = NULL;
- m_nIDResource = nIDResource;
- m_pDocClass = pDocClass;
- m_pFrameClass = pFrameClass;
- m_pViewClass = pViewClass;
- m_bAutoDelete = TRUE;
- theApp->
- m_pDocManager->AddDocTemplate(pTemplate);//就是上面的* pDocTemplate
- ->m_templateList.AddTail(pTemplate);
- 代码:ProcessShellCommand(cmdInfo)执行
复制代码AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL); 这条代码发送产生command消息从而执行该消息: case AfxSigCmd_v: // normal command or control notification ASSERT(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED ASSERT(pExtra == NULL); (pTarget->*mmf.pfnCmd_v_v)(); break; 执行函数名:OnFileNew(); m_pDocManager->OnFileNew();//属于theApp的文档管理类成员变量 继续执行:CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead(); theApp->m_pDocManager->m_templateList//因为只有一条链表 获取head = tail 执行代码:pTemplate->OpenDocumentFile(NULL); 执行代码:return OpenDocumentFile(lpszPathName, TRUE, bMakeVisible); - OpenDocumentFile(LPCTSTR lpszPathName, BOOL bAddToMRU, BOOL bMakeVisible)
- {
- CDocument* pDocument = NULL;
- CFrameWnd* pFrame = NULL;
- BOOL bCreated = FALSE; // => doc and frame created
- BOOL bWasModified = FALSE;
- pDocument = CreateNewDocument();
- {
- CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();
- //这里的m_pDocClass是* pDocTemplate的成员变量
- AddDocument(CDocument* pDocument)
- {
- CDocTemplate::AddDocument(pDocument);
- {
- pDocument->m_pDocTemplate = this;
- }
- m_pOnlyDoc = pDocument;
- //* pDocTemplate->m_pOnlyDoc = pDocument;
- }
- return pDocument;
- }
- bCreated = TRUE;
- //上面是创建了一份 pDocument 的对象
- pFrame = CreateNewFrame(pDocument, NULL);//创建一个主框架
- {//参数:CDocument* pDoc, CFrameWnd* pOther
- //下面结构体是关键
- CCreateContext context;
- context.m_pCurrentFrame = pOther;
- context.m_pCurrentDoc = pDoc;
- context.m_pNewViewClass = m_pViewClass;
- context.m_pNewDocTemplate = this;
- CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
- //* pDocTemplate->
- pFrame->LoadFrame(m_nIDResource,WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,NULL, &context);//LoadFrame会通过 context去完成一些自动创建的工作
- {
- Create(lpszClass, strTitle, dwDefaultStyle, rectDefault,pParentWnd, ATL_MAKEINTRESOURCE(nIDResource), 0L, pContext)
- {
- CreateEx(.........., pContext)//立即发送Frame的WM_CREATE消息
- //该消息为取出 CCreateContext* pContext参数
- //CWnd* pView = pContext->m_pNewViewClass->CreateObject();
- //动态创建 视图窗口
- // pView->Create(..,pContext)
- //立即发送 视图WM_CREATE消息
- //CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;
- //视图WM_CREATE消息获取 指针
- //m_viewList.AddTail(pView);pDoc保存视图
- //pView->m_pDocument = this;视图变量保存 pDoc对象地址
- }
- }
- }
- }
复制代码结束,以上是单文档程序的流程
HDC和CDC/HWND和CWnd 都是如何关联的 - CWnd* pWndInit = pThreadState->m_pWndInit;
- //取得主窗口指针
- pWndInit->Attach(hWnd);//开始双向绑定
- {
- CHandleMap* pMap = afxMapHWND(TRUE); //MFC的映射类。无需关注
- pMap->SetPermanent(m_hWnd = hWnd, permOb);
- //这里的m_hWnd是类里面成员函数绑定窗口句柄
- {
- BOOL bEnable = AfxEnableMemoryTracking(FALSE);
- m_permanentMap[(LPVOID)hWnd] = permOb;//permOb这个是主窗口类
- //这里的this指针就是 CHandleMap 映射类的
- //这里用句柄的值作为下标 显然是重载了[]符号
- //这样就形成了映射了
- AfxEnableMemoryTracking(bEnable);
- }
- }
复制代码
|