c++ - MFC 打开大文件

标签 c++ mfc

我有一个单文档界面 (SDI) Microsoft 基础类 (MFC) 应用程序,它必须加载一个大文档文件(大约需要 2 分钟)。出于这个原因,我的应用程序在我打开文档时保持无响应。

但是,我希望我的应用程序在打开文档时能够响应。问题是,如果我尝试在线程上加载我的文档,我的 OnopenDocument 函数(在我的文档中)将在我实际打开文档之前返回:

BOOL CmodguiDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
  if (!CDocument::OnOpenDocument(lpszPathName))
    return FALSE;
  start_tread(_open_doc); // just an example
  return TRUE; // Will return before the document will actually be open
}

我怎样才能做到这一点是非锁定的,但只在文档实际打开后才返回?或者我怎样才能至少让我的应用程序在加载文档时响应?

谢谢

最佳答案

创建线程后返回即可。您应该为文档定义一个状态,例如 loadingloaded。当您启动线程时,状态应该是loading。 View 应查看状态并相应地显示。当线程完成加载文档时,它应该向文档发送一条消息。在处理程序中,将状态设置为 loaded 并调用 UpdateAllViews() 以使 View 有机会使用新文档数据进行更新。

示例:这将在文档加载时打印“loading”,并在 View 中完成后打印“loaded”和加载。

enter image description here

在resource.h中:

#define IDD_NotifyDocumentFinished        101

在文档头部:

public:
   enum DocState
   {
      None,
      Failed,
      Loading,
      Loaded
   };

   DocState GetDocState() const {return m_state;}
private:
   DocState m_state;
   void StartLoading();

在文档实现中:

BOOL CMFCDocViewAsyncDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
   if(!CDocument::OnOpenDocument(lpszPathName))
      return FALSE;   

   m_state = Loading;

   StartLoading();

   return TRUE;
}

UINT LongRunningFunction(LPVOID param)
{
   Sleep(3000);

   HWND hWnd = AfxGetApp()->m_pMainWnd->GetSafeHwnd();

   NMHDR hdr = {hWnd, IDD_NotifyDocumentFinished, 0};
   ::SendMessage(hWnd, WM_NOTIFY, 0, reinterpret_cast<LPARAM>(&hdr));

   return 0;
}

void CMFCDocViewAsyncDoc::StartLoading()
{
   AfxBeginThread(&LongRunningFunction, nullptr);
}

BOOL CMFCDocViewAsyncDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
   if(HIWORD(nCode) == WM_NOTIFY)
   {
      WORD wCode = LOWORD(nCode);
      AFX_NOTIFY * notify = reinterpret_cast<AFX_NOTIFY*>(pExtra);
      if(notify->pNMHDR->idFrom == IDD_NotifyDocumentFinished)
      {
         m_state = Loaded;
         UpdateAllViews(nullptr);
      }
   }

   return TRUE;
}

在 View 中:

void CMFCDocViewAsyncView::OnDraw(CDC* pDC)
{
    CMFCDocViewAsyncDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    CMFCDocViewAsyncDoc::DocState state = pDoc->GetDocState();
   CString sstate;
   switch(state)
   {
   case CMFCDocViewAsyncDoc::None:
      sstate = "None";
      break;
   case CMFCDocViewAsyncDoc::Failed:
      sstate = "Failed";
      break;
   case CMFCDocViewAsyncDoc::Loading:
      sstate = "Loading";
      break;
   case CMFCDocViewAsyncDoc::Loaded:
      sstate = "Loaded";
      break;
   }
   pDC->TextOut(50, 50, sstate);
}

更新:也可以在此处查看类似的、更详细的示例 http://www.codeproject.com/Articles/14706/Notifying-the-Document .

关于c++ - MFC 打开大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30436745/

相关文章:

c++ - 如何制作节点图以与 Dijkstra 的最短路径一起使用?

c++ - 什么是 C++ 结构开头的函数列表指针

c++ - 使用模板元编程的位交换功能

c++ - 向 Microsoft 提供有关 MFC 的反馈

user-interface - 如何将测试驱动开发应用于GUI应用程序(VC MFC)?

c++ - 我可以在 MSVC++ 中使用 128 位整数吗?

C++按值而不是按位置删除 vector 元素?

c++ - Linux 上是否有等效的 .def 文件来控制共享库中导出的函数名称?

c++ - 如何在MFC上实现对话泡泡

c++ - CEdit 控件 MFC,将光标置于 SetWindowText 之后的字符串末尾