MFC第十八天 非模式对话框、对话框颜色管理、记事本项目(查找替换、文字和背景色、Goto(转到)功能的开发)

news2024/10/6 18:31:45

文章目录

  • 非模式对话框
    • 非模式对话框的特点
    • 非模式对话框与QQ聊天窗口开发
    • 非模态对话框(Modeless Dialog)和模态对话框(Modal Dialog)区别
  • 记事本开发
    • CFindReplaceDialog类的成员
    • 查找替换(算法分析)
    • 使用RichEdit控件 开发Goto(转到)功能
  • 对话框颜色管理
    • WM_CTLCOLOR控件
    • 记事本中文字颜色和背景颜色功能开发

非模式对话框

非模式对话框的特点

a)调用CDialog::Create函数实现,例如:QQ的聊天框,记事本的查找等。
b)非阻塞,对象的生命期必须足够,否则就析构时摧毁了。
c)可以采用堆空间申请多例模式,也可以用全局或者成员。
d)EndDialog只对模式对话框有效,对非模式对话框无效,如果要摧毁调用DestroyWindow
(只是隐藏了窗口,不会摧毁窗口,ShowWindow还可以再重新显示)
e)如果要让非模式对话框与主窗口形成兄弟关系,在任务栏中有图标,
就在pParent参数中代入GetDesktopWindow()

非模式对话框与QQ聊天窗口开发

在这里插入图片描述

CChatceDlg.cpp

void CChatceDlg::OnBnClickedCancel()
{
	DestroyWindow(); //真正的摧毁窗口
//	EndDialog(IDCANCEL); //只对模式对话框有效,对非模式对话框无效,只是隐藏窗口,不会摧毁窗口showWindows可以再次显示出来
	//CDialogEx::OnCancel();
}

void CChatceDlg::PostNcDestroy()
{
	CDialogEx::PostNcDestroy();
	//用于堆空间 delet this; 
}

CMainDlg.h

#include "CChatceDlg.h"
class CMainDlg : public CDialogEx
{
// 构造
	CChatceDlg m_dlgChat;
}

CMainDlg.cpp
拖动客户区
在这里插入图片描述

//在窗口过程中处理鼠标在非客户区(非工作区)的点击事件。
//它用于确定鼠标点击的位置位于窗口的哪个区域,比如标题栏、边框、系统菜单等
 LRESULT CMainDlg::OnNcHitTest(CPoint point)  //拖动客户区 
{
	ScreenToClient(&point);
	if (point.y<30)
		return HTCAPTION; //表示鼠标点击在标题栏上,用于移动窗口

	return CDialogEx::OnNcHitTest(point);
}
OnNcHitTest()用于处理WM_NCHITTEST消息,该消息用于确定鼠标点击的位置。返回值可以是以下之一:
HTERROR:在窗口的错误区域
HTTRANSPARENT:在透明区域
HTNOWHERE:在窗口的非客户区
HTCLIENT:在窗口的客户区
HTCAPTION:在窗口的标题栏
HTSYSMENU:在窗口的系统菜单
HTMENU:在窗口的一般菜单
HTLEFT、HTTOP、HTRIGHT、HTBOTTOM:在窗口的边界区域
HTBOTTOMLEFT、HTTOPLEFT、HTBOTTOMRIGHT、HTTOPRIGHT:在窗口的角落区域
通过重写OnNcHitTest()函数,可以根据返回值来实现特定的行为,例如拖动窗口、更改窗口大小等。
#include "CAboutDlg.h"
void CMainDlg::OnBnClickedAbout()
{
	CAboutDlg dlg;
	dlg.DoModal();  //模式对话框
}
#include "CChatceDlg.h"
void CMainDlg::OnBnClickedChat()   //非模式对话框 多例模式
{
	//auto pDlg = new CChatceDlg;  //加强了生命周期
	//pDlg->Create(IDD_CHAT, this);
	//pDlg->ShowWindow(SW_SHOW);

	if(!m_dlgChat)
		m_dlgChat.Create(IDD_CHAT, GetDesktopWindow()); 
		// GetDesktopWindow()使用这个函数使得其和主窗口是一个父亲
	m_dlgChat.ShowWindow(SW_SHOW);
}
//单例模式 对象只能有一个 可以用全局便利 成员变量里

非模态对话框(Modeless Dialog)和模态对话框(Modal Dialog)区别

  1. 控制权:模态对话框会阻塞用户与应用程序的其他部分进行交互,直到对话框关闭为止。而非模态对话框不会阻塞用户与应用程序的其他部分的交互,可以同时操作多个窗口或控件。

  2. 用户焦点:在模态对话框中,用户无法将焦点切换到其他应用程序的窗口或控件上,直到对话框关闭。而在非模态对话框中,用户可以在对话框和其他窗口或控件之间自由切换焦点。

  3. 程序控制:在模态对话框中,对话框被关闭后会返回到调用它的代码处,可以根据对话框的返回值或状态进行相应的处理。而在非模态对话框中,对话框关闭后不会立即返回到调用它的代码处,需要通过消息处理机制来处理对话框的事件和状态。

  4. 多任务处理:由于模态对话框阻塞了用户与应用程序的其他部分的交互,因此在处理耗时任务时可以使用模态对话框来防止用户对其他部分的操作。而非模态对话框通常用于需要同时操作多个窗口或控件的情况。

总的来说,模态对话框适合用于需要用户必须完成某个操作才能继续的情况,而非模态对话框适合用于需要用户可以同时进行其他操作的情况。选择使用哪种对话框类型要根据具体的应用场景和需求来决定。

记事本开发

CFindReplaceDialog类的成员

BOOL SearchDown() const;         // 向下打勾
BOOL FindNext() const;           // TRUE if command is find next
BOOL MatchCase() const;          //大小写匹配
BOOL MatchWholeWord() const;     // 全字匹配
BOOL ReplaceCurrent() const;     // TRUE if replacing current string
BOOL ReplaceAll() const;         // TRUE if replacing all occurrences
BOOL IsTerminating() const;      // TRUE if terminating dialog
CString GetReplaceString() const;// get replacement string
CString GetFindString() const;   // get find string

CFindReplaceDialog的按钮消息:
a)通过派生类截获消息,用Spy找到每个按钮ID
b)不通过派生类截获消息,用主窗口截获消息.
ON_REGISTERED_MESSAGE(WM_FINDREPLACE, &CMainDlg::OnFindReplace)
在这里插入图片描述

查找替换(算法分析)

获取选中的文字

CString CMainDlg::GetSelText()
{
	CString str;
	m_edit.GetWindowText(str);

	int nStart, nEnd;
	m_edit.GetSel(nStart, nEnd);

	if(nEnd<=nStart)
		return CString();
	return str.Mid(nStart, nEnd - nStart);
}

创建CFindReplaceDialog

//虚函数基本都是重写 必须参数和基类一样 ,如果加了参数 不一致时它就不执行了 跟基类不同叫重定义 
void CMainDlg::OnEditFind()
{
	if (IsWindow(m_pFRDlg->GetSafeHwnd()))
		m_pFRDlg->DestroyWindow();
	m_pFRDlg = new CFindReplaceDialog;
	m_pFRDlg->Create(TRUE,GetSelText());
}
void CMainDlg::OnEditReplace()
{
	if (IsWindow(m_pFRDlg->GetSafeHwnd()))
		m_pFRDlg->DestroyWindow();
	m_pFRDlg = new CFindReplaceDialog;
	m_pFRDlg->Create(FALSE, GetSelText());
}

查找替换

LRESULT CMainDlg::OnFindReplace(WPARAM wParam, LPARAM lParam){
	if (m_pFRDlg->IsTerminating())
		return false;
	if (m_pFRDlg->ReplaceAll())
		ReplaceAll();
	if (m_pFRDlg->ReplaceCurrent())	{
		ReplaceCurrent();
		AfxMessageBox(_T("替换"));	}
	if (m_pFRDlg->FindNext())
		if (m_pFRDlg->SearchDown())
			SerachDown();
		else
			SerachUp();
	return LRESULT();
}

向下查找算法

void CMainDlg::SerachDown(){
	if (!IsWindow(m_pFRDlg->GetSafeHwnd()))
		return;
	CString sText;
	m_edit.GetWindowText(sText);
	CString str = m_pFRDlg->GetFindString();
	int nStart, nEnd;
	m_edit.GetSel(nStart, nEnd);
	int n = sText.Find(str, nEnd);
	if (n<0){
		AfxMessageBox(_T("找不到 ") + str);		return;
	}
	m_edit.SetSel(n, n + str.GetLength());
	m_edit.GetFocus();
}

向上查找算法

void CMainDlg::SerachUp()
{
	if (!IsWindow(m_pFRDlg->GetSafeHwnd()))
		return;

	CString sText;
	m_edit.GetWindowText(sText);
	CString str = m_pFRDlg->GetFindString();

	if (!m_pFRDlg->MatchCase())  //区分大小写, 设置之后只能查找小写
	{
		str.MakeLower();
		sText.MakeLower();
	}

	int nStart, nEnd;
	m_edit.GetSel(nStart, nEnd)
	str.MakeReverse();
	sText.MakeReverse();
	int nLen = sText.GetLength();
	int n = sText.Find(str, nLen-nStart);
	if (n < 0)
	{
		AfxMessageBox(_T("找不到 ") + str);
		return;
	}
	nEnd = nLen - n;
	nStart = nEnd - str.GetLength();
	m_edit.SetSel(nStart, nEnd);
	m_edit.GetFocus();
}

替换全部算法

void CMainDlg::ReplaceAll()
{
	CString sText, sOld, sNew;
	sOld = m_pFRDlg->GetFindString();
	sNew = m_pFRDlg->GetReplaceString();
	m_edit.GetWindowText(sText);
	BOOL bMathCase = m_pFRDlg->MatchCase();
	int nStart, nEnd;
	m_edit.GetSel(nStart, nEnd);
	if (bMathCase)
	{
		sText.Replace(sOld, sNew);
		m_edit.SetWindowText(sText);
		m_edit.SetSel(nStart, nEnd);
	}
}

使用RichEdit控件 开发Goto(转到)功能

CGotoDlg
在这里插入图片描述

CGotoDlg.h

class CGotoDlg : public CDialogEx
{
	DECLARE_DYNAMIC(CGotoDlg)
public:
	CGotoDlg(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CGotoDlg();
	int m_nLine, m_nLines; //当前第几行,总共第几行
}

CGotoDlg.cpp
初始化对话框

BOOL CGotoDlg::OnInitDialog(){
	CDialogEx::OnInitDialog();
	SetDlgItemInt(IDC_LINE, m_nLine);
	CString str;
	str.Format(_T("行号(1-%d)(&L)"), m_nLines);
	SetDlgItemText(IDC_LINES, str);

	auto pEdit = (CRichEditCtrl*)GetDlgItem(IDC_LINE);
	pEdit->SetEventMask(pEdit->GetEventMask() | ENM_CHANGE); 

	m_stop.SetParent(pEdit);
	CRect rect;
	pEdit->GetClientRect(rect);
	rect.left = rect.right - rect.Height();
	int nDiff = rect.Width() - 15;
	if (nDiff > 1)
	{
		nDiff /= 2;
		rect.DeflateRect(nDiff, nDiff);
	}
	m_stop.MoveWindow(rect, FALSE);
	return TRUE;  // return TRUE unless you set the focus to a control
}

当改变行号时,显示或者隐藏m_stop图标(判断行号是否越界)

void CGotoDlg::OnChangeLine()
{
	int n = GetDlgItemInt(IDC_LINE);
	BOOL bEnable = (n > 0 && n <= m_nLines);
	m_stop.ShowWindow(bEnable ? SW_HIDE : SW_SHOW);
	GetDlgItem(IDOK)->EnableWindow(bEnable);
}

点击ok获取当前行号

void CGotoDlg::OnBnClickedOk()
{
	m_nLine = GetDlgItemInt(IDC_LINE);
	EndDialog(IDOK);
}

跳转行号导航

void CMainDlg::OnEditGoto(){
	CGotoDlg dlg;
	int nStart, nEnd;
	m_edit.GetSel(nStart, nEnd);
	dlg.m_nLines = m_edit.GetLineCount();
	dlg.m_nLine = m_edit.LineFromChar(nEnd)+1; //lineIndex  LineFromChar获得选中的字符数进行转换
	if (dlg.DoModal() == IDCANCEL)
		return;
	int nChar = m_edit.LineIndex(dlg.m_nLine)-1;  //用于获取指定行的起始字符的索引。行号是从1开始的,而字符索引是从0开始的。因此,在使用返回的索引进行操作时,可能需要将其减去1以适应零基索引。
	m_edit.SetSel(nChar, nChar);//设置编辑控件中的选定内容,两个参数分别是起始和结束位置的字符索引
}
/*要清除编辑控件中的选定内容,可以将起始位置和结束位置都设置为相同的值
m_edit.SetSel(-1, 0);
上述代码将选定内容的起始位置设置为-1,结束位置设置为0,这将导致编辑控件中的选定内容被清除。*/

对话框颜色管理

WM_CTLCOLOR控件

1、颜色管理:
a)COLORREF类型是4个字节,其中从低到高的3字节代表:Red Green Blub
b)把分量合成COLORREF类型:COLORREF col = RGB(88,99,222);
#define RGB(r,g,b) ((COLORREF)(((BYTE)®|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
c)把COLORREF拆分成3个分量数值:
#define GetRValue(rgb) (LOBYTE(rgb))
#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) (LOBYTE((rgb)>>16))

2、通用控件颜色管理:WM_CTLCOLOR消息
a)此消息并非完全通用,只适合于附录1中的控件类型。
(按钮,编辑框,静态文字,列表框ListBox)
b)很多复杂的控件包括树形控件,ListCtrl不支持。
就如同CDateTimeCtrl调用SetWindowText不好使。

附录1:
WM_CTLCOLOR支持的种类(UINT nCtlColor )
Contains one of the following values, specifying the type of control:
CTLCOLOR_BTN Button control
CTLCOLOR_DLG Dialog box
CTLCOLOR_EDIT Edit control
CTLCOLOR_LISTBOX List-box control
CTLCOLOR_MSGBOX Message box
CTLCOLOR_SCROLLBAR Scroll-bar control
CTLCOLOR_STATIC Static control

在这里插入图片描述

static CBrush brButton(0xff00);
static CBrush brEdit1(RGB(255,255,0));
static CBrush brEdit2(RGB(0,255,255));
static CBrush brDlg(RGB(255,122,123));
HBRUSH CSetColrDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
	switch (nCtlColor)
	{
	case CTLCOLOR_BTN:
		pDC->SetTextColor(255);
		return brButton;
	case CTLCOLOR_DLG:
		pDC->SetBkColor(RGB(255,0,255));
		return brDlg;
	case CTLCOLOR_EDIT:
		if (pWnd->GetDlgCtrlID() ==IDC_EDIT1)
			{
			pDC->SetTextColor(0xff00);
			pDC->SetBkColor(0xff0000);
			return brEdit1;
		}
		if (pWnd->GetDlgCtrlID() == IDC_EDIT2)
			{
			pDC->SetTextColor(255); //文字背景颜色和文字前景色
			pDC->SetBkColor(0x00ffff);
			return brEdit2;
		}
	}
	return hbr;
}

记事本中文字颜色和背景颜色功能开发

定义相应变量
在这里插入图片描述
加载注册表信息

void CMainDlg::LoadSetting()
{
	m_clback = theApp.GetProfileInt(_T("SETTINGS"), _T("BACK_COLOR"), 0xffffff);
	m_clText = theApp.GetProfileInt(_T("SETTINGS"), _T("TEXT_COLOR"), 0);
	m_brBack.DeleteObject();
	m_brBack.CreateSolidBrush(m_clback);
}

对文字进行设置颜色

void CMainDlg::OnFormatText()
{
	CColorDialog dlg(m_clText, CC_FULLOPEN);
	if (dlg.DoModal() == IDCANCEL)
		return;
	m_clText = dlg.GetColor();

	theApp.WriteProfileInt(_T("SETTINGS"), _T("TEXT_COLOR"), m_clText);
}

设置背景色


void CMainDlg::OnFormatBack()
{
	CColorDialog dlg(m_clback, CC_FULLOPEN);
	if (dlg.DoModal() == IDCANCEL)
		return;
	COLORREF color = dlg.GetColor();

	if (color!=m_clback)
	{
		m_clback = color;
		m_brBack.DeleteObject();
		m_brBack.CreateSolidBrush(m_clback);
		theApp.WriteProfileInt(_T("SETTINGS"), _T("BACK_COLOR"),m_clback);
	}
}

对IDC_TEXT设置背景色与文字颜色

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

	if (pWnd->GetDlgCtrlID() ==IDC_TEXT)
	{
		pDC->SetTextColor(m_clText);
		pDC->SetBkColor(m_clback);
		return m_brBack;
	}
	return hbr;

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

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

相关文章

Django实现接口自动化平台(十三)接口模块Interfaces序列化器及视图【持续更新中】

相关文章&#xff1a; Django实现接口自动化平台&#xff08;十二&#xff09;自定义函数模块DebugTalks 序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解&#xff0c;查看本章内容时&#xff0c;要结合整体项目代码来看&#xff1a; pytho…

3.13 Bootstrap 页面标题(Page Header)

文章目录 Bootstrap 页面标题&#xff08;Page Header&#xff09; Bootstrap 页面标题&#xff08;Page Header&#xff09; 页面标题&#xff08;Page Header&#xff09;是个不错的功能&#xff0c;它会在网页标题四周添加适当的间距。当一个网页中有多个标题且每个标题之间…

MotionBert论文解读及详细复现教程

MotionBert&#xff1a;统一视角学习人体运动表示 通过学习人体运动表征&#xff0c;论文原作者提出了处理以人为中心的视频任务的统一方法。使用双流时空transformer&#xff08;DSTformer&#xff09;网络实现运动编码器&#xff0c;能够全面、自适应地捕获骨骼关节之间的远…

数据结构——六大排序 (插入,选择,希尔,冒泡,堆,快速排序)

1. 插入排序 1.1基本思路 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 我们熟知的斗地主就是一个插入排序 1.2 代码实现 我们这里将一个无序数组变成有序数组 插入排序时…

CVE-2017-15715

CVE-2017-15715 一、环境搭建二、漏洞原理三、漏洞复现 一、环境搭建 如下介绍kali搭建的教程 cd ~/vulhub/httpd/CVE-2017-15715 // 进入指定环境 docker-compose build // 进行环境编译 docker-compose up -d // 启动环境docker-compose ps使用这条命令查看当前正在…

放射显影多肽1778691-88-5,DOTA Methyltetrazine ,四甲基四嗪修饰大环配体

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ 中文名称&#xff1a;四甲基四嗪修饰大环配体 英文名称&#xff1a;FOLATE-NOTA&#xff0c; Methyltetrazine-DOTA 规格标准&#xff1a;1g、5g、10g CAS&#xff1a;1778691-88-5 分子式&#xff1a;C37H52N12O12 分子量…

学习opencv.js之基本使用方法(读取,显示,灰度化,边缘检测,特征值点检测)

opencv.js是什么 OpenCV.js 是 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;的 JavaScript 版本。OpenCV 是一个广泛使用的计算机视觉和图像处理库&#xff0c;提供了一系列功能强大的算法和工具&#xff0c;用于处理图像、视频、特征提取、对象识别等…

php裁剪图片,并给图片加上水印

本次以裁剪四个图片为例&#xff0c;图片如下 代码如下 public function cutImg($imgUrl){try{// 读取原始图片$src_img imagecreatefromjpeg($imgUrl);// 获取原始图片的宽度和高度$src_width imagesx($src_img);$src_height imagesy($src_img);// 计算每个部分的宽度和高…

【C语言督学训练营 第十九天】关于C语言语法的一些补充

文章目录 1.条件运算符与逗号运算符2.自增自减运算符3.位运算4.switch do-while补充5.二维数组&二级指针6.总结 1.条件运算符与逗号运算符 条件运算符是C语言中唯一的一种三目运算符。三目运算符代表有三个操作数;双目运算符代表有两个操作数,如逻辑与运算符就是双目运算符…

传统工厂不再使用蓝牙LoRa而选择使用星斗1号之原因详解

物联网技术在不断发展的同时&#xff0c;化工企业对安全生产的重视也在逐渐增强。 在传统工厂进行安全管理数字化转型前&#xff0c;蓝牙Lora是其最为常用的化工人员定位技术&#xff0c;也曾广泛应用于工厂设备监控、数据传输、人员管理等。 然而&#xff0c;定位技术升级&a…

linux driver probe deferral 机制

1. 背景介绍 在偶然的一次实验中(具体是pinctrl实验)&#xff0c;我发现有些平台的pincontroller驱动起得很晚&#xff0c;而pinctrl client驱动却起得很早&#xff0c;在设备驱动模型中probe之前又会进行管脚复用的相关设置&#xff0c;按照常理来讲&#xff0c;这就产生了某…

前端工程中的设计模式应用

本文旨在系统性介绍一下23种设计模式&#xff0c;给出通俗易懂的案例、结构图及代码示例&#xff0c;这也是我自身学习理解的过程。或许其中的几种设计模式写的并不是很清晰明了易懂&#xff0c;更详细的可根据提到的参考文献进行深入学习。 什么是设计模式 设计模式这个概念是…

Python 算法基础篇之字符串操作:索引、切片、常用方法

Python 算法基础篇之字符串操作&#xff1a;索引、切片、常用方法 引言 1. 字符串的概念和创建2. 字符串的索引3. 字符串的切片4. 字符串的常用方法 a ) 查找子字符串 b ) 替换子字符串 c ) 拆分和连接字符串 总结 引言 字符串是一种常见的数据类型&#xff0c;在 Python 中对…

又整新活,新版 IntelliJ IDEA 有点东西!

作为一个经常使用IntelliJ IDEA来写代码的老用户&#xff0c;每次对于JetBrains软件的更新都是非常关注的。 这不最近这段时间&#xff0c;JetBrains连发了多个软件的EAP版本&#xff1a; 同时JetBrains的官博中也宣布了一个重要的新特性&#xff0c;那就是&#xff1a; 在所…

X.509数字证书的基本原理

一、前言 数字证书是现代互联网中个体间相互信任的基石。 如果没有了数字证书&#xff0c;那么也就没有了各式各样的电商平台以及方便的电子支付服务。 数字证书是网络安全中的一个非常重要组成部分。如果要学好网络安全&#xff0c;那么必须充分理解它的原理。 目前我们所…

keepalived 实现双机热备

文章目录 一、说明二、概念解释三、环境准备四、操作过程五、验证 一、说明 我们经常听说 nginx keepalived 双机热备&#xff0c;其实在这里&#xff0c;双机热备只是利用 keepalived 实现两个节点的故障切换&#xff0c;当主节点挂了&#xff0c;备用节点顶上&#xff0c;保…

深入浅出关于网易邮箱开启smtp服务教程

各平台邮箱开启SMTP服务教程 一、QQ邮箱 &#xff08;服务器地址&#xff1a;smtp.qq.com&#xff09; 第一步&#xff1a;复制https://mail.qq.com/ 登录QQ邮箱后电击左上角设置&#xff0c;如图&#xff1a; 第二步&#xff1a;点击进入“帐户”页面 &#xff0c;如图&…

CodeLocator简单使用(AndroidStudio中点击布局元素确认对应view信息)快速接手陌生项目利器

对于陌生项目的一些改动或重构需求时&#xff0c;如果可以在APP点点就能确定知道当前管理哪个activity或fragment必然是省去了很多去代码里搜来搜去的时间。在社群讨论中发现这款AS插件:CodeLocator ,虽然有2年没更新了 今天也试一试看看是否有帮助。 首先下载最新版本的插件&…

通过OSG实现对模型的日照模拟

1. 加载模型 通过OpenSceneGraph加载一个倾斜摄影的场景模型数据&#xff1a; #include <iostream> #include <Windows.h>#include <osgViewer/Viewer> #include <osgDB/ReadFile>using namespace std;int main() {string osgPath "D:/Data/Da…