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

文章目录

  • 非模式对话框
    • 非模式对话框的特点
    • 非模式对话框与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;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Minecraft 1.20.x Forge模组开发 01.Idea开发环境配置

我们本次来进行Minecraft 1.20.x 模组开发环境配置教程的介绍。 效果演示 效果演示 效果演示 1.首先我们需要下载Java17和1.20模组开发包: Java17下载官网

ylb-项目简介

1、各模块服务功能 注&#xff1a;其部分实体类、接口、mapper文件由MyBatis逆向工程生成。 2、Maven管理&#xff08;多模块&#xff0c;继承和聚合&#xff09; 2.1 parent模块 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"…

Prometheus、Grafana使用

文章目录 系统性能监控相关命令lscputopfreehtopdstatglancesiftopiptrafnethogs 监控软件Prometheus安装、使用将promethues做成服务监控其他机器 exportergrafana配置、使用密码忘记重置 系统性能监控 相关命令 lscpu lscpu 是一个 Linux 命令&#xff0c;用于显示关于 CP…

计算机网络基础-OSI七层模型 和 TCP/IP四层模型的对比

OSI七层模型 和 TCP/IP四层模型的对比 OSI七层模型&#xff1a; 理论上的网络通信模型 记忆&#xff1a; (物、链、网、输、会、示、用) TCP/IP四层模型&#xff1a; 实际上的网络通信标准 (1) 七层网络体系结构各层的主要功能&#xff1a; 应用层&#xff1a; 最上层的&am…

Spring学习记录---回顾反射机制

目录 10.回顾反射机制 10.1 分析方法四要素 //不使用反射机制调用这些方法 使用反射机制调用方法 代码&#xff1a; 运行结果&#xff1a; 10.4 假设你知道属性名 测试代码 运行结果 10.回顾反射机制 10.1 分析方法四要素 package com.dong.reflect;public class Som…

JMETERbeanshell多种姿势获取目标值

beanshell通过vars方式取值 JMETER三种取值方法步骤_securitor的博客-CSDN博客 beanshell通过props方式取值 JMETER取值二_securitor的博客-CSDN博客 beanshell通过source方式取值 JMETER取值三_securitor的博客-CSDN博客 beanshell通过jar包方式取值 JMETER取值四_securitor的…

在UI中使用SpriteMask裁减任意shader的粒子效果

前言 由于我们需要在Mask中对粒子效果进行裁减。但是我们的的特效同事不愿意每个shader都去添加Stencil。所以使用SpriteMask方式进行裁减。 使用步骤 1. 添加SpriteMask Component 更具你需要的Mask形状设置精灵图片。又因为实际是精灵&#xff0c;并不属于UI系统&#xff…

【react + antd】antd如何自定义请求使用antd的upload组件实现图片上传且可预览可删除

文章目录 1. 效果展示2. customRequest如何使用&#xff1f;特别注意&#xff1a; 3. 控制上传时什么时候使用customRequest&#xff0c;什么时候选择beforeUpload方法&#xff1f; 1. 效果展示 官网给出的案例无法使用封装好的请求方式上传图片&#xff0c;以及无法满足上传图…

Spring Cloud Alibaba【Nacos配置动态刷新、Nacos集群架构介绍 、Nacos的数据持久化、认识分布式流量防护 】(五)

目录 分布式配置中心_Nacos配置动态刷新 分布式配置中心_Dubbo服务对接分布式配置中心 分布式配置中心_Nacos集群架构介绍 分布式配置中心_Nacos的数据持久化 分布式配置中心_Nacos集群配置 分布式流量防护_认识分布式流量防护 分布式流量防护_认识Sentinel 分布式配置…

每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户

文章目录 每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户每日语录第26题 中级题: 活跃时长的均值1. 需求列表思路分析 答案获取加技术群讨论附表文末SQL小技巧 后记 每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户 大家好&#xff0c;我是Maynor。…

计组4——总线Plus IO

(CPU外部的)总线 用于连接computer3大模块(MC/GPUIO) CPU内部的片内总线判优由时序逻辑实现 composition& priority-judging 通信方式 CPU内部的片内总线用于取指、译码、执行、中断的数据通信&#xff1b; IO 总线分为控制线、数据线和地址线&#xff0c;对IO设备的…

python开发项目基于语音识别的智能垃圾分类系统的设计与实现

博主介绍&#xff1a;擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例…

基于Java+SpringBoot+Vue+Uniapp前后端分离考试学习一体机设计与实现(视频讲解,已发布上线)

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

mysql、redis 、RabbitMQ只能本机访问,怎么改?

如果只能本机访问&#xff0c;怎么改? 一、mysql - 改my.ini 刷脚本 bind-address0.0.0.0 然后重启一下mysql服务 任务管理器-关掉mysql 搜索 计算机管理-重启mysql服务 然后 打开查询&#xff0c;并选择mysql数据&#xff0c;输入这个sql语句&#xff0c;点击运行 sele…

状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

从今天起&#xff0c;我们开始学习状态模式。在实际的软件开发中&#xff0c;状态模式并不是很常用&#xff0c;但是在能够用到的场景里&#xff0c;它可以发挥很大的作用。从这一点上来看&#xff0c;它有点像我们之前讲到的组合模式。 可以简短的回顾一下组合模式&#xff1a…

基于深度学习的高精度道路瑕疵检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度道路瑕疵&#xff08;裂纹&#xff08;Crack&#xff09;、检查井&#xff08;Manhole&#xff09;、网&#xff08;Net&#xff09;、裂纹块&#xff08;Patch-Crack&#xff09;、网块&#xff08;Patch-Net&#xff09;、坑洼块&#x…

flutter开发实战-生日等日期选择器DatePicker

flutter开发实战-生日等日期选择器DatePicker 在开发遇到设置生日等信息需要选择日期&#xff0c;这里用到的是CupertinoDatePicker iOS效果的日期、时间选择器 一、效果图 运行后效果图如下 二、代码实现 我们需要调用底部弹窗显示 //显示底部弹窗static void bottomShe…

怎么学习Java I/O相关的知识和技术? - 易智编译EaseEditing

要学习Java I/O&#xff08;输入输出&#xff09;相关的知识和技术&#xff0c;可以按照以下步骤进行&#xff1a; 理解Java I/O基础知识&#xff1a; 首先&#xff0c;了解Java I/O的基本概念和术语&#xff0c;包括输入流和输出流、字节流和字符流、文件读写等。掌握Java中…

TCP/IP网络编程 第十六章:关于IO流分离的其他内容

分离I/O流 两次I/O流分离 我们之前通过2种方法分离过IO流&#xff0c;第一种是第十章的“TCPI/O过程&#xff08;Routine&#xff09;分离”。这种方法通过调用fork函数复制出1个文件描述符&#xff0c;以区分输入和输出中使用的文件描述符。虽然文件描述符本身不会根据输入和输…

[极客大挑战 2019]PHP(反序列化)

介绍说明&#xff0c;有备份的习惯&#xff0c;找常见的备份文件后缀名 使用dirsearch进行扫描 dirsearch -u http://f64378a5-a3e0-4dbb-83a3-990bb9e19901.node4.buuoj.cn:81/ -e php-e 指定网站语言 扫描出现&#xff0c;www.zip文件 查看index.php <?php include c…