home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_03_05 / 3n05056a < prev    next >
Text File  |  1992-03-10  |  10KB  |  335 lines

  1. Listing 5
  2.  
  3. /*****************************************************/
  4. /*  scroll.c                                         */
  5. /* -- Sample program captures the screen into an     */
  6. /*    offscreen bitmap that the user can view        */
  7. /*    "through" a scrollable window.                 */
  8. /*****************************************************/
  9.  
  10. #define NOCOMM
  11. #include <windows.h>
  12.  
  13. /*****************************************************/
  14. /* Prototypes.                                       */
  15. /*****************************************************/
  16. VOID                CaptureScreen(VOID);
  17. VOID                FreeBitmap(VOID);
  18. VOID                ScrollBitmap(HWND, int, int);
  19. int     FAR PASCAL  WinMain(HANDLE, HANDLE, LPSTR,
  20.                             int);
  21. LONG    FAR PASCAL  WndProc(HWND, WORD, WORD, DWORD);
  22.  
  23. /*****************************************************/
  24. /* Constants.                                       */
  25. /*****************************************************/
  26. #define szScroll    "Scroller"  /* Class name. */
  27.  
  28. /*****************************************************/
  29. /* Globals.                                          */
  30. /*****************************************************/
  31. int     dxScreen, dyScreen; /* Size of display. */
  32. int     dxWindow, dyWindow; /* Size of main window. */
  33. POINT   ptBitmap;           /* Bitmap position. */
  34. HDC     hdcMem;             /* Memory DC. */
  35. HBITMAP hbmp;               /* Off-screen bitmap. */
  36. HBITMAP hbmpSav;            /* Original 1x1 bitmap. */
  37.  
  38. /*****************************************************/
  39. /* Routines.                                         */
  40. /*****************************************************/
  41.  
  42. int FAR PASCAL
  43. WinMain(HANDLE hins, HANDLE hinsPrev, LPSTR lsz,
  44.   int wShow)
  45. /*****************************************************/
  46. /* -- hins        : This program's instance.         */
  47. /* -- hinsPrev    : Previous program's instance.     */
  48. /* -- lsz         : Command line I was invoked with. */
  49. /* -- wShow       : ShowWindow command.              */
  50. /*****************************************************/
  51.     {
  52.     MSG msg;
  53.  
  54.     if (hinsPrev == NULL)
  55.         {
  56.         WNDCLASS    wcs;
  57.  
  58.         /* First instance is responsible for */
  59.         /* registering a class. */
  60.         wcs.style = CS_HREDRAW | CS_VREDRAW;
  61.         wcs.lpfnWndProc = WndProc;
  62.         wcs.cbClsExtra = 0;
  63.         wcs.cbWndExtra = 0;
  64.         wcs.hInstance = hins;
  65.         wcs.hIcon = NULL;
  66.         wcs.hCursor = LoadCursor(NULL, IDC_ARROW);
  67.         wcs.hbrBackground =
  68.             GetStockObject(WHITE_BRUSH);
  69.         wcs.lpszMenuName = NULL;
  70.         wcs.lpszClassName = szScroll;
  71.  
  72.         if (!RegisterClass(&wcs))
  73.             return FALSE;
  74.         }
  75.  
  76.     /* Create the main window 1/16 the size of the */
  77.     /* screen. */
  78.     dxScreen = GetSystemMetrics(SM_CXSCREEN);
  79.     dyScreen = GetSystemMetrics(SM_CYSCREEN);
  80.     if (CreateWindow(
  81.         szScroll,
  82.         szScroll,
  83.         WS_OVERLAPPEDWINDOW | WS_VISIBLE,
  84.         CW_USEDEFAULT,
  85.         CW_USEDEFAULT,
  86.         dxScreen >> 2,
  87.         dyScreen >> 2,
  88.         NULL,
  89.         NULL,
  90.         hins,
  91.         NULL) == NULL)
  92.         return FALSE;
  93.  
  94.         while (GetMessage(&msg, NULL, 0, 0))
  95.             {
  96.             TranslateMessage(&msg);
  97.             DispatchMessage(&msg);
  98.             }
  99.  
  100.         return 0;
  101.         }
  102.  
  103. LONG FAR PASCAL
  104. WndProc(HWND hwnd, WORD wMessage, WORD wParam,
  105.   DWORD lwParam)
  106. /*****************************************************/
  107. /* -- WindowProc for our main window.                */
  108. /* -- hwnd    : Main window.                         */
  109. /* -- wMessage        : Message number.              */
  110. /* -- wParam, lwParam : Message parameters.          */
  111. /*****************************************************/
  112.     {
  113.     BOOL    fCallDef    = TRUE;
  114.  
  115.     switch (wMessage)
  116.         {
  117.     default:
  118.         break;
  119.  
  120.     case WM_DESTROY:
  121.         PostQuitMessage(0);
  122.         FreeBitmap();
  123.         break;
  124.  
  125.     case WM_SIZE:
  126.         dxWindow = LOWORD(lwParam);
  127.         dyWindow = HIWORD(lwParam);
  128.  
  129.         /* Just in case we would uncover past the */
  130.         /* right or bottom edges of the screen. */
  131.         ScrollBitmap(hwnd, 0, 0);
  132.         break;
  133.  
  134.     case WM_PAINT:
  135.         {
  136.         PAINTSTRUCT wps;
  137.  
  138.         /* Repaint the visible portion of the */
  139.         /* off-screen bitmap. */
  140.         BeginPaint(hwnd, &wps);
  141.         if (hdcMem != NULL)
  142.             BitBlt(wps.hdc,
  143.               wps.rcPaint.left,
  144.               wps.rcPaint.top,
  145.               wps.rcPaint.right - wps.rcPaint.left,
  146.               wps.rcPaint.bottom - wps.rcPaint.top,
  147.               hdcMem,
  148.               wps.rcPaint.left + ptBitmap.x,
  149.               wps.rcPaint.top + ptBitmap.y,
  150.               SRCCOPY);
  151.         EndPaint(hwnd, &wps);
  152.         fCallDef = FALSE;
  153.         }
  154.         break;  /* End case WM_PAINT. */
  155.  
  156.     case WM_KEYDOWN:
  157.         {
  158.         int dx  = 0;    /* Horizontal scroll amount. */
  159.         int dy  = 0;    /* Vertical scroll amount. */
  160.  
  161.         switch (wParam)
  162.             {
  163.         default:
  164.             break;
  165.  
  166.         case VK_LEFT:
  167.             dx = -1;
  168.             break;
  169.  
  170.         case VK_RIGHT:
  171.             dx = 1;
  172.             break;
  173.  
  174.         case VK_UP:
  175.             dy = -1;
  176.             break;
  177.  
  178.         case VK_DOWN:
  179.             dy = 1;
  180.             break;
  181.  
  182.         case VK_HOME:
  183.             dx = -(dxWindow >> 1);
  184.             break;
  185.  
  186.         case VK_END:
  187.             dx = (dxWindow >> 1);
  188.             break;
  189.  
  190.         case VK_PRIOR:
  191.             dy = -(dyWindow >> 1);
  192.             break;
  193.  
  194.         case VK_NEXT:
  195.             dy = (dyWindow >> 1);
  196.             break;
  197.  
  198.         case VK_RETURN:
  199.             FreeBitmap();
  200.             CaptureScreen();
  201.  
  202.             /* Force a repaint so we can see what's */
  203.             /* been captured. */
  204.             InvalidateRect(hwnd, NULL, TRUE);
  205.             UpdateWindow(hwnd);
  206.             break;
  207.             }   /* End switch wParam. */
  208.  
  209.         if (dx != 0 || dy != 0)
  210.             ScrollBitmap(hwnd, dx, dy);
  211.         }
  212.         break;  /* End VK_DOWN case. */
  213.         }       /* End switch wMessage. */
  214.  
  215.     return fCallDef ?
  216.       DefWindowProc(hwnd, wMessage, wParam, lwParam) : 0L;
  217.     }
  218.  
  219. VOID
  220. CaptureScreen()
  221. /*****************************************************/
  222. /* -- Create the off-screen bitmap.                  */
  223. /* -- Return TRUE for success.                       */
  224. /*****************************************************/
  225.     {
  226.     HWND    hwndDesktop = GetDesktopWindow();
  227.     HDC     hdcDesktop  = GetDC(hwndDesktop);
  228.  
  229.     if (hdcDesktop == NULL)
  230.         goto CaptureScreenExit;
  231.  
  232.     if ((hdcMem = CreateCompatibleDC(hdcDesktop)) ==
  233.       NULL)
  234.         goto CaptureScreenExit;
  235.  
  236.     /* Note.  When creating a compatible bitmap, */
  237.     /* don't base it on the memory dc unless you */
  238.     /* want a monochrome bitmap!  This is because */
  239.     /* the bitmap will be made compatible with the */
  240.     /* one already in the memory dc, which is a 1x1 */
  241.     /* monochrome by default.  So use the window */
  242.     /* based dc instead. */
  243.     if ((hbmp = CreateCompatibleBitmap(hdcDesktop,
  244.       dxScreen, dyScreen)) == NULL)
  245.         goto CaptureScreenExit;
  246.  
  247.     /* Copy the screen. */
  248.     if ((hbmpSav = SelectObject(hdcMem, hbmp)) == NULL)
  249.         goto CaptureScreenExit;
  250.  
  251.     BitBlt(hdcMem, 0, 0, dxScreen, dyScreen,
  252.       hdcDesktop, 0, 0, SRCCOPY);
  253.  
  254. CaptureScreenExit:
  255.     if (hdcDesktop != NULL)
  256.         ReleaseDC(hwndDesktop, hdcDesktop);
  257.     }
  258.  
  259. VOID
  260. FreeBitmap(VOID)
  261. /*****************************************************/
  262. /* -- Release bitmap and memory dc.                  */
  263. /*****************************************************/
  264.     {
  265.     if (hbmpSav != NULL)
  266.         {
  267.         SelectObject(hdcMem, hbmpSav);
  268.         hbmpSav = NULL;
  269.         }
  270.     if (hbmp != NULL)
  271.         {
  272.         DeleteObject(hbmp);
  273.         hbmp = NULL;
  274.         }
  275.     if (hdcMem != NULL)
  276.         {
  277.         DeleteDC(hdcMem);
  278.         hdcMem = NULL;
  279.         }
  280.     }
  281.  
  282. VOID
  283. ScrollBitmap(HWND hwnd, int dx, int dy)
  284. /*****************************************************/
  285. /* -- Scroll the contents of the window.             */
  286. /* -- hwnd   : Window to scroll.                     */
  287. /* -- dx, dy : Horizontal and vertical amounts to    */
  288. /*             scroll by.                            */
  289. /*****************************************************/
  290.     {
  291.     POINT   ptNew;
  292.  
  293.     if (hdcMem == NULL)
  294.         return;
  295.  
  296.     /* Make sure scroll would not put us over the */
  297.     /* edge. */
  298.     ptNew.x = ptBitmap.x + dx;
  299.     ptNew.y = ptBitmap.y + dy;
  300.  
  301.     if (ptNew.x < 0)
  302.         {
  303.         ptNew.x = 0;
  304.         dx = -ptBitmap.x;
  305.         }
  306.     else if (ptNew.x > dxScreen - dxWindow)
  307.         {
  308.         ptNew.x = dxScreen - dxWindow;
  309.         dx = ptNew.x - ptBitmap.x;
  310.         }
  311.  
  312.     if (ptNew.y < 0)
  313.         {
  314.         ptNew.y = 0;
  315.         dy = -ptBitmap.y;
  316.         }
  317.     else if (ptNew.y > dyScreen - dyWindow)
  318.         {
  319.         ptNew.y = dyScreen - dyWindow;
  320.         dy = ptNew.y - ptBitmap.y;
  321.         }
  322.  
  323.     if (dx == 0 && dy == 0)
  324.         return; /* No change. */
  325.  
  326.     /* Scroll the window.  Note that ScrollWindow() */
  327.     /* will invalidate the uncovered area, so we only */
  328.     /* have to update the window to force it to paint */
  329.     /* the exposed area. */
  330.     ScrollWindow(hwnd, -dx, -dy, NULL, NULL);
  331.     ptBitmap = ptNew;
  332.     UpdateWindow(hwnd);
  333.     }
  334.  
  335.