ARROW.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:11k
源码类别:

Windows编程

开发平台:

Visual C++

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