C Board  

Go Back   C Board > Platform Specific Boards > Windows Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 06-02-2009, 10:44 AM   #1
Registered User
 
Join Date: May 2009
Posts: 4
Drawing HBITMAP into CWnd, Acquired from "screenshot"

Hello everyone,

So I have my own "simpleBitmap" class which I use to acquire screenshots, and in turn I to a lot of low level manipulation of the pixels (the reason for making a class). Now I know my "screenshots" are working fine, I can save them to file, I can analyze individual pixels etc.

Now I want to be able to draw these simpleBitmap objects into a CWnd, however I want my class to remain MFC independant. Following is the code used to acquire the screenshot.

Code:
bool simpleBitmap::acquire( const string& wind_name, RECT rect )
{
	cleanup_resources();

	HWND hWnd = ::FindWindow(NULL,wind_name.c_str());
	if (!hWnd)
		return false;

	// If the target rect is 0,0,0,0 take the whole window.
	POINT start = {rect.left,rect.top};
	if ( (rect.left == 0 && rect.right == 0) || (rect.top == 0 && rect.bottom == 0) )
	{	
		RECT wndRect;
		::GetWindowRect(hWnd,&wndRect);
		rect = wndRect;
	}

	int w = rect.right-rect.left;
	int h = rect.bottom-rect.top;

	HDC hDc = ::GetWindowDC(hWnd);
	hMemDc = CreateCompatibleDC(hDc);
	hBmp = CreateCompatibleBitmap(hDc,w,h);

	if ( !hDc || !hMemDc || !hBmp )
		return false;
	
	::SelectObject(hMemDc,hBmp);

	::BitBlt(hMemDc,0,0,w,h,hDc,start.x,start.y,SRCCOPY);

	::ReleaseDC(hWnd, hDc);

	bmpRect = rect;

	return true;
}
Now the member variables hMemDC, and hBmp are stored within the class. Here is my... attempt at drawing to a window. Note however that this custom CWnd class is drawn onto a dialog, I know the class is capable of drawing succesfully (I have used simple CDC drawing stuff like coloring the background white).

Code:
void CBitmapWnd::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
	// Check if the simple bitmap is initialized.
	if ( sBmp )
	{
		// Get HDC and make sure the bitmap is selected into it.
		HBITMAP hBmp = sBmp->get_hbitmap();
		HDC hDC = sBmp->getSafeDC();
		::SelectObject(hDC,hBmp);

		// The rectangle describing the bitmap.
		CRect bmpRect;
		bmpRect = sBmp->get_rect();

		// Convert to MFC CDC
		CDC CMemDC;
		CMemDC.FromHandle(hDC);
		CRect wndRect;
		this->GetClientRect(&wndRect);	

		//Draw
		dc.StretchBlt(0,0,wndRect.Width(),wndRect.Height(),&CMemDC,0,0,bmpRect.Width()-1,bmpRect.Height()-1,SRCCOPY);

		/*		
		// This call works, and draws the background white.
		CBrush b(RGB(255,255,255));
		dc.SelectObject(&b);
		dc.Rectangle(wndRect);
		*/
	}
}
Sorry for the large amount of code, just trying to be complete in my question. So of course the question is... what would be the appropriate way to draw an HBITMAP/HDC acquired in the above manner to a simple CWnd class. I have looked around a lot, but there seem to be a huge number of combinations to draw Bitmaps, none of which have worked for me yet.

Thank you
DeusAduro is offline   Reply With Quote
Old 06-02-2009, 10:51 AM   #2
Registered User
 
Join Date: May 2009
Posts: 4
Ok well I seem to have... 5 minutes later found a solution to my own problem. The only change I made was:

Code:
// Replace:
CMemDC.FromHandle(hDC);
// With:
CMemDC.Attach(hDC);
Now any suggestions explanations are still welcome!! I have no idea why MFC has FromHandle then? The documentation states:

Quote:
Returns a pointer to a CDC object when given a handle to a device context.
Which I assumed meant it gave me a valid CDC object assuming my HDC was valid. Oh well.
DeusAduro is offline   Reply With Quote
Old 06-02-2009, 06:26 PM   #3
Registered User
 
valaris's Avatar
 
Join Date: Jun 2008
Location: RING 0
Posts: 462
FromHandle creates fills an the internal data structure to be compatible with and a copy of the platforms SDK's DC. CDC is just a wrapper around various DC functionality.

In the first case you are returning a CDC that has been created from a DC, in the second case you are internally creating a DC on the current object from the handle.
valaris is offline   Reply With Quote
Old 06-08-2009, 12:34 AM   #4
train spotter
 
Join Date: Aug 2001
Location: near a computer
Posts: 3,359
Is there a reason you are mixing MFC and WIN32? [HDC and CDC]

You seem to be doing more work than required because of this mix.

You can access the WIN32 GDI handle (HDC, HBITMAP etc) by casting the m_hObject member of any MFC CGdiObject.

I use something like….

Code:
 CWnd *pWnd=NULL;

if (pWnd = CWnd::FindWindow(wind_name.c_str(),NULL))
{
	CRect Area(&Rect);//init 
	if(!Area.Width() || !Area.Height())//validate
		pWnd->GetWindowRect(Area);

	//get the DC
	CDC *pDC=NULL;
	pDC = pWnd->GetWindowDC();

	//free members if required
	//TODO add free GDI resource code

	//fill members
	m_DC.CreateCompatibleDC(pDC);// CDC (is public in this example)
	m_Bmp.CreateCompatibleBitmap(pDC, Area.Width(),Area.Height()); // CBitmap

	//save original CBitmap to return our CDC to the default state before DeleteDC() 
	m_OrBmp=m_DC.SelectObject(&m_Bmp); // CBitmap *

	//copy
	m_DC.BitBlt(Area.left, Area.top, Area.Width(),Area.Height(),pDC,0,0, SRCCOPY );

	//clean up
	pWnd->ReleaseDC(pDC);
}
Then paint becomes
Code:
void CBitmapWnd::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
	// Check if the simple bitmap is initialized.
	if ( sBmp )
	{
		//get areas
		CRect Area;
		GetClientRect(Area,0);
		CRect bmpRect;
		bmpRect = sBmp->get_rect();
		//Draw	
		dc.StretchBlt(0, 0, Area.Width(),Area.Height(),&sBmp.m_DC,0,0,bmpRect.Width()-1,bmpRect.Height()-1,SRCCOPY);
	}
}
__________________
"Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
Friedrich Nietzsche

"I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
George Best

"If you are going through hell....keep going."
Winston Churchill

Last edited by novacain; 06-08-2009 at 12:37 AM.
novacain is offline   Reply With Quote
Old 07-01-2009, 05:16 PM   #5
Registered User
 
Join Date: Jun 2009
Posts: 5
CDC::FromHandle in winapi

I am trying to convert all my mfc codes to my own class (pure winapi). Since MFC is actually wrapping around the WinAPI. But I am having problem with CDC::FromHandle, there is no equivalent in WinAPI. I know, I can replace any call CDC::FromHandle and directly get the DC from ::GetDC, but it means I have to change all my code as well. Is there any way to replace CDC::FromHandle with pure WinAPI ? or any clue ?

thx
binyo66 is offline   Reply With Quote
Old 07-02-2009, 02:17 AM   #6
train spotter
 
Join Date: Aug 2001
Location: near a computer
Posts: 3,359
Quote:
Originally Posted by binyo66 View Post
I am trying to convert all my mfc codes to my own class (pure winapi). Since MFC is actually wrapping around the WinAPI. But I am having problem with CDC::FromHandle, there is no equivalent in WinAPI. I know, I can replace any call CDC::FromHandle and directly get the DC from ::GetDC, but it means I have to change all my code as well. Is there any way to replace CDC::FromHandle with pure WinAPI ? or any clue ?

thx
Please start your own thread, not necro others (which is against the forum rules)....



What EXACTLY are you trying to do?

BitBlt()? just use the HDC.
Change GDI objects? use SelectObject(), catching the released GDI object so you can clean up correctly.

Without details it is hard to give a meaningful response.


You appear to want to know how to construct a CDC (an MFC object) in pure WIN32, which is impossible.

CDC::FromHandle(HDC ) takes a WIN32 handle to a DC (a HDC) and returns a pointer to an MFC class CDC, initialised with that DC. You can't use a CDC in pure WIN32.



BTW anything with '::' in front of it is MFC not WIN32.
__________________
"Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
Friedrich Nietzsche

"I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
George Best

"If you are going through hell....keep going."
Winston Churchill
novacain is offline   Reply With Quote
Old 07-02-2009, 03:41 PM   #7
Registered User
 
Join Date: Jun 2009
Posts: 5
Quote:
Originally Posted by novacain View Post
Please start your own thread, not necro others (which is against the forum rules)....
Well, because I see the comment above me about CDC::FromHandle. Sorry if it is misplaced.


Quote:
You appear to want to know how to construct a CDC (an MFC object) in pure WIN32, which is impossible.
We have managed already all dialog based and its derived common controls (CWnd and its derived), and we are doing CDC, but got stuck with CDC::FromHandle. I believe there is nothing impossible in here

Quote:
CDC::FromHandle(HDC ) takes a WIN32 handle to a DC (a HDC) and returns a pointer to an MFC class CDC, initialised with that DC. You can't use a CDC in pure WIN32.
This is what I am guessing. CDC::FromHandle is static, and it accept only HDC as input, so it means MFC somehow have all attach HDCs in a global array or link list (so it can search from static function). MSDN said if the HDC is not attach when calling CDC::FromHandle, then it will attach to it. If i can know where MS start attaching HDC to MFC and put it in MFC object or when the array been created, then I can do similarity for it, and I can handle CDC::FromHandle (Like dialog based CWnd, we assume MFC has to store HWND somewhere in an array during the class initialization and enum all the childs so that all control child members variable can be attached to the right HWND).

Well you are probably right, it is not the right thread. again my apology for it (I just doesnt want to duplicate theread), and I will not attempt to reply this thread again, if u need to comment this post just pm me ). thx
binyo66 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
drawing on bitmaps eth0 Windows Programming 2 03-24-2006 05:56 PM
HBITMAP in Class Born_2B_Alone Windows Programming 1 10-09-2004 05:47 PM


All times are GMT -6. The time now is 07:25 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22