home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / DIBVIEW / CAPTURE.C_ / CAPTURE.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  12.8 KB  |  530 lines

  1. /*
  2.  * Capture.c
  3.  *
  4.  * Contains code for the following functions used in DibView:
  5.  *
  6.  *  CopyWindowToDIB()   - Copies a window to a DIB
  7.  *  CopyScreenToDIB()   - Copies entire screen to a DIB
  8.  *  DestroyDIB()        - Deletes DIB when finished using it
  9.  *  SelectWindow()      - Allows user to point to a window on the screen
  10.  *
  11.  * Copyright (c) 1991 Microsoft Corporation. All rights reserved.
  12.  *
  13.  */
  14.  
  15. #include "master.h"
  16.  
  17. // Prototypes for local functions
  18.  
  19. HBITMAP CopyScreenToBitmap(LPRECT lpRect);
  20. void HighlightWindow(HWND hwnd, BOOL fDraw);
  21.  
  22.  
  23.  
  24. // Locally used "globals"
  25.  
  26. static BOOL bHide = TRUE;   // TRUE if Parent window is to be hidden on capture
  27.  
  28.  
  29.  
  30. /***********************************************************************
  31.  *
  32.  * SelectWindow()
  33.  *
  34.  * This function allows the user to select a window on the screen.  The
  35.  * cursor is changed to a custom cursor, then the user clicks on the title
  36.  * bar of a window to capture, and the handle to this window is returned.
  37.  *
  38.  **********************************************************************/
  39.  
  40. HWND SelectWindow()
  41. {
  42.     HCURSOR hOldCursor;     // Handle to old cursor
  43.     POINT pt;               // Stores mouse position on a mouse click
  44.     HWND hWndClicked;       // Window we clicked on
  45.     MSG msg;
  46.  
  47.     /*
  48.      * Capture all mouse messages
  49.      */
  50.  
  51.     SetCapture(hWndMDIClient);
  52.  
  53.     /*
  54.      * Load custom Cursor
  55.      */
  56.  
  57.     hOldCursor = SetCursor(LoadCursor(hInst, "SelectCur"));
  58.  
  59.     /*
  60.      * Eat mouse messages until a WM_LBUTTONUP is encountered.
  61.      */
  62.  
  63.     for (;;){
  64.     WaitMessage();
  65.     if (PeekMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE)){
  66.             if (msg.message == WM_LBUTTONUP) {
  67.  
  68.               /*
  69.                * Get mouse position
  70.                */
  71.  
  72.                 pt.x = LOWORD(msg.lParam);
  73.                 pt.y = HIWORD(msg.lParam);
  74.  
  75.                 /*
  76.                  * Convert to screen coordinates
  77.                  */
  78.  
  79.                 ClientToScreen(hWndMDIClient, &pt);
  80.  
  81.                 /*
  82.                  * Get Window that we clicked on
  83.                  */
  84.  
  85.                 hWndClicked = WindowFromPoint(pt);
  86.  
  87.                 /*
  88.                  * If it's not a valid window, just return NULL
  89.                  */
  90.  
  91.                 if (!hWndClicked) {
  92.                     ReleaseCapture();
  93.                     SetCursor(hOldCursor);
  94.                     return NULL;
  95.                     }
  96.                 break;
  97.                 }
  98.  
  99.         }
  100.     else
  101.         continue;
  102.     }
  103.  
  104.     ReleaseCapture();
  105.     SetCursor(hOldCursor);
  106.     return (hWndClicked);
  107. }
  108.  
  109. /*************************************************************************
  110.  *
  111.  * CopyWindowToDIB()
  112.  *
  113.  * Parameters:
  114.  *
  115.  * HWND hWnd        - specifies the window
  116.  *
  117.  * WORD fPrintArea  - specifies the window area to copy into the device-
  118.  *                    independent bitmap
  119.  *
  120.  * Return Value:
  121.  *
  122.  * HDIB             - identifies the device-independent bitmap
  123.  *
  124.  * Description:
  125.  *
  126.  * This function copies the specified part(s) of the window to a device-
  127.  * independent bitmap.
  128.  *
  129.  ************************************************************************/
  130.  
  131.  
  132. HDIB CopyWindowToDIB(HWND hWnd, WORD fPrintArea)
  133. {
  134.   HDIB hDIB=NULL;  // handle to DIB
  135.  
  136.   /* check for a valid window handle */
  137.   if (!hWnd)
  138.     return NULL;
  139.  
  140.   switch (fPrintArea)
  141.   {
  142.     case PW_WINDOW: // copy entire window
  143.     {
  144.       RECT rectWnd;
  145.  
  146.       /* get the window rectangle */
  147.       GetWindowRect(hWnd, &rectWnd);
  148.  
  149.       /*  get the DIB of the window by calling
  150.        *  CopyScreenToDIB and passing it the window rect
  151.        */
  152.       hDIB = CopyScreenToDIB(&rectWnd);
  153.     }
  154.     break;
  155.  
  156.     case PW_CLIENT: // copy client area
  157.     {
  158.       RECT rectClient;
  159.       POINT pt1, pt2;
  160.  
  161.       /* get the client area dimensions */
  162.       GetClientRect(hWnd, &rectClient);
  163.  
  164.       /* convert client coords to screen coords */
  165.       pt1.x = rectClient.left;
  166.       pt1.y = rectClient.top;
  167.       pt2.x = rectClient.right;
  168.       pt2.y = rectClient.bottom;
  169.       ClientToScreen(hWnd, &pt1);
  170.       ClientToScreen(hWnd, &pt2);
  171.       rectClient.left   = pt1.x;
  172.       rectClient.top    = pt1.y;
  173.       rectClient.right  = pt2.x;
  174.       rectClient.bottom = pt2.y;
  175.  
  176.       /*  get the DIB of the client area by calling
  177.        *  CopyScreenToDIB and passing it the client rect
  178.        */
  179.       hDIB = CopyScreenToDIB(&rectClient);
  180.     }
  181.     break;
  182.  
  183.     default:    // invalid print area
  184.       return NULL;
  185.   }
  186.  
  187.   /* return the handle to the DIB */
  188.   return hDIB;
  189. }
  190.  
  191.  
  192. /*************************************************************************
  193.  *
  194.  * CopyScreenToDIB()
  195.  *
  196.  * Parameter:
  197.  *
  198.  * LPRECT lpRect    - specifies the window
  199.  *
  200.  * Return Value:
  201.  *
  202.  * HDIB             - identifies the device-independent bitmap
  203.  *
  204.  * Description:
  205.  *
  206.  * This function copies the specified part of the screen to a device-
  207.  * independent bitmap.
  208.  *
  209.  ************************************************************************/
  210.  
  211. HDIB CopyScreenToDIB(LPRECT lpRect)
  212. {
  213.   HBITMAP hBitmap;    // handle to device-dependent bitmap
  214.   HPALETTE hPalette;  // handle to palette
  215.   HDIB hDIB=NULL;     // handle to DIB
  216.  
  217.   /*  get the device-dependent bitmap in lpRect by calling
  218.    *  CopyScreenToBitmap and passing it the rectangle to grab
  219.    */
  220.   hBitmap = CopyScreenToBitmap(lpRect);
  221.  
  222.   /* check for a valid bitmap handle */
  223.   if (!hBitmap)
  224.     return NULL;
  225.  
  226.   /* get the current palette */
  227.   hPalette = GetSystemPalette();
  228.  
  229.   /* convert the bitmap to a DIB */
  230.   hDIB = BitmapToDIB(hBitmap, hPalette);
  231.  
  232.   /* clean up */
  233.   DeleteObject(hBitmap);
  234.   DeleteObject(hPalette);
  235.  
  236.   /* return handle to the packed-DIB */
  237.   return hDIB;
  238. }
  239.  
  240.  
  241.  
  242.  
  243. /*************************************************************************
  244.  *
  245.  * DestroyDIB ()
  246.  *
  247.  * Purpose:  Frees memory associated with a DIB
  248.  *
  249.  * Returns:  Nothing
  250.  *
  251.  *************************************************************************/
  252.  
  253. WORD DestroyDIB(HDIB hDib)
  254. {
  255.   GlobalFree(hDib);
  256.   return 0;
  257. }
  258.  
  259.  
  260. /*************************************************************************
  261.  *
  262.  * CopyScreenToBitmap()
  263.  *
  264.  * Parameter:
  265.  *
  266.  * LPRECT lpRect    - specifies the window
  267.  *
  268.  * Return Value:
  269.  *
  270.  * HDIB             - identifies the device-dependent bitmap
  271.  *
  272.  * Description:
  273.  *
  274.  * This function copies the specified part of the screen to a device-
  275.  * dependent bitmap.
  276.  *
  277.  ************************************************************************/
  278.  
  279. HBITMAP CopyScreenToBitmap(LPRECT lpRect)
  280. {
  281.   HDC hScrDC, hMemDC;           // screen DC and memory DC
  282.   HBITMAP hBitmap, hOldBitmap;  // handles to deice-dependent bitmaps
  283.   int nX, nY, nX2, nY2;         // coordinates of rectangle to grab
  284.   int nWidth, nHeight;          // DIB width and height
  285.   int xScrn, yScrn;             // screen resolution
  286.  
  287.   /* check for an empty rectangle */
  288.   if (IsRectEmpty(lpRect))
  289.     return NULL;
  290.  
  291.   /*  create a DC for the screen and create
  292.    *  a memory DC compatible to screen DC
  293.    */
  294.   hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  295.   hMemDC = CreateCompatibleDC(hScrDC);
  296.  
  297.   /* get points of rectangle to grab */
  298.   nX = lpRect->left;
  299.   nY = lpRect->top;
  300.   nX2 = lpRect->right;
  301.   nY2 = lpRect->bottom;
  302.  
  303.   /* get screen resolution */
  304.   xScrn = GetDeviceCaps(hScrDC, HORZRES);
  305.   yScrn = GetDeviceCaps(hScrDC, VERTRES);
  306.  
  307.   /* make sure bitmap rectangle is visible */
  308.   if (nX < 0)
  309.     nX = 0;
  310.   if (nY < 0)
  311.     nY = 0;
  312.   if (nX2 > xScrn)
  313.     nX2 = xScrn;
  314.   if (nY2 > yScrn)
  315.     nY2 = yScrn;
  316.   nWidth = nX2 - nX;
  317.   nHeight = nY2 - nY;
  318.  
  319.   /* create a bitmap compatible with the screen DC */
  320.   hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
  321.  
  322.   /* select new bitmap into memory DC */
  323.   hOldBitmap = SelectObject(hMemDC, hBitmap);
  324.  
  325.   /* bitblt screen DC to memory DC */
  326.   BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY) ;
  327.  
  328.   /*  select old bitmap back into memory DC and get handle to
  329.    *  bitmap of the screen
  330.    */
  331.   hBitmap = SelectObject(hMemDC, hOldBitmap);
  332.  
  333.   /* clean up */
  334.   DeleteDC(hScrDC);
  335.   DeleteDC(hMemDC);
  336.  
  337.   /* return handle to the bitmap */
  338.   return hBitmap;
  339. }
  340.  
  341.  
  342.  
  343.  
  344. /*************************************************************************
  345.  *
  346.  * CaptureWindow
  347.  *
  348.  * Parameters:
  349.  *
  350.  * HWND hWndParent  - specifies the "parent" window.  If bHide, this window
  351.  *                    is hidden during the capture operation.
  352.  *
  353.  * BOOL bCaptureClient - TRUE == Capture client area of window only.
  354.  *                      FALSE == Capture entire area of window.
  355.  *
  356.  * Return Value:
  357.  *
  358.  * HDIB             - identifies the device-independent bitmap
  359.  *
  360.  * Description:
  361.  *
  362.  * This function copies allows the user to select a window to capture.
  363.  * it then creates a device independent bitmap for this window, and
  364.  * returns it.
  365.  *
  366.  ************************************************************************/
  367.  
  368. HANDLE CaptureWindow (HWND hWndParent, BOOL bCaptureClient)
  369. {
  370.    // User wants to capture a window, either the entire window
  371.    // (including title bar and such), or the client area only
  372.  
  373.    HWND hWndSelect;              // Handle to window which was selected
  374.    HWND hWndDesktop;             // Handle to desktop window
  375.    HDIB hDib;                    // Handle to memory containing DIB
  376.  
  377.  
  378.    // Hide the DIBVIEW window
  379.    if (bHide)
  380.       ShowWindow(hWndParent, SW_HIDE);
  381.  
  382.    // Ask user to select a window
  383.    hWndSelect = SelectWindow();
  384.  
  385.    // Check to see that they didn't try to capture desktop window
  386.    hWndDesktop = GetDesktopWindow();
  387.  
  388.    if (hWndSelect == hWndDesktop) {
  389.       MessageBox(NULL,"Cannot capture Desktop window."
  390.                         "  Use 'Desktop' option to capture"
  391.                         " the entire screen.", NULL,
  392.                         MB_ICONEXCLAMATION | MB_OK);
  393.  
  394.       if (bHide)
  395.          ShowWindow(hWndParent, SW_SHOW);
  396.  
  397.       return NULL;
  398.       }
  399.  
  400.    // Do some sanity checks to make sure we have a valid hWnd
  401.  
  402.    if (!hWndSelect) {
  403.       MessageBox(NULL,
  404.                "Unable to capture that window! (hWnd is NULL)",
  405.                NULL, MB_ICONEXCLAMATION | MB_OK);
  406.  
  407.       if (bHide)
  408.          ShowWindow(hWndParent, SW_SHOW);
  409.  
  410.       return NULL;
  411.       }
  412.  
  413.  
  414.    // Move window which was selected to top of Z-order for
  415.    // the capture, and make it redraw itself
  416.  
  417.    SetWindowPos(hWndSelect, NULL, 0, 0, 0, 0,
  418.                   SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE);
  419.  
  420.    UpdateWindow(hWndSelect);
  421.  
  422.    // Call the function which captures screen
  423.  
  424.    hDib = CopyWindowToDIB (hWndSelect, bCaptureClient ? PW_CLIENT : PW_WINDOW);
  425.  
  426.  
  427.    // Restore the DIBVIEW window
  428.  
  429.    if (bHide)
  430.       ShowWindow(hWndParent, SW_SHOW);
  431.  
  432.    return hDib;
  433. }
  434.  
  435.  
  436.  
  437. /*************************************************************************
  438.  *
  439.  * CaptureFullScreen
  440.  *
  441.  * Parameters:
  442.  *
  443.  * HWND hWndParent  - specifies the "parent" window.  If bHide, this window
  444.  *                    is hidden during the capture operation.
  445.  *
  446.  *
  447.  * Return Value:
  448.  *
  449.  * HDIB             - identifies the device-independent bitmap
  450.  *
  451.  * Description:
  452.  *
  453.  * This function copies the entire screen into a DIB, returning a
  454.  * handle to the global memory with the DIB in it.
  455.  *
  456.  ************************************************************************/
  457.  
  458. HANDLE CaptureFullScreen (HWND hWndParent)
  459. {
  460.    RECT rScreen;        // Rect containing entire screen
  461.    HDC  hDC;            // DC to screen
  462.    MSG  msg;            // Message for the PeekMessage()
  463.    HDIB hDib;           // Handle to DIB
  464.  
  465.    // Create a DC for the display
  466.  
  467.    hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  468.    rScreen.left = rScreen.top = 0;
  469.    rScreen.right = GetDeviceCaps(hDC, HORZRES);
  470.    rScreen.bottom = GetDeviceCaps(hDC, VERTRES);
  471.  
  472.    // Hide the DIBVIEW window
  473.  
  474.    if (bHide)
  475.       ShowWindow(hWndParent, SW_HIDE);
  476.  
  477.    // Wait here until the apps on the screen have a chance to
  478.    // repaint themselves.  Make our own message loop, and process
  479.    // the messages we see.  When PeekMessage() returns, we know
  480.    // that all the other app's WM_PAINT messages have been
  481.    // processed.
  482.  
  483.    while (PeekMessage(&msg,NULL,0,0,PM_REMOVE) != 0) {
  484.    TranslateMessage(&msg);
  485.    DispatchMessage(&msg);
  486.    }
  487.  
  488.    // Call the function which captures screen
  489.  
  490.    hDib = CopyScreenToDIB(&rScreen);
  491.  
  492.    // Restore the DIBVIEW window
  493.  
  494.    if (bHide)
  495.       ShowWindow(hWndParent, SW_SHOW);
  496.  
  497.    return hDib;
  498. }
  499.  
  500.  
  501.  
  502. /*************************************************************************
  503.  *
  504.  * ToggleCaptureHide
  505.  *
  506.  * Parameters:
  507.  *
  508.  *    None
  509.  *
  510.  * Return Value:
  511.  *
  512.  *    New "Hide" state.
  513.  *
  514.  *
  515.  * Description:
  516.  *
  517.  *    Toggle the "Hide window on capture" option
  518.  *
  519.  *
  520.  ************************************************************************/
  521.  
  522. BOOL ToggleCaptureHide (void)
  523. {
  524.    bHide = !bHide;
  525.  
  526.    return bHide;
  527. }
  528.  
  529.  
  530.