Thread: Saving the static control's HDC into bitmap

  1. #1
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310

    Saving the static control's HDC into bitmap

    I'm trying to save into bitmap the contents of a static control:
    Code:
    int SaveDCToBitmap(HDC hDc, const char *lpszFile, int w, int h) {
    	HBITMAP hBitmap = CreateCompatibleBitmap(hDc, w, h);
    	if (hBitmap) {
    		HANDLE hFile = CreateFile(lpszFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    		if (hFile != INVALID_HANDLE_VALUE) {
    			BITMAPFILEHEADER bfh = {0};
    			BITMAPINFOHEADER bih = {0};
    			DIBSECTION ds = {0};
    			DWORD dwResult = 0;
    			int nImageSize = w * h * 3;
    			bfh.bfType = MAKEWORD('B','M');
    			bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nImageSize;
    			bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    			WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwResult, NULL);
    			bih.biSize = sizeof(BITMAPINFOHEADER);
    			bih.biWidth = w;
    			bih.biPlanes = 1;
    			bih.biHeight = h;
    			bih.biBitCount = 24;
    			bih.biSizeImage = nImageSize;
    			bih.biCompression = BI_RGB;
    			WriteFile(hFile, &bih, sizeof(BITMAPINFOHEADER), &dwResult, NULL);
    			GetObject(hBitmap, sizeof(DIBSECTION), &ds);
    			WriteFile(hFile, ds.dsBm.bmBits, nImageSize, &dwResult, NULL);
    			CloseHandle(hFile);
    			DeleteObject(hBitmap);
    		}
    	}
    	return 0;
    }
    
    // later on a command event
    case ID_ARCHIVO_GUARDAR:
    				{
    					HDC hdc = GetWindowDC(hStatic);
    					if (hdc) {
    						RECT rc = {0};
    						GetWindowRect(hStatic, &rc);
    						SaveDCToBitmap(hdc, "G:\\files\\teta.bmp", rc.right-rc.left, rc.bottom-rc.top);
    					}
    					ReleaseDC(hStatic, hdc);
    					break;
    				}
    			}
    Seems that the dimmensions are ok (in explorer status bar), but the image doesn't show...any ideas?
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    If you must use the device context (ie you can't/won't use the bitmap handle returned from an STM_GETIMAGE message sent to the static control) then:
    1. Get the control dc.
    2. Create a compatible bitmap with the same dimensions as the control.
    3. Create a memory dc.
    4. Select the previously created bitmap into the dc.
    5. Send a WM_PRINTCLIENT message to the control with the memory dc as the WPARAM and the LPARAM set to PRF_CLIENT; this copies the static control contents into your bitmap.
    6. Restore and release various dc's so that your memory bitmap is no longer selected.
    7. Use GetDIBits to obtain the image bits from the bitmap, fill appropriate bitmap file/header structures and write image to file.


    Alternatively, if you can use the bitmap handle returned from sending an STM_GETIMAGE to the static control you can just use GetObject to fill a DIBSECTION with everything and anything leaving you considerably less fiddling around to get the image bits.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310
    ok..I'll try the steps one

    /edit:
    After googling around I came out with this:
    Code:
    int SaveDCToBitmap(HWND hStatic, const char *pszFile) {
    	BITMAPFILEHEADER bmfh = {0};
        BITMAPINFOHEADER bmih = {0};
    	RECT rc = {0};
    	HDC hdc1;
    	HDC hdc2;
        HBITMAP aBmp;
        BITMAPINFO bi;
        HGDIOBJ OldObj;
        void *dibvalues;
        HANDLE fileHandle;
        DWORD bytes_write;
        DWORD bytes_written;
    	int w;
    	int h;
    
    	hdc1 = GetWindowDC(hStatic);
    	hdc2 = CreateCompatibleDC(hdc1);
    	GetWindowRect(hStatic, &rc);
    	w = rc.right-rc.left;
    	h = rc.bottom-rc.top;
    
    	bmih.biSize = sizeof(BITMAPINFOHEADER);
    	bmih.biWidth = w;
    	bmih.biHeight = h;
    	bmih.biPlanes = 1;
    	bmih.biBitCount = 24;
    	bmih.biCompression = BI_RGB;
    	bmih.biSizeImage = ((((bmih.biWidth * bmih.biBitCount) + 31) & ~31) >> 3) * bmih.biHeight;
    	bi.bmiHeader = bmih;
    
    	aBmp = CreateDIBSection(hdc1, &bi ,DIB_RGB_COLORS, (void**)&dibvalues, NULL, NULL);
    	OldObj = SelectObject(hdc2, aBmp);
    	BitBlt(hdc2, 0, 0, w, h, hdc1, 0, 0, SRCCOPY);
    	bmfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    	bmfh.bfSize = (3*bmih.biHeight*bmih.biWidth)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    	bmfh.bfType = 0x4d42;
    
    	fileHandle = CreateFile(pszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	bytes_write = sizeof(BITMAPFILEHEADER);
    	WriteFile(fileHandle, &bmfh, bytes_write, &bytes_written, NULL);
    	bytes_write = sizeof(BITMAPINFOHEADER); 
    	WriteFile(fileHandle, &bmih, bytes_write, &bytes_written, NULL);
    	bytes_write = bmih.biSizeImage;
    	WriteFile(fileHandle, (void*)dibvalues, bytes_write, &bytes_written, NULL);
    
    	CloseHandle(fileHandle);
        DeleteObject(SelectObject(hdc2,OldObj));
        DeleteDC(hdc2); 
    	ReleaseDC(hStatic, hdc1);
    	return 0;
    }
    Seems to be working.. what do you think?
    Last edited by Joelito; 09-13-2007 at 10:00 PM. Reason: code
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with Bitmap Display
    By The Brain in forum Windows Programming
    Replies: 7
    Last Post: 03-23-2009, 05:33 AM
  2. seg fault at vectornew
    By tytelizgal in forum C Programming
    Replies: 2
    Last Post: 10-25-2008, 01:22 PM
  3. My progress.. thnx to Cprogramming forumites
    By csonx_p in forum Windows Programming
    Replies: 6
    Last Post: 05-21-2008, 01:17 AM
  4. Avoiding Global variables
    By csonx_p in forum Windows Programming
    Replies: 32
    Last Post: 05-19-2008, 12:17 AM
  5. opengl program as win API menu item
    By SAMSAM in forum Game Programming
    Replies: 1
    Last Post: 03-03-2003, 07:48 PM