When should I call DeleteObject () in a bitmap

I am studying some old Win32 / MFC project.

I found the following (pseudo code):

HDC hDC = ::CreateCompatibleDC(hDCWnd); HANDLE hFileMap = ::CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, dwSize, FileMapName); HBITMAP hBmp = ::CreateDIBSection(hDCWnd, &zBI, DIB_RGB_COLORS, &pvNull, hFileMap, 0); ::SelectObject(hDC, hBmp); ::DeleteObject(hBmp); ::CloseHandle(hFileMap); // .. do something with hDC .. ::DeleteDC(hDC); 

It seems strange to me. Can someone explain if it is correct to delete the bitmap and / or close the file descriptor before I do something with DC?

Thanks.

+4
source share
2 answers

No, that is not right. The code calls SelectObject() to select a bitmap in the device context, then calls DeleteObject() in an attempt to delete the bitmap while it is still selected in the device context. In this case, DeleteObject() will fail, so the bitmap will leak.

http://msdn.microsoft.com/en-us/library/dd183539(v=vs.85).aspx

"Do not delete the drawing object (pen or brush) while it is still selected in the device context."

EDIT:

Well, that is interesting. I tried calling DeleteObject() while the bitmap was selected in the device context and it returns 1 for me too. Interestingly, the bitmap is not actually deleted at the moment; calling GetObject() on a "remote" raster file succeeds! However, once the deleted bitmap is selected outside the device context, it is actually deleted; the call to GetObject() fails at this point. I also checked by looking at the counter of the GDI descriptors in the task manager. Thus, it is obvious that DeleteObject() will DeleteObject() deletion if the bitmap is currently selected in the device context, although I do not believe that this is documented somewhere.

 HDC hdc = CreateCompatibleDC(NULL); if (hdc != NULL) { HBITMAP hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SAMPLE)); BITMAP bm = { 0 }; int numBytes; // this succeeds as expected numBytes = GetObject(hBitmap, sizeof(BITMAP), &bm); HBITMAP hOldBitmap = SelectBitmap(hdc, hBitmap); DeleteObject(hBitmap); // this succeeds -- NOT expected! numBytes = GetObject(hBitmap, sizeof(BITMAP), &bm); SelectBitmap(hdc, hOldBitmap); // this fails as expected numBytes = GetObject(hBitmap, sizeof(BITMAP), &bm); DeleteDC(hdc); } 

The bottom line is that the code you created works, but depends on undocumented behavior. My preference would be to ensure its safety and eliminate this addiction.

+6
source

There is a related post from Raymond Chen in The Old New Thing explaining this behavior:

GDI people have discovered that many people have messed up and are trying to destroy while they are still selected in DC. Failure to complete the call caused two categories of problems: some applications simply leaked resources (because they thought they were destroying the object, but there wasn’t). Other applications checked the return value and got scared if they saw that DeleteObject did not actually delete the object.

To support both of these types of applications, GDI sometimes (not always) lie and say, "Of course, I deleted your object." It doesn’t actually delete it, because it is still selected in DC, but it also connects the string around the finger, and when the object is finally Disabled, GDI will say: β€œOh wait, I had to delete this object” and perform the deletion. Thus, the lie made by the GDI was not so it was a lie, because it was an "optimistic forecast for the future."

http://blogs.msdn.com/b/oldnewthing/archive/2013/03/06/10399678.aspx

+5
source

Source: https://habr.com/ru/post/1386239/


All Articles