Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

WindowProc

Status
Not open for further replies.

Zyrenthian

Programmer
Mar 30, 2001
1,440
US
Hi All,
I am faced with a small problem. I have fixed size bitmaps for my application. When the user resizes the display, i want to catch the WindowProc for resizing the desktop size but I am trying to do it in a class I derived from CBitmap. Doing it in the dialogs that display my derived bitmap is not a problem and I can do it this way BUT doing it this way requires me to then call the derived class to resize.

What I would like to do is catch the WindowProc in the derived class. I thought of a few approaches to this but they seem to give too much overhead.

Approach 1: Derived my class from CWnd as well
Approach 2: Do it all myself but this would require every dialog I have to manually resize (not the approach I want but it will work)

And the last approach would be my derived class from CBitmap recieving the WindowProc without deriving it from CWnd.

I would like to not have to inherit from CWnd so is there a way to catch the API window proc when you are NOT a window?

Here is what I am trying to do in code

class CAutoResizeBitmap:public CBitmap
{
CAutoResizeBitmap(CWnd* pWnd);

LRESULT CALLBACK WindowProc(...);
}

LRESULT CAutoResizeBitmap::WindowProc(...)
{
// resize the bitmap if desktop area changed
return ::WindowProc(...);
}


Any thoughts on this?

Matt
 
CBitmap is not a CWnd derived class therefore you should not call WindowProc from there. Beside, you should let MFC route and handled message instead of calling the global WindowProc.

If I understand you correctly, I think this is what you can do:

1. Let the CBitmap derived class (CAutoResizeBitmap) resize itself by creating a member function say ResizeBitmap.

2. In your application (or the dialog), handle the message when the desktop resize and call your CAutoResizeBitmap object’s ResizeBitmap function.


Shyan
 
Ya, thats what I have right now. I just have a ton of dialogs and thought if the bitmap could recognize the proc and had a pointer to it's dialog, it could handle the resize on its own. Then it would just be a matter of changing my CBitmaps to CAutoResizeBitmaps. Oh well :), looks like I am going to take the long road.

Matt
 
Not sure how does the dialogs comes in to play...Do you mean all of your dialog has a data member CAutoResizeBitmaps?

Can you derived a CAutoResizeDialog from CDialog, put CAutoResizeBitmaps into CAutoReiszeDialog, and derived all your dialogs from CAutoResizeDialog?

Sorry I really don't understand what you're trying to do.

Shyan
 
Basically, for performance issues, BitBlt is prefered over StretchBlt. When OnEraseBkgrnd is called, stretching the bitmap every time is too taxing.

The original approach used StretchBlt to allow for different sized desktops but the problem is that if you stretchBlt each time you will see a flicker when the window redraws. Then the issue of "What if the user changes the desktop size while the program is running?" came up. I changed to code to keep track of the current bitmap and when the window proc message was

WM_DISPLAYCHANGE

I resized the bitmap using StretchBlt. All other times, i just selected the already stretched bitmap into a DC and did a regular BitBlt instead. The performance increased ten-fold and the flicker was gone. Doing this for all my dialogs and CBitmapButtons, however, will be a time consuming process.

I am now leaning away from the AutoResize class and trying to figure out if I would just be better off with a global function that recieved a DC, the original bitmap and the new dimentions.

I dont know if this will help explain it but here is a snip of code from OnEraseBkgnd. When the windowProc funciton is called, I delete m_pBackgroundBitmap and set the pointer to null.

Code:
/******************************************************************************************/
BOOL ClassName::OnEraseBkgnd(CDC* pDC)
{
	CRect rClient;
	GetClientRect(rClient);
	
	// if we have a null bitmap, lets create it
	if(!m_pBackgroundBitmap)
	{
		m_pBackgroundBitmap = new CBitmap;
		m_pBackgroundBitmap->CreateCompatibleBitmap(pDC,rClient.Width(),rClient.Height());

		// Create a DC to stretch into
		CDC backgroundDC;
		backgroundDC.CreateCompatibleDC(pDC);

		// Create a bitmap to load the original bitmap into
		// and a DC to select it into
		CBitmap bmpBkgrnd;
		BITMAP bmpStruct;
		CDC bitmapDC;
		bitmapDC.CreateCompatibleDC(pDC);

		if(!bmpBkgrnd.LoadBitmap(IDB_BACKGROUND_BITMAP))
		{
			ASSERT(FALSE);
		}

		// we will need the measurements of the original bitmap to 
		// use with the stretch blt ING
		bmpBkgrnd.GetBitmap(&bmpStruct);

		CBitmap* pOldBmp = bitmapDC.SelectObject(&bmpBkgrnd);
		CBitmap* pOrigBitmap = backgroundDC.SelectObject(m_pBackgroundBitmap);

		backgroundDC.StretchBlt(0,0,rClient.Width(),rClient.Height(),&bitmapDC,0,0,bmpStruct.bmWidth,bmpStruct.bmHeight,SRCCOPY);
	
		// Restoration before they go out of scope
		bitmapDC.SelectObject(pOldBmp);
		backgroundDC.SelectObject(pOrigBitmap);
	}

	// We now have a valid m_pBackgroundBitmap
	// Create a DC, Select it into the new DC
	// Blt it because it is already stretched
	// This removes the flicker of the constant StretchBlt ING
	CDC bkDC;
	bkDC.CreateCompatibleDC(pDC);
	CBitmap* pBmp = bkDC.SelectObject(m_pBackgroundBitmap);
	pDC->BitBlt(0,0,rClient.Width(),rClient.Height(),&bkDC,0,0,SRCCOPY);
	bkDC.SelectObject(pBmp);

/********************** END CODE SNIP ********************/

Matt
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top