MFC第二十四天 使用GDI对象画笔和画刷来开发控件(分页控件选择态的算法分析、使用CToolTipCtrl开发动静态提示)

news2024/11/16 11:56:11

文章目录

  • GDI对象画笔和画刷来开发控件
    • 梯形边框的按钮控件
      • CMainDlg.h
      • CMainDlg.cpp
      • CLadderCtrl.h
      • CLadderCtrl.cpp
    • 矩形边框的三态按钮控件 CToolTipCtrl开发动静态提示
      • CMainDlg.h
      • CMainDlg.cpp
      • CLadderCtrl.h
      • CLadderCtrl.cpp: 实现文件
    • 矩形边框的三态按钮控件 CToolTipCtrl开发动态提示
      • CMainDlg.h
      • CMainDlg.cpp
      • CLadderCtrl.h
      • CLadderCtrl.cpp
  • 附录

GDI对象画笔和画刷来开发控件

梯形边框的按钮控件

CMainDlg.h

class CMainDlg : public CDialogEx
{
// 构造
	CLadderCtrl m_ladd;

protected:
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
};

CMainDlg.cpp

void CMainDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);
	
	if (m_ladd)
	{
		m_ladd.SetWindowPos(NULL, 0, cy - 20, cx, cy, SWP_NOZORDER);
	}
}
BOOL CMainDlg::OnInitDialog(){
	CDialogEx::OnInitDialog();
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标
	CRect rect;
	GetClientRect(rect);
	rect.top = rect.bottom - 20;
	m_ladd.Create(WS_CHILD | WS_VISIBLE, rect, this,8888);
	m_ladd.InsertItem(0, _T("组建"));
	m_ladd.InsertItem(1, _T("调试"));
	m_ladd.InsertItem(2, _T("在文件1中查找"));
	m_ladd.InsertItem(3, _T("在文件2中查找"));
	m_ladd.InsertItem(4, _T("结果"));
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

CLadderCtrl.h

class CLadderCtrl : public CWnd{
	DECLARE_DYNAMIC(CLadderCtrl)
	CStringArray m_ds;  //存储一组字符串 使用Add方法添加新的字符串,使用RemoveAt方法删除指定位置的字符串,使用GetAt方法获取特定位置的字符串等。
	int m_nIndex{}; 
	CBrush m_br, m_brSel;
	CFont m_font, m_fontSel;
public:
	CLadderCtrl();
	virtual ~CLadderCtrl();
	BOOL Create(DWORD dwStyle, CRect rect, CWnd* pParent, int nID);
	LONG InsertItem(int nItem, LPCTSTR lpszItem);
	int SetCurSel(int nItem);
	int GetCurSel() const;
	int GetItemCount() const;
	BOOL DeleteAllItems();	BOOL DeleteItem(int nItem);
};

CLadderCtrl.cpp

CLadderCtrl::CLadderCtrl(){
	m_br.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
	m_brSel.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
	HFONT hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); // GetStockObject 返回的是void* 要给转为具体类型
	LOGFONT lf;
	GetObject(hfont, sizeof(lf), &lf);
	m_font.CreateFontIndirect(&lf);
	lf.lfWeight = 700;
	m_fontSel.CreateFontIndirect(&lf);
}
CLadderCtrl::~CLadderCtrl()	{}
BOOL CLadderCtrl::Create(DWORD dwStyle, CRect rect, CWnd* pParent, int nID){
	return CWnd::Create(NULL, NULL, dwStyle, rect, pParent, nID);
}
LONG CLadderCtrl::InsertItem(int nItem, LPCTSTR lpszItem)
{
	m_ds.InsertAt(nItem,lpszItem);
	return nItem;
}
int CLadderCtrl::SetCurSel(int nItem)
{
	return 0;
}
int CLadderCtrl::GetCurSel() const
{
	return 0;
}
int CLadderCtrl::GetItemCount() const
{
	return (int)m_ds.GetCount();
}
BOOL CLadderCtrl::DeleteAllItems()
{
	m_ds.RemoveAll();
	return TRUE;
}
BOOL CLadderCtrl::DeleteItem(int nItem)
{
	m_ds.RemoveAt(nItem);
	return TRUE;
}
void CLadderCtrl::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	CRect rect;
	GetClientRect(rect);
	dc.SetBkMode(TRANSPARENT);
	dc.FillSolidRect(rect, GetSysColor(COLOR_INFOBK));

	int i = -1, nCount =(int) m_ds.GetCount();
 
	const int H = rect.Height(); //创建一个宽度为矩形高度的四分之一,高度为整个矩形高度的矩形rc。
	CRect rc{ H/4,0,0,rect.bottom };
	dc.SelectObject(&m_br);
	POINT ptSel[4];
	CString sSel;
	CRect rSel;

	dc.SelectObject(&m_font); //宋体9 就是默认字体

	/*HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
	LOGFONT lf;
	GetObject(hFont, sizeof(lf), &lf);*/

	while (++i<nCount)
	{
		CString str = m_ds[i];

		CSize size = dc.GetTextExtent(str); //获取字符串str在设备上下文dc中的宽度和高度,并将结果存储在CSize对象size中
		rc.right = rc.left + size.cx +H; //左边界加上字符串宽度和一个常量H	 可以保证矩形rc的宽度至少能够容纳字符串,并且在右边留出一个宽度为常量H的空白区域
	
		POINT pts[] = { {rc.left-H/4,rc.top},{rc.right + H / 4,rc.top},{rc.right - H / 4,rc.bottom},{rc.left + H / 4,rc.bottom} };
		if (i!=m_nIndex)
		{
			dc.Polygon(pts, _countof(pts));
					//dc.Rectangle(rc);
			dc.DrawText(str, rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		}
		else
		{
			memcpy(ptSel, pts, sizeof(pts));
			sSel = str;
			rSel = rc;
		}
		rc.left = rc.right;
	}
	dc.SelectObject(&m_brSel);

	dc.Polygon(ptSel, _countof(ptSel)); //要覆盖二次绘画
	dc.SelectObject(&m_fontSel);
	dc.DrawText(sSel, rSel, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 }
//	dc.TextOut(0, 0, _T("测试系统颜色"));

void CLadderCtrl::OnLButtonDown(UINT nFlags, CPoint point)  //和上面算法一致 这个用来算出位置
{
	CWnd::OnLButtonDown(nFlags, point);
	CClientDC dc(this);
	dc.SelectStockObject(DEFAULT_GUI_FONT);
	int i = -1, nCount = (int)m_ds.GetCount();
	CRect rect;
	GetClientRect(rect);
	CRect rc{ 0,0,0,rect.bottom };

	while (++i<nCount)   
	{
		CString str = m_ds[i];

		CSize size = dc.GetTextExtent(str);
		rc.right = rc.left + size.cx + rect.Height();
		dc.SelectObject(i == m_nIndex ? &m_brSel : &m_br);
		if (rc.PtInRect(point))
		{
			if (i != m_nIndex)  //去除无效点击 
			{
				m_nIndex = i;
				Invalidate(FALSE);
			}
			break;
		}
		rc.left = rc.right;
	}
}

在这里插入图片描述

矩形边框的三态按钮控件 CToolTipCtrl开发动静态提示

CMainDlg.h

#include "CLadderCtrl.h"
class CMainDlg : public CDialogEx
{
// 构造
	CLadderCtrl m_ladd;	
	CToolTipCtrl m_tip;
public:
	CMainDlg(CWnd* pParent = nullptr);	// 标准构造函数	
public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
	virtual BOOL PreTranslateMessage(MSG* pMsg);
};

CMainDlg.cpp

BOOL CMainDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	CRect rect;
	GetClientRect(rect);
	rect.top = rect.bottom - 20;
	m_ladd.Create(WS_CHILD | WS_VISIBLE, rect, this,8888);
	m_ladd.InsertItem(0, _T("组建"));
	m_ladd.InsertItem(1, _T("调试"));
	m_ladd.InsertItem(2, _T("在文件1中查找"));
	m_ladd.InsertItem(3, _T("在文件2中查找"));
	m_ladd.InsertItem(4, _T("结果"));
	m_tip.Create(this);
	m_tip.AddTool(&m_ladd, _T("没想到吧"));
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
void CMainDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);
	if (m_ladd)
		m_ladd.SetWindowPos(NULL, 0, cy - 20, cx, 20, SWP_NOZORDER);
}
BOOL CMainDlg::PreTranslateMessage(MSG* pMsg) //皇军的岗楼
{
	m_tip.RelayEvent(pMsg);
	return CDialogEx::PreTranslateMessage(pMsg);
}

CLadderCtrl.h

class CLadderCtrl : public CWnd
{
	DECLARE_DYNAMIC(CLadderCtrl)
	CStringArray m_ds;
	int m_nIndex{};
	int m_nTrack{};
	CBrush m_br, m_brSel,m_brTrack; //三态按钮  三态控件  没有选中色(普通) 选中色 放在上面的框色(追踪态)
	CBrush m_brBack;
	CPen m_pen;
	int GetIndex(CPoint point);
public:
	CLadderCtrl();
	virtual ~CLadderCtrl();
	BOOL Create(DWORD dwStyle, CRect rect, CWnd* pParent, int nID);

	LONG InsertItem(int nItem, LPCTSTR lpszItem);
	int SetCurSel(int nItem);
	int GetCurSel() const;
	int GetItemCount() const;
	BOOL DeleteAllItems();
	BOOL DeleteItem(int nItem);
// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_MAIN_DIALOG };
#endif

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnPaint();
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
};

CLadderCtrl.cpp: 实现文件

#include "pch.h"
#include "CreatControl.h"
#include "afxdialogex.h"
#include "CLadderCtrl.h"
CLadderCtrl::CLadderCtrl()  //有对应的构造函数可以在定义时直接给予初始化{}
{
	m_br.CreateSolidBrush(RGB(64,86,140));
	m_brSel.CreateSolidBrush(RGB(230,245,255)); 
	m_brTrack.CreateSolidBrush(RGB(187, 194, 241));
	m_brBack.CreateSolidBrush(RGB(93, 107, 153)); //默认的背景
	m_pen.CreatePen(PS_SOLID, 1, RGB(93, 107, 153));
}
CLadderCtrl::~CLadderCtrl()
{
}
BOOL CLadderCtrl::Create(DWORD dwStyle, CRect rect, CWnd* pParent, int nID)
{
	return CWnd::Create(NULL, NULL, dwStyle, rect, pParent, nID);
}
LONG CLadderCtrl::InsertItem(int nItem, LPCTSTR lpszItem)
{
	m_ds.InsertAt(nItem,lpszItem);
	return nItem;
}
int CLadderCtrl::SetCurSel(int nItem)
{
	ASSERT(nItem > -1 && nItem < m_ds.GetCount());
	m_nIndex = nItem;
	Invalidate(FALSE);
	return 0;
}
int CLadderCtrl::GetCurSel() const
{
	return m_nIndex;
}

int CLadderCtrl::GetItemCount() const
{
	
	return (int)m_ds.GetCount();
}

BOOL CLadderCtrl::DeleteAllItems()
{
	m_ds.RemoveAll();
	return TRUE;
}

BOOL CLadderCtrl::DeleteItem(int nItem)
{
	m_ds.RemoveAt(nItem);
	return TRUE;
}

void CLadderCtrl::DoDataExchange(CDataExchange* pDX)
{
	CWnd::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CLadderCtrl, CWnd)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
void CLadderCtrl::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	CRect rect;
	GetClientRect(rect);
	dc.SetBkMode(TRANSPARENT);
	dc.FillRect(rect,&m_brBack);

	int i = -1, nCount =(int) m_ds.GetCount();
	int nLeft = 0;
	CRect rc{ 0,0,0,rect.bottom };

	CFont* pFont = GetFont();
	dc.SelectStockObject(DEFAULT_GUI_FONT); //宋体9 就是默认字体
	dc.SelectObject(&m_pen);

	/*HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
	LOGFONT lf;
	GetObject(hFont, sizeof(lf), &lf);*/

	while (++i<nCount)
	{
		CString str = m_ds[i];

		CSize size = dc.GetTextExtent(str);
		rc.right = rc.left + size.cx + rect.Height();
		if (i == m_nIndex)
		{
			dc.SelectObject(&m_brSel);
			dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
		}
		else if (i == m_nTrack)
		{
			dc.SelectObject(&m_brTrack);
			dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
		}
		else
		{
			dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
			dc.SelectObject(&m_br);
		}
		//dc.SelectObject(i == m_nIndex ? &m_brSel:&m_br); 

		dc.Rectangle(rc);
		dc.DrawText(str, rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	 
		rc.left = rc.right;
	}

 }
//	dc.TextOut(0, 0, _T("测试系统颜色"));
int CLadderCtrl::GetIndex(CPoint point)
{
	CClientDC dc(this);
	dc.SelectStockObject(DEFAULT_GUI_FONT);
	int i = -1, nCount = (int)m_ds.GetCount();
	CRect rect;
	GetClientRect(rect);
	CRect rc{ 0,0,0,rect.bottom };

	while (++i < nCount)
	{
		CString str = m_ds[i];

		CSize size = dc.GetTextExtent(str);
		rc.right = rc.left + size.cx + rect.Height();
		dc.SelectObject(i == m_nIndex ? &m_brSel : &m_br);
		if (rc.PtInRect(point))
		{
			return i;
		}
		rc.left = rc.right;
	}
	return -1;
}
void CLadderCtrl::OnLButtonDown(UINT nFlags, CPoint point)  //和上面算法一致 这个用来算出位置
{
	int nIndex = GetIndex(point);
	if (nIndex != m_nIndex)  //去除无效点击 
	{
		m_nIndex = nIndex;
		Invalidate(FALSE);
	}

	CWnd::OnLButtonDown(nFlags, point);
}
void CLadderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
	int nIndex = GetIndex(point);
	if (nIndex == m_nIndex)   
		return;
		
	if (m_nTrack!=nIndex)   
	{
		m_nTrack = nIndex;
		Invalidate(FALSE);
	}
	CWnd::OnMouseMove(nFlags, point);
}

在这里插入图片描述

矩形边框的三态按钮控件 CToolTipCtrl开发动态提示

本次只添加了与静态提示不同之处的代码

CMainDlg.h

#include "CLadderCtrl.h"
class CMainDlg : public CDialogEx
{
// 构造
	CLadderCtrl m_ladd;	
	CToolTipCtrl m_tip;
public:
	CMainDlg(CWnd* pParent = nullptr);	// 标准构造函数
	
public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	afx_msg BOOL SetTipText(UINT id, NMHDR* pHdr, LRESULT* pResult);
	//反射型消息 手动创建的 一消息一函数一控件 一ID
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
};

CMainDlg.cpp

设置动态文字的函数

BOOL CMainDlg::SetTipText(UINT id, NMHDR* pHdr, LRESULT* pResult){
	int nIndex = m_ladd.GetTrack();
	if (nIndex < 0 || nIndex >= m_ladd.GetItemCount())
		return FALSE;
	TOOLTIPTEXT* pText = (TOOLTIPTEXT*)pHdr;
	if (pText->uFlags & TTF_IDISHWND){
		auto nID = (int)pHdr->idFrom;
		CString str = m_ladd.GetItemText(nIndex);
		_tcscpy_s(pText->szText, 80, str);
		return TRUE;
	}
	return FALSE;
	return 0;
}
BOOL CMainDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){
	switch (pWnd->GetDlgCtrlID())	{
	case 8888:
	{
		static int nTrack = -1; // 用来看它是否切换 全局变量
		int n = m_ladd.GetTrack();
		if (nTrack !=n ){	 //切换算法
			nTrack = n;
			m_tip.Update();
		}
	}
		break;
	}
	return CDialogEx::OnSetCursor(pWnd, nHitTest, message);
}

CLadderCtrl.h

class CLadderCtrl : public CWnd{
	CStringArray m_ds;
	int m_nIndex{};
	int m_nTrack{};
	CBrush m_br, m_brSel,m_brTrack; //三态按钮 没有选中色(普通) 选中色 放在上面的框色(追踪态)
	CBrush m_brBack;
	int GetIndex(CPoint point);
public:
	int GetTrack() const{
		return m_nTrack; //拿到你追踪到的是几号
	}
	CString GetItemText(int nIndex) const{
		return m_ds[nIndex]; //拿到的对应的索引来获取文字
	}
	CLadderCtrl();

CLadderCtrl.cpp

int CLadderCtrl::GetIndex(CPoint point)
{
	CClientDC dc(this);
	dc.SelectStockObject(DEFAULT_GUI_FONT);
	int i = -1, nCount = (int)m_ds.GetCount();
	CRect rect;
	GetClientRect(rect);
	CRect rc{ 0,0,0,rect.bottom };

	while (++i < nCount)
	{
		CString str = m_ds[i];

		CSize size = dc.GetTextExtent(str);
		rc.right = rc.left + size.cx + rect.Height();
		dc.SelectObject(i == m_nIndex ? &m_brSel : &m_br);
		if (rc.PtInRect(point))
		{
			return i;
		}
		rc.left = rc.right;
	}
	return -1;
}
void CLadderCtrl::OnLButtonDown(UINT nFlags, CPoint point)  //和上面算法一致 这个用来算出位置
{
	int nIndex = GetIndex(point);
	if (nIndex != m_nIndex)  //去除无效点击 
	{
		m_nIndex = nIndex;
		Invalidate(FALSE);
	}
	CWnd::OnLButtonDown(nFlags, point);
}
void CLadderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
	int nIndex = GetIndex(point);
	//if (nIndex == m_nIndex)   
	//	return;
	if (m_nTrack!=nIndex)   
	{
		m_nTrack = nIndex;
		Invalidate(FALSE);
	}
	CWnd::OnMouseMove(nFlags, point);
}

在这里插入图片描述

附录

CDC::FillSolidRect:无边框的纯色填充
GetSysColor获取系统常用的颜色。
GetStockObject(API) 获取系统预定义对象
CDC::SelectStockObject:选择系统预定义对象。
来自于API:GetStockObject
GDI对象的构造函数:CFile的构造函数
a)CPen的构造函数:
CPen(int nPenStyle, int nWidth, COLORREF crColor);
CPen pen;pen.CreatePen(PS_XXX...);
两句合成一句就是:CPen pen(PS_XXX...);


b)CBrush的构造函数
	CBrush(COLORREF crColor);             // CreateSolidBrush
	CBrush(int nIndex, COLORREF crColor); // CreateHatchBrush
	explicit CBrush(CBitmap* pBitmap);          // CreatePatternBrush

MouseMove 进入任意控件都不会理你 除非回到主窗口范围内
OnSetCursor 不论在什么控件都会显示出来 还可以switch getDlgCtrlID 任何控件都会执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/804873.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux服务器安装redis

一、安装下载 下载安装参考文章 下载安装包地址&#xff1a;https://download.redis.io/releases/ 亲测有效&#xff0c;但是启动的步骤有一些问题 安装完成&#xff01;&#xff01;&#xff01; 二、启动 有三种启动方式 默认启动指定配置启动开机自启 说明&#xff1a…

CentOS下 Docker、Docker Compose 的安装教程

Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。 Docker Compose是用于定义…

【Lua学习笔记】Lua进阶——Table(4)继承,封装,多态

文章目录 封装继承多态 封装 // 定义基类 Object {}//由于表的特性&#xff0c;该句就相当于定义基类变量 Object.id 1//该句相当于定义方法&#xff0c;Object可以视为定义的对象&#xff0c;Test可以视为方法名 //我们知道Object是一个表&#xff0c;但是抽象地看&#xff…

为什么要有虚拟内存?

操作系统是通过内存分段和内存分页的方式管理虚拟内存地址和物理内存地址之间的关系 内存分段 程序是由若干个逻辑分段组成的&#xff0c;代码分段、数据分段、栈段、堆段组成&#xff0c;不同的段有不同的属性&#xff0c;所以就用分段的形式分离开。 分段机制下的虚拟内存…

【业务功能篇58】Springboot + Spring Security 权限管理 【下篇】

4.2.2.3 SpringSecurity工作流程分析 SpringSecurity的原理其实就是一个过滤器链&#xff0c;内部包含了提供各种功能的过滤器。这里我们可以看看入门案例中的过滤器。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KjoRRost-1690534711077)(http…

使用Django自带的后台管理系统进行数据库管理的实例

Django自带的后台管理系统主要用来对数据库进行操作和管理。它是Django框架的一个强大功能&#xff0c;可以让你快速创建一个管理界面&#xff0c;用于管理你的应用程序的数据模型。 使用Django后台管理系统&#xff0c;你可以轻松地进行以下操作&#xff1a; 数据库管理&…

详解机器学习中的熵、条件熵、相对熵和交叉熵

这个是讲的不错的链接 https://www.cnblogs.com/kyrieng/p/8694705.html 这个是交叉熵 https://blog.csdn.net/m0_57236802/article/details/129554878

《焊接点云处理》-角焊焊缝处理

角焊缝点云处理 前言一、代码二、实现步骤3、验证前言 针对T型板,识别效果如下所示 一、代码 主函数 #include "CGALRECONSTRUCT.h" #include "CGALREGIONPLANE.h" #include

设计利器,掌握CAD辅助命令的必备指南

CAD设计中的辅助命令是提高效率和确度的关键工具。掌握并正确运用CAD中的各种辅助命令对于设计师们来说至关重要。本文将为你详细介绍如何使用CAD中的辅助命令&#xff0c;从而帮助你在设计过程中更加高效地实现你的创意。、 大家有没有发现&#xff0c;当我们的直线命令移动到…

Rethinking the Image Fusion(PMGI)

1.摘要 本文提出了一种基于梯度和强度比例维护&#xff08;PMGI&#xff09;的快速统一图像融合网络&#xff0c;可以端到端实现各种图像融合任务&#xff0c;包括红外和可见图像融合、多曝光图像融合、医学图像融合、多焦点图像融合和全色增强。我们将图像融合问题统一为源图…

C++信号量与共享内存实现进程间通信

关于信号量和共享内存的相关知识可参考下面链接&#xff1a; 进程间通信方式介绍_夜雨听萧瑟的博客-CSDN博客 C 创建共享内存_c共享内存_夜雨听萧瑟的博客-CSDN博客 信号量SytemV与Posix信号量的介绍与用法_夜雨听萧瑟的博客-CSDN博客 直接上代码&#xff0c;代码如下&#…

蓝桥杯单片机第十二届国赛 真题+代码

iic.c /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础&#xff0c;根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求&#xff0c;进行代码调试和修改。 */ #include <STC1…

golang文件锁,目录锁,syscall包的使用

先说结论 1. golang提供了syscall包来实现文件/目录的加锁&#xff0c;解锁 2. syscall包属于文件锁&#xff0c;是比较底层的技术&#xff0c;并不能在所有操作系统上完全实现&#xff0c;linux上实现了&#xff0c;windows下面就没有 3. 加锁时调用syscall.Flock(fd&#…

安全学习DAY09_加密逆向,特征识别

算法逆向&加密算法分类&#xff0c;特征识别 文章目录 算法逆向&加密算法分类&#xff0c;特征识别算法概念&#xff0c;分类单向散列加密 - MD5对称加密 - AES非对称加密 - RSA 常见加密算法识别特征&#xff0c;解密特点MD5密文特点BASE64编码特点AES、DES特点RSA密文…

leaftjs实现全国温度降水气压风速等值面风场洋流效果

实现内容 数据爬取、地图marker聚合、鼠标移动显示pop&#xff0c;风场&#xff0c;洋流&#xff0c;温度等值面、降水等值面、气压等值面、风速等值面&#xff0c;洋流方向、洋流流速展示、风场方向、风场风速展示&#xff0c;后期扩展小时预报&#xff0c;分钟预报、7天预报…

Modbus RTU协议 + 调试工具 + java工具类

春风若有怜花意&#xff0c;可否容我再少年 Modbus RTU通信协议指令学习 Modbus RTU协议是一种紧凑的&#xff0c;采用二进制表示数据的方式&#xff0c;带有循环冗余校验的校验和。 读取指令格式 使用过程中03功能码比较常用&#xff0c;所以以03读取为例 读请求&#xff…

Java的代理模式

java有三种代理模式 静态代理 jdk动态代理 cglib实现动态代理 代理模式的定义&#xff1a; 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的…

打包出现ProjectBuildingException异常原因之一

一次正常打包操作突然出现 原因是同事不小心在集合模块里面添加了重复的模块引入

Github 上 爆火,标星 103K的 Spring Security 手册及源码笔记,YYDS

Spring Security 是一个基于 Spring AOP 和 Servlet 过滤器的安全框架&#xff0c;它提供了安全性方面的解决方案 Spring Security 作为非常强大的框架&#xff0c;作为程序员是非常热爱的&#xff0c;我这里整理了四份 Spring Security 手写笔记及实战手册原文档见文末 目录…