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

Windows编程

开发平台:

Visual C++

  1. /************************************************************************
  2.  *      Module:  shadow.c
  3.  *
  4.  ***********************************************************************/
  5. // This is a part of the Microsoft Foundation Classes C++ library.
  6. // Copyright (C) 1992-1998 Microsoft Corporation
  7. // All rights reserved.
  8. //
  9. // This source code is only intended as a supplement to the
  10. // Microsoft Foundation Classes Reference and related
  11. // electronic documentation provided with the library.
  12. // See these sources for detailed information regarding the
  13. // Microsoft Foundation Classes product.
  14. #include "stdafx.h"
  15. #include "shadow.h"
  16. VOID NEAR PASCAL Draw3DLine1( HDC hDC, UINT x, UINT y, UINT nLen, UINT wFlags ) ;
  17. VOID NEAR PASCAL DrawFrame( HDC hDC, LPRECT lprc ) ;
  18. #define SHADOWWIDTH  1
  19. /****************************************************************
  20.  *  VOID WINAPI tdDraw3DCrease( HDC hDC, LPRECT lprc, UINT uiFlags )
  21.  *
  22.  *  Description:
  23.  *
  24.  *
  25.  *
  26.  *  Comments:
  27.  *
  28.  ****************************************************************/
  29. VOID WINAPI tdDraw3DCrease( HDC hDC, LPRECT lpRect, UINT uiFlags )
  30. {
  31.    RECT       rc ;
  32.    COLORREF   rgbOld ;
  33.    rc = *lpRect ;
  34.    if (uiFlags & DRAW3D_OUT)
  35.   OffsetRect( &rc, 1, 1 ) ;
  36.    rgbOld = SetBkColor( hDC, tdGetShadowColor( GetBkColor( hDC ) ) ) ;
  37.    DrawFrame( hDC, &rc ) ;
  38.    if (uiFlags & DRAW3D_OUT)
  39.   OffsetRect( &rc, -1, -1 ) ;
  40.    else
  41.   OffsetRect( &rc, 1, 1 ) ;
  42.    SetBkColor( hDC, tdGetHighlightColor( rgbOld ) ) ;
  43.    DrawFrame( hDC, &rc ) ;
  44.    SetBkColor( hDC, rgbOld ) ;
  45. } /* tdDraw3DCrease()  */
  46. /** VOID WINAPI tdDraw3DRect( HDC, LPRECT, UINT, UINT )
  47.  *
  48.  *  DESCRIPTION:
  49.  *      Draws a 3D rectangle that is shaded.  wFlags can be used to
  50.  *      control how the rectangle looks.
  51.  *
  52.  *  ARGUMENTS:
  53.  *      HDC hDC             :   Handle to the device context that will be
  54.  *                              used to display the rectangle.
  55.  *
  56.  *      RECT rect           :   A rectangle describing the dimensions of
  57.  *                              the rectangle in device coordinates.
  58.  *
  59.  *      UINT wShadowWidth   :   Width of the shadow in device coordinates.
  60.  *
  61.  *      UINT wFlags         :   The following flags may be passed to describe
  62.  *                              the style of the rectangle:
  63.  *
  64.  *                              DRAW3D_IN   :   The shadow is drawn such that
  65.  *                              the box appears to be sunk in to the screen.
  66.  *                              This is default if 0 is passed.
  67.  *
  68.  *                              DRAW3D_OUT  :   The shadow is drawn such that
  69.  *                              the box appears to be sticking out of the
  70.  *                              screen.
  71.  *
  72.  *  RETURN (VOID WINAPI):
  73.  *      The 3D looking rectangle will have been drawn into the DC.
  74.  *
  75.  *  NOTES:
  76.  *
  77.  ** cjp */
  78. VOID WINAPI tdDraw3DRect( HDC hDC, LPRECT lpRect,
  79.    UINT uiShadowWidth, UINT uiFlags )
  80. {
  81.    /* sanity check--don't work if you don't have to! */
  82.    if ( !uiShadowWidth || !RectVisible( hDC, lpRect ) )
  83.    return ;
  84.    if (uiFlags & DRAW3D_CREASE)
  85.    {
  86.   tdDraw3DCrease( hDC, lpRect, uiFlags ) ;
  87.   return ;
  88.    }
  89.    /* if width is 1 use lines instead of polygons */
  90.    if (uiShadowWidth == 1)
  91.    {
  92.   /* draw the top line */
  93.   Draw3DLine1( hDC, lpRect->left, lpRect->top,
  94.  lpRect->right - lpRect->left,
  95.  DRAW3D_TOPLINE | uiFlags ) ;
  96.   /* right line */
  97.   Draw3DLine1( hDC, lpRect->right, lpRect->top,
  98.  lpRect->bottom - lpRect->top,
  99.  DRAW3D_RIGHTLINE | uiFlags ) ;
  100.   /* bottom line */
  101.   Draw3DLine1( hDC, lpRect->left, lpRect->bottom,
  102.  lpRect->right - lpRect->left,
  103.  DRAW3D_BOTTOMLINE | uiFlags ) ;
  104.   /* left line */
  105.   Draw3DLine1( hDC, lpRect->left, lpRect->top,
  106.  lpRect->bottom - lpRect->top,
  107.  DRAW3D_LEFTLINE | uiFlags ) ;
  108.    }
  109.    else
  110.    {
  111.   /* draw the top line */
  112.   tdDraw3DLine( hDC, lpRect->left, lpRect->top,
  113.  lpRect->right - lpRect->left,
  114.  uiShadowWidth, DRAW3D_TOPLINE | uiFlags ) ;
  115.   /* right line */
  116.   tdDraw3DLine( hDC, lpRect->right, lpRect->top,
  117.  lpRect->bottom - lpRect->top,
  118.  uiShadowWidth, DRAW3D_RIGHTLINE | uiFlags ) ;
  119.   /* bottom line */
  120.   tdDraw3DLine( hDC, lpRect->left, lpRect->bottom,
  121.  lpRect->right - lpRect->left,
  122.  uiShadowWidth, DRAW3D_BOTTOMLINE | uiFlags ) ;
  123.   /* left line */
  124.   tdDraw3DLine( hDC, lpRect->left, lpRect->top,
  125.  lpRect->bottom - lpRect->top,
  126.  uiShadowWidth, DRAW3D_LEFTLINE | uiFlags ) ;
  127.    }
  128. } /* Draw3DRect() */
  129. /** VOID WINAPI tdDraw3DLine( HDC hDC, UINT x, UINT y, UINT nLen,
  130.  *
  131.  *  DESCRIPTION:
  132.  *      Draws a 3D line that can be used to make a 3D box.
  133.  *
  134.  *  ARGUMENTS:
  135.  *      HDC hDC             :   Handle to the device context that will be
  136.  *                              used to display the 3D line.
  137.  *
  138.  *      UINT x, y           :   Coordinates of the beginning of the line.
  139.  *                              These coordinates are in device UINTs and
  140.  *                              represent the _outside_ most point. Horiz-
  141.  *                              ontal lines are drawn from left to right and
  142.  *                              vertical lines are drawn from top to bottom.
  143.  *
  144.  *      UINT uiShadowWidth   :   Width of the shadow in device coordinates.
  145.  *
  146.  *      UINT  uiFlags        :   The following flags may be passed to
  147.  *                              describe the style of the 3D line:
  148.  *
  149.  *                              DRAW3D_IN   :   The shadow is drawn such that
  150.  *                              the box appears to be sunk in to the screen.
  151.  *                              This is default if 0 is passed.
  152.  *
  153.  *                              DRAW3D_OUT  :   The shadow is drawn such that
  154.  *                              the box appears to be sticking out of the
  155.  *                              screen.
  156.  *
  157.  *                              DRAW3D_TOPLINE, _BOTTOMLINE, _LEFTLINE, and
  158.  *                              _RIGHTLINE  :   Specifies that a "top",
  159.  *                              "Bottom", "Left", or"Right" line is to be
  160.  *                              drawn.
  161.  *
  162.  *  RETURN (VOID WINAPI):
  163.  *      The line will have been drawn into the DC.
  164.  *
  165.  *  NOTES:
  166.  *
  167.  ** cjp */
  168. VOID WINAPI tdDraw3DLine( HDC hDC, UINT x, UINT y, UINT uiLen,
  169.    UINT uiShadowWidth, UINT uiFlags )
  170. {
  171.    HBRUSH  hBrush ;
  172.    BOOL    fDark ;
  173.    POINT   Point[ 4 ] ;         /* define a polgon with 4 points    */
  174.    /* if width is zero, don't do nothin'! */
  175.    if ( !uiShadowWidth )
  176.    return ;
  177.    /* if width is 1 use lines instead of polygons */
  178.    if (uiShadowWidth == 1)
  179.    {
  180.   Draw3DLine1( hDC, x, y, uiLen, uiFlags ) ;
  181.   return ;
  182.    }
  183.    /* define shape of polygon--origin is always the same */
  184.    Point[0].x = x ;
  185.    Point[0].y = y ;
  186.    /*  To do this we'll simply draw a polygon with four sides, using
  187. *  the appropriate brush.  I dare you to ask me why this isn't a
  188. *  switch/case!
  189. */
  190.    if ( uiFlags & DRAW3D_TOPLINE )
  191.    {
  192.    /* across to right */
  193.    Point[1].x = x + uiLen - (uiShadowWidth == 1 ? 1 : 0) ;
  194.    Point[1].y = y ;
  195.    /* down/left */
  196.    Point[2].x = x + uiLen - uiShadowWidth ;
  197.    Point[2].y = y + uiShadowWidth ;
  198.    /* accross to left */
  199.    Point[3].x = x + uiShadowWidth ;
  200.    Point[3].y = y + uiShadowWidth ;
  201.    /* select 'dark' brush if 'in'--'light' for 'out' */
  202.    fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ;
  203.    }
  204.    /* possibly the bottom? */
  205.    else if ( uiFlags & DRAW3D_BOTTOMLINE )
  206.    {
  207.    /* across to right */
  208.    Point[1].x = x + uiLen ;
  209.    Point[1].y = y ;
  210.    /* up/left */
  211.    Point[2].x = x + uiLen - uiShadowWidth ;
  212.    Point[2].y = y - uiShadowWidth ;
  213.    /* accross to left */
  214.    Point[3].x = x + uiShadowWidth ;
  215.    Point[3].y = y - uiShadowWidth ;
  216.    /* select 'light' brush if 'in' */
  217.    fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ;
  218.    }
  219.    /* ok, it's gotta be left? */
  220.    else if ( uiFlags & DRAW3D_LEFTLINE )
  221.    {
  222.    /* down */
  223.    Point[1].x = x ;
  224.    Point[1].y = y + uiLen - (uiShadowWidth == 1 ? 1 : 0) ;
  225.    /* up/right */
  226.    Point[2].x = x + uiShadowWidth ;
  227.    Point[2].y = y + uiLen - uiShadowWidth ;
  228.    /* down */
  229.    Point[3].x = x + uiShadowWidth ;
  230.    Point[3].y = y + uiShadowWidth ;
  231.    /* select 'dark' brush if 'in'--'light' for 'out' */
  232.    fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ;
  233.    }
  234.    /* well maybe it's for the right side? */
  235.    else if ( uiFlags & DRAW3D_RIGHTLINE )
  236.    {
  237.    /* down */
  238.    Point[1].x = x ;
  239.    Point[1].y = y + uiLen ;
  240.    /* up/left */
  241.    Point[2].x = x - uiShadowWidth ;
  242.    Point[2].y = y + uiLen - uiShadowWidth ;
  243.    /* up */
  244.    Point[3].x = x - uiShadowWidth ;
  245.    Point[3].y = y + uiShadowWidth ;
  246.    /* select 'light' brush if 'in' */
  247.    fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ;
  248.    }
  249.    else
  250. return ;
  251.    /* select NULL_PEN for no borders */
  252.    SelectObject( hDC, GetStockObject( NULL_PEN ) ) ;
  253.    /* select the appropriate color for the fill */
  254.    hBrush = CreateSolidBrush( GetNearestColor( hDC, fDark ?
  255.   tdGetShadowColor( GetBkColor( hDC ) ) :
  256.   tdGetHighlightColor( GetBkColor( hDC ) ) ) ) ;
  257.    hBrush = (HBRUSH)SelectObject( hDC, hBrush ) ;
  258.    /* finally, draw the dern thing */
  259.    Polygon( hDC, (LPPOINT)&Point, 4 ) ;
  260.    /* restore what we killed */
  261.    hBrush = (HBRUSH)SelectObject( hDC, hBrush ) ;
  262.    DeleteObject( hBrush ) ;
  263. } /*tdDraw3DLine() */
  264. /****************************************************************
  265.  *  COLORREF WINAPI tdGetHighLightColor( COLORREF rgb )
  266.  *
  267.  *  Description:
  268.  *
  269.  *    This function returns the highlight color that corresponds
  270.  *    to the given rgb value.  If there is no "high intensity"
  271.  *    color that matches, white is used (or yellow if the color
  272.  *    is white).
  273.  *
  274.  *  Comments:
  275.  *
  276.  ****************************************************************/
  277. COLORREF WINAPI tdGetHighlightColor( COLORREF rgb )
  278. {
  279.    BYTE  cRed, cGreen, cBlue ;
  280. #if _MFC_VER >= 0x0300
  281. if (rgb == GetSysColor( COLOR_BTNFACE ))
  282. return GetSysColor( COLOR_BTNHIGHLIGHT ) ;
  283. #endif
  284.    if (rgb == RGBLTRED     ||
  285.    rgb == RGBLTGREEN   ||
  286.    rgb == RGBLTBLUE    ||
  287.    rgb == RGBLTMAGENTA ||
  288.    rgb == RGBLTCYAN    ||
  289.    rgb == RGBLTGRAY    ||
  290.    rgb == RGBYELLOW)
  291.   return RGBWHITE ;
  292.    if (rgb == RGBWHITE)
  293.   return RGBLTGRAY ;
  294.    if (rgb == RGBBLACK || rgb == RGBGRAY)
  295.   return RGBLTGRAY ;
  296.    cRed = (BYTE)(rgb & 0x000000FF) ;
  297.    cGreen = (BYTE)((rgb & 0x0000FF00) >> 8) ;
  298.    cBlue = (BYTE)((rgb & 0x00FF0000) >> 16) ;
  299.    if (cRed == 128)
  300.   cRed += 64 ;
  301.    if (cGreen == 128)
  302.   cGreen += 64 ;
  303.    if (cBlue == 128)
  304.   cBlue += 64 ;
  305.    return RGB( cRed, cGreen, cBlue ) ;
  306. } /* tdGetHighlightColor()  */
  307. /****************************************************************
  308.  *  COLORREF WINAPI tdGetShadowColor( COLORREF rgb )
  309.  *
  310.  *  Description:
  311.  *
  312.  *    Returns an appropriate shadow color for the given rgb.
  313.  *
  314.  *  Comments:
  315.  *
  316.  ****************************************************************/
  317. COLORREF WINAPI tdGetShadowColor( COLORREF rgb )
  318. {
  319. if (rgb == GetSysColor( COLOR_BTNFACE ))
  320. return GetSysColor( COLOR_BTNSHADOW ) ;
  321.    BYTE  cRed, cGreen, cBlue ;
  322.    if (rgb == RGBBLACK)
  323.   return RGBGRAY ;
  324.    if (rgb == RGBRED     ||
  325.    rgb == RGBGREEN   ||
  326.    rgb == RGBBLUE    ||
  327.    rgb == RGBBROWN   ||
  328.    rgb == RGBMAGENTA ||
  329.    rgb == RGBCYAN    ||
  330.    rgb == RGBWHITE   ||
  331.    rgb == RGBGRAY)
  332.   return RGBBLACK ;
  333.    if (rgb == RGBLTGRAY)
  334.   return RGBGRAY ;
  335.    cRed = (BYTE)(rgb & 0x000000FF) ;
  336.    cGreen = (BYTE)((rgb & 0x0000FF00) >> 8) ;
  337.    cBlue = (BYTE)((rgb & 0x00FF0000) >> 16) ;
  338.    if (cRed > 128)
  339.   cRed -= 64 ;
  340.    if (cGreen > 128)
  341.   cGreen -= 64 ;
  342.    if (cBlue > 128)
  343.   cBlue -= 64 ;
  344.    return RGB( cRed, cGreen, cBlue ) ;
  345. } /* tdGetShadowColor()  */
  346. /*
  347.  *====================================================================
  348.  *  Internal functions
  349.  *====================================================================
  350.  */
  351. /****************************************************************
  352.  *  VOID NEAR PASCAL
  353.  *   Draw3DLine1( HDC hDC, UINT x, UINT y, UINT uiLen, UINT uiFlags )
  354.  *
  355.  *  Description:
  356.  *
  357.  *    Does the same thing astdDraw3DLine but for single width lines.
  358.  *
  359.  *  Comments:
  360.  *
  361.  ****************************************************************/
  362. VOID NEAR PASCAL
  363.    Draw3DLine1( HDC hDC, UINT x, UINT y, UINT uiLen, UINT uiFlags )
  364. {
  365.    BOOL    fDark ;
  366.    RECT    rc ;
  367.    COLORREF   rgbOld ;
  368.    if ( uiFlags & DRAW3D_TOPLINE )
  369.    {
  370.   rc.left = x ;
  371.   rc.right = rc.left + uiLen - 1 ;
  372.   rc.top = y ;
  373.   rc.bottom = y + 1 ;
  374.   fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ;
  375.    }
  376.    /* possibly the bottom? */
  377.    else if ( uiFlags & DRAW3D_BOTTOMLINE )
  378.    {
  379.   rc.left = x ;
  380.   rc.right = rc.left + uiLen - 1 ;
  381.   rc.top = y - 1 ;
  382.   rc.bottom = y ;
  383.   fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ;
  384.    }
  385.    /* ok, it's gotta be left? */
  386.    else if ( uiFlags & DRAW3D_LEFTLINE )
  387.    {
  388.   rc.left = x ;
  389.   rc.right = x + 1 ;
  390.   rc.top = y ;
  391.   rc.bottom = y + uiLen ;
  392.   fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ;
  393.    }
  394.    /* well maybe it's for the right side? */
  395.    else if ( uiFlags & DRAW3D_RIGHTLINE )
  396.    {
  397.   rc.left = x - 1 ;
  398.   rc.right = x ;
  399.   rc.top = y ;
  400.   rc.bottom = y + uiLen ;
  401.   fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ;
  402.    }
  403.    /* bad drugs? */
  404.    else return ;
  405.    /* select the appropriate color for the fill */
  406.    if ( fDark )
  407.   rgbOld = SetBkColor( hDC,
  408.    GetNearestColor( hDC, tdGetShadowColor( GetBkColor( hDC ) ) ) ) ;
  409.    else
  410.   rgbOld = SetBkColor( hDC,
  411.    GetNearestColor( hDC, tdGetHighlightColor( GetBkColor( hDC ) ) ) ) ;
  412.    /* finally, draw the dern thing */
  413.    ExtTextOut( hDC, x, y, ETO_OPAQUE, &rc, NULL, 0, NULL ) ;
  414.    SetBkColor( hDC, rgbOld ) ;
  415. } /* Draw3DLine1()  */
  416. VOID NEAR PASCAL DrawFrame( HDC hDC, LPRECT lprc )
  417. {
  418.    RECT    rc1 ;
  419.    /* perform CopyRect w/o bloody windows style overhead */
  420.    rc1 = *lprc ;
  421.    /* top */
  422.    rc1.top = lprc->top ;
  423.    rc1.left = lprc->left ;
  424.    rc1.bottom = lprc->top + 1 ;
  425.    rc1.right = lprc->right ;
  426.    /* blast it out */
  427.    ExtTextOut( hDC, rc1.left, rc1.top, ETO_OPAQUE, &rc1, NULL, 0, NULL ) ;
  428.    /* right */
  429.    rc1.left = lprc->right - 1 ;
  430.    rc1.bottom = lprc->bottom ;
  431.    /* blast this part now */
  432.    ExtTextOut( hDC, rc1.left, rc1.top, ETO_OPAQUE, &rc1, NULL, 0, NULL ) ;
  433.    /* left */
  434.    rc1.left = lprc->left ;
  435.    rc1.right = lprc->left + 1 ;
  436.    /* and another part */
  437.    ExtTextOut( hDC, rc1.left, rc1.top, ETO_OPAQUE, &rc1, NULL, 0, NULL ) ;
  438.    /* bottom */
  439.    rc1.right = lprc->right ;
  440.    rc1.top = lprc->bottom - 1 ;
  441.    /* finish it off */
  442.    ExtTextOut( hDC, rc1.left, rc1.top, ETO_OPAQUE, &rc1, NULL, 0, NULL ) ;
  443. } /* DrawFaceFrame() */
  444. /************************************************************************
  445.  * End of File: shadow.c
  446.  ***********************************************************************/