#1
  1. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    11

    Taking desktop capture?


    What API calls would I look at for taking a capture of the desktop? Also for converting to JPEG, I'v heard about the intel jpeg library, but on their site it's no longer available (I think it is but they charge $?). I have the dll, ijl15.dll.No doc's or any info tho, anyone have any idea how I would use it?
  2. #2
  3. jasondoucette.com
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Canada
    Posts
    378
    Rep Power
    12
  4. #3
  5. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    11
    Any other links?

    Code:
    		case WM_PAINT: 
    		{
    			HBITMAP hbmScreen; 
    			HDC hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL); 
    			HDC hdcCompatible = CreateCompatibleDC(hdcScreen); 
    			if(hdcCompatible==NULL)
    			{
    				MessageBox(NULL,"hdcCompatible","****",0); 
    				PostQuitMessage(0); 
    				return 0; 
    			}
    			hbmScreen = CreateCompatibleBitmap(hdcScreen,GetDeviceCaps(hdcScreen, HORZRES), GetDeviceCaps(hdcScreen, VERTRES)); 
    			SelectObject(hdcCompatible, hbmScreen); 
    			BitBlt(hdcCompatible,0,0,500, 500,hdcScreen,0,0,SRCCOPY); 
    			return 0; 
    			break; 
    		}
    I don't really know anything about GDI, I just want to write a quick app to take screenshots, this will probably be the only thing I ever do with gdi anyway. I don't want to learn the whole thing.
  6. #4
  7. jasondoucette.com
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Canada
    Posts
    378
    Rep Power
    12
    Unfortunately, you need to know a bit about the GDI to even do something simple like this. No, I do not have any other links, sorry. And, this also doesn't touch the subject on saving it as a .JPG. Bitmaps are handled (usually) as .BMP files within memory, so it's not a big deal to save them as .BMP. .JPG is another problem. I have not coded anything to do with .JPG, but I do believe that there is support for them in the GDI somewhere... do a search on MSDN, that's the best bet.
  8. #5
  9. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    11
    What is wrong with this code?

    Code:
    		case WM_CREATE: 
    		{
    			PAINTSTRUCT ps; 
    			RECT rEct; 
    			HDC FORMX, hMemdc;   
    			HBITMAP hTempBitmap; 
    			int HRez, VRez; 
    			char buffer[5000]; 
    
    			FORMX = BeginPaint(hwnd,&ps); 
    			if(FORMX==NULL)
    				MessageBox(NULL,"hf","wo",MB_OK);  
    
    			hMemdc = CreateCompatibleDC(FORMX); 
    			if(hMemdc==NULL)
    				MessageBox(NULL,"hMemdc","wo",MB_OK);  
    
    			GetClientRect(hwnd,&rEct); 
    			
    			//bmp
    			hTempBitmap = CreateCompatibleBitmap(CreateDC("DISPLAY",NULL,NULL,NULL),500,500); 
    			if(hTempBitmap==NULL)
    				MessageBox(NULL,"hTemp","wo",MB_OK); 
    			//
    			SelectObject(hMemdc, hTempBitmap); 
    
    			BitBlt(FORMX, 0, 0, 500, 500, hMemdc, 0, 0, SRCCOPY); 
    			if(BitBlt==NULL)
    				MessageBox(NULL,"BIT","wo",MB_OK); 
    
    			//ReleaseDC(GetDesktopWindow, hwndDesktop); 
    			EndPaint(hwnd,&ps); 
    			break; 
    		}
  10. #6
  11. jasondoucette.com
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Canada
    Posts
    378
    Rep Power
    12
    Take a look at this: MSDN - BeginPaint.

    "An application should not call BeginPaint except in response to a WM_PAINT message."
  12. #7
  13. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    27
    >>What is wrong with this code?

    Apart from what JD said it has many GDI memory leaks. The HDC's are not returned to the default state before they are freed. The GDI objects created are not freed.

    You will have to write the function CreateBitmapInfoStruct (or I will send it to you as soon as you pay my wages)
    // Get bitmap header information
    //Use GetObject() to find the bitmap color format, width, and height.
    // Convert the color format to a count of bits.
    // Allocate memory for the BITMAPINFO structure
    // Initialize the fields in the BITMAPINFO structure
    // Compute the number of bytes in the array of color indices and store the result in biSizeImage. This is OS dependent ie Win9x re-acts diff to Win NT (DWORD aligned) ect
    // Set biClrImportant to 0 (all are iimportant)

    Then write a function,CreateBMPFile() to save the bits and a use GDI+ or a third party lib (as I did) to convert to JPG and save
    // Retrieve the color table (RGBQUAD array) and the bits (array of palette indices) from the DIB. GetDIBits()
    // Compute the size of the entire file & alloc mem
    //convert and resize based on the colour depth used on the screen ie display settings ie 24bit BMP has an array of BGR so just convert to RGB. Other colour depths will have to be converted to RGB based on how they stored the colours
    //write file
    //clean up and free mem

    Code:
    //Screen Capture function
    
    	hDC=GetDC(NULL);//get screen DC
    	hdcMem=CreateCompatibleDC(hDC); //create temp DC and find the size
    	iWidth	= GetDeviceCaps(hdc,HORZRES);
    	iHeight	= GetDeviceCaps(hdc,VERTRES);
    
    
    	hImage=CreateCompatibleBitmap(hDC,iWidth,iHeight); // create the BMP
    
    	hSysBMP=SelectObject(hdcMem,hImage);
    	BitBlt(hdcMem,0,0,iWidth,iHeight,hDC,0,0,SRCCOPY);
    	SelectObject(hdcMem,hSysBMP); // capture the image off screen
    	BMPINFO=CreateBitmapInfoStruct(hWnd, hImage); // fill a BMP header
    	CreateBMPFile(hWnd, BMPINFO, hImage,hdcMem,pHeader->iCode); // convert and save (send)
    	// Clean up GDI's
    	DeleteObject(hImage);
    	DeleteDC(hdcMem);
    	ReleaseDC(NULL,hDC);

    Comments on this post

    • Jason Doucette agrees : good analysis
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  14. #8
  15. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Bulgaria
    Posts
    22
    Rep Power
    0
    Originally posted by movEAX_444
    What is wrong with this code?

    Code:
    		case WM_CREATE: 
    		{
    			PAINTSTRUCT ps; 
    			RECT rEct; 
    			HDC FORMX, hMemdc;   
    			HBITMAP hTempBitmap; 
    			int HRez, VRez; 
    			char buffer[5000]; 
    
    			FORMX = BeginPaint(hwnd,&ps); 
    			if(FORMX==NULL)
    				MessageBox(NULL,"hf","wo",MB_OK);  
    
    			hMemdc = CreateCompatibleDC(FORMX); 
    			if(hMemdc==NULL)
    				MessageBox(NULL,"hMemdc","wo",MB_OK);  
    
    			GetClientRect(hwnd,&rEct); 
    			
    			//bmp
    			hTempBitmap = CreateCompatibleBitmap(CreateDC("DISPLAY",NULL,NULL,NULL),500,500); 
    			if(hTempBitmap==NULL)
    				MessageBox(NULL,"hTemp","wo",MB_OK); 
    			//
    			SelectObject(hMemdc, hTempBitmap); 
    
    			BitBlt(FORMX, 0, 0, 500, 500, hMemdc, 0, 0, SRCCOPY); 
    			if(BitBlt==NULL)
    				MessageBox(NULL,"BIT","wo",MB_OK); 
    
    			//ReleaseDC(GetDesktopWindow, hwndDesktop); 
    			EndPaint(hwnd,&ps); 
    			break; 
    		}
    It is completely wrong.
    - in the WM_CREATE you cannot use BeginPaint and EndPaint. To get the DC in WM_CREATE you use the GetDC function.
    - Don't check for errors when painting in the WM_PAINT, it is completely unnecesary
    - Use the CreateIC function instead of CreateDC for the Display. The way you call it you cannot delete the DC and there is a memory leak. It is very important that you clean all objects after use in the WM_PAINT handler BECAUSE GDI RESOURCES IN WINDOWS ARE VERY LIMITED AND AFTER A WHILE YOUR OS WILL BECOME STRANGE AND SLOW, WILL CHANGE ALL FONTS AND BACKGROUNDS, ETC. To see what i am talking about start your app, start task manager, resize multiple times your window and see what is going on in the "Gdi objects" header tab of the processes view in task manager. Your app will quickly create thousands of gdi objects and that is VERY BAD. So cleanup them immediately after finish with them. If you GetDC use ReleaseDC, if you Create a DC use DeleteDC, after finish with each object use DeleteObject
    In WM_CREATE use GetDC and ReleaseDC, in WM_PAINT use BeginPaint and EndPaint. Don't check for errors. The functions are pretty simple and you always know if the DC or some object is valid or not

IMN logo majestic logo threadwatch logo seochat tools logo