QQ登录

只需一步,快速开始

上位机VC MFC通过自绘实现三角形按钮

[ 复制链接 ]
上位机VC MFC通过自绘实现三角形按钮

上位机VC MFC通过自绘实现三角形按钮

上位机VC MFC通过自绘实现三角形按钮


请点击此处下载

请先注册会员后在进行下载

已注册会员,请先登录后下载

文件名称:上位机VC MFC实现三角开按钮.rar 
文件大小:223.72 KB  售价:10金币
下载权限: 不限 以上或 VIP会员   [购买捐助会员]   [充值积分]   有问题联系我

  

如果您认可,可联系功能定制!

  

如果您着急,充值会员可直接联系发您资料!

  

QQ联系我

微信扫扫联系我

  



例程通过自绘实现三角形按钮,效果如图,程序运行会启动一定时器不停地设置按钮方向,可以通过复选按钮设备,另外按钮的文本与使能状态也可以实现修改;
主要也是通过自绘的形式实现三角形按钮效果。要通过重载函数PreSubclassWindow设置按钮类属性为自绘属性ModifyStyle(0, BS_OWNERDRAW);
另外为使按钮重绘时不致于难看,自己写了个窗口位置设备的函数SetWindowPos,保证按钮的窗口大小为2的倍数

1.新建基于对话框的应用程序
2.从Cbutton派生自己的类CTriangleBtn,添加自己的成员变量与函数
public:
  enumPOINTDIRECTION {POINT_UP, POINT_DOWN, POINT_LEFT, POINT_RIGHT};
  POINTDIRECTIONGetDirection(){return PointDirection;}
    voidSetDirection(POINTDIRECTION Direction){ PointDirection = DirectionreSubclassWindow();}
  BOOLSetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINTnFlags );
protected:
  POINTDIRECTIONPointDirection;
  CRgnCurrentRegion;
3.重载DrawItem,PreSubclassWindow实现自绘,
  1. void CTriangleBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  2. {
  3.         ASSERT(lpDrawItemStruct != NULL);
  4.         CRect rect = lpDrawItemStruct->rcItem;
  5.         CDC* pDC   = CDC::FromHandle(lpDrawItemStruct->hDC);
  6.         UINT state = lpDrawItemStruct->itemState;
  7.         UINT nStyle = GetStyle();

  8.         int nSavedDC = pDC->SaveDC();

  9.         //make the rect a square
  10.         rect.bottom = rect.right = min(rect.bottom, rect.right);
  11.         pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE));
  12.         
  13.         rect.right -= 1; rect.bottom -= 1;        //avoid drawing outside area

  14.         //make some pens
  15.         CPen HighlightPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT));
  16.         CPen DarkShadowPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW));
  17.         CPen ShadowPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
  18.         CPen BlackPen(PS_SOLID, 1, RGB(0,0,0));
  19.         //NOTE: If U use this class for NT apps only, use the implementation of FocusPen below
  20.         //                        instead, as WIN95 doesn't support this yet (though the doc says **dang ms-fools**)
  21.         //                        (WIN98 might also support this)
  22.         //LOGBRUSH logbrush; logbrush.lbStyle = BS_SOLID; logbrush.lbColor = RGB(0,0,0); logbrush.lbHatch = NULL;
  23.         //CPen FocusPen(PS_COSMETIC | PS_ALTERNATE, 1, &logbrush);
  24.         CPen FocusPen(PS_DOT, 0, RGB(0,0,0));
  25.          

  26.         //Draw button
  27.         switch (PointDirection) {
  28.                 case POINT_UP : {
  29.                         //Draw the raised/sunken edges of the button (unless flat)
  30.                         if (nStyle & BS_FLAT) {                                        //style is flat
  31.                                 pDC->SelectObject(BlackPen);
  32.                                 pDC->MoveTo(rect.right / 2, 0);
  33.                                 pDC->LineTo(0, rect.bottom);
  34.                                 pDC->LineTo(rect.right, rect.bottom);
  35.                                 pDC->LineTo(rect.right / 2, 0);
  36.                                 pDC->SelectObject(HighlightPen);
  37.                                 pDC->MoveTo(rect.right / 2, 2);
  38.                                 pDC->LineTo(2, rect.bottom - 1);
  39.                                 pDC->LineTo(rect.right - 2, rect.bottom - 1);
  40.                                 pDC->LineTo(rect.right / 2, 2);
  41.                         }        else {                                                                                                //style not flat
  42.                                 if ((state & ODS_SELECTED))        {        //Button is down        
  43.                                         pDC->SelectObject(HighlightPen);
  44.                                         pDC->MoveTo(0, rect.bottom);
  45.                                         pDC->LineTo(rect.right - 1, rect.bottom);
  46.                                         pDC->LineTo(rect.right / 2, 0);

  47.                                         pDC->SelectObject(ShadowPen);
  48.                                         pDC->LineTo(0, rect.bottom);                        
  49.                                        
  50.                                         pDC->SelectObject(DarkShadowPen);
  51.                                         pDC->MoveTo(rect.right / 2 - 1, 4);
  52.                                         pDC->LineTo(1, rect.bottom);
  53.                                 } else {                                                                                        //Button is not down
  54.                                         pDC->SelectObject(HighlightPen);
  55.                                         pDC->MoveTo(rect.right /2, 0);
  56.                                         pDC->LineTo(0, rect.bottom - 1);
  57.                                        
  58.                                         pDC->SelectObject(ShadowPen);
  59.                                         pDC->LineTo(rect.right - 1, rect.bottom - 1);
  60.                                         pDC->LineTo(rect.right / 2, 0);

  61.                                         pDC->SelectObject(DarkShadowPen);
  62.                                         pDC->MoveTo(rect.right / 2 + 2, 3);
  63.                                         pDC->LineTo(rect.right + 1, rect.bottom + 1);
  64.                                        
  65.                                         pDC->MoveTo(rect.right - 1, rect.bottom);
  66.                                         pDC->LineTo(1, rect.bottom);
  67.                                 }//else|if
  68.                         }//else|if        
  69.                         break;
  70.                 }//case
  71.         
  72.                 case POINT_DOWN : {
  73.                         //Draw the raised/sunken edges of the button (unless flat)
  74.                         if (nStyle & BS_FLAT) {                                        //style is flat
  75.                                 pDC->SelectObject(BlackPen);
  76.                                 pDC->MoveTo(rect.right / 2, rect.bottom);
  77.                                 pDC->LineTo(0, 0);
  78.                                 pDC->LineTo(rect.right, 0);
  79.                                 pDC->LineTo(rect.right / 2, rect.bottom);
  80.                                 
  81.                                 pDC->SelectObject(HighlightPen);
  82.                                 pDC->MoveTo(rect.right / 2, rect.bottom - 2);
  83.                                 pDC->LineTo(2, 1);
  84.                                 pDC->LineTo(rect.right - 2, 1);
  85.                                 pDC->LineTo(rect.right / 2, rect.bottom - 2);
  86.                         }        else {                                                                                                //style not flat
  87.                                 if ((state & ODS_SELECTED))        {        //Button is down        
  88.                                         pDC->SelectObject(ShadowPen);
  89.                                         pDC->MoveTo(rect.right, 1);
  90.                                         pDC->LineTo(1, 1);
  91.                                         pDC->LineTo(rect.right / 2, rect.bottom - 1);
  92.                                        
  93.                                         pDC->SelectObject(BlackPen);
  94.                                         pDC->MoveTo(rect.right - 2, 2);
  95.                                         pDC->LineTo(1, 2);
  96.                                        
  97.                                         pDC->SelectObject(HighlightPen);
  98.                                         pDC->MoveTo(rect.right + 1, 0);
  99.                                         pDC->LineTo(rect.right / 2 + 1, rect.bottom + 1);

  100.                                 } else {                                                                                        //Button is not down
  101.                                         pDC->SelectObject(ShadowPen);
  102.                                         pDC->MoveTo(0, 0);
  103.                                         pDC->LineTo(rect.right / 2, rect.bottom);
  104.                                         pDC->LineTo(rect.right, 0);
  105.                                         pDC->MoveTo(1, 1);
  106.                                         pDC->LineTo(rect.right / 2 + 1, rect.bottom);
  107.                                        
  108.                                         pDC->SelectObject(DarkShadowPen);
  109.                                         pDC->MoveTo(rect.right, 2);
  110.                                         pDC->LineTo(rect.right / 2 + 1, rect.bottom + 1);
  111.                                        
  112.                                         pDC->SelectObject(HighlightPen);
  113.                                         pDC->MoveTo(0, 0);
  114.                                         pDC->LineTo(rect.right, 0);
  115.                                 
  116.                                 }
  117.                         }//else|if
  118.                         break;
  119.                 }//case

  120.                 case POINT_LEFT : {
  121.                         if (nStyle & BS_FLAT) {                                        //style is flat
  122.                                 pDC->SelectObject(BlackPen);
  123.                                 pDC->MoveTo(rect.right, 0);
  124.                                 pDC->LineTo(0, rect.bottom / 2);
  125.                                 pDC->LineTo(rect.right, rect.bottom);
  126.                                 pDC->LineTo(rect.right, 0);
  127.                                 
  128.                                 pDC->SelectObject(HighlightPen);
  129.                                 pDC->MoveTo(rect.right - 1, 2);
  130.                                 pDC->LineTo(3, rect.bottom / 2);
  131.                                 pDC->LineTo(rect.right - 1, rect.bottom - 2);
  132.                                 pDC->LineTo(rect.right - 1, 2);
  133.                         }        else {                                                                                                //style not flat
  134.                                 if ((state & ODS_SELECTED))        {        //Button is down        
  135.                                         pDC->SelectObject(ShadowPen);
  136.                                         pDC->MoveTo(rect.right, 0);
  137.                                         pDC->LineTo(0, rect.bottom / 2);

  138.                                         pDC->SelectObject(DarkShadowPen);
  139.                                         pDC->MoveTo(rect.right, 1);
  140.                                         pDC->LineTo(2, rect.bottom / 2);
  141.                                        
  142.                                         pDC->SelectObject(HighlightPen);
  143.                                         pDC->MoveTo(rect.right, 0);
  144.                                         pDC->LineTo(rect.right, rect.bottom);
  145.                                         pDC->LineTo(0, rect.bottom / 2);
  146.                                 } else {                                                                                        //Button is not down
  147.                                         pDC->SelectObject(ShadowPen);
  148.                                         pDC->MoveTo(rect.right - 1, 0);
  149.                                         pDC->LineTo(rect.right - 1, rect.bottom - 1);
  150.                                         pDC->LineTo(0, rect.bottom / 2);
  151.                                         pDC->MoveTo(1, rect.bottom / 2 + 1);
  152.                                         pDC->LineTo(6, rect.bottom / 2 + 4);

  153.                                         pDC->SelectObject(DarkShadowPen);
  154.                                         pDC->MoveTo(rect.right, 1);
  155.                                         pDC->LineTo(rect.right, rect.bottom);
  156.                                         pDC->LineTo(2, rect.bottom / 2 + 2);
  157.                                        
  158.                                         pDC->SelectObject(HighlightPen);
  159.                                         pDC->MoveTo(0, rect.bottom / 2);
  160.                                         pDC->LineTo(rect.right, 0);
  161.                                 }
  162.                         }//else|if
  163.                         break;
  164.                 }//case

  165.                 case POINT_RIGHT : {
  166.                         if (nStyle & BS_FLAT) {                                        //style is flat
  167.                                 pDC->SelectObject(BlackPen);
  168.                                 pDC->MoveTo(0, 0);
  169.                                 pDC->LineTo(rect.right, rect.bottom / 2);
  170.                                 pDC->LineTo(0, rect.bottom);
  171.                                 pDC->LineTo(0, 0);
  172.                                 
  173.                                 pDC->SelectObject(HighlightPen);
  174.                                 pDC->MoveTo(1, 2);
  175.                                 pDC->LineTo(rect.right - 2, rect.bottom / 2);
  176.                                 pDC->LineTo(1, rect.bottom - 2);
  177.                                 pDC->LineTo(1, 2);
  178.                         }        else {                                                                                                //style not flat
  179.                                 if ((state & ODS_SELECTED))        {        //Button is down        
  180.                                         pDC->SelectObject(ShadowPen);
  181.                                         pDC->MoveTo(0, rect.bottom);
  182.                                         pDC->LineTo(0, 0);
  183.                                         pDC->LineTo(rect.right, rect.bottom / 2);

  184.                                         pDC->SelectObject(DarkShadowPen);
  185.                                         pDC->MoveTo(1, rect.bottom - 2);
  186.                                         pDC->LineTo(1, 1);
  187.                                         pDC->MoveTo(rect.right - 3, rect.bottom / 2);
  188.                                         pDC->LineTo(0, 1);
  189.                                        
  190.                                         pDC->SelectObject(HighlightPen);
  191.                                         pDC->MoveTo(0, rect.bottom);
  192.                                         pDC->LineTo(rect.right, rect.bottom / 2);
  193.                                        
  194.                                 } else {                                                                                        //Button is not down
  195.                                         pDC->SelectObject(ShadowPen);
  196.                                         pDC->MoveTo(0, rect.bottom);
  197.                                         pDC->LineTo(rect.right, rect.bottom / 2);

  198.                                         pDC->SelectObject(DarkShadowPen);
  199.                                         pDC->MoveTo(0, rect.bottom + 1);
  200.                                         pDC->LineTo(rect.right, rect.bottom / 2 + 1);
  201.                                        
  202.                                         pDC->SelectObject(HighlightPen);
  203.                                         pDC->MoveTo(0, rect.bottom);
  204.                                         pDC->LineTo(0, 0);
  205.                                         pDC->LineTo(rect.right, rect.bottom / 2);
  206.                                 }
  207.                         }//else|if

  208.                         break;
  209.                 }//case

  210.                 default :
  211.                         ASSERT(FALSE);
  212.         }//switch


  213.         //Draw text        if any
  214.         CString strText;
  215.         GetWindowText(strText);
  216.         if (!strText.IsEmpty()) {
  217.                 CSize TextExtent = pDC->GetTextExtent(strText);
  218.                 CPoint TextPos;
  219.                 pDC->SetBkMode(TRANSPARENT);

  220.                 switch (PointDirection) {
  221.                         case POINT_UP : {
  222.                                 TextPos = CPoint((int)(rect.right / 2.0 - TextExtent.cx / 2.0),
  223.                                                                                          rect.bottom - (int)(rect.bottom / 5.0 + TextExtent.cy));

  224.                                 int iXLimit = (int)((rect.bottom / 5.0 + TextExtent.cy) * 4.0 / 7.0);

  225.                                 CRgn rgn; rgn.CreateRectRgn(iXLimit, TextPos.y, rect.right - iXLimit, rect.bottom - 2);
  226.                                 pDC->SelectClipRgn(&rgn);
  227.                                 
  228.                                 break;
  229.                         }//case
  230.                         case POINT_DOWN : {
  231.                                 TextPos = CPoint((int)(rect.right / 2.0 - TextExtent.cx / 2.0),
  232.                                                                                          (int)(rect.bottom / 5.0));

  233.                                 int iXLimit = (int)((rect.bottom / 5.0 + TextExtent.cy) * 4.0 / 7.0);

  234.                                 CRgn rgn; rgn.CreateRectRgn(iXLimit, (int)(rect.bottom / 5.0), rect.right - iXLimit, (int)(rect.bottom / 5.0) + TextExtent.cy + 2);
  235.                                 pDC->SelectClipRgn(&rgn);
  236.                                 
  237.                                 break;
  238.                         }
  239.                         
  240.                         case POINT_LEFT : {
  241.                                 TextPos = CPoint((int)((rect.right / 2.0 - TextExtent.cx / 2.0) + (rect.right / 8.0)),
  242.                                                                                            (int)(rect.bottom / 2.0 - TextExtent.cy / 2.0) );

  243.                                 int iXLimitLeft = (int)(TextExtent.cy / 2.0 * 7.0 / 4.0) + 4;
  244.                                 int iXLimitRight = rect.right - 4;
  245.                         
  246.                                 CRgn rgn; rgn.CreateRectRgn(iXLimitLeft, (int)(rect.bottom / 2.0 - TextExtent.cy / 2.0),
  247.                                                                                                                                                 iXLimitRight, (int)(rect.bottom / 2.0 + TextExtent.cy / 2.0) );
  248.                                 pDC->SelectClipRgn(&rgn);

  249.                                 break;
  250.                         }//case

  251.                         case POINT_RIGHT : {
  252.                                 TextPos = CPoint((int)((rect.right / 2.0 - TextExtent.cx / 2.0) - (rect.right / 8.0)),
  253.                                                                                            (int)(rect.bottom / 2.0 - TextExtent.cy / 2.0) );

  254.                                 int iXLimitLeft = 4;
  255.                                 int iXLimitRight = rect.right - (int)(TextExtent.cy / 2.0 * 7.0 / 4.0) - 4;
  256.                                        
  257.                                 CRgn rgn; rgn.CreateRectRgn(iXLimitLeft, (int)(rect.bottom / 2.0 - TextExtent.cy / 2.0),
  258.                                                                                                                                                 iXLimitRight, (int)(rect.bottom / 2.0 + TextExtent.cy / 2.0) );
  259.                                 pDC->SelectClipRgn(&rgn);

  260.                                 break;
  261.                         }//case

  262.                         default :
  263.                                 ASSERT(FALSE);
  264.                 }//switch

  265.                 //common for all directions
  266.                 if (state & ODS_SELECTED) TextPos.Offset(1,1);

  267.                 if (state & ODS_DISABLED) {
  268.                         pDC->DrawState(TextPos, TextExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
  269.                 } else {
  270.                         pDC->TextOut(TextPos.x, TextPos.y, strText);
  271.                 }

  272.         }//if                        


  273.         //Draw the focus triangle on the inside of the button if we have focus
  274.         if ((state & ODS_FOCUS)) {
  275.                 CRgn rgn; rgn.CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
  276.                 pDC->SelectClipRgn(&rgn);
  277.                 pDC->SelectObject(FocusPen);
  278.                 switch (PointDirection) {
  279.                         case POINT_UP : {
  280.                                 pDC->MoveTo(rect.right / 2, 12);
  281.                                 pDC->LineTo(9, rect.bottom - 6);
  282.                                 pDC->LineTo(rect.right - 9, rect.bottom - 6);
  283.                                 pDC->LineTo(rect.right / 2, 12);
  284.                                 break;
  285.                         }
  286.                         case POINT_DOWN : {
  287.                                 pDC->MoveTo(rect.right / 2 + 1, rect.bottom - 13);
  288.                                 pDC->LineTo(10, 6);
  289.                                 pDC->LineTo(rect.right - 9, 6);
  290.                                 pDC->LineTo(rect.right / 2 + 1, rect.bottom - 13);
  291.                                 break;
  292.                         }
  293.                         case POINT_LEFT : {
  294.                                 pDC->MoveTo(12, rect.bottom / 2);
  295.                                 pDC->LineTo(rect.right - 6, 9);
  296.                                 pDC->LineTo(rect.right - 6, rect.bottom - 9);
  297.                                 pDC->LineTo(12, rect.bottom / 2);
  298.                                 break;
  299.                         }//case
  300.                         case POINT_RIGHT : {
  301.                                 pDC->MoveTo(6, 9);
  302.                                 pDC->LineTo(rect.right - 12, rect.bottom / 2);
  303.                                 pDC->LineTo(6, rect.bottom - 9);
  304.                                 pDC->LineTo(6, 9);
  305.                                 break;
  306.                         }//case

  307.                         default :
  308.                                 ASSERT(FALSE);
  309.                 }//switch
  310.         }//if

  311.         pDC->RestoreDC(nSavedDC);

  312. }

  313. void CTriangleBtn::PreSubclassWindow()
  314. {
  315.         CButton::PreSubclassWindow();

  316.         //get client rectangle
  317.         CRect rect;
  318.         GetClientRect(rect);
  319.         rect.bottom = rect.right = min(rect.bottom,rect.right);        //make it square
  320.         rect.bottom -= rect.bottom % 2; rect.right -= rect.right % 2;

  321.         SetWindowPos(NULL, 0, 0, rect.right, rect.bottom, SWP_NOMOVE | SWP_NOZORDER);

  322.         CPoint Head, RightLeg, LeftLeg;

  323.         switch (PointDirection) {
  324.                 case POINT_UP :
  325.                         Head.x = rect.right / 2; Head.y = 0;
  326.                         RightLeg.x = rect.right; RightLeg.y = rect.bottom;
  327.                         LeftLeg.x = 0; LeftLeg.y = rect.bottom;
  328.                         break;
  329.                 case POINT_DOWN :
  330.                         Head.x = rect.right / 2; Head.y = rect.bottom;
  331.                         RightLeg.x = 0; RightLeg.y = 0;
  332.                         LeftLeg.x = rect.right; LeftLeg.y = 0;
  333.                         break;
  334.                 case POINT_LEFT :
  335.                         Head.x = 0; Head.y = rect.bottom / 2;
  336.                         RightLeg.x = rect.right; RightLeg.y = 0;
  337.                         LeftLeg.x = rect.right; LeftLeg.y = rect.bottom;
  338.                         break;
  339.                 case POINT_RIGHT :
  340.                         Head.x = rect.right; Head.y = rect.bottom / 2;
  341.                         RightLeg.x = 0; RightLeg.y = rect.bottom;
  342.                         LeftLeg.x = 0; LeftLeg.y = 0;
  343.                         break;
  344.                 default :
  345.                         ASSERT(FALSE);
  346.         }//switch
  347.                                                         
  348.         CPoint points[3];
  349.         points[0] = Head; points[1] = RightLeg; points[2] = LeftLeg;
  350.         
  351.         SetWindowRgn(NULL, FALSE);

  352.         CurrentRegion.DeleteObject();
  353.         CurrentRegion.CreatePolygonRgn(points, 3, ALTERNATE);

  354.         SetWindowRgn(CurrentRegion, TRUE);
  355.                
  356.         ModifyStyle(0, BS_OWNERDRAW);
  357. }
复制代码


4.类写好了就是如何使用,如例程界面添加控件,其中按钮控件全部关联CTriangleBtn的变量。依次双击单选框与复选框,添加点击函数便可


回复

使用道具 举报

点击查看
快速回复 返回列表 客服中心 搜索