home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / video / vidcap / arrow.c next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  10.8 KB  |  374 lines

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (C) 1992 - 1997 Microsoft Corporation.  All Rights Reserved.
  9.  *
  10.  **************************************************************************/
  11. /****************************************************************************
  12.  *
  13.  *   arrow.c: Arrow control window
  14.  *
  15.  *   Vidcap32 Source code
  16.  *
  17.  ***************************************************************************/
  18.  
  19.  
  20. #include <windows.h>
  21. #include <windowsx.h>
  22.  
  23. #include <stdlib.h>
  24.  
  25. #include "arrow.h"
  26.  
  27.  
  28. // a few porting macros
  29. #ifdef _WIN32
  30. #define SENDSCROLL(hwnd, msg, a, b, h)           \
  31.         SendMessage(hwnd, msg, (UINT)MAKELONG(a,b), (LONG)(h))
  32.  
  33. #define EXPORT
  34.  
  35. #else
  36. #define SENDSCROLL(hwnd, msg, a, b, h)
  37.         SendMessage(hwnd, msg, a, MAKELONG(b,h))   // handle is in HIWORD
  38.  
  39. #endif
  40.  
  41.  
  42. #ifndef LONG2POINT
  43.     #define LONG2POINT(l, pt)               ((pt).x = (SHORT)LOWORD(l), (pt).y = (SHORT)HIWORD(l))
  44. #endif
  45. #define GWID(hwnd)      (GetDlgCtrlID(hwnd))
  46.  
  47.  
  48. #define SHIFT_TO_DOUBLE 1
  49. #define DOUBLECLICK     0
  50. #define POINTSPERARROW  3
  51. #define ARROWXAXIS      15
  52. #define ARROWYAXIS      15
  53.  
  54. POINT ArrowUp[POINTSPERARROW] = {7,1, 3,5, 11,5};
  55. POINT ArrowDown[POINTSPERARROW] = {7,13, 3,9, 11,9};
  56.  
  57. static    BOOL      bRight;
  58. static    RECT      rUp, rDown;
  59. static    LPRECT    lpUpDown;
  60. static    FARPROC   lpArrowProc;
  61. static    HANDLE    hParent;
  62. BOOL      fInTimer;
  63.  
  64.  
  65. #define TEMP_BUFF_SIZE    32
  66.  
  67. #define SCROLLMSG(hwndTo, msg, code, hwndId)                                     \
  68.                           SENDSCROLL(hwndTo, msg, code, GWID(hwndId), hwndId)
  69.  
  70. /*
  71.  * @doc EXTERNAL WINCOM
  72.  *
  73.  * @api LONG | ArrowEditChange | This function is helps process the WM_VSCROLL
  74.  * message when using the Arrow controlled edit box.
  75.  * It will increment/decrement the value in the given edit box and return
  76.  * the new value.  Increment/decrement bounds are checked and Beep 0 is produced if
  77.  * the user attempts to go beyond the bounds.
  78.  *
  79.  * @parm        HWND | hwndEdit | Specifies a handle to the edit box window.
  80.  *
  81.  * @parm        UINT | wParam | Specifies the <p wParam> passed to the WM_VSCROLL message.
  82.  *
  83.  * @parm        LONG | lMin | Specifies the minimum value bound for decrements.
  84.  *
  85.  * @parm        LONG | lMax | Specifies the maximum value bound for increments.
  86.  *
  87.  * @rdesc       Returns the updated value of the edit box.
  88.  *
  89.  */
  90. LONG FAR PASCAL ArrowEditChange( HWND hwndEdit, UINT wParam,
  91.                                  LONG lMin, LONG lMax )
  92. {
  93.     char achTemp[TEMP_BUFF_SIZE];
  94.     LONG l;
  95.  
  96.     GetWindowText( hwndEdit, achTemp, TEMP_BUFF_SIZE );
  97.     l = atol(achTemp);
  98.     if( wParam == SB_LINEUP ) {
  99.         /* size kluge for now */
  100.         if( l < lMax ) {
  101.             l++;
  102.             wsprintf( achTemp, "%ld", l );
  103.             SetWindowText( hwndEdit, achTemp );
  104.         } else {
  105.         MessageBeep( 0 );
  106.         }
  107.     } else if( wParam == SB_LINEDOWN ) {
  108.         if( l > lMin ) {
  109.             l--;
  110.             wsprintf( achTemp, "%ld", l );
  111.             SetWindowText( hwndEdit, achTemp );
  112.         } else {
  113.             MessageBeep( 0 );
  114.         }
  115.     }
  116.     return( l );
  117.  
  118. }
  119.  
  120.  
  121.  
  122. UINT NEAR PASCAL UpOrDown()
  123. {
  124.     LONG pos;
  125.     UINT retval;
  126.     POINT pt;
  127.  
  128.     pos = GetMessagePos();
  129.     LONG2POINT(pos,pt);
  130.     if (PtInRect((LPRECT)&rUp, pt))
  131.         retval = SB_LINEUP;
  132.     else if (PtInRect((LPRECT)&rDown, pt))
  133.         retval = SB_LINEDOWN;
  134.     else
  135.         retval = (UINT)(-1);      /* -1, because SB_LINEUP == 0 */
  136.  
  137.     return(retval);
  138. }
  139.  
  140.  
  141.  
  142. UINT FAR PASCAL ArrowTimerProc(hWnd, wMsg, nID, dwTime)
  143. HANDLE hWnd;
  144. UINT wMsg;
  145. short nID;
  146. DWORD dwTime;
  147. {
  148.     UINT wScroll;
  149.  
  150.     if ((wScroll = UpOrDown()) != -1)
  151.     {
  152.         if (bRight == WM_RBUTTONDOWN)
  153.             wScroll += SB_PAGEUP - SB_LINEUP;
  154.         SCROLLMSG( hParent, WM_VSCROLL, wScroll, hWnd);
  155.     }
  156. /* Don't need to call KillTimer(), because SetTimer will reset the right one */
  157.     SetTimer(hWnd, nID, 50, (TIMERPROC)lpArrowProc);
  158.     return(0);
  159. }
  160.  
  161.  
  162. void InvertArrow(HANDLE hArrow, UINT wScroll)
  163. {
  164.     HDC hDC;
  165.  
  166.     lpUpDown = (wScroll == SB_LINEUP) ? &rUp : &rDown;
  167.     hDC = GetDC(hArrow);
  168.     ScreenToClient(hArrow, (LPPOINT)&(lpUpDown->left));
  169.     ScreenToClient(hArrow, (LPPOINT)&(lpUpDown->right));
  170.     InvertRect(hDC, lpUpDown);
  171.     ClientToScreen(hArrow, (LPPOINT)&(lpUpDown->left));
  172.     ClientToScreen(hArrow, (LPPOINT)&(lpUpDown->right));
  173.     ReleaseDC(hArrow, hDC);
  174.     ValidateRect(hArrow, lpUpDown);
  175.     return;
  176. }
  177.  
  178.  
  179. LONG FAR PASCAL EXPORT ArrowControlProc(HWND hArrow, unsigned message,
  180.                                          WPARAM wParam, LPARAM lParam)
  181. {
  182.     PAINTSTRUCT ps;
  183.     RECT        rArrow;
  184.     HBRUSH      hbr;
  185.     short       fUpDownOut;
  186.     UINT        wScroll;
  187.  
  188.     switch (message) {
  189. /*
  190.         case WM_CREATE:
  191.             break;
  192.  
  193.         case WM_DESTROY:
  194.             break;
  195. */
  196.  
  197.         case WM_MOUSEMOVE:
  198.             if (!bRight)  /* If not captured, don't worry about it */
  199.                 break;
  200.  
  201.             if (lpUpDown == &rUp)
  202.                 fUpDownOut = SB_LINEUP;
  203.             else if (lpUpDown == &rDown)
  204.                 fUpDownOut = SB_LINEDOWN;
  205.             else
  206.                 fUpDownOut = -1;
  207.  
  208.             switch (wScroll = UpOrDown()) {
  209.                 case SB_LINEUP:
  210.                     if (fUpDownOut == SB_LINEDOWN)
  211.                         InvertArrow(hArrow, SB_LINEDOWN);
  212.  
  213.                     if (fUpDownOut != SB_LINEUP)
  214.                         InvertArrow(hArrow, wScroll);
  215.  
  216.                     break;
  217.  
  218.                 case SB_LINEDOWN:
  219.                     if (fUpDownOut == SB_LINEUP)
  220.                         InvertArrow(hArrow, SB_LINEUP);
  221.  
  222.                     if (fUpDownOut != SB_LINEDOWN)
  223.                         InvertArrow(hArrow, wScroll);
  224.  
  225.                     break;
  226.  
  227.                 default:
  228.                     if (lpUpDown) {
  229.                         InvertArrow(hArrow, fUpDownOut);
  230.                         lpUpDown = 0;
  231.                     }
  232.                 }
  233.  
  234.                 break;
  235.  
  236.         case WM_RBUTTONDOWN:
  237.         case WM_LBUTTONDOWN:
  238.             if (bRight)
  239.                 break;
  240.  
  241.             bRight = message;
  242.             SetCapture(hArrow);
  243.             hParent = GetParent(hArrow);
  244.             GetWindowRect(hArrow, (LPRECT) &rUp);
  245.             CopyRect((LPRECT)&rDown, (LPRECT) &rUp);
  246.             rUp.bottom = (rUp.top + rUp.bottom) / 2;
  247.             rDown.top = rUp.bottom + 1;
  248.             wScroll = UpOrDown();
  249.             InvertArrow(hArrow, wScroll);
  250. #if SHIFT_TO_DOUBLE
  251.             if (wParam & MK_SHIFT) {
  252.                 if (message != WM_RBUTTONDOWN)
  253.                     goto ShiftLClick;
  254.                 else
  255.                     goto ShiftRClick;
  256.             }
  257. #endif
  258.             if (message == WM_RBUTTONDOWN)
  259.                 wScroll += SB_PAGEUP - SB_LINEUP;
  260.  
  261.             SCROLLMSG(hParent, WM_VSCROLL, wScroll, hArrow);
  262.  
  263.             lpArrowProc = MakeProcInstance((FARPROC) ArrowTimerProc,ghInst);
  264.             SetTimer(hArrow, GWID(hArrow), 200, (TIMERPROC)lpArrowProc);
  265.  
  266.             break;
  267.  
  268.         case WM_LBUTTONUP:
  269.         case WM_RBUTTONUP:
  270.             if ((bRight - WM_LBUTTONDOWN + WM_LBUTTONUP) == (int)message) {
  271.                 bRight = 0;
  272.                 ReleaseCapture();
  273.                 if (lpUpDown)
  274.                     InvertArrow(hArrow,(UINT)(lpUpDown==&rUp)?
  275.                                                         SB_LINEUP:SB_LINEDOWN);
  276.                 if (lpArrowProc) {
  277.                     SCROLLMSG(hParent, WM_VSCROLL, SB_ENDSCROLL, hArrow);
  278.                     KillTimer(hArrow, GWID(hArrow));
  279.  
  280.                     FreeProcInstance(lpArrowProc);
  281.                     ReleaseCapture();
  282.                     lpArrowProc = 0;
  283.                 }
  284.             }
  285.             break;
  286.  
  287.         case WM_LBUTTONDBLCLK:
  288. ShiftLClick:
  289.             wScroll = UpOrDown() + SB_TOP - SB_LINEUP;
  290.             SCROLLMSG(hParent, WM_VSCROLL, wScroll, hArrow);
  291.             SCROLLMSG(hParent, WM_VSCROLL, SB_ENDSCROLL, hArrow);
  292.  
  293.             break;
  294.  
  295.         case WM_RBUTTONDBLCLK:
  296. ShiftRClick:
  297.             wScroll = UpOrDown() + SB_THUMBPOSITION - SB_LINEUP;
  298.             SCROLLMSG(hParent, WM_VSCROLL, wScroll, hArrow);
  299.             SCROLLMSG(hParent, WM_VSCROLL, SB_ENDSCROLL, hArrow);
  300. /*
  301.             hDC = GetDC(hArrow);
  302.             InvertRect(hDC, (LPRECT) &rArrow);
  303.             ReleaseDC(hArrow, hDC);
  304.             ValidateRect(hArrow, (LPRECT) &rArrow);
  305. */
  306.             break;
  307.  
  308.         case WM_PAINT:
  309.             BeginPaint(hArrow, &ps);
  310.             GetClientRect(hArrow, (LPRECT) &rArrow);
  311.             hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  312.             FillRect(ps.hdc, (LPRECT)&rArrow, hbr);
  313.             DeleteObject(hbr);
  314.             hbr = SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH));
  315.             SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWFRAME));
  316.             SetMapMode(ps.hdc, MM_ANISOTROPIC);
  317.  
  318.             SetViewportOrgEx(ps.hdc, rArrow.left, rArrow.top, NULL);
  319.  
  320.             SetViewportExtEx(ps.hdc, rArrow.right - rArrow.left,
  321.                                                     rArrow.bottom - rArrow.top, NULL);
  322.             SetWindowOrgEx(ps.hdc, 0, 0, NULL);
  323.             SetWindowExtEx(ps.hdc, ARROWXAXIS, ARROWYAXIS, NULL);
  324.             MoveToEx(ps.hdc, 0, (ARROWYAXIS / 2), NULL);
  325.             LineTo(ps.hdc, ARROWXAXIS, (ARROWYAXIS / 2));
  326. /*
  327.             Polygon(ps.hdc, (LPPOINT) Arrow, 10);
  328. */
  329.             Polygon(ps.hdc, (LPPOINT) ArrowUp, POINTSPERARROW);
  330.             Polygon(ps.hdc, (LPPOINT) ArrowDown, POINTSPERARROW);
  331.             SelectObject(ps.hdc, hbr);
  332.  
  333.             EndPaint(hArrow, &ps);
  334.  
  335.             break;
  336.  
  337.         default:
  338.             return(DefWindowProc(hArrow, message, wParam, lParam));
  339.  
  340.             break;
  341.         }
  342.  
  343.     return(0L);
  344. }
  345.  
  346. #ifndef _WIN32
  347. #pragma alloc_text(_INIT, ArrowInit)
  348. #endif
  349.  
  350.  
  351. BOOL FAR PASCAL ArrowInit(HANDLE hInst)
  352. {
  353.     WNDCLASS wcArrow;
  354.  
  355.     wcArrow.lpszClassName = SPINARROW_CLASSNAME;
  356.     wcArrow.hInstance     = hInst;
  357.     wcArrow.lpfnWndProc   = ArrowControlProc;
  358.     wcArrow.hCursor       = LoadCursor(NULL, IDC_ARROW);
  359.     wcArrow.hIcon         = NULL;
  360.     wcArrow.lpszMenuName  = NULL;
  361.     wcArrow.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  362.     wcArrow.style         = CS_HREDRAW | CS_VREDRAW;
  363. #if DOUBLECLICK
  364.     wcArrow.style         |= CS_DBLCLKS;
  365. #endif
  366.     wcArrow.cbClsExtra    = 0;
  367.     wcArrow.cbWndExtra    = 0;
  368.  
  369.     if (!RegisterClass(&wcArrow))
  370.         return FALSE;
  371.  
  372.     return TRUE;
  373. }
  374.