xuson 发表于 2020-1-9 09:22

自绘Checkbox控件初稿

/*********************** |\(^o^)/| ***********************
Create: 2011.09.15
Version: 1.0.0
Author: 宅
Description: [原版]自绘Checkbox控件
********************************************************/

#include "Checkbox.h"

ucCheckBox Checkbox;

static LRESULT CALLBACK ucCheckboxProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    switch( uMsg ) {

    case WM_CREATE:
      Checkbox.Paint(hwnd);
      //Checkbox.SetHWND( hwnd );
      return 0;

    case WM_PAINT:
      Checkbox.Paint(hwnd);
      return 0;

    case WM_LBUTTONDOWN:
      Checkbox.Click( Checkbox.Index(hwnd));
      //__raise Checkbox.Click( Checkbox.Index(hwnd));
      return 0;

    case WM_KEYUP:
      if( wParam == VK_UP ) {
            //Checkbox.MoveUp();
            return 0;
      } else if( wParam == VK_DOWN ) {
            //Checkbox.MoveDown();
            return 0;
      }
      break;
    }
    return DefWindowProc( hwnd, uMsg, wParam, lParam );
}

void ucCheckBox::RegCtrl(){
    WNDCLASS wc = { 0 };
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = ucCheckboxProc;
    wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
    wc.lpszClassName = TEXT(UserControl_CheckBox);
    RegisterClass( &wc );
    _Width= 18;
    _Height = 18;
    _Count= 0;
    ucCheckBox::Font();
}
void ucCheckBox::UnRegCtrl(){
    UnregisterClass( TEXT(UserControl_CheckBox), NULL );
}
// 创建控件
void ucCheckBox::Create(int x, int y, const wchar_t *Text, HWND hWndParent, HINSTANCE hInstance)
{
    _Pty.Label(Text);
    _Pty.Enabled(true);
    _Pty.Value(_Count);
    _Pty.hWnd = CreateWindow( TEXT(UserControl_CheckBox), NULL, WS_CHILD | WS_TABSTOP | WS_VISIBLE, x, y, _Width, _Height, hWndParent, NULL, hInstance, NULL );
    _Count++;
}

void ucCheckBox::Paint(HWND hwnd){
    PAINTSTRUCT ps;
    HDC hDC;
    RECT Rect;
    int ActId=ucCheckBox::Index(hwnd);
    if (ActId==-1) return;

    GetClientRect(hwnd, &Rect );
    hDC = BeginPaint( hwnd, &ps );
    //设置字体和自动宽度
    CreateFont(hDC);
    int len = lstrlen(_Pty.Label());
    SIZE size;
    GetTextExtentPoint32(hDC, _Pty.Label(), len, &size);
    SetWindowPos(hwnd,NULL,0,0,_Width+5+size.cx, _Height,SWP_NOMOVE);
    GetClientRect(hwnd, &Rect );
    //绘制控件
    ucCheckBox::CheckBox(hDC, Rect, ActId);
    EndPaint( hwnd, &ps );
}

void ucCheckBox::Font(const wchar_t *Name, int Size, int Bold)
{
    lstrcpy(_FontName, Name);
    _FontSize=Size;
    _FontBold=Bold;
}
// 根据字体属性创建字体对象
void ucCheckBox::CreateFont(HDC _hDC)
{
    LOGFONT lf;
    HFONT   hFont;

    FillMemory(&lf, sizeof(lf), 0);
    lf.lfHeight      = _FontSize;                      //字体高度
    lf.lfCharSet       = DEFAULT_CHARSET | ANSI_CHARSET; //字符集
    lf.lfWeight      = _FontBold;                      //粗体, 取值: 0/700/1000
    lf.lfOutPrecision= OUT_STROKE_PRECIS;            //输出精度
    lf.lfClipPrecision = CLIP_CHARACTER_PRECIS;          //剪裁精度
   
    //lfItalic   //斜体
    //lfUnderline//下划线
    //lfStrikeOut//删除线
    lstrcpy(lf.lfFaceName, _FontName);                  //字体名称

    hFont = CreateFontIndirect(&lf);
    //GlobalFree(&lf);
    // 设置字体到场景
    SelectObject(_hDC, hFont);
    DeleteObject(hFont);
}

void ucCheckBox::Line(HDC _hDC, int frX, int frY, int toX, int toY, int liW, int _ClrR, int _ClrG, int _ClrB)
{
   HPEN hPen;
   POINT ptAPI;
   hPen = CreatePen(0, liW, RGB(_ClrR, _ClrG, _ClrB));
   SelectObject(_hDC, hPen);
   MoveToEx(_hDC, frX, frY, &ptAPI);
   LineTo(_hDC, toX, toY);
   DeleteObject(hPen);
}

void ucCheckBox::CheckBox(HDC hDC, RECT objRect, int Id)
{
    RECT Rect;
    int iStep;
    long clrBG, clrFra;
    int bgR, bgG, bgB, ckR, ckG, ckB, sdR,sdG,sdB,
      frasdR, frasdG, frasdB,fraR, fraG, fraB;
   
    clrBG= GetSysColor(COLOR_WINDOW);
    clrFra = GetSysColor(COLOR_WINDOWTEXT);
   
    bgR = clrBG>>16 & 0xFF;
    bgG = clrBG>>8& 0xFF;
    bgB = clrBG   & 0xFF;

    fraR = clrFra>>16 & 0xF3;
    fraG = clrFra>>8& 0x92;
    fraB = clrFra   & 0x2A;
    fraR = ucCheckBox::gPercent(bgR, fraR, 50);
    fraG = ucCheckBox::gPercent(bgG, fraG, 50);
    fraB = ucCheckBox::gPercent(bgB, fraB, 50);
    frasdR = ucCheckBox::gPercent(bgR, fraR, 30);
    frasdG = ucCheckBox::gPercent(bgG, fraG, 30);
    frasdB = ucCheckBox::gPercent(bgB, fraB, 30);
      sdR = fraR; sdG = fraG; sdB = fraB;

    if ( _Pty.Enabled()) {
      if (_Pty.Value()==0){
            ckR = 0xFF; ckG = 0x00; ckB = 0x00;
      }else {
            ckR = 0x00; ckG = 0xAA; ckB = 0x00;
      }
    } else {
      ckR = frasdR; ckG = frasdR; ckB = frasdR;
    }

    iStep = (_Width - 15) / 2;
    if (iStep<=0) iStep = 0;
   
    Rect.left   = 0;
    Rect.top    = 0;
    Rect.right= _Width;
    Rect.bottom = _Height;
   
    HBRUSH hBrush = CreateSolidBrush(clrBG);
    FillRect(hDC, &Rect, hBrush);
    DeleteObject(hBrush);

    //边框
    ucCheckBox::Line( hDC, Rect.left,    Rect.top,      Rect.right,   Rect.top,      1, fraR, fraG, fraB); //上
    ucCheckBox::Line( hDC, Rect.left,    Rect.bottom-1, Rect.right,   Rect.bottom-1, 1, fraR, fraG, fraB); //下
    ucCheckBox::Line( hDC, Rect.left,    Rect.top,      Rect.left,    Rect.bottom,   1, fraR, fraG, fraB); //左
    ucCheckBox::Line( hDC, Rect.right-1, Rect.top,      Rect.right-1, Rect.bottom,   1, fraR, fraG, fraB); //右

    //阴影
    ucCheckBox::Line( hDC, Rect.left+1,Rect.top+1,    Rect.right-1, Rect.top+1,    1, frasdR, frasdG, frasdB); //上
    ucCheckBox::Line( hDC, Rect.left+1,Rect.bottom-2, Rect.right-1, Rect.bottom-2, 1, frasdR, frasdG, frasdB); //下
    ucCheckBox::Line( hDC, Rect.left+1,Rect.top+1,    Rect.left+1,Rect.bottom-2, 1, frasdR, frasdG, frasdB); //左
    ucCheckBox::Line( hDC, Rect.right-2, Rect.top+1,    Rect.right-2, Rect.bottom-2, 1, frasdR, frasdG, frasdB); //右
   
    Rect.left = iStep;
    Rect.top= iStep;
   
    if (_Pty.Value()==0){
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top + 5 + 2, Rect.left + 12, Rect.top + 5 + 2, 1, ckR, ckG, ckB);
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top + 5 + 3, Rect.left + 12, Rect.top + 5 + 3, 1, ckR, ckG, ckB);
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top + 5 + 4, Rect.left + 12, Rect.top + 5 + 4, 1, ckR, ckG, ckB);
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top + 5 + 1, Rect.left + 12, Rect.top + 5 + 1, 1, sdR, sdG, sdB);
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top + 5 + 5, Rect.left + 12, Rect.top + 5 + 5, 1, sdR, sdG, sdB);
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top + 5 + 1, Rect.left +3, Rect.top + 5 + 5, 1, sdR, sdG, sdB);
      ucCheckBox::Line( hDC, Rect.left + 12, Rect.top + 5 + 1, Rect.left + 12, Rect.top + 5 + 6, 1, sdR, sdG, sdB);
    } else {
      ucCheckBox::Line( hDC, Rect.left +4, Rect.top +7, Rect.left +7, Rect.top + 10, 1, ckR, ckG, ckB);
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top +7, Rect.left +8, Rect.top + 12, 1, ckR, ckG, ckB);
      ucCheckBox::Line( hDC, Rect.left +3, Rect.top +8, Rect.left +7, Rect.top + 12, 1, ckR, ckG, ckB);
   
      ucCheckBox::Line( hDC, Rect.left +7, Rect.top +9, Rect.left + 12, Rect.top +4, 1, ckR, ckG, ckB);
      ucCheckBox::Line( hDC, Rect.left +7, Rect.top + 10, Rect.left + 13, Rect.top +4, 1, ckR, ckG, ckB);
   
      ucCheckBox::Line( hDC, Rect.left +2, Rect.top +7, Rect.left +4, Rect.top +6, 1, sdR, sdG, sdB);
      ucCheckBox::Line( hDC, Rect.left +4, Rect.top +6, Rect.left +7, Rect.top +9, 1, sdR, sdG, sdB);
      ucCheckBox::Line( hDC, Rect.left +2, Rect.top +8, Rect.left +7, Rect.top + 13, 1, sdR, sdG, sdB);
   
      ucCheckBox::Line( hDC, Rect.left +7, Rect.top +8, Rect.left + 12, Rect.top +3, 1, sdR, sdG, sdB);
      ucCheckBox::Line( hDC, Rect.left +7, Rect.top + 11, Rect.left + 13, Rect.top +5, 1, sdR, sdG, sdB);
      ucCheckBox::Line( hDC, Rect.left + 12, Rect.top +4, Rect.left + 14, Rect.top +6, 1, sdR, sdG, sdB);
    }
    Rect.left = iStep + _Width + 2;
    Rect.top= iStep;
   
    Rect.right = objRect.right;
    Rect.bottom= _Height;

      SetBkMode(hDC, 1);
      SetTextColor(hDC, clrFra);
      DrawText(hDC, _Pty.Label(), -1, &Rect, DT_END_ELLIPSIS | DT_WORDBREAK | DT_VCENTER | DT_SINGLELINE);
}

/*********************** |\(^o^)/| ***********************
Create: 2011.09.15
Version: 1.0.0
Author: 宅
Description: [原版]自动画图功能,根据图片类型自动处理
********************************************************/

#include "Draw.h"

void CDraw::Init(HDC objDC, int objW, int objH){
   _hDC=objDC; Width=objW; Height=objH;
   //_hMemDC = CreateCompatibleDC(_hDC);
   _hMemDC = CreateCompatibleBitmap(_hDC, Width, Height);
}

// 设置背景颜色
void CDraw::BgColor(int r, int g, int b){
   _BGClrR=r; _BGClrG=g; _BGClrB=b;
   RECT Rect;
   Rect.left=0;
   Rect.top=0;
   Rect.right = Width;
   Rect.bottom = Height;
   // 纯色
   HBRUSH hBrush = CreateSolidBrush(RGB(r,g,b));
   SelectObject(_hDC, hBrush);
   FloodFill(_hDC, 0, 0, 0x850617);
   FillRect(_hDC, &Rect, hBrush);
   DeleteObject(hBrush);
}

// 根据字体属性创建字体对象
void CDraw::Font(int Size, int Bold, char *Name)
{
    _FontSize=Size; _FontBold=Bold;
    sprintf(_FontName, Name);
   
    LOGFONT lf;
    HFONT   hFont;

    FillMemory(&lf, sizeof(lf), 0);
    lf.lfHeight      = _FontSize;                      //字体高度
    lf.lfCharSet       = DEFAULT_CHARSET | ANSI_CHARSET; //字符集
    lf.lfWeight      = _FontBold;                      //粗体, 取值: 0/700/1000
    lf.lfOutPrecision= OUT_STROKE_PRECIS;            //输出精度
    lf.lfClipPrecision = CLIP_CHARACTER_PRECIS;          //剪裁精度
   
    //lfItalic   //斜体
    //lfUnderline//下划线
    //lfStrikeOut//删除线
    lstrcpy(lf.lfFaceName, _FontName);                   //字体名称

    hFont = CreateFontIndirect(&lf);
    GlobalFree(&lf);
    // 设置字体到场景
    SelectObject(_hDC, hFont);
    DeleteObject(hFont);
}
// 获取 开始颜色到结束颜色之间的占比颜色
long CDraw::gColor(long frColor, int iPercent, long toColor)
{
    int bR, bG, bB;
    int eR, eG, eB;
    int nR, nG, nB;
   
    float iPt=0;

    bR = (frColor & 0xFF);
    bG = (frColor & 0xFF00)>>8;
    bB = (frColor & 0xFF0000)>>16;
   
    eR = (toColor & 0xFF);
    eG = (toColor & 0xFF00)>>8;
    eB = (toColor & 0xFF0000)>>16;
   
    iPt = iPercent / 100.0f;
    nR = bR + (eR - bR) * iPt;
    nG = bG + (eG - bG) * iPt;
    nB = bB + (eB - bB) * iPt;

    return RGB(nR, nG, nB);
}

// 画线条到场景
void CDraw::Line(int frX, int frY, int toX, int toY, int liW)
{
    HPEN hPen;
    LPPOINT ptAPI;
    hPen = CreatePen(0, liW, RGB(_lineClrR, _lineClrG, _lineClrB));
    SelectObject(_hDC, hPen);
    MoveToEx(_hDC, frX, frY, ptAPI);
    LineTo(_hDC, toX, toY);
    DeleteObject(hPen);
}

// 设置焦点框
void CDraw::Focus(){
   RECT Rect;
   Rect.left=2;
   Rect.top=2;
   Rect.right = Width-4;
   Rect.bottom = Height-4;
   DrawFocusRect( _hDC, &Rect);
}

rosoon 发表于 2020-1-9 09:28

不明觉厉~~!!

鲸鱼jerry 发表于 2020-1-9 09:37

重复造轮子了{:1_901:}

田田爱崽崽 发表于 2020-1-9 10:23

鲸鱼jerry 发表于 2020-1-9 09:37
重复造轮子了

大佬,我请教下,在VS2019中用C++语言写窗体的时候怎么才能和C#一样开启拖放式的界面设计过程?为什么我的VS2019做窗体程序的时候调不出那个窗体设计器?

coolcalf 发表于 2020-1-9 10:23

我就喜欢造轮子
但是VC要造轮子,再把周边都造出来,太难了。
不年轻了,玩不起

鲸鱼jerry 发表于 2020-1-9 15:36

田田爱崽崽 发表于 2020-1-9 10:23
大佬,我请教下,在VS2019中用C++语言写窗体的时候怎么才能和C#一样开启拖放式的界面设计过程?为什么我 ...

我不是大佬,你用的QT ?MFC?还是什么?

田田爱崽崽 发表于 2020-1-9 15:40

鲸鱼jerry 发表于 2020-1-9 15:36
我不是大佬,你用的QT ?MFC?还是什么?

MFC,不过界面确实好丑

鲸鱼jerry 发表于 2020-1-10 09:41

田田爱崽崽 发表于 2020-1-9 15:40
MFC,不过界面确实好丑

qt的界面好看点

田田爱崽崽 发表于 2020-1-10 09:54

鲸鱼jerry 发表于 2020-1-10 09:41
qt的界面好看点

是的,可是QT涉及授权啥的,怕担法律风险

xuson 发表于 2020-1-13 09:24

rosoon 发表于 2020-1-9 09:28
不明觉厉~~!!

我的目标是在MFC上使用自己的画图控件,抛弃系统默认的。用第三方的控件,又要给别人钱,而且还有学会他们的调用方式,太麻烦了。
页: [1]
查看完整版本: 自绘Checkbox控件初稿