VC++ CComboBox自绘

2023-11-16

头文件定义(CSWComboBox.h):

#pragma once

class CSWComboBox : 
	public CComboBox
{
	DECLARE_DYNAMIC(CSWComboBox)

public:
	CSWComboBox();
	~CSWComboBox();

private:
	// 初始化
	void CommonConstruct();

	// 销毁申请的内存空间
	void ResetContent();

	// 自适应列表框宽度
	void AutoFitDroppedWidth();

	// 获取子控件CEdit
	CEdit* FindChildEdit();

	// 偏移CEdit子窗体位置
	void SetChildEditOffset(int nOffset = 20);

private:
	struct ComboData {
		DWORD_PTR dwItemData;
		UINT nImageIndex;
		std::string sItemText;
	};

	std::map<UINT, Gdiplus::Bitmap*> m_mapItemImage;
	CBrush m_brEdge;		// 边框画刷
	BOOL m_bIsMouseHover;	// 鼠标停留
	BOOL m_bIsMouseDown;	// 鼠标按下
	BOOL m_bShow3DEdge;		// 3D边框
	CSize m_szImage;		// 图标尺寸

public:
	void Show3DEdge(BOOL bShow = TRUE);
	UINT AddImageList(Gdiplus::Bitmap* pBitmap);
	
protected:
	void DrawEdge(COLORREF clrTopLeft, COLORREF clrBottomRight);

public:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
	virtual void PreSubclassWindow();

	virtual int AddString(LPCTSTR lpszString, int nImageIndex = -1);//加载每一项的文字和对应的图标索引
	virtual int InsertString(int nIndex, LPCTSTR lpszString, int nImageIndex = -1);
	virtual int GetLBText(int nIndex, CString& strText);//根据项索引获取对应的文字
	virtual int GetLBImage(int nIndex, int& nImageIndex);//根据项索引获取对应的图标索引
	virtual int SetItemData(int nItem, DWORD_PTR dwItemData);
	virtual DWORD_PTR GetItemData(int nIndex) const;
	virtual int SetCurSel(int nSelect);
	virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);

protected:
	afx_msg void OnPaint();
	afx_msg void OnDestroy();
	afx_msg void OnCbnSelchange();
	afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
	afx_msg void OnCbnEditchange();
	afx_msg HRESULT OnResetEditPositionMsg(WPARAM, LPARAM);
	DECLARE_MESSAGE_MAP()
};

源码实现(CSWComboBox.cpp):

#include "stdafx.h"
#include "CSWComboBox.h"

// CSWComboBox
CSWComboBox::CSWComboBox()
{
	CommonConstruct();
}

CSWComboBox::~CSWComboBox()
{
}

IMPLEMENT_DYNAMIC(CSWComboBox, CComboBox)
BEGIN_MESSAGE_MAP(CSWComboBox, CComboBox)
	//{{AFX_MSG_MAP(CSWComboBox)
	ON_WM_PAINT()
	ON_WM_DESTROY()
	ON_CONTROL_REFLECT(CBN_SELCHANGE, &CSWComboBox::OnCbnSelchange)
	ON_WM_MEASUREITEM()
	ON_WM_CTLCOLOR()
	ON_CONTROL_REFLECT(CBN_EDITCHANGE, &CSWComboBox::OnCbnEditchange)
	ON_WM_SIZE()
	ON_MESSAGE(WM_USER + 1, OnResetEditPositionMsg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CSWComboBox::CommonConstruct()
{
	m_brEdge.CreateSolidBrush(RGB(151, 151, 151));
	m_bIsMouseHover = FALSE;
	m_bIsMouseDown = FALSE;
	m_bShow3DEdge = FALSE;
	m_szImage = CSize(0, 0);
}

void CSWComboBox::OnPaint() 
{
	ModifyStyleEx (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, 0, SWP_FRAMECHANGED);
	Default(); // 如果需要绘制下拉三角形,屏蔽此行代码

	// 绘制下拉三角形
	CRect rcClient;
	GetClientRect(&rcClient);
// 	CDC* pDC = GetDC();
// 	CRect rcButton = rcClient;
// 	rcButton.left = rcButton.right - 16;
// 	if (rcButton.left < rcClient.left) rcButton.left = rcClient.left;
// 	static CPen penBlack(PS_SOLID, 1, RGB(0, 0, 0));
// 	static CPen penBtnShadow(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
// 	CPen* ppenOld;
// 	if (IsWindowEnabled())
// 		ppenOld = pDC->SelectObject(&penBlack);
// 	else	ppenOld = pDC->SelectObject(&penBtnShadow);
// 	for (long i = 0; i < 4; i++) {
// 		pDC->MoveTo(rcButton.left + 3 + i, rcButton.top + rcButton.Height() / 2 - 2 + i);
// 		pDC->LineTo(rcButton.left + 3 + 7 - i, rcButton.top + rcButton.Height() / 2 - 2 + i);
// 		if (!IsWindowEnabled())
// 			pDC->SetPixel(rcButton.left + 3 + 7 - i, rcButton.top + rcButton.Height() / 2 - 2 + i + 1, 0xFFFFFF);
// 	}
// 	pDC->SelectObject(ppenOld);
// 	ReleaseDC(pDC);

	if (m_bShow3DEdge)
	{		
		COMBOBOXINFO comboBoxInfo;
		comboBoxInfo.cbSize = sizeof(COMBOBOXINFO);
		GetComboBoxInfo(&comboBoxInfo);
		CRect rcComboBoxBtn = comboBoxInfo.rcButton;
		rcClient.right -= rcComboBoxBtn.Width();
		CDC* pDC = GetDC();
		rcClient.DeflateRect(1, 1, 2, 2);
		if (!IsWindowEnabled()) 
		{
			pDC->Draw3dRect(rcClient, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNHIGHLIGHT));
			rcClient.OffsetRect(1, 1);
			pDC->Draw3dRect(rcClient, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNHIGHLIGHT));
		}
		else
		{
			pDC->Draw3dRect(rcClient, ::GetSysColor(COLOR_BTNFACE), ::GetSysColor(COLOR_BTNSHADOW));
			rcClient.OffsetRect(1, 1);
			pDC->Draw3dRect(rcClient, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNFACE));
		}

		ReleaseDC(pDC);
		return;
	}

	DrawEdge(::GetSysColor(COLOR_BTNFACE), ::GetSysColor(COLOR_BTNFACE));
}

void CSWComboBox::DrawEdge(COLORREF clrTopLeft, COLORREF clrBottomRight)
{
	CRect rcClient;
	GetClientRect(&rcClient);
	CDC* pDC = GetDC();
	rcClient.DeflateRect(1, 1);
	if (!IsWindowEnabled())
		pDC->Draw3dRect(rcClient, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNHIGHLIGHT));
	else
		pDC->Draw3dRect(rcClient, ::GetSysColor(COLOR_BTNFACE), ::GetSysColor(COLOR_BTNFACE));

	if (!IsWindowEnabled()) 
	{
		ReleaseDC(pDC);
		return;
	}

	// 画边框颜色
	GetClientRect(&rcClient);
	CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_BTNSHADOW));
	HGDIOBJ hOldPen = (HGDIOBJ)::SelectObject(pDC->GetSafeHdc(), (HGDIOBJ)pen.GetSafeHandle()); //选择画笔
 	HBRUSH hOldBrush = (HBRUSH)::SelectObject(pDC->GetSafeHdc(), (HBRUSH)::GetStockObject(HOLLOW_BRUSH)); // 选择一个空的画刷
 	pDC->Rectangle(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height());
	::SelectObject(pDC->GetSafeHdc(), hOldBrush);
	::SelectObject(pDC->GetSafeHdc(), hOldPen);

	// 绘制右侧下拉按钮的外框,使其看起来平面化
	{
		COMBOBOXINFO comboBoxInfo;
		comboBoxInfo.cbSize = sizeof(COMBOBOXINFO);
		GetComboBoxInfo(&comboBoxInfo);
		CRect rcComboBoxBtn = comboBoxInfo.rcButton;
		CRect rcComboBoxItem = comboBoxInfo.rcItem;
		CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_BTNFACE));
		HGDIOBJ hOldPen = (HGDIOBJ)::SelectObject(pDC->GetSafeHdc(), (HGDIOBJ)pen.GetSafeHandle());
		HBRUSH hOldBrush = (HBRUSH)::SelectObject(pDC->GetSafeHdc(), (HBRUSH)::GetStockObject(HOLLOW_BRUSH));
		pDC->Rectangle(rcComboBoxItem.right - 1, rcComboBoxItem.top - 1, rcComboBoxItem.right + rcComboBoxBtn.Width() + 1, rcComboBoxItem.bottom + 1);
		::SelectObject(pDC->GetSafeHdc(), hOldBrush);
		::SelectObject(pDC->GetSafeHdc(), hOldPen);
	}

	int nIndex = GetCurSel();
	if (nIndex != CB_ERR)
	{
		int nImageIndex;
		GetLBImage(nIndex, nImageIndex);
		if (nImageIndex >= 0)
		{
			Gdiplus::Bitmap* pBitmap = m_mapItemImage[nImageIndex];
			if (pBitmap && pBitmap->GetLastStatus() == Gdiplus::Ok)
			{
				Gdiplus::Graphics g(pDC->GetSafeHdc());
				g.DrawImage(pBitmap, RectF(6, 6, 15, 15),
					0,
					0,
					pBitmap->GetWidth(),
					pBitmap->GetHeight(),
					UnitPixel,
					NULL,
					NULL,
					NULL);
			}
		}
	}

	ReleaseDC(pDC);
}

BOOL CSWComboBox::PreTranslateMessage(MSG* pMsg) 
{
	if (pMsg->message == WM_KEYDOWN || pMsg->message==WM_KEYUP)
	{
		::TranslateMessage(pMsg);
		::DispatchMessage(pMsg);
		return TRUE;
	}
	
	if (pMsg->message == WM_SYSCHAR)
		return TRUE;
		
	return CComboBox::PreTranslateMessage(pMsg);
}

void CSWComboBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	TRACE("%s::DrawItem(%d)\n", this->GetRuntimeClass()->m_lpszClassName, GetTickCount());
	CDC dc;
	dc.Attach(lpDIS->hDC);
	CRect rcItem = lpDIS->rcItem;
	int nItem = lpDIS->itemID;
	if (nItem == -1)
		return;

	dc.SetBkMode(TRANSPARENT);
	if (lpDIS->itemState & ODS_SELECTED)
	{
		dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
		dc.FillSolidRect(&rcItem, GetSysColor(COLOR_HIGHLIGHT));
		if (lpDIS->itemAction & ODA_FOCUS)
			dc.DrawFocusRect(&rcItem);
	}
	else
	{
		dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
		dc.FillSolidRect(&rcItem, GetSysColor(COLOR_WINDOW));		
	}

	// 画下拉项左侧图标
	CRect rcIcon = rcItem;
	rcIcon.DeflateRect(2, 2);
	rcIcon.right = rcIcon.left + rcIcon.Height();
	int nImageIndex;
	GetLBImage(nItem, nImageIndex);
	if (nImageIndex >= 0)
	{
		Gdiplus::Bitmap* pBitmap = m_mapItemImage[nImageIndex];
		if (pBitmap && pBitmap->GetLastStatus() == Gdiplus::Ok)
		{
			Gdiplus::Graphics g(dc.GetSafeHdc());
			g.DrawImage(pBitmap, RectF(rcIcon.left, rcIcon.top, rcIcon.Width(), rcIcon.Height()),
				0, 
				0, 
				pBitmap->GetWidth(), 
				pBitmap->GetHeight(), 
				UnitPixel, 
				NULL, 
				NULL, 
				NULL);
			rcItem.left += m_szImage.cx; 
		}
	}

	CRect rcText = rcItem;
	CString strText;
	GetLBText(nItem, strText);
	dc.DrawText(strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
	if (lpDIS->itemState & ODS_SELECTED && GetDroppedState())
	{
		HICON hIcon = LoadIcon(NULL, IDI_ERROR);
		ICONINFO icoObj;
		GetIconInfo(hIcon, &icoObj);
		CRect rcRIcon(rcItem);
		rcRIcon.left = rcRIcon.right - icoObj.xHotspot - 2;
		rcRIcon.top += (rcRIcon.Height() - icoObj.yHotspot) / 2;
		DrawIconEx(dc.m_hDC, rcRIcon.left, rcRIcon.top, hIcon, icoObj.xHotspot, icoObj.yHotspot, NULL, NULL, DI_NORMAL);
	}

 	dc.Detach();
}

void CSWComboBox::AutoFitDroppedWidth()
{
	// 计算下拉列表最长宽度
	CString csItem;
	int nWidth = GetDroppedWidth();
	CDC* pDC = this->GetDC();
	for (int i = 0; i < GetCount(); i++)
	{
		GetLBText(i, csItem);
		CSize sz = pDC->GetTextExtent(csItem);
		if (sz.cx > nWidth)
		{
			// 如果非只读,则预留出删除叉叉的宽度
// 			if (m_bReadOnly)
// 				nWidth = sz.cx;
// 			else
				nWidth = sz.cx + m_szImage.cx;
		}
	}

	SetDroppedWidth(nWidth);
	ReleaseDC(pDC);
}

int CSWComboBox::AddString(LPCTSTR lpszString, int nImageIndex)
{
	int nItem = CComboBox::AddString(lpszString);//插入一条文本
	ComboData* pData = new ComboData;
	if (pData == NULL)
		return -1; 

	pData->sItemText = lpszString;
	pData->nImageIndex = nImageIndex;
	CComboBox::SetItemData(nItem, (DWORD)pData);
	AutoFitDroppedWidth();
	return nItem;
}

int CSWComboBox::SetItemData(int nIndex, DWORD_PTR dwItemData)
{
	ComboData* pData = (ComboData*)CComboBox::GetItemData(nIndex);
	if (pData == NULL)
		return 0;

	pData->dwItemData = dwItemData;
	return CComboBox::SetItemData(nIndex, (DWORD)pData);
}

DWORD_PTR CSWComboBox::GetItemData(int nIndex) const
{
	ComboData* pData = (ComboData*)CComboBox::GetItemData(nIndex);
	if (pData == NULL)
		return 0;

	return pData->dwItemData;
}

int CSWComboBox::InsertString(int nIndex, LPCTSTR lpszString, int nImageIndex)
{
	int nItem = CComboBox::InsertString(nIndex, lpszString);//插入一条文本
	ComboData* pData = new ComboData;
	if (pData == NULL)
		return -1;

	pData->sItemText = lpszString;
	pData->nImageIndex = nImageIndex;
	CComboBox::SetItemData(nItem, (DWORD)pData); 
	AutoFitDroppedWidth();
	return nItem;
}

int CSWComboBox::GetLBText(int nIndex, CString& strText) //获取当前绘制项的文本
{
	ComboData* pData = (ComboData*)CComboBox::GetItemData(nIndex);
	if (pData == NULL)
		return 0;

	strText = pData->sItemText.c_str();
	return 1;
}

int CSWComboBox::GetLBImage(int nIndex, int& nImageIndex) //获取当前绘制项的图像
{
	ComboData* pData = (ComboData*)CComboBox::GetItemData(nIndex);
	if (pData == NULL) 
		return 0;

	nImageIndex = pData->nImageIndex;
	return 1;
}

void CSWComboBox::ResetContent()//释放所申请的内存
{
	int nItemIndex = GetCount();
	while (nItemIndex--)
	{
		ComboData* pData = (ComboData*)CComboBox::GetItemData(nItemIndex);
		if (pData)
		{
			delete pData;
			pData = NULL;
		}
	}

	CComboBox::ResetContent();
}

void CSWComboBox::OnDestroy()
{
	CComboBox::OnDestroy();
	ResetContent();
}

void CSWComboBox::OnCbnSelchange()
{
	int nSelIndex = GetCurSel();
	if (nSelIndex == CB_ERR)
		return;

	ComboData* pData = (ComboData*)CComboBox::GetItemData(nSelIndex);
	if (pData->nImageIndex!=-1)
	{
		CListBox* pListBox = NULL;
		COMBOBOXINFO combInfo;
		combInfo.cbSize = sizeof(COMBOBOXINFO);
		GetComboBoxInfo(&combInfo);
		if (combInfo.hwndList)
			pListBox = (CListBox*)CWnd::FromHandle(combInfo.hwndList);

		if (pListBox == NULL)
			return;

		CRect rcItem;
		pListBox->GetItemRect(nSelIndex, rcItem);
		CPoint point;
		GetCursorPos(&point);
		ScreenToClient(&point);
		CEdit *pEdit = FindChildEdit();
		if (pEdit)
		{
			CRect rcEdit;
			pEdit->GetClientRect(&rcEdit);
			point.y -= rcEdit.Height();
		}
		
		rcItem.left = rcItem.right - 18;
		if (rcItem.PtInRect(point))
		{
			if (pData)
			{
				delete pData;
				pData = NULL;
			}
			this->DeleteString(nSelIndex);
			//pListBox->DeleteString(nSelIndex);
			SetWindowText(_T(""));
		}
		else
		{
			SetChildEditOffset(20);
		}

		Invalidate();
	}
}

void CSWComboBox::Show3DEdge(BOOL bShow)
{
	m_bShow3DEdge = bShow;
	RedrawWindow();
}

UINT CSWComboBox::AddImageList(Gdiplus::Bitmap* pBitmap)
{
	if (pBitmap == NULL)
		return UINT(-1);

	UINT nCount = m_mapItemImage.size();
	m_mapItemImage[nCount] = pBitmap;
	m_szImage = CSize(max(m_szImage.cx, pBitmap->GetWidth()), max(m_szImage.cy, pBitmap->GetHeight()));
	return nCount;
}

void CSWComboBox::PreSubclassWindow()
{
	// TODO: 在此添加专用代码和/或调用基类
	SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_STYLE) | BS_OWNERDRAW);
	CComboBox::PreSubclassWindow();
}

void CSWComboBox::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CComboBox::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}

HBRUSH CSWComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  在此更改 DC 的任何特性
	if (nCtlColor == CTLCOLOR_STATIC)
	{
// 		CFont* font = new CFont;
// 		font->CreatePointFont(72, _T("宋体"));
//		pDC->SelectObject(font);
		pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
		pDC->SetBkMode(TRANSPARENT);
		HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
// 		font->DeleteObject();
// 		delete font;
		return (HBRUSH)hBrush;
	}

	if (nCtlColor == CTLCOLOR_EDIT)
	{
		CEdit* pEdit = reinterpret_cast<CEdit*>(pWnd);
		//pEdit->SetLimitText(256);
		pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
// 		CFont* font = new CFont;
// 		font->CreatePointFont(72, _T("宋体"));
// 		pDC->SelectObject(font);
		pDC->SetBkMode(TRANSPARENT);
		HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
//		font->DeleteObject();
//		delete font;
		return (HBRUSH)hBrush;
	}

	if (nCtlColor == CTLCOLOR_LISTBOX)
	{
// 		CFont* font = new CFont;
// 		font->CreatePointFont(72, _T("宋体"));
// 		pDC->SelectObject(font);
		pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
		pDC->SetBkMode(TRANSPARENT);
		HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
// 		font->DeleteObject();
// 		delete font;
		return (HBRUSH)hBrush;
	}

	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
}


void CSWComboBox::OnCbnEditchange()
{
	// TODO: 在此添加控件通知处理程序代码
	SetChildEditOffset(0);
}

int CSWComboBox::SetCurSel(int nSelect)
{
	int nIndex = CComboBox::SetCurSel(nSelect);
	if (nIndex != CB_ERR)
		PostMessage(WM_USER+1);

	return nIndex;
}

// 获取子控件CEdit
CEdit* CSWComboBox::FindChildEdit()
{
	::CWnd *pWnd = GetWindow(GW_CHILD);
	while (pWnd)
	{
		TCHAR classname[256];
		::GetClassName(pWnd->m_hWnd, classname, 256);
		if (lstrcmpi(classname, _T("Edit")) == 0)
			break;
		if (pWnd)
			pWnd = pWnd->GetNextWindow();
	}

	return (CEdit*)pWnd;
}

// 偏移CEdit子窗体位置
void CSWComboBox::SetChildEditOffset(int nOffset/* = 20*/)
{
	CEdit *pEdit = FindChildEdit();
	if (pEdit)
	{
		CRect rcEditWindow; pEdit->GetWindowRect(rcEditWindow);
		CRect rcWindow; GetWindowRect(rcWindow);
		rcEditWindow.left = nOffset + 3;
		rcEditWindow.top = 6; // 相对位置本来是3,考虑到文本居中显示,6比较合适
		rcEditWindow.right = rcWindow.Width() - 20;
		rcEditWindow.bottom = rcWindow.Height() - 3;
		pEdit->MoveWindow(rcEditWindow);
	}
}

HRESULT CSWComboBox::OnResetEditPositionMsg(WPARAM wParam, LPARAM lParam)
{
	SetChildEditOffset();
	return S_OK;
}

BOOL CSWComboBox::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
	// TODO: 在此添加专用代码和/或调用基类
	dwStyle &= ~0x0F;
	dwStyle |= CBS_DROPDOWNLIST;
	dwStyle |= CBS_OWNERDRAWFIXED;
	dwStyle |= CBS_HASSTRINGS;
	return CComboBox::Create(dwStyle, rect, pParentWnd, nID);
}

效果图如下:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VC++ CComboBox自绘 的相关文章

随机推荐

  • c++命名空间

    命名空间 主要解决全局变量的冲突 内部不允许私有变量 所有变量都是公有的 namespace data int x 10 data x 为域作用符 直接使用等同于使用全局变量 不存在就是0 不包含匿名命名空间内变量 同一个文件引用stati
  • 相见恨晚的办公插件合集(二)

    之前有分享过一些办公的插件 如不坑盒子 打工人插件 易用宝等 下面就简单的介绍一下上面的几个神器后再补充一些其它办公神器吧 不坑盒子 word wps 这是一个非常好用的插件工具 专门应用在Word文档和wps 支持Office 2010以
  • 拓数派入选中国信通院 “铸基计划”「高质量数字化转型产品及服务全景图」

    7 月 27 日 由中国信息通信研究院 以下简称 中国信通院 主办的 2023 数字生态发展大会 暨中国信通院 铸基计划 年中会议在京召开 本次大会深度展示了中国信通院在数字化领域的工作成果 并正式发布了 高质量数字化转型产品及服务全景图
  • GUI基础知识

    GUI编程 1 简介 图形用户界面 Graphical User Interface 又称图形用户接口 是指采用图形方式显示的计算机操作用户界面 GUI的核心技术 AWT Swing 2 Awt 2 1 AWT简介 AWT Abstract
  • springboot报错Could not autowire. No beans of ‘RedisConnectionFactory‘ type found

    这个报错提示是因为springboot升级到2 6 9以后版本就会出现 报错界面 其实上面报错不影响程序使用 但是总是觉得别扭 提供3种解决方式 第一种方案 springboot版本降到2 6 9或以下 第二种方案 通过idea设置不提示该
  • Unity&Webform(2):自定义LifetimeManager和TypeConverter使Unity从HttpContext中取值注入WebForm页面...

    上一篇 Unity WebForm 1 自定义IHttpHandlerFactory使用Unity对ASP NET Webform页面进行依赖注入中让Unity和WebForm结合在一起 通过使用HttpHandlerFactory实现了对
  • 模式匹配算法

    下面分别介绍 朴素模式匹配算法 和 改进模式匹配算法 KMP 朴素模式匹配算法思想 从目标S中的第一个字符开始和模式T中的的第一个比较 用 i 和 j 分别指示S串和T串中正在比较字符的位置 若相等 则继续逐个比较后续字符 否则 从S 的第
  • 【PYTHON】conda/pip一些命令记录

    查看环境 conda info env conda env list 删除某环境 conda remove n
  • 数据结构:设计实现抽象数据类型“有理数”内容

    题目 设计实现抽象数据类型 有理数 内容 设计并上机实现抽象数据类型 有理数 有理数的基本操作包括 两个有理数的加 减 乘 除等 包括有理数的创建和输出 要求 有理数的类型 我们可以构造成一个结构体类型 这个结构体由两个整数构成 分别表示有
  • 深入理解设计原则之最少知识原则/迪米特法则(LOD)【软件架构设计】

    系列文章目录 高级C 并发线程编程 C 高性能优化编程系列 软件架构设计系列 深入理解设计模式系列 不怕别人瞧不起 就怕自己不争气 Are not afraid to look down upon he was afraid his dis
  • JavaWeb 【基础】 IDEA 创建javaweb项目,并使用servelet 开发简单接口

    目录 创建项目 配置web项目 创建servelet 添加servelet路径映射 方法一 使用 web xml 配置servelet映射 方法二 使用注解配置servelet映射 初学javaweb的时候 通常会遇到很多坑 下面系统的做一
  • transform: translateY(-100%)偏移实现上滑隐藏导航栏

    transform translateY 100 语法 Transform字面上就是变形 改变的意思 在CSS3中transform主要包括以下几种 旋转rotate 扭曲skew 缩放scale和移动translate以及矩阵变形matr
  • python办公自动化-按需求批量提取EXCEL数据,python只需要几秒钟!

    作者 锋小刀 微信搜索 Python与Excel之交 关注我的公众号查看更多内容 Hi 大家好 又到Python偷懒时刻 今天讲解的是如何利用Python来按需求批量提取EXCEL表格数据 然后进行保存 在用excel进行工作时 这样的操作
  • GLSL (3)输入和输出

    1 in和out 着色器使用in和out两个关键字设定输入和输出 只要一个输出变量与下一个着色器阶段的输入匹配 它就会传递下去 既是一个着色器向另一个着色器发送数据 我们必须在发送方着色器中声明一个输出 在接收方着色器中声明一个类似的输入
  • AI应用

    上一期 AI应用 从模仿到超越 视觉智能下一步会怎样进化 我们介绍了机器的 眼睛 视觉识别 这一期我们来分析机器的 耳朵 语音识别能力 语音识别能带来什么 场景一 打开电视 不再需要遥控器 坐在沙发上说一声 打开电视 就可以尽情观赏 类似的
  • 上传论文到arxiv教程

    由于文章需要引用或者虽然已经被期刊或者会议录用 但还未发表 可能需要先占坑 具体步骤如图 1 arxiv 注册 最好用 edu 邮箱 就不需要资格审查了 官网是 http arxiv org 注册好后直接登录 2 开始一个新的提交 以前记录
  • ADC学习系列(一):ADC基础概念

    本章主要是进行ADC的基础概念学习 从模拟和数字信号进行入手 分析各自的优缺点和应用场合 从而引出数模转换的重要性 紧接着提到了ADC部分最重要的奈奎斯特采样定理 了解采样频率和被测信号频率之间的关系 最后介绍了ADC的采样保持放大电路 作
  • Python全栈开发工程师 第一模块作业

    1 编程题 100分 第一模块作业 1 学习计算机运行原理 绘制一张python代码从输入电脑 到处理 到输出结果的整个流程图 2 构建自己的python编程环境 整个过程做笔记 把截图放到word里提交 3 写下自己学习编程的目标 建议按
  • 【IntelliJ IDEA】升级之后又要激活的解决方法

    用了几个月的idea 在它升级之后 又不听话了 启动时候需要重新激活 解决方法 1 找到C Windows System32 drivers etc 下的hosts文件 在文件中添加如下 0 0 0 0 account jetbrains
  • VC++ CComboBox自绘

    头文件定义 CSWComboBox h pragma once class CSWComboBox public CComboBox DECLARE DYNAMIC CSWComboBox public CSWComboBox CSWCom