NO

Author Topic: Gdi+ and LayeredWindows  (Read 5096 times)

czerny

  • Guest
Gdi+ and LayeredWindows
« on: December 20, 2014, 03:02:50 PM »
Hallo,

I use the flat api to make gdi+ calls.

To draw an image in the WM_PAINT handler, I use something like this:

Code: [Select]
            PAINTSTRUCT ps;
            GpGraphics *graphics;

            BeginPaint(hwnd, &ps);

            GdipCreateFromHDC(ps.hdc, &graphics);
            GdipDrawImage(graphics, image, 0.0, 0.0);
            GdipDeleteGraphics(graphics);

            EndPaint(hwnd, &ps);

This works ok.

Now I am looking for a way to do this with layered windows.

I have found an example. But I have same questions about it:
Code: [Select]
// Get dimensions
int iWidth = img.GetWidth();
int iHeight = img.GetHeight();
// Make mem DC + mem  bitmap
HDC hdcScreen = GetDC(NULL);
HDC hDC = CreateCompatibleDC(hdcScreen);
HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight);
HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, hBmp);
// Draw image to memory DC
img.Draw(hDC, 0, 0, iWidth, iHeight, 0, 0, iWidth, iHeight);

// Call UpdateLayeredWindow
BLENDFUNCTION blend = {0};
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
POINT ptPos = {0, 0};
SIZE sizeWnd = {iWidth, iHeight};
POINT ptSrc = {0, 0};
UpdateLayeredWindow(hWnd, hdcScreen, &ptPos, &sizeWnd, hDC, &ptSrc, 0, &blend, ULW_ALPHA);

SelectObject(hDC, hBmpOld);
DeleteObject(hBmp);
DeleteDC(hDC);
ReleaseDC(NULL, hdcScreen);

Here is my first question:
Why are the two HBITMAP vaiables hBmp and hBmpOld needed. Compared with my code above, it seems as a long way round.

« Last Edit: December 20, 2014, 03:04:55 PM by czerny »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Gdi+ and LayeredWindows
« Reply #1 on: December 20, 2014, 05:14:57 PM »
Because in GDI+ the class constructor and destructor take care of the cleaning duties.
You have to restore the handle of the former HBITMAP fro two reasons, the first because the code that used the hdc before you mapped the new bitmap can destroy previous resources, yourself because each time you insert a new bitmap the memory used for the previous one remains around clogging the memory manager. The last is expressly required see remarks section.

I forget to mension that GDI have to be handled carefully because the GDI resources are global and limited, they are shared for all windows running on your computer. Each program receives a limited ammount of GDI handles, that it can use, borrowed from the global GDI handles still available. If you don't restore GDI object allocated from OS they cannot be freed and made available again after program shutdown. Acting that way after a while your system will refuse to open windows and you'll get a message about system getting low on available GDI resources.
« Last Edit: December 20, 2014, 05:31:14 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

czerny

  • Guest
Re: Gdi+ and LayeredWindows
« Reply #2 on: December 21, 2014, 12:43:06 AM »
Because in GDI+ the class constructor and destructor take care of the cleaning duties.
You have to restore the handle of the former HBITMAP fro two reasons, the first because the code that used the hdc before you mapped the new bitmap can destroy previous resources, yourself because each time you insert a new bitmap the memory used for the previous one remains around clogging the memory manager. The last is expressly required see remarks section.
Frankie: I am sorry, but I don' t understand, what you are saying here. Maybe, this is the case because my english is limited.

I will ask my question in a different way. So, hopefully, I wil be better understood?

In my first (WM_PAINT) example, it is not necessary to work with HBITMAP variables or to SelectObject's. Though behind the scenery the gdi+ functions will do this for me. Why it is necessary to do this myself in the second case?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Gdi+ and LayeredWindows
« Reply #3 on: December 21, 2014, 02:17:29 AM »
Because he called directly the UpdateLayeredWindow API function and this has to be treated that way for the reasons that I told before.
Take a look to a nice plain C example here.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

czerny

  • Guest
Re: Gdi+ and LayeredWindows
« Reply #4 on: December 21, 2014, 12:22:32 PM »
Because he called directly the UpdateLayeredWindow API function ...
Sorry, who is 'he'?
... and this has to be treated that way for the reasons that I told before.
Take a look to a nice plain C example here.
Frankie: I have not understood your previous post. So it is not helpfull to refer to even this post.
I know the example above. But that is not a gdi+ example.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Gdi+ and LayeredWindows
« Reply #5 on: December 21, 2014, 01:51:11 PM »
Sorry, who is 'he'?
Marc Gregoire the originator of the code of your example!!

Frankie: I have not understood your previous post. So it is not helpfull to refer to even this post.
I know the example above. But that is not a gdi+ example.
I'm sorry indeed, but there are some basics of GDI usage, that are required to know much before using GDI+, that evidently I'm not able to explain, nor maybe it is praticable because I should write tons of things.
I'm definetly unable to help for sure, maybe you can find good tutorials around.
Good luck!
« Last Edit: December 21, 2014, 01:52:47 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide