View Single Post
 
Old 05-26-2004, 12:24 PM
Csharp's Avatar
Csharp Csharp is offline
Senior Contributor

* Expert *
 
Join Date: Jul 2003
Location: Ashby, Leicestershire.
Posts: 967
Post Printscreen / alt+Printscreen including Cursor , in C++

An example of taking a screenshot of either the entire desktop , or a window by it's handle. included in the screenshot is the Cursor at it's position at the time of the shot ( unlike windows , which doesn't show the Cursor )
This for me has proved to be the most challenging of projects, i've built it all in C++ ( .NET win forms , but using standard C++ api calls etc... )
Code:
[COLOR=Green]// at the very top of the Form's .h file ... [/COLOR] [COLOR=Blue]#pragma once[/COLOR] [COLOR=Blue]#include[/COLOR] <windows.h> [COLOR=Blue]#include[/COLOR] "Winuser.h" [COLOR=Green]// then to use the sample ( i've used a button and 2 radio buttons in this case ) ... [/COLOR] [COLOR=Blue]private[/COLOR]: [COLOR=Blue]void[/COLOR] button1_Click(System::Object * sender, System::EventArgs * e) { IntPtr handle = IntPtr::Zero; [COLOR=Blue]int[/COLOR] width = NULL; [COLOR=Blue]int[/COLOR] height = NULL; [COLOR=Blue]int[/COLOR] x = NULL; [COLOR=Blue]int[/COLOR] y = NULL; [COLOR=Blue]if[/COLOR](radioButton1->Checked == [COLOR=Blue]true[/COLOR]) { [COLOR=Green]/// // specify the handle of the Form // and the form's sizes / positions.[/COLOR] handle = [COLOR=Blue]this[/COLOR]->get_Handle(); width = [COLOR=Blue]this[/COLOR]->get_Width(); height = [COLOR=Blue]this[/COLOR]->get_Height(); x = [COLOR=Blue]this[/COLOR]->get_Location().get_X(); y = [COLOR=Blue]this[/COLOR]->get_Location().get_Y(); } [COLOR=Blue]else[/COLOR] { [COLOR=Green]/// // specify the handle of the Desktop // and the Desktop's sizes / positions.[/COLOR] handle = GetDesktopWindow(); Screen *r = Screen::PrimaryScreen; width = r->Bounds.get_Width(); height = r->Bounds.get_Height(); x = 0; y = 0; } [COLOR=Green]/// // now lets try to make a Screenshot which includes the Cursor ( unlike the Screenshot that Windows takes )[/COLOR] Snapshot(handle , width , height , x , y); } [COLOR=Blue]private[/COLOR]: [COLOR=Blue]void[/COLOR] Snapshot(IntPtr hHandle , [COLOR=Blue]int[/COLOR] width , [COLOR=Blue]int[/COLOR] height , [COLOR=Blue]int[/COLOR] x , [COLOR=Blue]int[/COLOR] y) { [COLOR=Green]/// //The GetWindowDC function retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars. ///See Msdn Article for more info ... [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_0hcz.asp[/url][/COLOR] HDC srcHDC = GetWindowDC((HWND)hHandle.ToInt32()); [COLOR=Green]/// //The CreateCompatibleDC function creates a memory device context (DC) compatible with the specified device. ///See Msdn Article for more info ... [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_499f.asp[/url][/COLOR] HDC destHDC = CreateCompatibleDC(srcHDC); [COLOR=Green]/// //The CreateCompatibleBitmap function creates a bitmap compatible with the device that is associated with the specified device context. ///See Msdn Article for more info ... [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1cxc.asp[/url][/COLOR] HBITMAP bmpDC = CreateCompatibleBitmap(srcHDC , width , height); [COLOR=Green]/// //The SelectObject function selects an object into the specified device context (DC). The new object replaces the previous object of the same type. ///See Msdn Article for more info ... [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_9v3o.asp[/url][/COLOR] HGDIOBJ objHDC = SelectObject(destHDC, bmpDC); [COLOR=Green]/// //The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context. ///See Msdn Article for more info ... [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_0fzo.asp[/url][/COLOR] BitBlt(destHDC, 0, 0, width, height, srcHDC, 0, 0, SRCCOPY); SelectObject(destHDC, objHDC); [COLOR=Green]/// // here i cast a Bitmap ( .NET / C# type Bitmap ) from the C++ style HBITMAP /// for this i use " dynamic_cast " , which is seen in .NET as DirectCast. [/COLOR] Bitmap *bmp = [COLOR=Blue]dynamic_cast[/COLOR]<Bitmap*>(Bitmap::FromHbitmap(bmpDC)); [COLOR=Green]/// //now i create a Graphics object , to enable the Cursor to be Drawn in it's Correct Position.[/COLOR] Graphics *g = [COLOR=Blue]dynamic_cast[/COLOR]<Graphics*>(Graphics::FromImage(bmp)); System::Windows::Forms::Cursor *csr=Cursor::get_Current(); System::Drawing::Point pnt = (System::Drawing::Point)csr->get_Position(); [COLOR=Green]/// // this was quite tricky as creating a new Rectangle threw alsorts of problems, until i found the FromLTRB property.[/COLOR] System::Drawing::Rectangle r= System::Drawing::Rectangle::FromLTRB(([COLOR=Blue]int[/COLOR])(pnt.get_X() - 10) - x,([COLOR=Blue]int[/COLOR])(pnt.get_Y() - 10) - y,([COLOR=Blue]int[/COLOR])csr->get_Size().get_Width() ,([COLOR=Blue]int[/COLOR])csr->get_Size().get_Width()); [COLOR=Green]/// // now i draw the Cursor on to the Graphics object of the bitmap.[/COLOR] csr->Draw( g , r); [COLOR=Green]/// //next i clean up any Resources used by the above calls.[/COLOR] ReleaseDC((HWND)hHandle.ToInt32(), srcHDC); DeleteDC(destHDC); DeleteObject(bmpDC); [COLOR=Green]/// // finally i save the Bitmap ( this was the Reason for using a .NET Bitmap , makes saving alot simpler ) .[/COLOR] bmp->Save("C:\\test123.bmp" , System::Drawing::Imaging::ImageFormat::Bmp ); MessageBox(NULL , "ScreenShot Complete","Dynamic's C++ ScreenShot App",MB_ICONINFORMATION); }
i've included a sample project ( it's VS2003 , so VS2002 users would need to convert the project or copy the code in to their version )
Attached Files
File Type: zip PrintScreen_in_C.zip (9.4 KB, 85 views)
__________________
~~ please don't PM me regarding code, I only reply to personnal messages ~~
Reply With Quote