首页 > 解决方案 > 将文本设置为大量数据后释放编辑控件堆?

问题描述

在拉入大量数据后,我正在任务管理器中查看我的流程,CEditView然后再设置回少量数据。我注意到提交大小仍然很大。然后我用VMMMap也看到了,所以我在VS2017诊断工具中做了“内存使用”。我看到它最终来自::SetWindowText()电话。所以这显然在堆上分配了一个大缓冲区,但是当我将它设置回一个小量时,分配仍然很大。问题是,有没有一种方法可以让编辑控件释放它不需要的内存来减少少量文本以减少提交的内存?说,我可以在设置新文本之前释放它,它会根据需要分配吗?

谢谢!!

标签: winapimemory-managementcomctl32

解决方案


  // From within CEditView
  
  // based on an answer RbMm using EM_GETHANDLE/EM_SETHANDLE and further
  // from https://stackoverflow.com/questions/5500237/how-to-use-em-sethandle-on-edit-control
 
  // reduce size to 64K if larger than that and not needed
  #define EDITctrlLimitSize 65536  
 
  // check if we should reduce size of buffer
  HLOCAL horgmem = (HLOCAL) SendMessage(EM_GETHANDLE,0,0);
  SIZE_T sizeused=LocalSize(horgmem);
 
  int cbCh = sizeof(TCHAR) > 1 ? sizeof(TCHAR) : IsUsingComCtlV6() ? sizeof(WCHAR) : sizeof(char);
  if (sizeused > EDITctrlLimitSize && (string.GetLength()*cbCh) < EDITctrlLimitSize) {
    // EM_GETHANDLE says to not change the data, yet EM_SETHANDLE tells you to
    // get the handle then LocalFree it, so why not just LocalReAlloc it and set
    // again.
    HLOCAL hnewmem=(HLOCAL) LocalReAlloc(horgmem, EDITctrlLimitSize, LMEM_MOVEABLE);
    if (hnewmem) {
      // zero full buffer because seems like good thing to do
      LPVOID pnewmem=LocalLock(hnewmem);
      if (pnewmem) {
        memset(pnewmem, 0, EDITctrlLimitSize);
        LocalUnlock(hnewmem);
      }

      // viola - process memory reduced.
      SendMessage(EM_SETHANDLE, (WPARAM) hnewmem, 0);
    }
  }
  

推荐阅读