使用纯代码绘制CheckBox



作者:刘树伟

www.iuishop.com

LibUIDK界面库系列文档
日期:2017-09-14 11:04


使用代码绘制CheckBox

DWORD FormsDrawDiagonalLine(HDC hdc, LPRECT lprc, int iDirection, int iThickness, UINT flags)
{
 RECT    rc;
 LPINT   py;
 int     cx;
 int     cy;
 int     dx;
 int     dy;
 LPINT   pc;
 int     cxBorder = GetSystemMetrics(SM_CXBORDER);
 int     cyBorder = GetSystemMetrics(SM_CYBORDER);

 if (IsRectEmpty(lprc))
 {
  return (0L);
 }

 CopyRect(&rc, lprc);

 //
 // We draw slopes < 1 by varying y instead of x.
 //
 --iThickness;

 // HACK HACK HACK. REMOVE THIS ONCE MARLETT IS AROUND
 cy = rc.bottom - rc.top;
 cx = rc.right - rc.left;

 if (!flags && (cy != cx))
 {
  cy -= iThickness * cyBorder;
 }

 if (cy >= cx)
 {
  // "slope" is >= 1, so vary x by 1
  cy /= cx;
  pc = &cy;

  cx = cxBorder;
 }
 else
 {
  // "slope" is < 1, so vary y by 1
  cx /= cy;
  pc = &cx;

  cy = cyBorder;
 }

 dx = cx;
 dy = iDirection * cy;

 *pc = (*pc + iThickness) * cyBorder;

 rc.right -= cx;
 rc.bottom -= cy;

 // For negative slopes, start from opposite side.
 if (iDirection < 0)
 {
  py = (int *)&rc.top;
 }
 else
 {
  py = (int *)&rc.bottom;
 }

 while ((rc.left <= rc.right) && (rc.top <= rc.bottom))
 {
  if (!(flags & BF_MIDDLE))
  {
   PatBlt(hdc, rc.left, *py, cx, cy, PATCOPY);
  }
  else
  {
   // Fill interior.  We can determine vertex in interior
   // by vector define.

   if (cy > cyBorder)
   {
    if (flags & BF_LEFT)
    {
     PatBlt(hdc, rc.left, lprc->top, cx, *py - lprc->top + cy, PATCOPY);
    }
    else
    {
     PatBlt(hdc, rc.left, *py, cx, lprc->bottom - *py, PATCOPY);
    }
   }
   else
   {
    if (flags & BF_TOP)
    {
     PatBlt(hdc, rc.left, *py, lprc->right - rc.left, cy, PATCOPY);
    }
    else
    {
     PatBlt(hdc, lprc->left, *py, rc.left - lprc->left + cx, cy, PATCOPY);
    }
   }
  }

  rc.left += dx;
  *py -= dy;
 }

 return (MAKELONG(cx, cy));
}

BOOL FormsDrawCheckMark(HDC hdc, LPRECT lprc, int iThickness)
{
 int i = (lprc->right - lprc->left + 2) / 3;
 int saveRight = lprc->right;

 lprc->top += ((lprc->bottom - lprc->top - (i * 2)) / 2) + i - 1;
 lprc->bottom = lprc->top + i + (iThickness - 1);

 lprc->left += (lprc->right - lprc->left - ((i * 3) - 1)) / 2;

 lprc->right = lprc->left + i - 1;
 FormsDrawDiagonalLine(hdc, lprc, -1, iThickness, 0);
 lprc->top -= i;
 lprc->left = lprc->right;
 lprc->right = saveRight;
 FormsDrawDiagonalLine(hdc, lprc, 1, iThickness, 0);
 return (TRUE);
}

GraphicsPath *CreateRoundRectRgnGp(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse)
{
 int nLeft = min(nLeftRect, nRightRect);
 int nRight = max(nLeftRect, nRightRect);

 int nTop = min(nTopRect, nBottomRect);
 int nBottom = max(nTopRect, nBottomRect);

 GraphicsPath *pPathRet = ::new GraphicsPath();

 // 右上角的圆弧,第5个参数表示圆弧的起始角度(x轴向右为0度,顺时针为正);第6个参数表示圆弧扫过的角度。
 pPathRet->AddArc(nRight - nWidthEllipse, nTop, nWidthEllipse, nHeightEllipse, 270, 90);
 // 右下角
 pPathRet->AddArc(nRight - nWidthEllipse, nBottom - nHeightEllipse, nWidthEllipse, nHeightEllipse, 0, 90);
 // 左下角
 pPathRet->AddArc(nLeft, nBottom - nHeightEllipse, nWidthEllipse, nHeightEllipse, 90, 90);
 // 左上角
 pPathRet->AddArc(nLeft, nTop, nWidthEllipse, nHeightEllipse, 180, 90);

 // 封闭Path
 pPathRet->CloseFigure();

 return pPathRet;
}

// lprcCheckMarkMargin: 对勾相对于CheckBox边距
// nLineWidth, 对钩的线宽
int DrawCheckBox(HDC hDC, LPCRECT lprc, COLORREF crBk,
 COLORREF crBorder, int nBorderWeight, int nBorderCorner, LPCRECT lprcCheckMarkMargin, int nLineWidth)
{
 Graphics g(hDC);

 g.SetSmoothingMode(SmoothingModeAntiAlias);

 int nWidth = lprc->right - lprc->left;
 int nHeight = lprc->bottom - lprc->top;

 // 画背景
 Color crBackground;
 crBackground.SetFromCOLORREF(crBk);
 SolidBrush crBrush(crBackground);
 GraphicsPath *pgp = CreateRoundRectRgnGp(lprc->left, lprc->top, lprc->right, lprc->bottom, nBorderCorner, nBorderCorner);
 g.FillPath(&crBrush, pgp);

 // 画边框
 if (nBorderWeight > 0)
 {
  Color cr;
  cr.SetFromCOLORREF(crBorder);
  Pen pen(cr, (REAL)nBorderWeight);
  g.DrawPath(&pen, pgp);
 }

 ::delete pgp;

 // 画对勾
 CRect rc(lprc);
 if (lprcCheckMarkMargin != NULL)
 {
  rc.DeflateRect(lprcCheckMarkMargin);
 }
 FormsDrawCheckMark(hDC, rc, nLineWidth);

 return 0;
}

用法:
 DrawCheckBox(hDC, CRect(50, 50, 100, 100), RGB(26, 188, 156), RGB(255, 0, 0), 0, 5, CRect(9, 9, 9, 9), 5);

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值