c++ 无法释放内存DC [已关闭]

tag5nh1u  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(178)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

2天前关闭。
Improve this question
这是我做的一个打开BMP图片的程序。当我需要打开一个新文件时,我需要清空上次加载的内存,但总是失败。我不知道哪里出错了。

static BYTE *data;
HDC memDC, winDC;
HBITMAP hBit;
HANDLE hFile;
if (data != NULL) {
  DeleteObject(hBit);

  ReleaseDC(hWnd, memDC); // faild,Invalid DC
  DWORD dwError = GetLastError();
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL, dwError, 0, szBuffer, 255, NULL);
  // DeleteDC(memDC);
  DeleteObject(memDC);
  \\Although the return value indicates success,
      the data memory cannot be released and an exception will be generated
          DWORD dd = GetLastError();
  ReleaseDC(hWnd, winDC);
  dd = GetLastError();

  int ss = ReleaseDC(hWnd, memDC);
  free(data); //产生异常
}
szFile = OpenBmp(hWnd);
if (szFile != NULL) {
  wcscpy_s(fName, lstrlen(szFile) * 2, szFile);
} else
  return NULL;
hFile = CreateFile(fName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL, NULL);
R = ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &num, NULL);
if (R) {
  R = ReadFile(hFile, &fif, sizeof(BITMAPINFOHEADER), &num, NULL);
  winDC = GetDC(hWnd);
  memDC = CreateCompatibleDC(winDC);
  GetClientRect(hWnd, &rect);
  dataSize = bfh.bfSize - bfh.bfOffBits;
  data = (BYTE *)malloc(dataSize);

  pbmi.bmiHeader = fif;
  width = fif.biWidth;
  height = fif.biHeight;

  hBit =
      CreateDIBSection(memDC, &pbmi, DIB_RGB_COLORS, (void **)&data, NULL, 0);
  R = ReadFile(hFile, data, dataSize, &num, NULL);
  SelectObject(memDC, hBit);
  open = TRUE;
  InvalidateRect(hWnd, &rect, TRUE);
}
CloseHandle(hFile);

这是我做的一个打开BMP图片的程序。当我需要打开一个新文件时,我需要清空上次加载的内存,但总是失败。我不知道哪里出错了。

nzk0hqpo

nzk0hqpo1#

ReleaseDC(hWnd, memDC)失败是因为您最初不是从hWnd获得memDC,而是从CreateCompatibleDC()获得的,因此您需要将memDC传递给DeleteDC()(而不是DeleteObject())。
您从hWnd获得了winDC,因此winDC是您需要传递给ReleaseDC()的DC。
此外,您将hBit选择到memDC中,但在将它们都删除之前不能取消选择hBit
此外,您还在泄漏内存,因为CreateDIBSection()用它自己的内存指针覆盖了您的data指针,从而丢失了malloc内存的地址。当hSection参数为NULL时,您不能使用CreateDIBSection()的预分配内存。
除此之外,GDI函数不使用GetLastError()来报告错误,并且您错误地使用了wcscpy_s()
试试这样的方法:

static BYTE *data = NULL;

HDC memDC = NULL, winDC = NULL;
HBITMAP hBit = NULL, hOldBit = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;

...

if (data) {
  data = NULL;
  SelectObject(memDC, hOldBit); hOldBit = NULL;
  DeleteObject(hBit); hBit = NULL;
  DeleteDC(memDC); memDC = NULL;
  ReleaseDC(hWnd, winDC); winDC = NULL;
}

szFile = OpenBmp(hWnd);
if (szFile == NULL) {
  return NULL;
}

wcscpy_s(fName, _countof(wcscpy_s), szFile);
hFile = CreateFile(fName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
  return NULL;
}

R = (ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &num, NULL) && (num == sizeof(BITMAPFILEHEADER)));
if (R) {
    R = (ReadFile(hFile, &fif, sizeof(BITMAPINFOHEADER), &num, NULL) && (num == sizeof(BITMAPINFOHEADER)));
}
if (R) {
  GetClientRect(hWnd, &rect);

  winDC = GetDC(hWnd);
  memDC = CreateCompatibleDC(winDC);

  pbmi.bmiHeader = fif;
  width = fif.biWidth;
  height = fif.biHeight;

  hBit = CreateDIBSection(memDC, &pbmi, DIB_RGB_COLORS, (void**)&data, NULL, 0);
  if (!hBit) {
    data = NULL;
    DeleteDC(memDC); memDC = NULL;
    ReleaseDC(hWnd, winDC); winDC = NULL;
    CloseHandle(hFile);
    return NULL;
  }

  dataSize = bfh.bfSize - bfh.bfOffBits;

  R = (ReadFile(hFile, data, dataSize, &num, NULL) && (num == dataSize));

  hOldBit = (HBITMAP) SelectObject(memDC, hBit);

  open = TRUE;
  InvalidateRect(hWnd, &rect, TRUE);
}

CloseHandle(hFile);

相关问题