home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_03_03 / fader.exe / FADER / FADER.C < prev    next >
Text File  |  1991-11-17  |  17KB  |  545 lines

  1. /*
  2.      File name:    FADER.C
  3.      Description:  Main program for the fader custom control
  4.      Sequence:     This is Listing #1
  5. */
  6.  
  7. #include <windows.h>
  8. #include "fader.h"
  9.  
  10. #define NO_DRAG              0    /* Values of FADER_THUMBSTATE */
  11. #define DRAG                 1
  12.  
  13. #define FADER_THUMB_OFFSET   2    /* Distance in pixels from edge */
  14.  
  15. /* Window extra bytes */
  16. #define FADER_RANGE          0    /* logical range values returned */
  17. #define FADER_VALUE          4    /* Current logical value */
  18. #define FADER_THUMBSTATE     6    /* DRAG or NO_DRAG */
  19. #define FADER_WNDEXTRA       8    /* Total # of window extra bytes */
  20.  
  21. HANDLE hGlobFaderInstance = NULL;
  22. char szGlobControlName[] = "Fader";
  23.  
  24. /* Forward declarations for completeness */
  25.  
  26. static BOOL NEAR PASCAL RegisterControlClass (HANDLE hInstance);
  27. LONG FAR PASCAL FaderWndFn (HWND hWnd, WORD wMsg,
  28.             WORD wParam, LONG lParam);
  29. int GetThumbHeight(int iTotalHeight);
  30. void GetFaderThumbRect(HWND hWnd, LPRECT pRc, LPRECT pThumbRect,
  31.             int iCurPos);
  32. int  XlatPosPhysicalToLogical(LONG lLogRange, int iPhysMax,
  33.             int iPhysMin, int iCurPos);
  34. int  XlatPosLogicalToPhysical(LONG lLogRange, int iPhysMax,
  35.             int iPhysMin, int iLogPos);
  36. static void DrawCaret(HDC hDC, LPRECT lprc);
  37. static void PaintFader(HWND hWnd);
  38.  
  39. /* These are DLL initialization and control functions */
  40.  
  41. BOOL FAR PASCAL LibMain (HANDLE hModule, WORD wDataSeg,
  42.    WORD wHeapSize, LPSTR lpszCmdLine)
  43. {
  44.    hGlobFaderInstance = hModule;
  45.    if (wHeapSize != 0)  /* Moveable DS */
  46.       UnlockData(0);
  47.    return RegisterControlClass(hModule);
  48. }
  49.  
  50.  
  51. int FAR PASCAL WEP (int nSystemExit)
  52. {
  53.    UnregisterClass(szGlobControlName, hGlobFaderInstance);
  54.    return 1;                 /* never fails */
  55. }
  56.  
  57.  
  58. /* This function can be static if you only plan to use it
  59.    in a DLL */
  60.  
  61. BOOL NEAR PASCAL RegisterControlClass (HANDLE hInstance)
  62. {
  63.    WNDCLASS wc;
  64.  
  65.    wc.style         = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
  66.    wc.lpfnWndProc   = FaderWndFn;
  67.    wc.cbClsExtra    = 0;
  68.    wc.cbWndExtra    = FADER_WNDEXTRA;
  69.    wc.hInstance     = hInstance;
  70.    wc.hIcon         = NULL;
  71.    wc.hCursor       = LoadCursor(NULL, IDC_SIZENS);
  72.    wc.hbrBackground = COLOR_WINDOW + 1;
  73.    wc.lpszMenuName  = NULL;
  74.    wc.lpszClassName = szGlobControlName;
  75.    return RegisterClass(&wc);
  76. }
  77.  
  78.  
  79. /* This function is handy for sending the FDRN_... messages
  80.    back to the parent.  Note that FDRN_THUMBTRACK is disabled
  81.    unless FDRS_TRACK is enabled */
  82.  
  83. static LONG NEAR PASCAL NotifyParent (HWND hWnd,
  84.    WORD wNotifyCode)
  85. {
  86.    BOOL bSend=TRUE;
  87.  
  88.    if (wNotifyCode == FDRN_THUMBTRACK)
  89.       bSend = (BOOL) (GetWindowLong(hWnd, GWL_STYLE) & FDRS_TRACK);
  90.  
  91.    if (bSend)
  92.       return SendMessage(GetParent(hWnd), WM_COMMAND,
  93.              GetWindowWord(hWnd, GWW_ID),
  94.              MAKELONG(hWnd, wNotifyCode));
  95.    else
  96.       return 0;
  97. }
  98.  
  99.  
  100. /* This is the main "window function" procedure, it is called
  101.    sometimes by the SDK Dialog box editor */
  102.  
  103. LONG FAR PASCAL FaderWndFn (HWND hWnd, WORD wMsg,
  104.    WORD wParam, LONG lParam)
  105. {
  106.    LONG lResult = 0;
  107.    HDC hDC;
  108.    POINT pt;
  109.    RECT rc;
  110.    int iLogPos;
  111.    int iOldLogPos;
  112.    int iPhyPos;
  113.    int iMaxLog;
  114.    int iMinLog;
  115.    RECT thumb_rect;
  116.    LONG lLogRange;
  117.    int iThumbHalf;
  118.    HANDLE hNewBrush, hOldBrush;
  119.  
  120.    switch (wMsg) {
  121.       case WM_CREATE:
  122.          SendMessage(hWnd, FDRM_SETRANGE, 0, MAKELONG(0, 100));
  123.          SendMessage(hWnd, FDRM_SETLOGVALUE, 0, 0);
  124.          break;
  125.  
  126.       case WM_GETDLGCODE: /* interface query by dialog manager */
  127.          lResult = DLGC_WANTARROWS;
  128.          break;
  129.  
  130.       case WM_PAINT:
  131.          PaintFader(hWnd);
  132.          break;
  133.  
  134.       case WM_SETFOCUS: /* receiving the keyboard focus */
  135.       case WM_KILLFOCUS: /* losing the keyboard focus */
  136.             /* calculate update region */
  137.             GetClientRect(hWnd, &rc);
  138.             iLogPos = GetWindowWord(hWnd, FADER_VALUE);
  139.             GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect,
  140.                iLogPos);
  141.             if (thumb_rect.left == rc.left)
  142.                break;
  143.  
  144.             /* force a repaint */
  145.             hDC = GetDC( hWnd );
  146.             if (hDC) {
  147.                /* define appropriate brush & text colors */
  148.                if (hNewBrush = (HBRUSH)SendMessage( GetParent(hWnd),
  149.                   WM_CTLCOLOR, hDC, MAKELONG(hWnd,CTLCOLOR_BTN) ) )
  150.                   hOldBrush = SelectObject(hDC,hNewBrush);
  151.                else
  152.                   hOldBrush = NULL;
  153.  
  154.                /* draw caret */
  155.                DrawCaret(hDC, (LPRECT)&thumb_rect);
  156.  
  157.                /* restore original brush */
  158.                if ( hNewBrush ) {
  159.                   SelectObject( hDC, hOldBrush );
  160.                   DeleteObject( hNewBrush );
  161.                   }
  162.  
  163.                /* release display context */
  164.                ReleaseDC( hWnd, hDC );
  165.                }
  166.          break;
  167.  
  168.       case WM_KEYDOWN:    /* process virtual key code */
  169.          GetClientRect(hWnd, &rc);
  170.          iLogPos = (int)GetWindowWord(hWnd, FADER_VALUE);
  171.          iOldLogPos = iLogPos;
  172.          lLogRange = GetWindowLong(hWnd, FADER_RANGE);
  173.          iMaxLog = HIWORD(lLogRange);
  174.          iMinLog = LOWORD(lLogRange);
  175.  
  176.          switch (wParam) {
  177.             case VK_HOME : /* home key */
  178.                iLogPos = iMinLog;
  179.                break;
  180.  
  181.             case VK_END : /* end key */
  182.                iLogPos = iMaxLog;
  183.                break;
  184.  
  185.             case VK_LEFT : /* cursor left key */
  186.             case VK_DOWN : /* cursor down key */
  187.                if (iLogPos < iMaxLog)
  188.                   iLogPos++;
  189.                break;
  190.  
  191.             case VK_UP : /* cursor up key */
  192.             case VK_RIGHT : /* cursor right key */
  193.                if (iLogPos > iMinLog)
  194.                   iLogPos--;
  195.                break;
  196.  
  197.             case VK_PRIOR : /* page up key */
  198.                iLogPos -= (iMaxLog - iMinLog) / 8;
  199.                if (iLogPos < iMinLog)
  200.                   iLogPos = iMinLog;
  201.                break;
  202.  
  203.             case VK_NEXT : /* page down key */
  204.                iLogPos += (iMaxLog - iMinLog) / 8;
  205.                if (iLogPos > iMaxLog)
  206.                   iLogPos = iMaxLog;
  207.                break;
  208.  
  209.             default : /* something else */
  210.                break;
  211.             }
  212.  
  213.          if (iLogPos != iOldLogPos) /* did it change? */
  214.             {
  215.             SendMessage(hWnd, FDRM_SETLOGVALUE, iLogPos, 0);
  216.             NotifyParent(hWnd, FDRN_THUMBTRACK);
  217.  
  218.             /* Invalidate old position */
  219.             GetFaderThumbRect(hWnd, (LPRECT)&rc,
  220.                  (LPRECT)&thumb_rect, iOldLogPos);
  221.             InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
  222.  
  223.             /* Invalidate new position */
  224.             GetFaderThumbRect(hWnd, (LPRECT)&rc,
  225.                 (LPRECT)&thumb_rect, iLogPos);
  226.             InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
  227.             }
  228.          break;
  229.  
  230.       case WM_LBUTTONDOWN:
  231.          GetClientRect(hWnd, &rc);
  232.          iLogPos = GetWindowWord(hWnd, FADER_VALUE);
  233.          GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect, iLogPos);
  234.          pt = MAKEPOINT(lParam);
  235.          /* is the mouse in the "hot" rectangle? */
  236.          if ((thumb_rect.top <= pt.y) && (thumb_rect.bottom >= pt.y) &&
  237.             (thumb_rect.left <= pt.x) && (thumb_rect.right  >= pt.x)) {
  238.             SetWindowWord(hWnd, FADER_THUMBSTATE, DRAG);
  239.             hDC = GetDC(hWnd);
  240.             InvertRect(hDC, (LPRECT)&thumb_rect);
  241.             ReleaseDC(hWnd, hDC);
  242.  
  243.             NotifyParent(hWnd, FDRN_THUMBTRACK);
  244.             /* grab focus if necessary */
  245.             if ( GetFocus() != hWnd )
  246.                 SetFocus( hWnd );
  247.             /* Lock mouse on to this window */
  248.             SetCapture(hWnd);
  249.             }
  250.          break;
  251.  
  252.       case WM_MOUSEMOVE:
  253.       case WM_LBUTTONUP:
  254.          /* Nothing to do if not in drag! */
  255.          if ((wMsg == WM_MOUSEMOVE) &&
  256.              (GetWindowWord(hWnd, FADER_THUMBSTATE) != DRAG) ) {
  257.             lResult = DefWindowProc(hWnd, wMsg, wParam, lParam);
  258.             break;
  259.             }
  260.  
  261.          /* set the new current position and ask for redraw */
  262.          pt = MAKEPOINT(lParam);
  263.          GetClientRect(hWnd, &rc);
  264.          iLogPos = GetWindowWord(hWnd, FADER_VALUE);
  265.          lLogRange = GetWindowLong(hWnd, FADER_RANGE);
  266.  
  267.          /* Invalidate old position */
  268.          GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect, iLogPos);
  269.          InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
  270.  
  271.          iPhyPos = pt.y;
  272.          iThumbHalf = GetThumbHeight(rc.bottom)/2;
  273.          if (iPhyPos < iThumbHalf)
  274.             iPhyPos = iThumbHalf;
  275.          if (iPhyPos > rc.bottom-iThumbHalf)
  276.             iPhyPos = rc.bottom-iThumbHalf;
  277.  
  278.          iLogPos = XlatPosPhysicalToLogical(lLogRange,
  279.             rc.bottom-iThumbHalf, rc.top+iThumbHalf, iPhyPos);
  280.          GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect, iLogPos);
  281.          InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
  282.  
  283.          SetWindowWord(hWnd, FADER_VALUE, iLogPos);
  284.          NotifyParent(hWnd, FDRN_THUMBTRACK);
  285.  
  286.          if (wMsg == WM_LBUTTONUP) {
  287.             SetWindowWord(hWnd, FADER_THUMBSTATE, NO_DRAG);
  288.             NotifyParent(hWnd, FDRN_ENDFADER);
  289.             ReleaseCapture();
  290.             }
  291.          break;
  292.  
  293.       case FDRM_SETRANGE:
  294.          GetClientRect(hWnd, &rc);
  295.          InvalidateRect(hWnd, (LPRECT)&rc, TRUE);
  296.          SetWindowLong(hWnd, FADER_RANGE, lParam);
  297.          break;
  298.  
  299.       case FDRM_GETRANGE:
  300.          lResult = GetWindowLong(hWnd, FADER_RANGE);
  301.          break;
  302.  
  303.       case FDRM_SETLOGVALUE:
  304.          GetClientRect(hWnd, &rc);
  305.          InvalidateRect(hWnd, (LPRECT)&rc, TRUE);
  306.          SetWindowWord(hWnd, FADER_VALUE, wParam);
  307.          break;
  308.  
  309.       case FDRM_GETLOGVALUE:
  310.          lResult = GetWindowWord(hWnd, FADER_VALUE);
  311.          break;
  312.  
  313.       case FDRM_GETPHYSVALUE:
  314.          GetClientRect(hWnd, &rc);
  315.          iThumbHalf = GetThumbHeight(rc.bottom)/2;
  316.          lLogRange = GetWindowLong(hWnd, FADER_RANGE);
  317.          iLogPos = GetWindowWord(hWnd, FADER_VALUE);
  318.          lResult = (long) XlatPosLogicalToPhysical(lLogRange,
  319.             rc.bottom-iThumbHalf, rc.top+iThumbHalf, iLogPos);
  320.          break;
  321.  
  322.       case FDRM_SETPHYSVALUE:
  323.          GetClientRect(hWnd, &rc);
  324.          iThumbHalf = GetThumbHeight(rc.bottom)/2;
  325.          lLogRange = GetWindowLong(hWnd, FADER_RANGE);
  326.          iLogPos = XlatPosPhysicalToLogical(lLogRange,
  327.             rc.bottom-iThumbHalf, rc.top+iThumbHalf, wParam);
  328.          SetWindowWord(hWnd, FADER_VALUE, iLogPos);
  329.          InvalidateRect(hWnd, NULL, TRUE);
  330.          break;
  331.  
  332.       default:
  333.          lResult = DefWindowProc(hWnd, wMsg, wParam, lParam);
  334.          break;
  335.    }
  336.    return(lResult);
  337. }
  338.  
  339.  
  340.  
  341. /* This is a "helper" function which draws the entire fader */
  342.  
  343. static void PaintFader(HWND hWnd)
  344. {
  345.    PAINTSTRUCT ps;
  346.    HANDLE  hOldPen;
  347.    HANDLE hNewBrush, hOldBrush;
  348.    HANDLE hMyParent;
  349.    RECT thumb_rect;
  350.    int x_center, y_coord;
  351.    int iLogPos;
  352.    int iPhyPos;
  353.    int iThumbHalf;
  354.    LONG lLogRange;
  355.    HDC hDC;
  356.    RECT rc;
  357.  
  358.    /* Default system color is COLOR_BTNFACE  from WNDCLASS structure */
  359.    hDC = BeginPaint(hWnd, &ps);
  360.  
  361.    GetClientRect(hWnd, &rc);
  362.  
  363.    hOldPen = SelectObject( hDC,
  364.        CreatePen(PS_SOLID,1,GetSysColor(COLOR_WINDOWFRAME)) );
  365.  
  366.    /* define appropriate brush & text colors */
  367.    hMyParent = GetParent(hWnd);
  368.    if (hNewBrush = (HBRUSH)SendMessage( hMyParent, WM_CTLCOLOR,
  369.       ps.hdc, MAKELONG(hWnd,CTLCOLOR_FADER) ) )
  370.       hOldBrush = SelectObject(ps.hdc,hNewBrush);
  371.    else
  372.       hOldBrush = NULL;
  373.  
  374.    /* Draws with horizontal symmetry */
  375.    x_center = rc.right / 2;
  376.  
  377.    /* draw fader slot (clockwise) */
  378.    MoveTo(hDC, x_center, 1);
  379.    LineTo(hDC, x_center+1, 2);
  380.    LineTo(hDC, x_center+1, rc.bottom-2);
  381.    LineTo(hDC, x_center, rc.bottom-1);
  382.    LineTo(hDC, x_center-1, rc.bottom-2);
  383.    LineTo(hDC, x_center-1, 2);
  384.    LineTo(hDC, x_center, 1);
  385.  
  386.    /* draw gridlines (top to bottom, left to right) */
  387.    for (y_coord=3; y_coord < rc.bottom-3; y_coord+=3) {
  388.       /* Left half first */
  389.       MoveTo(hDC, 1, y_coord);
  390.       LineTo(hDC, x_center-1, y_coord);
  391.       /* Then right half */
  392.       MoveTo(hDC, x_center+2, y_coord);
  393.       LineTo(hDC, rc.right-1, y_coord);
  394.       }
  395.  
  396.    /* draw filled box and then dividing line */
  397.    iThumbHalf = GetThumbHeight(rc.bottom)/2;
  398.    iLogPos = GetWindowWord(hWnd, FADER_VALUE);
  399.    lLogRange = GetWindowLong(hWnd, FADER_RANGE);
  400.    iPhyPos =  XlatPosLogicalToPhysical(lLogRange, rc.bottom-iThumbHalf,
  401.             rc.top+iThumbHalf, iLogPos);
  402.  
  403.    GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect, iLogPos);
  404.  
  405.    /* restore original brush */
  406.    DeleteObject( SelectObject(hDC,hOldBrush) );
  407.  
  408.    /* now go to 3D button face brush */
  409.    hOldBrush = SelectObject( hDC,
  410.       CreateSolidBrush(GetSysColor(COLOR_BTNFACE)) );
  411.  
  412.    Rectangle(hDC, thumb_rect.left, thumb_rect.top,
  413.             thumb_rect.right, thumb_rect.bottom);
  414.  
  415.    DeleteObject( SelectObject(hDC,hOldBrush) );
  416.    if (iThumbHalf > 2)  /* Big enough for 3D paint */
  417.       {
  418.       DeleteObject( SelectObject(hDC,hOldPen) );
  419.       hOldPen = SelectObject( hDC,
  420.          CreatePen(PS_SOLID,1,GetSysColor(COLOR_WINDOW)) );
  421.       MoveTo(hDC, thumb_rect.left+1, thumb_rect.bottom-1);
  422.       LineTo(hDC, thumb_rect.left+1, thumb_rect.top+1);
  423.       LineTo(hDC, thumb_rect.right-1, thumb_rect.top+1);
  424.       DeleteObject( SelectObject(hDC,hOldPen) );
  425.  
  426.       hOldPen = SelectObject( hDC,
  427.          CreatePen(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW)) );
  428.       MoveTo(hDC, thumb_rect.right-1, thumb_rect.top+1);
  429.       LineTo(hDC, thumb_rect.right-1, thumb_rect.bottom-1);
  430.       LineTo(hDC, thumb_rect.left+1, thumb_rect.bottom-1);
  431.       }
  432.    /* restore original pen */
  433.    DeleteObject( SelectObject(hDC,hOldPen) );
  434.    DeleteObject( SelectObject(hDC,hOldBrush) );
  435.  
  436.  
  437.    EndPaint(hWnd, &ps);
  438. }
  439.  
  440.  
  441.  
  442. /* Thumb height is magically 1/8th of window height */
  443.  
  444. int GetThumbHeight(int iTotalHeight)
  445. {
  446.    return max(iTotalHeight/8, 2);
  447. }
  448.  
  449.  
  450. /* The fader button is always 1/8th the heighth of the window
  451.    and 1/2 the width of the window */
  452.  
  453. void GetFaderThumbRect(HWND hWnd, LPRECT pRc,
  454.      LPRECT pThumbRect, int iLogPos)
  455. {
  456.    int x_center;
  457.    int iPhyPos;
  458.    int iThumbHalf;
  459.    LONG lLogRange;
  460.  
  461.    lLogRange = GetWindowLong(hWnd, FADER_RANGE);
  462.    iThumbHalf = GetThumbHeight(pRc->bottom) / 2;
  463.    iPhyPos = XlatPosLogicalToPhysical(lLogRange,
  464.       pRc->bottom - iThumbHalf, pRc->top + iThumbHalf,
  465.       iLogPos);
  466.    x_center = pRc->right / 2;
  467.    pThumbRect->left   = x_center / 2;
  468.    pThumbRect->top    = iPhyPos - iThumbHalf;
  469.    pThumbRect->right  = (3 * x_center) / 2;
  470.    pThumbRect->bottom = iPhyPos + iThumbHalf;
  471. }
  472.  
  473.  
  474. /* This "helper" function maps from pixel coordinates to
  475.    logical positions */
  476.  
  477. int XlatPosPhysicalToLogical(LONG lLogRange, int iPhysMax,
  478.             int iPhysMin, int iPhyPos)
  479. {
  480.    int iLogMin;
  481.    int iLogMax;
  482.    int iResult;
  483.    double dScale;
  484.  
  485.    iLogMax = HIWORD(lLogRange);
  486.    iLogMin = LOWORD(lLogRange);
  487.    dScale = (double)(iPhysMax - iPhyPos) /
  488.             (double)(iPhysMax - iPhysMin);
  489.    iResult = (int) ((double)iLogMin + (iLogMax-iLogMin)*(1-dScale));
  490.    return iResult;
  491. }
  492.  
  493.  
  494. /* This "helper" function maps from logical positions to
  495.    physical pixel coordinates */
  496.  
  497. int XlatPosLogicalToPhysical(LONG lLogRange, int iPhysMax,
  498.             int iPhysMin, int iLogPos)
  499. {
  500.    int iLogMin;
  501.    int iLogMax;
  502.    int iResult;
  503.    double dScale;
  504.  
  505.    iLogMax = HIWORD(lLogRange);
  506.    iLogMin = LOWORD(lLogRange);
  507.  
  508.    dScale = (double)(iLogMax - iLogPos) /
  509.             (double)(iLogMax - iLogMin);
  510.    iResult = (int) ((double)iPhysMin + (iPhysMax-iPhysMin)*(1-dScale));
  511.    return iResult;
  512. }
  513.  
  514.  
  515.  
  516. /* The "caret" is a way of highlighting the controls which are
  517.    active and inactive.  Note that a ones-complement is used so we
  518.    don't need to know the previous state */
  519.  
  520. void DrawCaret(HDC hDC, LPRECT lprc)
  521. {
  522.    HBRUSH      hOldBrush;
  523.    int iWidth;
  524.    int iHeight;
  525.  
  526.    if (lprc->bottom - lprc->top < 4)
  527.       return;
  528.  
  529.    /* initialize display context */
  530.    hOldBrush = (HBRUSH)SelectObject( hDC,
  531.       GetStockObject(GRAY_BRUSH) );
  532.  
  533.    /* draw caret */
  534.    iWidth = lprc->right - lprc->left;
  535.    iHeight = lprc->bottom - lprc->top;
  536.  
  537.    PatBlt( hDC, lprc->left+1, lprc->top+1, iWidth-2, 3, PATINVERT );
  538.    PatBlt( hDC, lprc->right-4, lprc->top+1, 3, iHeight-2, PATINVERT );
  539.    PatBlt( hDC, lprc->left+1, lprc->bottom-4, iWidth-2, 3, PATINVERT );
  540.    PatBlt( hDC, lprc->left+1, lprc->top+1, 3, iHeight-2, PATINVERT );
  541.  
  542.    /* restore display context */
  543.    SelectObject( hDC, hOldBrush );
  544. }
  545.