Grabbing part of dialog to another dialog

Pushkins 156 Reputation points
2020-11-16T23:06:33.34+00:00

Hi

I’m wondering is it possible to grab a picture on one part of a dialog and place it on another dialog,

I’m thinking it has got something to do with BitBlt. But I can’t seem to figure out how to do it

Thank you

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,575 questions
{count} votes

Accepted answer
  1. Rita Han - MSFT 2,161 Reputation points
    2020-11-17T06:44:40.56+00:00

    Hello @Pushkins ,

    Yes the two dialogs belong to the same program. The first dialog is used to programmatically construct a picture out of several controls I then want to grab that as a picture and place it on another dialog.

    The following CaptureAnImage() shows an example based on this official document. You can pass in the window handle of the first dialog and it will capture the dialog window and save it as a BITMAP image (captureqwsx.bmp).

    Then you can load this bitmap and draw it on another dialog. Second code piece show how you can draw it in WM_PAINT message of the dialog.

    int CaptureAnImage(HWND hWnd)  
    {  
        HDC hdcWindow;  
        HDC hdcMemDC = NULL;  
        HBITMAP hbmScreen = NULL;  
        BITMAP bmpScreen;  
      
        // Retrieve the handle to a display device context for the client   
        // area of the window.   
        hdcWindow = GetDC(hWnd);  
      
        // Create a compatible DC which is used in a BitBlt from the window DC  
        hdcMemDC = CreateCompatibleDC(hdcWindow);   
      
        if(!hdcMemDC)  
        {  
            MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);  
        }  
      
        // Get the client area for size calculation  
        RECT rcClient;  
        GetClientRect(hWnd, &rcClient);  
      
        //This is the best stretch mode  
        SetStretchBltMode(hdcWindow,HALFTONE);  
          
        // Create a compatible bitmap from the Window DC  
        hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);  
          
        if(!hbmScreen)  
        {  
            MessageBox(hWnd, L"CreateCompatibleBitmap Failed",L"Failed", MB_OK);  
        }  
      
        // Select the compatible bitmap into the compatible memory DC.  
        SelectObject(hdcMemDC,hbmScreen);  
          
        // Bit block transfer into our compatible memory DC.  
        if(!BitBlt(hdcMemDC,   
                   0,0,   
                   rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,   
                   hdcWindow,   
                   0,0,  
                   SRCCOPY))  
        {  
            MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK);  
        }  
      
        // Get the BITMAP from the HBITMAP  
        GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);  
           
        BITMAPFILEHEADER   bmfHeader;      
        BITMAPINFOHEADER   bi;  
           
        bi.biSize = sizeof(BITMAPINFOHEADER);      
        bi.biWidth = bmpScreen.bmWidth;      
        bi.biHeight = bmpScreen.bmHeight;    
        bi.biPlanes = 1;      
        bi.biBitCount = 32;      
        bi.biCompression = BI_RGB;      
        bi.biSizeImage = 0;    
        bi.biXPelsPerMeter = 0;      
        bi.biYPelsPerMeter = 0;      
        bi.biClrUsed = 0;      
        bi.biClrImportant = 0;  
      
        DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;  
      
        // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that   
        // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc   
        // have greater overhead than HeapAlloc.  
        HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);   
        char *lpbitmap = (char *)GlobalLock(hDIB);      
      
        // Gets the "bits" from the bitmap and copies them into a buffer   
        // which is pointed to by lpbitmap.  
        GetDIBits(hdcWindow, hbmScreen, 0,  
            (UINT)bmpScreen.bmHeight,  
            lpbitmap,  
            (BITMAPINFO *)&bi, DIB_RGB_COLORS);  
      
        // A file is created, this is where we will save the screen capture.  
        HANDLE hFile = CreateFile(L"captureqwsx.bmp",  
            GENERIC_WRITE,  
            0,  
            NULL,  
            CREATE_ALWAYS,  
            FILE_ATTRIBUTE_NORMAL, NULL);     
          
        // Add the size of the headers to the size of the bitmap to get the total file size  
        DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
       
        //Offset to where the actual bitmap bits start.  
        bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);   
          
        //Size of the file  
        bmfHeader.bfSize = dwSizeofDIB;   
          
        //bfType must always be BM for Bitmaps  
        bmfHeader.bfType = 0x4D42; //BM     
       
        DWORD dwBytesWritten = 0;  
        WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);  
        WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);  
        WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);  
          
        //Unlock and Free the DIB from the heap  
        GlobalUnlock(hDIB);      
        GlobalFree(hDIB);  
      
        //Close the handle for the file that was created  
        CloseHandle(hFile);  
    
        done = TRUE;  
             
        //Clean up  
        DeleteObject(hbmScreen);  
        DeleteObject(hdcMemDC);  
        ReleaseDC(hWnd,hdcWindow);  
      
        return 0;  
    }  
    

    Second code piece:

    case WM_PAINT:  
    	PAINTSTRUCT ps;  
    	HDC hdc = BeginPaint(hDlg, &ps);  
    	// TODO: Add any drawing code that uses hdc here...  
    	if (done)  
    	{  
    		HBITMAP hBitmap = (HBITMAP)LoadImage(hInst, L"captureqwsx.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);  
    		HDC hdcMem = CreateCompatibleDC(hdc);  
    		HGDIOBJ oldBitmap = SelectObject(hdcMem, hBitmap);  
    		BITMAP          bitmap;  
    		GetObject(hBitmap, sizeof(bitmap), &bitmap);  
    		BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);  
    
    		SelectObject(hdcMem, oldBitmap);  
    		DeleteDC(hdcMem);  
    	}  
    	EndPaint(hDlg, &ps);  
    	break;  
    

    Thank you!


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


1 additional answer

Sort by: Most helpful
  1. RLWA32 44,926 Reputation points
    2020-11-17T01:27:25.583+00:00

    Take a look at the discussion and code sample here - capturing-an-image. Of course you would need to customize the code to suit your particular purpose.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.