Click here to Skip to main content
Licence 
First Posted 26 Mar 2002
Views 119,109
Bookmarked 56 times

Drawing Image on MDI Main Frame background

By | 26 Mar 2002 | Article
This article explains how to draw images on MDI Main Frame background using window subclassing

Sample Image - Image1.jpg

Introduction

Some time ago I worked with Altera Max Plus II to design simple electronic chip. I noticed that this application draws a company logo on Main Frame background. Once I had more free time then usually, I wanted to implement this by myself. This article is the result :)

Implementation

So you may wonder how to draw image on background window of MDI application. First you have to subclass window you want to draw on. To do this call GetWindowLong(hMain, GWL_WNDPROC). This function returns pointer to old window procedure and we want to store it for further use. Place this code in CBackgroundImageApp::InitInstance() just before showing the Main Frame.

HWND hMain = pMainFrame->GetWindow(GW_CHILD)->GetSafeHwnd();
pfnOldWndProc = (WNDPROC)GetWindowLong(hMain, GWL_WNDPROC);
SetWindowLong(hMain, GWL_WNDPROC, (long)pfnNewWndProc);

Now we have sub-classed window, but the window procedure is missing. Lets write it now. The window procedure should handle at least two messages to work well :

  • WM_ERASEBKGND
  • WM_SIZE

First message is sent when Windows wants application to draw its background - we'll use this to draw our image. Second message is also important because when you resize window image should also change its size to fit into new window size. Our window proc would look like this :

LRESULT CALLBACK pfnNewWndProc(HWND hwnd, 
       UINT uMsg, WPARAM wParam,LPARAM lParam)
{
    // local variables goes here

    switch (uMsg)   {
        case WM_SIZE :
            // ...
        case WM_ERASEBKGND :
            // ...
            return 1;
        default :
            return CallWindowProc(pfnOldWndProc,
                hwnd, uMsg, wParam, lParam);
    }
}

Important note

Returing 1 from WM_ERASEBKGND case is very important because it tells Windows that we already erased window and it has nothing to do, otherwise Windows would erase this window again with standard background, which I suppose is not we wanted to achieve.

What about other messages ?

Here is the moment we are using stored old window procedure pointer. We simply call old procedure and return its result. So lets look closer to the WM_SIZE and WM_ERASEBKGND cases.

WM_SIZE - Simply force window background to redraw itself by sending WM_ERASEBKGND to it :

SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)GetDC(hwnd), 0);
return 1;

WM_ERASEBKGND - Code below will simply BitBlt the bitmap. Because the window size generally very rarely is the same as image size BitBlt() becomes StretchBlt(). Finally it looks like below :

hcompdc = CreateCompatibleDC(hdc);
SelectObject(hcompdc, hBmp);
GetClientRect(hwnd, &rect);

if (0 == StretchBlt(hdc, 
    rect.left, rect.top, rect.right, rect.bottom,
    hcompdc, 0, 0, 1152, 864, SRCCOPY))
    MessageBox(hwnd, "error",
        "while StretchBlt", MB_OK);

DeleteDC(hcompdc);
return 1;

Where :

  • hdc, hcompdc - Device context
  • hBmp - bitmap handle

It is very important to invoke DeleteDC() because we don't want to cause memory leaks.

Final notes

Performance of this solution strongly depends on operating system , graphics card installed, and on window size. In my case Windows 98 was better choice than Windows 2000. On second one redrawing an image took significantly more time to make the user feel comfortably. Application running on Windows 98 looked very nice. My graphics device is Geforce 2 GTS. If you have experiences from other systems or configurations please post it below at article's discussion board. StretchBlt function also differs between systems. One used in Windows 98 was better this time too.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Konrad Rotuski

Web Developer

Poland Poland

Member

At the moment I'm a student at Warsaw University of Technology in Poland.
 
My programming langugage of choice is C++.
I also like C# and Java.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralWM_SIZE Pinmembermail762616:44 28 Jun '10  
Generalwhy can't we do it in mainframe Pinmemberbaolin,jiang21:44 2 Jul '07  
GeneralRe: why can't we do it in mainframe PinmemberJames Vanderhyde10:45 20 Feb '09  
GeneralA new found Pinmemberyongbin_jing17:27 26 Oct '06  
GeneralClick on Background Pinmemberblubb7:35 24 Oct '06  
GeneralRe: Click on Background Pinmemberblubb8:07 24 Oct '06  
GeneralHard-Coded image size Pinmemberjocool4:07 15 Sep '04  
GeneralTile not Stretch Pinmembersammyc16:19 17 Jun '04  
GeneralRe: Tile not Stretch Pinmembersammyc16:29 17 Jun '04  
Generalchild windows does not maximize PinmemberCamran8:36 10 Feb '04  
GeneralRe: child windows does not maximize Pinmembermickdo20:30 18 Oct '04  
GeneralRe: child windows does not maximize PinmemberPavel Machyniak4:23 13 Oct '06  
GeneralReading the Pixels From the Graph PinmemberRajeev Kumar M18:36 5 Feb '04  
Generalchild windows overpaint PinmemberRostislaw11:18 7 Oct '03  
GeneralImage quality Pinmemberajh5:22 26 Jun '03  
GeneralRe: Image quality Pinmemberajh5:29 26 Jun '03  
GeneralRe: Image quality PinmemberWhiTeWo1F10:34 6 Nov '05  
GeneralRe: Image quality Pinmemberdrai_kin0:09 4 Apr '06  
GeneralGreat article, but... Pinmemberarek20:27 1 Apr '02  
GeneralRe: Great article, but... Pinmemberarek - Fluffy20:54 1 Apr '02  
GeneralWM_ERASEBKGND Pinmemberkilowatt21:13 1 Apr '02  
GeneralRe: WM_ERASEBKGND PinmemberKonrad Rotuski1:17 3 Apr '02  
Generalm_hWndMDIClient PinmemberTomasz Sowinski3:36 27 Mar '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 27 Mar 2002
Article Copyright 2002 by Konrad Rotuski
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid