Trying to re-size a BITMAP - doesn't work

Hello again
I was handling with BITMAPS all these days and what I am trying to do now is to resize a bitmap (give it the half size of its parent window). I am trying to do it by using StretchBlt()
It doesn't work and I don't know what is wrong:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Global variables
PAINTSTRUCT ps;
HDC hdc;
HBITMAP image;
HWND parent;


//Controls creation
case WM_CREATE:
     parent= CreateWindowEx(
                   0, 
                   "STATIC", 
                   NULL, 
                   WS_CHILD|WS_VISIBLE|SS_BITMAP, 
                   10, 10, 500, 500, 
                   hWnd, 
                   (HMENU)PARENT_ID, 
                   hInstance, 
                   NULL
             );
     hdc = BeginPaint(newsimg, &ps);
     image = LoadBitmap(hInstance, MAKEINTRESOURCE(IMAGE));
     SendDlgItemMessage(hWnd, PARENT_ID, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)image);
     EndPaint(newsimg, &ps);
break;
//Controls re-sizing
case WM_SIZE:
     RECT rect;
     GetClientRect(hWnd, &rect);

     MoveWindow(parent, 0, 0, (rect.right-rect.left)/2, (rect.bottom-top.left)/2, true);
     int sx = GetSystemMetrics(SM_CXSCREEN), sy = GetSystemMetrics(SM_CXSCREEN);
     StretchBlt(hdc, 0, 0, sx/2, sy/2, hdc, 0, 0, sx, sy, SRCCOPY);
break;


The images does show up at its original size (500x500) but when I resize the window it doesn't change its size, it doesn't stretch

Thanks for your answers!
Last edited on
I see the call to StrechBlt() in the handler for WM_SIZE. That is bad practice, but the most worrisome part is: There's no function call in there to obtain the device context used in StretchBlt(). So how are you obtaining the DC?
closed account (DSLq5Di1)
MSDN wrote:
An application should not call BeginPaint except in response to a WM_PAINT message.

http://msdn.microsoft.com/en-us/library/windows/desktop/bb760773#ss_realsizecontrol
As I see, I am going the wrong way.
So, what I suppose I have to do in first place is:
1.) Load the bitmap inside the WM_CREATE message. If I load the image in WM_PAINT my computer is gonna explode (loading a file 10 times (or more) per second)
2.) BeginPaint and SendDlgItemMessage must be executed inside the WM_PAINT message
3.) Use StretchBlt inside the WM_PAINT message
4.) Use GetDC to get the device context

I cannot use SS_REALSIZECONTROL. The compiler says that it was not declared. What headers should I use?

Thanks
Last edited on
Look at that, I didn't notice. Yes, that is SUPER bad. BeginPaint()/EndPaint() is only called during WM_PAINT.

Which of course leads me to the bad practice I mentioned: You should always do your painting in WM_PAINT. If the size changes, the window rectangle should be invalidated. This is done automatically by Windows if your window class has the styles CS_HREDRAW and CS_VREDRAW.

Then, during WM_PAINT, you do your StrecthBlt().
Now, when I have this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Global variables
HBITMAP image;
HWND parent;
int sx, sy;

//Controls creation
case WM_CREATE:
     parent= CreateWindowEx(
                   0, 
                   "STATIC", 
                   NULL, 
                   WS_CHILD|WS_VISIBLE|SS_BITMAP, 
                   10, 10, 500, 500, 
                   hWnd, 
                   (HMENU)PARENT_ID, 
                   hInstance, 
                   NULL
             );
     image = LoadBitmap(hInstance, MAKEINTRESOURCE(IMAGE));
     SendDlgItemMessage(hWnd, PARENT_ID, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)image);
break;
//Controls re-sizing
case WM_PAINT:
     sx = GetSystemMetrics(SM_CXSCREEN);
     sy = GetSystemMetrics(SM_CXSCREEN);
     StretchBlt(GetDC(parent), 0, 0, sx/2, sy/2, GetDC(parent), 0, 0, sx,sy, SRCCOPY);
     InvalidateRect(parent, NULL, TRUE);
     UpdateWindow(parent);
break;


Now, when I resize the window, only the image is displayed (and with a poor quality)
Last edited on
MSDN says that "The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle"

What I don't understand is what is the source and what is the destination if I only want to re-size an image inside the same HDC.
Still far from correct. You MUST use BeginPaint()/EndPaint() in WM_PAINT, and you can only copy bitmaps and you NEVER invalidate from WM_PAINT.

In WM_PAINT you:

1. Obtain the HDC using BeginPaint().
2. Obtain any additional information needed. For example, the dimension of the client area using GetClientRect().
3. Create a compatible DC using the function call CreateCompatibleDC(<the HDC from BeginPaint()>).
4. Select your bitmap into the compatible DC; make sure you save the old bitmap returned by SelectObject().
5. Call StretchBlt() using the DC from BeginPaint() as destination and the compatible DC as source.
6. Select the old bitmap (obtained in step 4) back into the compatible DC using SelectObject().
7. Delete the compatible DC using DeleteDC().
8. Call EndPaint().
O.K. Thanks man for showing me the path.
Topic archived. No new replies allowed.