LAPTOP-SNT8I5JK\Boounion
2025-01-04 b8af4c380f4454915e556423b71c2ceb1a5abdd4
1.RxWindows库
已添加5个文件
已修改10个文件
682 ■■■■■ 文件已修改
.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Document/企业微信截图_17351944833737.png 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/BlButton.cpp 499 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/BlButton.h 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.cpp 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/stdafx.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -37,3 +37,4 @@
SourceCode/Bond/x64/Debug/Bonder.dat
SourceCode/Bond/x64/Release/BEQ.exp
SourceCode/Bond/x64/Release/Bonder.dat
SourceCode/Bond/Servo/x64/
Document/Æóҵ΢ÐŽØÍ¼_17351944833737.png
SourceCode/Bond/Servo/BlButton.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,499 @@
#include "stdafx.h"
#include "BlButton.h"
#define BADGE_HIDE                  0
#define BADGE_DOT                   1
#define BADGE_NUMBER                2
#define BADGE_DOT_WIDTH             12
#define BADGE_NUMBER_WIDTH          20
CBlButton::CBlButton()
{
    m_nState = BS_NORMAL;
    m_crFrame[BS_NORMAL] = RGB(225, 225, 225);
    m_crFrame[BS_HOVER] = RGB(0, 120, 215);
    m_crFrame[BS_PRESS] = RGB(0, 84, 153);
    m_crFrame[BS_FOCUS] = RGB(0, 120, 215);
    m_crFrame[BS_DISABLE] = RGB(191, 191, 191);
    m_crBkgnd[BS_NORMAL] = RGB(225, 225, 225);
    m_crBkgnd[BS_HOVER] = RGB(229, 241, 251);
    m_crBkgnd[BS_PRESS] = RGB(204, 228, 247);
    m_crBkgnd[BS_FOCUS] = RGB(225, 225, 225);
    m_crBkgnd[BS_DISABLE] = RGB(204, 204, 204);
    m_crText[BS_NORMAL] = RGB(0, 0, 0);
    m_crText[BS_HOVER] = RGB(0, 0, 0);
    m_crText[BS_PRESS] = RGB(0, 0, 0);
    m_crText[BS_FOCUS] = RGB(0, 0, 0);
    m_crText[BS_DISABLE] = RGB(131, 131, 131);
    m_bHover = FALSE;
    m_bSelected = FALSE;
    m_bTracking = FALSE;
    memset(&m_badge, 0, sizeof(BADGE));
    m_nRoundWidth = 0;
    m_hMenu = nullptr;
    m_hIcon[0] = nullptr;
    m_hIcon[1] = nullptr;
    m_nIconWidth = 0;
    m_nFlashState = 0;
}
CBlButton::~CBlButton()
{
}
void CBlButton::SetFrameColor(int index, COLORREF color)
{
    if (BS_NORMAL <= index && index <= BS_DISABLE) {
        m_crFrame[index] = color;
    }
}
void CBlButton::SetFrameColor(COLORREF color)
{
    m_crFrame[BS_NORMAL] = color;
    m_crFrame[BS_HOVER] = color;
    m_crFrame[BS_PRESS] = color;
    m_crFrame[BS_FOCUS] = color;
    Invalidate();
}
void CBlButton::SetRoundWidth(int width)
{
    m_nRoundWidth = width;
}
void CBlButton::SetBkgndColor(int index, COLORREF color)
{
    if (BS_NORMAL <= index && index <= BS_DISABLE) {
        m_crBkgnd[index] = color;
    }
}
void CBlButton::SetTextColor(int index, COLORREF color)
{
    if (BS_NORMAL <= index && index <= BS_DISABLE) {
        m_crText[index] = color;
    }
}
void CBlButton::SetFaceColor(COLORREF color)
{
    m_crBkgnd[BS_NORMAL] = color;
    m_crBkgnd[BS_HOVER] = color;
    m_crBkgnd[BS_PRESS] = color;
    m_crBkgnd[BS_FOCUS] = color;
    Invalidate();
}
void CBlButton::SetTextColor(COLORREF color)
{
    m_crText[BS_NORMAL] = color;
    m_crText[BS_HOVER] = color;
    m_crText[BS_PRESS] = color;
    m_crText[BS_FOCUS] = color;
    Invalidate();
}
void CBlButton::SetBadgeNumber(int number)
{
    m_badge.badgeBackground = RGB(255, 0, 0);
    m_badge.badgeForeground = RGB(255, 255, 255);
    m_badge.type = number > 0 ? BADGE_NUMBER : BADGE_HIDE;
    m_badge.number = number;
    Invalidate();
}
void CBlButton::ShowDotBadge(BOOL bShow, COLORREF color)
{
    m_badge.badgeBackground = color;
    m_badge.type = bShow ? BADGE_DOT : BADGE_HIDE;
    Invalidate();
}
void CBlButton::SetBkgndBmp(const char* pszBmpFile)
{
    m_strBkgndBmp = pszBmpFile;
}
void CBlButton::SetMenu(HMENU hMenu)
{
    m_hMenu = hMenu;
}
void CBlButton::SetCurrentMenuItem(UINT nPosition)
{
    char szTxt[256];
    GetMenuString(::GetSubMenu(m_hMenu, 0), nPosition, szTxt, 256, MF_BYPOSITION);
    SetWindowText(szTxt);
}
HMENU CBlButton::GetMenu()
{
    return m_hMenu;
}
void CBlButton::SetIcon(HICON hIcon, HICON hIconGray, int width)
{
    m_hIcon[0] = hIcon;
    m_hIcon[1] = hIconGray;
    m_nIconWidth = width;
}
void CBlButton::Flash(int ms)
{
    m_nFlashState = 1;
    SetTimer(1, ms, nullptr);
}
void CBlButton::StopFlash()
{
    m_nFlashState = 0;
    KillTimer(1);
    Invalidate();
}
BOOL CBlButton::IsFlash()
{
    return m_nFlashState != 0;
}
void CBlButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    HDC hDC = lpDrawItemStruct->hDC;
    RECT rcClient;
    GetClientRect(&rcClient);
    // è¾¹æ¡†+背景
    int state = GetDrawState();
    if (m_nFlashState != 0) {
        if (state != BS_DISABLE) {
            state = m_nFlashState == 1 ? BS_NORMAL : BS_PRESS;
        }
    }
    HBRUSH hBrush = CreateSolidBrush(m_crBkgnd[state]);
    HPEN hPen = CreatePen(PS_SOLID, state == BS_FOCUS ? 2 : 1, m_crFrame[state]);
    HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
    HPEN hOldBrush = (HPEN)::SelectObject(hDC, hBrush);
    ::RoundRect(hDC, state == BS_FOCUS ? rcClient.left + 1 : rcClient.left,
        state == BS_FOCUS ? rcClient.top + 1 : rcClient.top, rcClient.right,
        rcClient.bottom, m_nRoundWidth, m_nRoundWidth);
    ::SelectObject(hDC, hOldPen);
    ::SelectObject(hDC, hOldBrush);
    ::DeleteObject(hBrush);
    ::DeleteObject(hPen);
    // è´´å›¾
    CustomBitBlt(hDC, &rcClient, m_strBkgndBmp, state, 5, 2, 2, 2, 2, RGB(255,0,255));
    // èŽ·å¾—æ–‡æœ¬
    char szText[64];
    int nTextLen = GetWindowText(szText, 64);
    // å›¾æ ‡
    RECT rcText = rcClient;
    HICON hIcon = this->IsWindowEnabled() ? m_hIcon[0] : m_hIcon[01];
    if (hIcon != nullptr) {
        int xIcon = (rcClient.right - rcClient.top - m_nIconWidth) / 2;
        if (m_hMenu != nullptr) xIcon -= 10;
        int yIcon = (rcClient.bottom - rcClient.top - m_nIconWidth) / 2;
        if (nTextLen != 0) {
            yIcon -= 8;
        }
        DrawIconEx(hDC, xIcon, yIcon,
            hIcon, m_nIconWidth, m_nIconWidth, 0, 0, DI_NORMAL);
        rcText.top = yIcon + m_nIconWidth + 2;
    }
    // æ–‡æœ¬
    HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
    CFont* pFont = GetFont();
    if (pFont != nullptr) {
        hFont = (HFONT)pFont->GetSafeHandle();
    }
    ::SelectObject(hDC, hFont);
    ::SetBkMode(hDC, TRANSPARENT);
    ::SetTextColor(hDC, m_crText[state]);
    if ((BS_MULTILINE & GetStyle()) == BS_MULTILINE) {
        CRect rcBound;
        int height = DrawTextA(hDC, szText, (int)strlen(szText), &rcBound,  DT_CENTER | DT_CALCRECT | DT_EDITCONTROL);
        rcText.top = rcBound.top + (rcClient.bottom - rcClient.top - height) / 2;
        rcText.bottom = rcText.top + height;
        DrawTextA(hDC, szText, (int)strlen(szText), &rcText,  DT_CENTER | DT_EDITCONTROL);
    }
    else {
        if (m_hMenu != nullptr) {
            rcText.right -= (10);
        }
        DrawTextA(hDC, szText, (int)strlen(szText), &rcText, DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
    }
    // æ˜¯å¦æœ‰å°åœ†ç‚¹
    if (m_badge.type == BADGE_DOT) {
        Gdiplus::Graphics graphics(hDC);
        graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
        Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(m_badge.badgeBackground), GetGValue(m_badge.badgeBackground), GetBValue(m_badge.badgeBackground)));
        int x = rcClient.right - 8 - BADGE_DOT_WIDTH;
        int y = rcClient.top + 8;
        graphics.FillEllipse(&brush, x, y, BADGE_DOT_WIDTH, BADGE_DOT_WIDTH);
    }
    else if (m_badge.type == BADGE_NUMBER) {
        Gdiplus::Graphics graphics(hDC);
        graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
        Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(m_badge.badgeBackground), GetGValue(m_badge.badgeBackground), GetBValue(m_badge.badgeBackground)));
        int x = rcClient.right - 8 - BADGE_NUMBER_WIDTH;
        int y = rcClient.top + 8;
        graphics.FillEllipse(&brush, x, y, BADGE_NUMBER_WIDTH, BADGE_NUMBER_WIDTH);
        RECT rcBadge;
        rcBadge.left = x;
        rcBadge.right = rcBadge.left + BADGE_NUMBER_WIDTH;
        rcBadge.top = y;
        rcBadge.bottom = rcBadge.top + BADGE_NUMBER_WIDTH;
        ::SetTextColor(hDC, m_badge.badgeForeground);
        char szBuffer[32];
        sprintf_s(szBuffer, 32, "%d%s", min(m_badge.number, 9), m_badge.number > 9 ? "+" : "");
        DrawText(hDC, szBuffer, (int)strlen(szBuffer), &rcBadge, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    }
    // èœå•项小三角
    if (m_hMenu != nullptr) {
        HPEN hPenDrop = CreatePen(PS_SOLID, 1, m_crText[state]);
        HBRUSH hbrDrop = CreateSolidBrush(m_crText[state]);
        HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hbrDrop);
        HPEN hOldPen = (HPEN)::SelectObject(hDC, hPenDrop);
        POINT pt[3];
        pt[0].x = rcClient.right - 20;
        pt[0].y = rcClient.top + (rcClient.bottom - rcClient.top - 5) / 2;
        pt[1].x = pt[0].x + 10;
        pt[1].y = pt[0].y;
        pt[2].x = pt[0].x + (pt[1].x - pt[0].x) / 2;
        pt[2].y = pt[0].y + 5;
        ::Polygon(hDC, pt, 3);
        ::SelectObject(hDC, hOldBrush);
        ::SelectObject(hDC, hOldPen);
        ::DeleteObject(hBrush);
        ::DeleteObject(hPen);
    }
}
int CBlButton::GetDrawState()
{
    if (!IsWindowEnabled()) {
        return BS_DISABLE;
    }
    //if (GetFocus() == this) {
    //    return BS_FOCUS;
    //}
    return m_nState;
}
void CBlButton::PreSubclassWindow()
{
    m_bHover = false;
    m_bSelected = false;
    m_bTracking = FALSE;
    ModifyStyle(0, BS_OWNERDRAW);
    CButton::PreSubclassWindow();
}
BEGIN_MESSAGE_MAP(CBlButton, CButton)
    ON_WM_MOUSEMOVE()
    ON_WM_MOUSEHOVER()
    ON_WM_MOUSELEAVE()
    ON_WM_LBUTTONDOWN()
    ON_CONTROL_REFLECT_EX(BN_CLICKED, &CBlButton::OnBnClicked)
    ON_WM_LBUTTONUP()
    ON_WM_TIMER()
END_MESSAGE_MAP()
void CBlButton::OnMouseMove(UINT nFlags, CPoint point)
{
    if (!m_bTracking)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize = sizeof(tme);
        tme.dwFlags = TME_HOVER | TME_LEAVE;        // å‘送WM_MOUSEHOVER和WM_MOUSELEAVE
        tme.hwndTrack = m_hWnd;                        // æŒ‡å®šè¦è¿½è¸ªçš„窗口
        tme.dwHoverTime = 10;                        // é¼ æ ‡åœ¨æŒ‰é’®ä¸Šåœç•™è¶…过10ms,才认为状态为HOVER
        m_bTracking = _TrackMouseEvent(&tme);        // å¼€å¯Windows的WM_MOUSELEAVEWM_MOUSEHOVER事件支持
    }
    CButton::OnMouseMove(nFlags, point);
}
void CBlButton::OnMouseHover(UINT nFlags, CPoint point)
{
    m_bHover = true;
    m_nState = BS_HOVER;
    InvalidateRect(NULL);
    return;
    // CButton::OnMouseHover(nFlags, point);
}
void CBlButton::OnMouseLeave()
{
    m_bHover = false;
    m_bTracking = FALSE;    // è‹¥å·²ç»ç¦»å¼€ï¼Œåˆ™åœæ­¢è¿½è¸ª
    m_nState = BS_NORMAL;
    InvalidateRect(NULL);
    CButton::OnMouseLeave();
}
BOOL CBlButton::CustomBitBlt(HDC hDC, LPRECT lprc, CString& strBkgndBmp, int nFrame, int nAllFrame,
    int nB0, int nB1, int nB2, int nB3, COLORREF crTransparent)
{
    // è½½å…¥BMP
    HBITMAP hBmpTemp = (HBITMAP)LoadImage(AfxGetInstanceHandle(),
        strBkgndBmp, IMAGE_BITMAP, 0, 0,
        LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
    if (hBmpTemp == NULL)
        return FALSE;
    HDC hDCTemp = ::CreateCompatibleDC(hDC);
    ::SelectObject(hDCTemp, hBmpTemp);
    BITMAP bitmap;
    ::GetObject(hBmpTemp, sizeof(BITMAP), &bitmap);
    int nFrameWidth = bitmap.bmWidth / nAllFrame;        // æ¯å¸§çš„宽
    int nFrameX = nFrameWidth*nFrame;                // æŒ‡å®šå¸§ç›¸ç´ èµ·ç‚¹
                                                    // å¦‚果角或边厚为0
    if (nB0 == 0 && nB1 == 0 &&
        nB2 == 0 && nB3 == 0) {
        ::TransparentBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
            hDCTemp, nFrameX, 0, nFrameWidth, bitmap.bmHeight, crTransparent);
        ::DeleteObject(hBmpTemp);
        ::DeleteDC(hDCTemp);
        return TRUE;
    }
    // å…¶å®ƒ
    int x = lprc->left + nB3;
    int y = lprc->top + nB0;
    ::TransparentBlt(hDC, x, y, lprc->right - lprc->left - (nB1 + nB3), lprc->bottom - lprc->top - (nB0 + nB2),
        hDCTemp, nFrameX + nB3, nB0, nFrameWidth - (nB1 + nB3), bitmap.bmHeight - (nB0 + nB2), crTransparent);
    x = lprc->left;
    y = lprc->top;
    ::TransparentBlt(hDC, x, y, nB3, nB0,
        hDCTemp, nFrameX + 0, 0, nB3, nB0, crTransparent);
    x += nB3;
    y = lprc->top;
    ::TransparentBlt(hDC, x, y, lprc->right - lprc->left - (nB1 + nB3), nB0,
        hDCTemp, nFrameX + nB3, 0, nFrameWidth - (nB1 + nB3), nB0, crTransparent);
    x = lprc->right - nB1;
    y = lprc->top;
    ::TransparentBlt(hDC, x, y, nB1, nB0,
        hDCTemp, nFrameX + nFrameWidth - nB1, 0, nB1, nB0, crTransparent);
    x = lprc->right - nB1;
    y = lprc->top + nB0;
    ::TransparentBlt(hDC, x, y, nB1, lprc->bottom - lprc->top - (nB0 + nB2),
        hDCTemp, nFrameX + nFrameWidth - nB1, nB0, nB1, bitmap.bmHeight - (nB0 + nB2), crTransparent);
    x = lprc->right - nB1;
    y = lprc->bottom - nB2;
    ::TransparentBlt(hDC, x, y, nB1, nB2,
        hDCTemp, nFrameX + nFrameWidth - nB1, bitmap.bmHeight - nB2, nB1, nB2, crTransparent);
    x = lprc->left + nB3;
    y = lprc->bottom - nB2;
    ::TransparentBlt(hDC, x, y, lprc->right - lprc->left - (nB1 + nB3), nB2,
        hDCTemp, nFrameX + nB3, bitmap.bmHeight - nB2, nFrameWidth - (nB1 + nB3), nB2, crTransparent);
    x = lprc->left;
    y = lprc->bottom - nB2;
    ::TransparentBlt(hDC, x, y, nB3, nB2,
        hDCTemp, nFrameX + 0, bitmap.bmHeight - nB2, nB3, nB2, crTransparent);
    x = lprc->left;
    y = lprc->top + nB0;
    ::TransparentBlt(hDC, x, y, nB3, lprc->bottom - lprc->top - (nB0 + nB2),
        hDCTemp, nFrameX + 0, nB0, nB3, bitmap.bmHeight - (nB0 + nB2), crTransparent);
    ::DeleteObject(hBmpTemp);
    ::DeleteDC(hDCTemp);
    return TRUE;
}
void CBlButton::OnLButtonDown(UINT nFlags, CPoint point)
{
    m_nState = BS_PRESS;
    CButton::OnLButtonDown(nFlags, point);
}
void CBlButton::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_nState = BS_HOVER;
    CButton::OnLButtonUp(nFlags, point);
}
BOOL CBlButton::OnBnClicked()
{
    if (m_hMenu != NULL) {
        RECT rect;
        GetWindowRect(&rect);
        int cmd = ::TrackPopupMenu(::GetSubMenu(m_hMenu, 0),
            TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, rect.left, rect.bottom, 0, m_hWnd, NULL);
        if (cmd > 0) {
            int position = cmd - GetMenuItemID(::GetSubMenu(m_hMenu, 0), 0);
            Notify((int)BLBUTTON_MENU_ITEM_CLICKED, position);
        }
    }
    return FALSE;
}
void CBlButton::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1/* = 0*/, DWORD_PTR dwData2/* = 0*/)
{
    CWnd* pParent;
    pParent = GetParent();
    if (pParent != nullptr) {
        BLBUTTON_NMHDR blbNmhdr;
        blbNmhdr.nmhdr.code = nCode;
        blbNmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
        blbNmhdr.nmhdr.hwndFrom = m_hWnd;
        blbNmhdr.dwData = dwData;
        blbNmhdr.dwData1 = dwData1;
        blbNmhdr.dwData2 = dwData2;
        pParent->SendMessage(WM_NOTIFY, (WPARAM)blbNmhdr.nmhdr.idFrom, (LPARAM)&blbNmhdr);
    }
}
void CBlButton::OnTimer(UINT_PTR nIDEvent)
{
    if (1 == nIDEvent) {
        m_nFlashState++;
        if (m_nFlashState > 2) m_nFlashState = 1;
        Invalidate();
    }
    CButton::OnTimer(nIDEvent);
}
SourceCode/Bond/Servo/BlButton.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
#pragma once
#include "afxwin.h"
#define BS_NORMAL        0
#define BS_HOVER        1
#define BS_PRESS        2
#define BS_FOCUS        3
#define BS_DISABLE        4
#define BLBUTTON_MENU_ITEM_CLICKED        0x1345
typedef struct tagBLBUTTON_NMHDR
{
    NMHDR        nmhdr;
    DWORD_PTR    dwData;
    DWORD_PTR    dwData1;
    DWORD_PTR    dwData2;
} BLBUTTON_NMHDR;
class CBlButton :
    public CButton
{
private:
    typedef struct tagBADGE
    {
        COLORREF badgeBackground;
        COLORREF badgeForeground;
        int type;                       /* 0: æ— ,不显示*/
        int number;
    } BADGE;
public:
    CBlButton();
    ~CBlButton();
public:
    void SetRoundWidth(int width);
    int GetDrawState();
    void SetFrameColor(int index, COLORREF color);
    void SetFrameColor(COLORREF color);
    void SetBkgndColor(int index, COLORREF color);
    void SetTextColor(int index, COLORREF color);
    void SetBkgndBmp(const char* pszBmpFile);
    void SetFaceColor(COLORREF color);
    void SetTextColor(COLORREF color);
    void SetBadgeNumber(int number);
    void ShowDotBadge(BOOL bShow, COLORREF color);
    void SetMenu(HMENU hMenu);
    void SetCurrentMenuItem(UINT nPosition);
    HMENU GetMenu();
    void SetIcon(HICON hIcon, HICON hIconGray, int width);
    void Flash(int ms);
    void StopFlash();
    BOOL IsFlash();
private:
    BOOL CustomBitBlt(HDC hDC, LPRECT lprc, CString& strBkgndBmp, int nFrame, int nAllFrame,
        int nB0, int nB1, int nB2, int nB3, COLORREF crTransparent);
    void CBlButton::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1 = 0, DWORD_PTR dwData2 = 0);
private:
    bool m_bHover;            // æ‚¬åœ
    bool m_bSelected;        // æŒ‰ä¸‹
    BOOL m_bTracking;        // è·Ÿè¸ª
    int m_nState;
    int m_nRoundWidth;
private:
    COLORREF m_crFrame[5];    // è¾¹æ¡†é¢œè‰²
    COLORREF m_crBkgnd[5];    // èƒŒæ™¯é¢œè‰²
    COLORREF m_crText[5];    // æ–‡æœ¬é¢œè‰²
    CString m_strBkgndBmp;
private:
    BADGE m_badge;
    HMENU m_hMenu;
    HICON m_hIcon[2];
    int m_nIconWidth;
    int m_nFlashState;        // é—ªçƒçŠ¶æ€ï¼Œ0:不闪;1和2为闪烁切换中
public:
    virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
    virtual void PreSubclassWindow();
    DECLARE_MESSAGE_MAP()
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnMouseHover(UINT nFlags, CPoint point);
    afx_msg void OnMouseLeave();
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg BOOL OnBnClicked();
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnTimer(UINT_PTR nIDEvent);
};
SourceCode/Bond/Servo/Model.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
#include "stdafx.h"
#include "Model.h"
CModel::CModel()
{
}
CModel::~CModel()
{
}
int CModel::init()
{
    return 0;
}
int CModel::term()
{
    return 0;
}
SourceCode/Bond/Servo/Model.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
#pragma once
class CModel
{
public:
    CModel();
    ~CModel();
public:
    int init();
    int term();
};
SourceCode/Bond/Servo/Servo.cpp
@@ -87,6 +87,10 @@
    CServoGraph::RegisterWndClass();
    // åˆå§‹åŒ–BEQ库
    RX_Init();
    CServoDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
@@ -117,3 +121,10 @@
    return FALSE;
}
int CServoApp::ExitInstance()
{
    m_model.term();
    RX_Term();
    return CWinApp::ExitInstance();
}
SourceCode/Bond/Servo/Servo.h
@@ -9,6 +9,7 @@
#endif
#include "resource.h"        // ä¸»ç¬¦å·
#include "Model.h"
// CServoApp: 
@@ -22,7 +23,7 @@
public:
    // CModel m_model;
    CModel m_model;
    HANDLE m_hAppMutex;
    CString m_strAppDir;
    CString m_strAppFile;
@@ -36,6 +37,7 @@
// å®žçް
    DECLARE_MESSAGE_MAP()
    virtual int ExitInstance();
};
extern CServoApp theApp;
SourceCode/Bond/Servo/Servo.rc
Binary files differ
SourceCode/Bond/Servo/Servo.vcxproj
@@ -189,6 +189,8 @@
    <Text Include="ReadMe.txt" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="BlButton.h" />
    <ClInclude Include="Model.h" />
    <ClInclude Include="Resource.h" />
    <ClInclude Include="Servo.h" />
    <ClInclude Include="ServoDlg.h" />
@@ -197,6 +199,8 @@
    <ClInclude Include="targetver.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="BlButton.cpp" />
    <ClCompile Include="Model.cpp" />
    <ClCompile Include="Servo.cpp" />
    <ClCompile Include="ServoDlg.cpp" />
    <ClCompile Include="ServoGraph.cpp" />
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -36,6 +36,12 @@
    <ClInclude Include="ServoGraph.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="Model.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="BlButton.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="Servo.cpp">
@@ -50,6 +56,12 @@
    <ClCompile Include="ServoGraph.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="Model.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="BlButton.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc">
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -70,11 +70,13 @@
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_crBkgnd = RGB(255, 255, 255);
    m_hbrBkgnd = nullptr;
    m_bShowLogWnd = FALSE;
}
void CServoDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_BUTTON_LOG, m_btnLog);
}
BEGIN_MESSAGE_MAP(CServoDlg, CDialogEx)
@@ -85,6 +87,7 @@
    ON_BN_CLICKED(IDCANCEL, &CServoDlg::OnBnClickedCancel)
    ON_WM_CTLCOLOR()
    ON_WM_DESTROY()
    ON_BN_CLICKED(IDC_BUTTON_LOG, &CServoDlg::OnBnClickedButtonLog)
END_MESSAGE_MAP()
@@ -291,3 +294,14 @@
        ::DeleteObject(m_hbrBkgnd);
    }
}
void CServoDlg::OnBnClickedButtonLog()
{
    m_bShowLogWnd = !m_bShowLogWnd;
    m_btnLog.SetFrameColor(BS_NORMAL, BTN_JOG_FRAME_NORMAL);
    m_btnLog.SetFrameColor(BS_HOVER, BTN_JOG_FRAME_HOVER);
    m_btnLog.SetFrameColor(BS_PRESS, BTN_JOG_FRAME_PRESS);
    m_btnLog.SetBkgndColor(BS_NORMAL, BTN_JOG_BKGND_NORMAL);
    m_btnLog.SetBkgndColor(BS_HOVER, BTN_JOG_BKGND_HOVER);
    m_btnLog.SetBkgndColor(BS_PRESS, BTN_JOG_BKGND_PRESS);
}
SourceCode/Bond/Servo/ServoDlg.h
@@ -4,6 +4,7 @@
#pragma once
#include "ServoGraph.h"
#include "BlButton.h"
// CServoDlg å¯¹è¯æ¡†
@@ -22,12 +23,17 @@
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
private:
    BOOL m_bShowLogWnd;
// å®žçް
protected:
    HICON m_hIcon;
    CServoGraph* m_pGraph;
    COLORREF m_crBkgnd;
    HBRUSH m_hbrBkgnd;
    CBlButton m_btnLog;
    // ç”Ÿæˆçš„æ¶ˆæ¯æ˜ å°„函数
    virtual BOOL OnInitDialog();
@@ -40,4 +46,5 @@
    afx_msg void OnBnClickedCancel();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnDestroy();
    afx_msg void OnBnClickedButtonLog();
};
SourceCode/Bond/Servo/resource.h
Binary files differ
SourceCode/Bond/Servo/stdafx.h
@@ -35,8 +35,7 @@
#include "..\RxWindows1.0\include\RxWindowsLib.h"