【PB案例学习笔记】-32制作一个简单记事本程序

大家好,我是晓凡

写在前面

这是PB案例学习笔记系列文章的第32篇,该系列文章适合具有一定PB基础的读者。

通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。

文章中设计到的源码,晓凡都上传到了gitee代码仓库https://gitee.com/xiezhr/pb-project-example.git

gitee代码仓库

需要源代码的小伙伴们可以自行下载查看,后续文章涉及到的案例代码也都会提交到这个仓库【pb-project-example

如果对小伙伴有所帮助,希望能给一个小星星⭐支持一下小凡。

一、小目标

本案例我们将制作一个类似于windows 自带的记事本程序。

程序包含了记事本的打开、保存、编辑、复制、剪切、删除、设置字体等功能。

为了能实现上述功能,我们需要借助对文件进行操作的GetFileOpenName()FileLength()FileOpen()FileRead()GetFileSaveName()FileWrite()等文件操作函数。

同时为了实现文本的编辑功能,我们还需要使用到Clare()CopyCutPaste()Undo()等多行编辑框函数。

为了实现文本格式的设置,我们需要用到CreateFile()全局扩展函数

希望小伙伴能和我一样,通过本案例熟练掌握文件相关操作

最终实现效果如下

记事本

二、函数简介

2.1 GetFileOpenName函数

用于显示一个标准的文件打开对话框,让用户选择要打开的文件,并返回用户选择的文件路径

使用示例:

string ls_fileName

ls_fileName = GetFileOpenName("请选择要打开的文件", "C:\", "Text Files (*.txt),*.txt")

IF Len(ls_fileName) > 0 THEN
    MessageBox("选择文件", "你选择的文件是: " + ls_fileName)
ELSE
    MessageBox("未选择文件", "你没有选择文件")
END IF

调用GetFileOpenName函数会弹出一个文件打开对话框,标题为"请选择要打开的文件",初始文件夹路径为"C:",并且只显示文本文件(.txt)类型的文件。

用户选择文件后,将返回选中文件的路径,并显示在消息框中。

如果用户取消选择文件,则会显示"你没有选择文件"的消息框。

2.2 FileLength函数

用于获取指定文件的长度(以字节为单位)。通过这个函数,您可以快速了解文件的大小

使用示例:

string ls_filePath
long ll_fileLength

ls_filePath = 'C:\test\file.txt'

ll_fileLength = FileLength(ls_filePath)

MessageBox("文件长度", "文件的长度是: " + string(ll_fileLength) + " bytes")

在上面的示例中,首先设置要获取长度的文件路径为 ls_filePath 。然后使用 FileLength 函数来获取该文件的长度,并将结果存储在 ll_fileLength 中。最后使用 MessageBox 函数显示文件的长度,以字节为单位。

2.3 FileOpen 函数

用于打开一个文件并返回文件句柄,以便进行读取或写入操作

使用示例:

long ll_fileHandle
string ls_filePath, ls_fileContent, ls_line
integer li_fileNum

ls_filePath = 'C:\test\file.txt'
ll_fileHandle = FileOpen(ls_filePath, LineMode!)

IF ll_fileHandle > 0 THEN
    li_fileNum = 1
    ls_fileContent = ""

    DO WHILE FileRead(ll_fileHandle, li_fileNum, ls_line) > 0
        ls_fileContent += ls_line + "~r~n"
        li_fileNum++
    LOOP

    FileClose(ll_fileHandle)

    MessageBox("文件内容", ls_fileContent)
ELSE
    MessageBox("文件打开错误", "文件打开错误")
END IF

首先设置要打开的文件路径为 ls_filePath ,然后使用 FileOpen 函数打开该文件,并将返回的文件句柄存储在 ll_fileHandle 中。如果文件成功打开(文件句柄大于0),则使用 FileRead 函数逐行读取文件内容,并将内容存储在 ls_fileContent 中。最后关闭文件并显示文件内容。如果文件打开失败,则显示相应的错误消息。

2.4 FileRead 函数

用于从已打开的文件中读取指定行的内容。通过这个函数,您可以逐行读取文件的内容并进行处理。

这个函数,我们在上面已经使用过

2.5 FileClose 函数

用于关闭先前通过FileOpen函数打开的文件。通过这个函数,您可以确保在完成文件操作后正确关闭文件句柄,释放资源。

这个函数,我们在上面已经使用过,一般FileOpen FileRead FileClose 这三个函数我们都是配套使用的

2.6 GetFileSaveName 函数

用于显示一个标准的文件保存对话框,让用户选择要保存的文件路径和名称,并返回用户选择的文件路径。

使用示例:

string ls_fileName

ls_fileName = GetFileSaveName("请选择文件保存路径", "C:\", "Text Files (*.txt),*.txt", "txt")

IF Len(ls_fileName) > 0 THEN
    MessageBox("选择文件", "你选择保存文件路径是: " + ls_fileName)
ELSE
    MessageBox("未选择", "你没有选择文件保存路径.")
END IF

调用GetFileSaveName函数会弹出一个文件保存对话框,标题为"请选择文件保存路径",初始文件夹路径为"C:",并且只显示文本文件(.txt)类型的文件。

用户选择保存文件的路径和名称后,将返回选中的文件路径,并显示在消息框中。

如果用户取消选择文件保存位置,则会显示"你没有选择文件保存路径"的消息框。

2.7 Filewrite 函数

用于向已打开的文件中写入内容。通过这个函数,您可以将数据写入文件中,可以是文本、二进制等格式的数据。

使用示例:

long ll_fileHandle
string ls_filePath, ls_content

ls_filePath = 'C:\test\output.txt'
ll_fileHandle = FileOpen(ls_filePath, LineMode!)

IF ll_fileHandle > 0 THEN
    ls_content = "hello ! 我是程序员晓凡"

    FileWrite(ll_fileHandle, ls_content)

    FileClose(ll_fileHandle)
    MessageBox("文件写入", "内容写入成功")
ELSE
    MessageBox("文件打开错误", "文件打开失败")
END IF

首先使用FileOpen函数打开文件并获取文件句柄。如果文件成功打开(文件句柄大于0),

则使用FileWrite函数向文件中写入“hello ! 我是程序员晓凡”内容。

在示例中,我们写入了一个简单的文本内容。

最后关闭文件并显示消息框表示内容已成功写入文件。

如果文件打开失败,则显示相应的错误消息。

2.8 Clare函数

用于清除一个字符串中的空格和控制字符。

string ls_text, ls_cleanText

ls_text = " Hello,我是程序员晓凡,   	我的博客是:	www.xiezhrspace.cn  "
ls_cleanText = Clare(ls_text)

MessageBox("清除文本", "原始字符串: " + ls_text + "~n~n清除后的字符串是: " + ls_cleanText)

我们定义了一个包含空格和控制字符的字符串 ls_text

然后使用Clare函数清除该字符串中的空格和控制字符,并将结果存储在 ls_cleanText 中。

最后使用MessageBox显示原始文本和清理后的文本。

2.9 Copy 函数

用于复制一个字符串的一部分到另一个字符串中

使用示例:

string ls_source, ls_target

ls_source = "Hello, World!"
ls_target = ""

Copy(ls_source, 8, 5, ls_target)

MessageBox("复制文本", "原始文本: " + ls_source + "~n~n复制后文本: " + ls_target)

我们定义了一个原始字符串 ls_source ,然后使用Copy函数从第8个字符开始复制长度为5的子字符串到目标字符串 ls_target 中。

最后使用MessageBox显示原始字符串和复制后的字符串。

2.10 Paste 函数

用于将一个字符串粘贴(插入)到另一个字符串的指定位置。通过这个函数,您可以方便地在一个字符串中插入另一个字符串

使用实例:

string ls_source, ls_target

ls_source = "World!"
ls_target = "Hello, "

Paste(ls_target, 7, ls_source)

MessageBox("粘贴后", "原始文本: " + ls_target)

我们定义了一个源字符串 ls_source ,一个目标字符串 ls_target

然后使用Paste函数将源字符串插入到目标字符串的第7个位置之后。

最后使用MessageBox显示插入后的目标字符串。

2.11 Undo 函数

用于撤消最近的文本编辑操作。通过这个函数,您可以在文本框或富文本控件中撤消用户最后一次的编辑操作,恢复到之前的状态。

使用示例:

// 假设有一个文本框控件名为te_text
te_text.Undo()

假设存在一个名为 te_text 的文本框控件。通过调用 Undo 函数,可以撤消用户最近的文本编辑操作。

2.12 CreateFile 函数

Windows API中的一个函数,用于创建或打开一个文件,并返回一个文件句柄。

使用示例:

CONSTANT LONG GENERIC_WRITE = 1073741824
CONSTANT LONG CREATE_ALWAYS = 2

FUNCTION long CreateFile( &
    string lpFileName, &
    long dwDesiredAccess, &
    long dwShareMode, &
    long lpSecurityAttributes, &
    long dwCreationDisposition, &
    long dwFlagsAndAttributes, &
    long hTemplateFile) Library "kernel32.dll"

long ll_fileHandle
string ls_filePath

ls_filePath = 'C:\test\newfile.txt'
ll_fileHandle = CreateFile(ls_filePath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0)

IF ll_fileHandle > 0 THEN
    MessageBox("提示信息", "一个文件创建成功")
    CloseHandle(ll_fileHandle)
ELSE
    MessageBox("提示信息", "文件创建失败.")
END IF

我们使用CreateFile函数创建了一个名为 newfile.txt 的新文件,并获取了文件句柄。

如果文件成功创建(文件句柄大于0),则显示消息框表示文件已成功创建。

最后使用CloseHandle函数关闭文件句柄。

如果文件创建失败,则显示相应的错误消息。

三、创建程序基本框架

上一小节中我们介绍了接下来程序中需要使用到的函数,接下来就该实操了

① 创建examplework工作空间

② 创建exampleapp创建应用

③ 新建w_file窗口,并将Title设置成“记事本”

④ 新建w_font窗口,并将Title设置为“字体”

⑤ 新建Menu菜单,并将其保存为m_main

由于文字篇幅原因,以上步骤不再赘述,如果忘记了的小伙伴可以翻一翻之前的文字复习一下

四、设置w_file窗口

① 建立控件

在窗口中添加两个MultiLineEdit控件,分别命名为mle_editmle_time

勾选mle_edit控件的VScrollBar属性,并将两个控件Position属性中的XY都设置成0

控件布局

② 创建全局变量

string current_file_name

③ 创建全局扩展函数

Function string CreateFile(char FileName) LIBRARY "user32.dll"

④ 在窗口w_fileResize事件 中输入如下脚本

mle_edit.width  = this.workspacewidth()
mle_edit.height = this.workspaceheight()

五、设置w_font窗口

这个窗口用了选择字体

① 新建控件

在窗口中添加3个StaticEdit控件、3个SingleLineEdit控件、2个ListBox控件和2个CommandButton控件

各个控件名称分别为st_1st_2st_sizesle_fontsle_stylesle_sizelb_fontlb_stylecb_okcb_cancel

② 设置各控件属性

设置lb_fontItems属性

设置的属性

设置lb_styleItems属性

设置的属性

其余控件如下所示

控件布局

③ 在cb_cancel按钮的clicked事件中输入如下脚本

close(w_font)

④ 在cb_ok按钮的clicked事件中输入如下代码

if sle_font.text <> "" then w_file.mle_edit.facename = sle_font.text          //字形
if sle_size.text <> "" then w_file.mle_edit.textsize = integer(sle_size.text) //大小

if sle_style.text <> "" then //风格
	if sle_style.text = "常规"   then 
		w_file.mle_edit.weight = 400
		w_file.mle_edit.italic = false
		return
	end if
	if sle_style.text = "斜体"   then 
		w_file.mle_edit.italic = true		
	end if
	if sle_style.text = "粗体"   then 
		w_file.mle_edit.weight = 700		
	end if
	if sle_style.text = "粗斜体" then 
		w_file.mle_edit.weight = 700
		w_file.mle_edit.italic = true		
	end if
end if

close(w_font)

⑤ 在lb_font控件的selectionchanged事件中输入如下代码

int i , j
i = lb_font.selectedindex()
sle_font.text = lb_font.selecteditem()
//sle_font.text = lb_font.text(i)
j = lb_font.setstate(i,false)

⑥ 在lb_style控件的selectionchanged事件中输入如下代码

int i , j
i = lb_style.selectedindex()
sle_style.text = lb_style.selecteditem()
//sle_font.text = lb_font.text(i)
j = lb_style.setstate(i,false)

六、设置m_main菜单

6.1 新建m_main菜单基本框架

新建m_main菜单

6.2 文件相关菜单

① 在新建菜单中添加如下代码

//清空编辑区内容
w_file.mle_edit.text = ""
//新建文件的统一名称为Untitle
current_file_name = "无标题"
//修改窗口标题
w_file.title = current_file_name+" - 记事本"

② 在打开菜单中添加如下代码

string docname,named
integer value,rc,fd
long ll_Flength
//选择要打开的文件
value = GetFileOpenName("选择要打开的文件",docname,named,"TXT","文本文件(*.txt),*.txt,所有文件(*.*),*.*")
							  
if value = 1 then
	//获取文件长度
	ll_Flength = FileLength(docname)
	//打开文件
	fd = FileOpen(docname,StreamMode!)
	if ll_Flength < 32767 then
		//读取文件内容到多行编辑框中
		rc = FileRead(fd,w_file.mle_edit.text)
		FileClose(fd)
		//保存文件名,用于将来保存文件
		current_file_name = docname
		//修改窗口标题
		w_file.title = "记事本__文件" + current_file_name
	end if
end if

③ 在保存中添加如下代码

string docname,named
integer value,rc,fd,ret
long ll_Flength
boolean file_exist

value = GetFileSaveName("保存为",docname,named,"TXT","文本文件(*.txt),*.txt,所有文件(*.*),*.*")
if value = 1 then
	ll_Flength = FileLength(docname)
	fd = FileOpen(docname,StreamMode!)
	if ll_Flength < 32767 then
		file_exist = FileExists(docname)
		IF file_exist THEN ret = MessageBox("保存", &
		"按OK按钮覆盖所选文件" + docname, &
		Question!, YesNo!)
		rc = Filewrite(fd,w_file.mle_edit.text)
		FileClose(fd)
		current_file_name = docname
		w_file.title = current_file_name + " - 记事本__文件"  
	end if
end if
fd = FileOpen(current_file_name,StreamMode!,Write!,LockWrite!,Replace!)
//将多行编辑框mle_edit中的内容写入文件
FileWrite(fd,w_file.mle_edit.text)
FileClose(fd)

④ 在退出菜单中添加如下代码

close(w_file)
6.3 编辑相关菜单

①在撤销菜单中添加如下代码

w_file.mle_edit.undo()

② 在复制菜单中添加如下代码

w_file.mle_edit.copy()

③ 在剪切中菜单添加如下代码

w_file.mle_edit.cut()

④ 在拷贝菜单中添加如下代码

w_file.mle_edit.paste()

⑤ 在删除菜单中添加如下代码

w_file.mle_edit.clear()

⑥ 在全选菜单中添加如下代码

w_file.mle_edit.setfocus()
w_file.mle_edit.selecttext(1,888888)

⑦ 在时间菜单中添加如下代码

w_file.mle_time.text = string(now()) + " " + string(today())
w_file.mle_time.setfocus()
w_file.mle_time.selecttext(1,20)
w_file.mle_time.copy()
w_file.mle_edit.setfocus()
w_file.mle_edit.paste()
6.4 格式相关菜单

① 在自动换行菜单中添加如下代码

if m_main.m_option.m_retuen.checked = true then
	m_main.m_option.m_retuen.checked = false
	w_file.mle_edit.hScrollBar = true
else
	m_main.m_option.m_retuen.checked = true
	w_file.mle_edit.hScrollBar = false
end if

② 在字体菜单中添加如下代码

open(w_font)
6.5 窗口设置

①将w_file窗口的MenuName设置为m_main

② 在开发界面左边的System Tree窗口中双击exampleapp应用,并在其Open事件中添加如下代码

open(w_file)

七、运行程序

经过上面的代码编码,接下来检验下我们的劳动成果

记事本

本期内容到这儿就结束了 ★,°:.☆( ̄▽ ̄)/$:.°★ 。 希望对您有所帮助

我们下期再见 ヾ(•ω•`)o (●’◡’●)

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

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

相关文章

Web3D:WebGL为什么在渲染性能上输给了WebGPU。

WebGL已经成为了web3D的标配&#xff0c;市面上有N多基于webGL的3D引擎&#xff0c;WebGPU作为挑战者&#xff0c;在渲染性能上确实改过webGL一头&#xff0c;由于起步较晚&#xff0c;想通过这个优势加持&#xff0c;赶上并超越webGL仍需时日。 贝格前端工场为大家分享一下这…

leetcode 1459 矩形面积(postgresql)

需求 表: Points ---------------------- | Column Name | Type | ---------------------- | id | int | | x_value | int | | y_value | int | ---------------------- id 是该表主键 每个点都用二维坐标 (x_value, y_value) 表示 写一个 SQL 语句&#xff0c;报告由表中任…

Redis-基础概念

目录 概念 Redis是什么 Redis 和 MySQL 的区别&#xff1f; Redis单线程有什么极端场景的瓶颈 Redis为什么快? 为什么Redis是单线程? Redis是单线程还是多线程 Redis为什么选择单线程做核心处理 Redis6.0之后引入了多线程&#xff0c;你知道为什么吗? 瓶颈是内存和I…

MySQL-事务、日志

事务 特性 原子性 是指事务开始后&#xff0c;必须成功执行完所有的操作才会结束&#xff0c;否则会回滚到事务刚开始前。 拿转账来说&#xff0c;一个成功的 A向B转账100元的过程 会涉及如下过程&#xff1a; A&#xff1a;从数据库读取A的余额&#xff1b;A的余额-100&am…

Pytorch学习笔记day1—— 安装教程

这里写自定义目录标题 Pytorch安装方式 工作需要&#xff0c;最近开始搞一点AI的事情。但是这个国产的AI框架&#xff0c;实话说对初学者不太友好 https://www.mindspore.cn/ 比如说它不支持win下的CUDA&#xff0c;可是我手里只有3070Ti和4060也不太可能自己去买昇腾就有点绷不…

C. Alternating Subsequence[双指针,贪心]

题目描述&#xff1a; 思路分析&#xff1a;题目俩要求&#xff0c;最长&#xff0c;值最大&#xff0c;异号&#xff0c;保证异号的情况是找到最长而且尽可能大&#xff0c;其实很容易想到&#xff0c;一开始先把第一个数单独放进去&#xff0c;保证不浪费任何一个元素&#…

迈克尔的44岁:时间的感悟与人生的智慧

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【JavaEE】HTTP(2)

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;下一篇文章&#xff1a;【JavaEE】HTTP协议(…

短链接day8

短链接监控 开发访问单个短链接监控统计功能 不知道是哪里复制错了&#xff0c;反正就是一顿报错&#xff0c;改了这个又改那个&#xff0c;还是报错。。暂时不管了。 记录短链接访问日志 logdo新增networt、device、local属性。 分页查询短链接访问日志 分页查询短链接今…

Qt 多语言

记录Qt多语言的实现过程 目录 1.项目配置文件.pro配置 2.程序中的字符串用tr()封装 3.生成翻译文件 4.使用Qt语言家修改翻译文件 4.1使用Qt语言家打开 4.2 .更改文件配置 5. 生成qm文件 6.代码执行切换语言 6.1入口处 6.2 事件执行 0.效果 1.项目配置文件.pro配置 T…

集合媒体管理、分类、搜索于一体的开源利器:Stash

Stash&#xff1a;强大的媒体管理工具&#xff0c;让您的影音生活井井有条- 精选真开源&#xff0c;释放新价值。 概览 Stash是一个专为个人媒体管理而设计的开源工具&#xff0c;基于 Go 编写&#xff0c;支持自部署。它以用户友好的界面和强大的功能&#xff0c;满足了现代用…

2024华为数通HCIP-datacom最新题库(变题更新⑥)

请注意&#xff0c;华为HCIP-Datacom考试831已变题 请注意&#xff0c;华为HCIP-Datacom考试831已变题 请注意&#xff0c;华为HCIP-Datacom考试831已变题 近期打算考HCIP的朋友注意了&#xff0c;如果你准备去考试&#xff0c;还是用的之前的题库&#xff0c;切记暂缓。 1、…

ModuleNotFoundError: No module named ‘_cffi_backend‘的二中情况解决方案

1、问题概述? 创作时间:2024年7月 在pycharm中执行python脚本出现如下问题: No module named _cffi_backend 主要说明二中情况: 第一种原因:最常见的原因就是没有安装cffi模块,我们通过命令安装就可以了。 第二种原因:不常见的原因,如果你在pycharm中运行了别人的…

【UE5.1】NPC人工智能——02 NPC移动到指定位置

效果 步骤 1. 新建一个蓝图&#xff0c;父类选择“AI控制器” 这里命名为“BP_NPC_AIController”&#xff0c;表示专门用于控制NPC的AI控制器 2. 找到我们之前创建的所有NPC的父类“BP_NPC” 打开“BP_NPC”&#xff0c;在类默认值中&#xff0c;将“AI控制器类”一项设置为“…

记录些MySQL题集(8)

ACID原则、事务隔离级别及事务机制原理 一、事务的ACID原则 什么是事务呢&#xff1f;事务通常是由一个或一组SQL组成的&#xff0c;组成一个事务的SQL一般都是一个业务操作&#xff0c;例如聊到的下单&#xff1a;「扣库存数量、增加订单详情记录、插入物流信息」&#xff0…

gradle学习及问题

一、下载安装 参考&#xff1a;https://blog.csdn.net/chentian114/article/details/123344839 1、下载Gradle并解压 安装包&#xff1a;gradle-6.7-bin.zip 可以在idea的安装目录查看自己适配的版本 路径&#xff1a;D:\IDEA2021.3\plugins\gradle\lib 下载地址&#xff1a…

idea中使用maven

默认情况下&#xff0c;idea会自动下载并安装maven&#xff0c;这不便于我们管理。 最好是自行下载maven&#xff0c;然后在idea中指定maven的文件夹路径

VMware安装CentOS 7

在虚拟机中安装无论是Windows还是Linux其实都差不多&#xff0c;主要还是需要熟悉VMware的使用&#xff0c;多新增几次就熟悉了&#xff0c;可以反复删除再新增去练习… 如下是安装CentOS 7 安装过程&#xff1a; VMare Workstation 16 PRO 中安装CentOS 7 CentOS 7 下载推荐…

工业三防平板可优化工厂流程管理

在当今高度自动化和数字化的工业生产环境中&#xff0c;工业三防平板正逐渐成为优化工厂流程管理的关键工具。其强大的功能和卓越的性能&#xff0c;为工厂带来了更高的效率、更低的成本以及更出色的质量控制。 工业三防平板&#xff0c;顾名思义&#xff0c;具备防水、防尘、防…

在AWS创建一台Windows主机并登录

正文共&#xff1a;1111 字 21 图&#xff0c;预估阅读时间&#xff1a;1 分钟 因为之前微软云Azure免费&#xff0c;我们还做了简单的测试&#xff08;白嫖党618福利&#xff01;来Azure领200美刀&#xff01;外加云主机免费用一年&#xff01;&#xff09;&#xff1b;并且通…