From b8af4c380f4454915e556423b71c2ceb1a5abdd4 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期六, 04 一月 2025 08:46:38 +0800
Subject: [PATCH] 1.RxWindows库

---
 SourceCode/Bond/Servo/Servo.vcxproj         |    4 
 .gitignore                                  |    1 
 SourceCode/Bond/Servo/BlButton.h            |   94 +++++++
 SourceCode/Bond/Servo/resource.h            |    0 
 Document/企业微信截图_17351944833737.png          |    0 
 SourceCode/Bond/Servo/Servo.cpp             |   11 
 SourceCode/Bond/Servo/stdafx.h              |    3 
 SourceCode/Bond/Servo/Model.cpp             |   21 +
 SourceCode/Bond/Servo/ServoDlg.cpp          |   14 +
 SourceCode/Bond/Servo/Servo.vcxproj.filters |   12 +
 SourceCode/Bond/Servo/Model.h               |   12 +
 SourceCode/Bond/Servo/Servo.rc              |    0 
 SourceCode/Bond/Servo/Servo.h               |    4 
 SourceCode/Bond/Servo/BlButton.cpp          |  499 +++++++++++++++++++++++++++++++++++++++++
 SourceCode/Bond/Servo/ServoDlg.h            |    7 
 15 files changed, 679 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index be16749..df2c187 100644
--- a/.gitignore
+++ b/.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/
diff --git "a/Document/\344\274\201\344\270\232\345\276\256\344\277\241\346\210\252\345\233\276_17351944833737.png" "b/Document/\344\274\201\344\270\232\345\276\256\344\277\241\346\210\252\345\233\276_17351944833737.png"
new file mode 100644
index 0000000..11ffb64
--- /dev/null
+++ "b/Document/\344\274\201\344\270\232\345\276\256\344\277\241\346\210\252\345\233\276_17351944833737.png"
Binary files differ
diff --git a/SourceCode/Bond/Servo/BlButton.cpp b/SourceCode/Bond/Servo/BlButton.cpp
new file mode 100644
index 0000000..5eb7694
--- /dev/null
+++ b/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);
+}
diff --git a/SourceCode/Bond/Servo/BlButton.h b/SourceCode/Bond/Servo/BlButton.h
new file mode 100644
index 0000000..7b9bcea
--- /dev/null
+++ b/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);
+};
+
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
new file mode 100644
index 0000000..d80aee1
--- /dev/null
+++ b/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;
+}
diff --git a/SourceCode/Bond/Servo/Model.h b/SourceCode/Bond/Servo/Model.h
new file mode 100644
index 0000000..acba736
--- /dev/null
+++ b/SourceCode/Bond/Servo/Model.h
@@ -0,0 +1,12 @@
+#pragma once
+class CModel
+{
+public:
+	CModel();
+	~CModel();
+
+public:
+	int init();
+	int term();
+};
+
diff --git a/SourceCode/Bond/Servo/Servo.cpp b/SourceCode/Bond/Servo/Servo.cpp
index 81b50bc..4e005c6 100644
--- a/SourceCode/Bond/Servo/Servo.cpp
+++ b/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();
+}
diff --git a/SourceCode/Bond/Servo/Servo.h b/SourceCode/Bond/Servo/Servo.h
index 54c0bbe..bb306cd 100644
--- a/SourceCode/Bond/Servo/Servo.h
+++ b/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;
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 18d9953..ae0acba 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
Binary files differ
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index 02d8a5d..3fcf88f 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/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" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 3add087..fffacb3 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/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">
diff --git a/SourceCode/Bond/Servo/ServoDlg.cpp b/SourceCode/Bond/Servo/ServoDlg.cpp
index b2e5d04..dcf92d2 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/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);
+}
diff --git a/SourceCode/Bond/Servo/ServoDlg.h b/SourceCode/Bond/Servo/ServoDlg.h
index 1353deb..d305005 100644
--- a/SourceCode/Bond/Servo/ServoDlg.h
+++ b/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();
 };
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 802dfd2..c8d683b 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ
diff --git a/SourceCode/Bond/Servo/stdafx.h b/SourceCode/Bond/Servo/stdafx.h
index 7d8a96a..ee67f29 100644
--- a/SourceCode/Bond/Servo/stdafx.h
+++ b/SourceCode/Bond/Servo/stdafx.h
@@ -35,8 +35,7 @@
 
 
 
-
-
+#include "..\RxWindows1.0\include\RxWindowsLib.h"
 
 
 

--
Gitblit v1.9.3