二、多窗体程序设计
当应用程序功能较强和分类较多,程序和用户的交互频繁时,如果只用一个窗体和用户进行交互,一方面难以进行合乎美观原则的设计,另一方面分类工作很难,设计出来的界面不符合友好原则。这时使用多重窗体程序设计,增强程序界面的友好性。
多窗体指的应用中有多个窗体,它们之间没有绝对的从属关系。每个窗体的界面设计与单窗体的完全一样,只是在设计之前应先建立窗体,这可以通过菜单“工程”/“添加窗体”命令实现。程序代码是针对每个窗体编写的,当然,应注意窗体之间存在的先后顺序和相互调用的关系。所以,多重窗体实际上是单一窗体的集合,而单一窗体是多重窗体程序设计的基础。
一般说来,多窗体的设计基本分成以下几个步骤:
◆分析应用要求,将其功能划分为不同的几部分
◆分别创建各个窗体、模块
◆在创建窗体时,除各窗体自身要完成的功能外,还要考虑窗体之间的调用关系
◆点击[工程]/[属性]菜单,在[启动对象]中选择应用运行时首先执行的对象
◆运行应用程序,检验应用及各窗体的运行情况
1、多窗体程序设计常用的方法
在单窗体程序设计中,所有的 *** 作都在一个窗体中完成,不需要在多个窗体中切换。而在多窗体程序中,需要打开、关闭、隐藏或显示指定的窗体,这可以通过相应的语句和方法来实现。
在多窗体程序设计经常用到下面四种方法:Load,Show Hide和Unload
(1)Load方法
它的语法结构如下:
Load [窗体名称]
使用Load方法调用的窗体被存入内存,并不显示出来,同时会产生一个Form_Load()事件。
例如:Load Form2 '将Form2窗体存入内存
(2)Show方法
它的语法结构如下:
[窗体名称]Show
Show方法用来显示被调用的窗体。Show方法兼有装入和显示两种功能,也就是说,在执行Show方法时,如果窗体不在内存中,则Show方法会自动的把窗体调入内存,然后再显示出来。
例如: Load Form2
Form2Show '将Form2存于内存,并显示Form2窗体
(3)Hide方法
它的语法结构如下:
[窗体名称]Hide
使用Hide方法会隐藏被调用的窗体,既不在屏幕上显示,但仍在内存中(与Unload方法不同),被调用的窗体中的属性等已经处于无效的状态。
例如:
Form1Hide
Form2Show '将Form隐藏,并显示Form2窗体
(4)Unload方法
它的语法结构如下:
Unload [窗体名称]
使用Unload方法会清除内存中指定的窗体,与此同时,窗体中的变量和属性等都会处于无效的状态,在移去窗体的同时会产生一个Form_QueryUnload()事件。
例如:Form1Show
Unload Form2'显示Form1窗体,从内存中移去Form2窗体。
2、一个多窗体程序设计示例
下面就以一个示例来说明如何运进多窗体的程序设计(见教材P283)。
(1)启动新工程
1)设置属性
首先启动一个新的工程,屏幕出现一个空白的窗体,窗体的属性设置如下:
属性 设置
Name
Form1
Caption
Form1
BorderStyle
3-Fixed Dialog'窗体的大小不能够在程序的运行过程中改变
MDIChild
False
StartUpPosition
2-CenterScreen'窗体在程序的运行过程中始终位于屏幕的中央
Moveable
False'在程序的运行过程中不能够移动窗体
2)添加控件
在空白的窗体上添加如下控件:五个Label控件、四个TextBox控件和两个CommandButton控件。
(2)添加窗体
选择菜单“工程(Project)”/“添加窗体(add form)”命令,d出对话框,在添加窗体的对话框中选择"窗体"项,单击[打开]按钮,系统就会自动的向原有的工程中添加一个窗体。
1)添加控件
在新的窗体上放置一CommandButton控件,作用是在隐藏新增的窗体的同时显示原有的窗体。
则窗体如下:
2)添加代码
在"继续"按钮的Command1_Click()事件中添加下列代码:
Private Sub Command1_Click()
Form2Hide '隐藏窗体2
Form1Show '显示窗体1
End Sub
程序说明:在窗体Form2被显示的过程中,单击[继续]按钮,就会激活Command1_Click()事件,然后通过Form2Hide 和Form2Show两条语句实现隐藏窗体和显示窗体的功能。
(3)添加说明模块
选择菜单[工程]/[添加模块],就会d出对话框:
在模块的声明段中添加下列代码:
Global a1 as Single
Global a2 as Single
Global a3 as Single
Global a3 as Single '定义四个全局变量,分别用来存储第一季度,第二季度、第三季度和第四季度的销售情况
(4)添加程序代码
1)窗体Form1中的代码如下:
Private Sub Command1_Click()
Form1Hide
Form2Show
End Sub
Private Sub Command2_Click()
End
End Sub
Private Sub Text1_Change()
a1 = Val(Text1Text) 'VAL()函数用于将字符串转化为数值型
End Sub
Private Sub Text2_Change()
a2 = Val(Text2Text)
End Sub
Private Sub Text3_Change()
a3 = Val(Text3Text)
SDI,MDI和基于对话框的程序都可以用CDC绘图。 SDI和MDI的程序,可以在View类的OnDraw(CDC pDC)里直接用这个pDC参数来画图,也可以在自己添加的View类的成员函数中,使用CClientDC dc(this);或者CDC pDC=GetDC(),然后用dc或者pD
分类: 电脑/网络 >> 程序设计 >> 其他编程语言
问题描述:
我写了一个基于CFormView的多重文旦程序,我为他的子框架窗口(基于CFormView)添加了:afx_msg void OnMove(int x, int y)函数,为何当我移动子框架窗口时,OnMove(int x, int y)函数没有被调用,OnMove函数只有在子框架窗口生成时被调用
怎样实现在子框架窗口移动时调用OnMove(int x, int y)?
解析:
void CMainFrame::OnMove(int x, int y)
{
CMDIFrameWnd::OnMove(x, y);
MessageBox("MainFrame::OnMove!");
TODO: Add your message handler code here
---------------------得到子架窗口的指针-------------------------------------
CMDIFrameWnd pFrame = (CMDIFrameWnd)AfxGetApp()->m_pMainWnd;
CMyChildFrame pChild = (CMyChildFrame) pFrame->GetActiveFrame();
if(pChild->GetActiveView()==NULL)假如没有当前子架窗口
return;
CString m_ChildFrameName="";储存主架窗口的名称
GetWindowText(m_ChildFrameName);得到主架窗口的名称
----------------------------------------------------------------------------
------------------------隐藏进货入库窗口的d出式列表框-----------------------
int a=m_ChildFrameNameFind("进货入库");判断当前窗口是不是进货入库窗口
MessageBox(m_ChildFrameName);
if(a!=-1)假如是进货入库子架窗口
{
CFormJHRK pView = (CFormJHRK ) pChild->GetActiveView();
pView->m_LineBottomSetFocus();设置焦点到m_LineBottom控件--为防止其他控件得到焦点
if(pView->m_EGYSm_poplist->IsWindowVisible())
{
pView->m_EGYSm_poplist->ShowWindow(false);隐藏供应商列表框
}
if(pView->m_EYGm_poplist->IsWindowVisible())
{
pView->m_EYGm_poplist->ShowWindow(false);隐藏员工列表框
}
if(pView->m_ECKm_poplist->IsWindowVisible())
{
pView->m_ECKm_poplist->ShowWindow(false);隐藏仓库列表框
}
if(pView->m_EKPLXm_poplist->IsWindowVisible())
{
pView->m_EKPLXm_poplist->ShowWindow(false);隐藏开票类型列表框
}
return;
}
------------------隐藏进货入库窗口的d出式列表框结束------------------------
/也跟着主框架窗体移动
::PostMessage(pView->m_EGYSGetSafeHwnd(),MYMESSAGE_EDIT_MOVED,0,0);
::PostMessage(pView->m_EYGGetSafeHwnd(),MYMESSAGE_EDIT_MOVED,0,0);
::PostMessage(pView->m_ECKGetSafeHwnd(),MYMESSAGE_EDIT_MOVED,0,0);
::PostMessage(pView->m_EKPLXGetSafeHwnd(),MYMESSAGE_EDIT_MOVED,0,0);
另外一种方法
/ CView pView = this->GetActiveFrame()->GetActiveView();
if(pView==NULL)
HWND mm=static_cast<CFormJHRK>(pView)->m_EGYSGetSafeHwnd();
::PostMessage(mm,MYMESSAGE_EDIT_MOVED,0,0);/
}
结合上一节介绍的方法 通过Visual Basic Net的菜单设计器 按照图 和图 所示的菜单结构设计菜单 图 MDI编程项目的菜单结构之一 图 MDI编程项目的菜单结构之二 在利用菜单设计器设计完菜单后 分别在窗体中双击 新建 退出 层叠显示 横行平铺 纵向平铺 和 排列图标 菜单项 这样Visual Basic Net会在Form vb文件中分别产生这些菜单项的Click事件对应的处理代码 设定Form 的 IsMdiContainer 属性值为 True 这把Form 窗体定义为MDI窗体容器 这一步设置是后面编程的基础 当设置此属性值后 Form 的窗体也发生了改变 图 是设置此属性后的窗体模样 图 把Form 窗体设置为MDI窗体容器后的模样 选中图 中的 窗口 菜单项 并设置此菜单项的 MdiList 属性值为 True 其作用是当程序运行后 如果新建了一个MDI窗体 就会在 窗口 菜单项后 自动加入一个以新建MDI窗体名称命名的菜单项 如果新建了多个MDI窗体 则会在 窗口 菜单项后 会加入以这些MDI窗体名称命名的菜单项 当MDI窗体被关闭 那些以此MDI窗体命名的菜单项也会自动删除 具体可图 所示 把Visua Basic Net的当前窗口切换到Form vb的代码编辑窗口 并在定义Form 中组件的代码区加入下列代码 下列代码是定义一个变量 此变量用以统计程序中新建MDI窗体的数量 Private iFormCount As Integer = 用下列代码替换Form vb中的MenuItem 的Click事件对应的处理代码 MenuItem 即为图 中的 新建 菜单项 下列代码的作用是在新建一个MDI窗体 Private Sub MenuItem _Click ( ByVal sender As System Object ByVal e As System EventArgs ) Handles MenuItem ClickDim frmTemp As Form = New Form ( ) 新建一个窗体frmTemp MdiParent = Me 为当前创建的窗体设置MDI父窗体frmTemp Text = MDI窗体 + iFormCount ToString ( )iFormCount = iFormCount + frmTemp Show ( ) 把此MDI窗体显示出来End Sub 用下列代码替换Form vb中的MenuItem 的Click事件对应的处理代码 MenuItem 即为图 中的 退出 菜单项 下列代码的作用是退出应用程序 Private Sub MenuItem _Click ( ByVal sender As System Object ByVal e As System EventArgs ) Handles MenuItem ClickApplication Exit ( ) 退出应用程序End Sub 用下列代码替换Form vb中的MenuItem 的Click事件对应的处理代码 MenuItem 即为图 中的 层叠显示 菜单项 下列代码的作用是层叠排列窗体中的所有MDI窗体 Private Sub MenuItem _Click ( ByVal sender As System Object ByVal e As System EventArgs ) Handles MenuItem ClickMe LayoutMdi ( MdiLayout Cascade ) 层叠排列窗体中的所有MDI窗体End Sub 用下列代码替换Form vb中的MenuItem 的Click事件对应的处理代码 MenuItem 即为图 中的 水平平铺 菜单项 下列代码的作用是水平平铺窗体中的所有MDI窗体 Private Sub MenuItem _Click ( ByVal sender As System Object ByVal e As System EventArgs ) Handles MenuItem ClickMe LayoutMdi ( MdiLayout TileHorizontal ) 水平平铺窗体中的所有MDI窗体End Sub 用下列代码替换Form vb中的MenuItem 的Click事件对应的处理代码 MenuItem 即为图 中的 垂直平铺 菜单项 下列代码的作用是垂直平铺窗体中的所有MDI窗体 Private Sub MenuItem _Click ( ByVal sender As System Object ByVal e As System EventArgs ) Handles MenuItem ClickMe LayoutMdi ( MdiLayout TileVertical ) 垂直平铺窗体中的所有MDI窗体End Sub 用下列代码替换Form vb中的MenuItem 的Click事件对应的处理代码 MenuItem 即为图 中的 排列图标 菜单项 下列代码的作用是窗体中的所有MDI窗体排列图标 Private Sub MenuItem _Click ( ByVal sender As System Object ByVal e As System EventArgs ) Handles MenuItem ClickMe LayoutMdi ( MdiLayout ArrangeIcons ) 窗体中的所有MDI窗体排列图标End Sub至此MDI编程项目的全部工作就完成了 图 图 和图 是程序运行后的界面 图 MDI编程运行界面之一 图 MDI编程运行界面之二 图 MDI编程运行界面之三 此时我们注意到图 所示的 窗口 菜单中增加许多子菜单 而在程序设计时 并没有处理这些功能的代码 这是由于第十一步中设置 窗口 菜单项的 MdiList 属性值为 True 造成的 可见正确的设置组件的属性值有时的确能够代替烦杂的代码编写工作 五 总结 本文主要内容有二个 其一是介绍的在Visual Basic Net定制不规则窗体的实现方法 在Visual Basic Net中创建不规则窗体主要使用的是Region类和GraphicsPath类 GraphicsPath主要是绘制窗体的形状 Region主要是以GraphicsPath来构建窗体 结合本文的实现思路和具体方法 我想对于其他形状的窗体 在掌握GraphicsPath类提供的使用方法的前提下 加上对所要创建不规则窗体的规划设计 用Visual Basic Net实现起来应该不算很困难 本文的另外一个主要内容就是介绍在Visual Basic Net编写MDI应用程序的基本过程 技巧和注意事项 通过本文的介绍可见Visual Basic Net的MDI编程并没有什么复杂的地方 只需了解一些对MDI窗体处理的方法及其调用方式 当然更重要的是要了解并掌握某些组件的针对MDI的属性及其设置方式 lishixinzhi/Article/program/net/201311/11698
登录
首页
学习
实践
活动
专区
工具
TVP
返回腾讯云官网
全栈程序员站长
551K 篇文章
关注
写字板(Windows程序设计)
2022-09-06 09:52:05阅读 1730
大家好,又见面了,我是你们的朋友全栈君。
前言
c# 正编译生成debug,exe等文件,同样也可以通过exe反编译生成相对应的文件,一劳永逸,任君选择(`・ω・´) (我们老师为了给我们看要求效果给了我们一个半成品exe,cv工程师上线了,真为所欲为)
问题描述
验证简易相册程序的实现(不需要写入报告)
设计一个类似Windows写字板的程序,使其具有以下功能:
提供基本的写字板功能,如文件的打开,保存,支持txt、rtf;
实现多格式的文本的编辑、修饰等,均有相应的菜单来控制,常用的菜单项配备相应的工具栏按钮(可参照Windows自带的写字板)
按需添加其他的代码,如窗口的布局等;
实现自定义的查找对话框,有能力的同学可进一步实现替换/全文替换等功能
状态栏中显示学生学号、姓名等信息,在窗口的标题中显示当前正在编辑的文件名
(可选)其他你觉得实用的功能:如支持word等
(可选)将其改造成MDI程序:父窗口中包含新建、窗口、帮助等菜单;在运行时,子窗口的菜单会与其合并,合理设置各菜单项的MergeIndex/MergeAction属性,使其符合我们的使用习惯;编程允许用户调整各自窗口间的布局关系(平铺、层叠等)等
先看效果
解决方法
richtextbox
用richtextbox是一个类似写字板的一个控件,能满足rtf,txt等格式,如果要满足doc文档,去百度MicrosoftOfficeInteropWorddll,下载并引用,打开保存代码如下(其中saveName为文件名)
/// <summary>
/// 打开文档 *** 作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void 打开OToolStripMenuItem_Click(object sender, EventArgs e)
{
openFileDialog1InitialDirectory = "C:\\";
openFileDialog1Filter = "rtf 文件|rtf|txt 文件|txt|doc files|doc";
if (openFileDialog1ShowDialog() != DialogResultOK)
return;
saveName = openFileDialog1FileName;
if (openFileDialog1FilterIndex == 1)
richTextBox1LoadFile(saveName);
else if (openFileDialog1FilterIndex == 2)
richTextBox1LoadFile(saveName, RichTextBoxStreamTypePlainText);
else
OpenWord(saveName);
Text = saveName;
}
public void 父窗体打开Open(WritingBoard writingBoard)
{
writingBoardopenFileDialog1InitialDirectory = "C:\\";
writingBoardopenFileDialog1Filter = "rtf 文件|rtf|txt 文件|txt|doc files|doc";
if (writingBoardopenFileDialog1ShowDialog() != DialogResultOK)
return;
saveName = writingBoardopenFileDialog1FileName;
if (writingBoardopenFileDialog1FilterIndex == 1)
writingBoardrichTextBox1LoadFile(saveName);
else if (writingBoardopenFileDialog1FilterIndex == 2)
writingBoardrichTextBox1LoadFile(saveName, RichTextBoxStreamTypePlainText);
else
OpenWord(saveName);
writingBoardText = saveName;
return;
}
public void OpenWord(string fileName)
{
ApplicationClass applicationClass = new ApplicationClass();
Document document = null;
object obj = MissingValue;
object FileName = fileName;
object ReadOnly = false;
object Visible = true;
try
{
document = applicationClassDocumentsOpen(ref FileName, ref obj, ref ReadOnly, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref Visible, ref obj, ref obj, ref obj, ref obj);
documentActiveWindowSelectionWholeStory();
documentActiveWindowSelectionCopy();
richTextBox1Paste();
}
finally
{
documentClose(ref obj, ref obj, ref obj);
applicationClassQuit(ref obj, ref obj, ref obj);
}
}
/// <summary>
/// 保存 *** 作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void 保存SToolStripMenuItem_Click(object sender, EventArgs e)
{
if (saveName != "")
{
richTextBox1SaveFile(saveName, RichTextBoxStreamTypeRichText);
}
else
{
saveFileDialog1Filter = "rtf files|rtf";
if (saveFileDialog1ShowDialog() == DialogResultOK)
{
saveName = saveFileDialog1FileName;
richTextBox1SaveFile(saveName, RichTextBoxStreamTypeRichText);
}
}
}
/// <summary>
/// 另存为 *** 作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void 另存为AToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog1FileName = saveNameSubstring(saveNameLastIndexOf('\\') + 1);
saveFileDialog1Filter = "rtf files|rtf|txt files|txt|doc files|doc";
saveFileDialog1AddExtension = true;
if (saveFileDialog1ShowDialog() != DialogResultOK)
return;
saveName = saveFileDialog1FileName;
if (saveFileDialog1FilterIndex == 1)
richTextBox1SaveFile(saveName, RichTextBoxStreamTypeRichText);
else if (saveFileDialog1FilterIndex == 2)
richTextBox1SaveFile(saveName, RichTextBoxStreamTypePlainText);
else
SaveAsWord(saveName);
}
public void SaveAsWord(string fileName)
{
ApplicationClass applicationClass = new ApplicationClass();
Document document = null;
object obj = MissingValue;
object FileName = fileName;
try
{
document = applicationClassDocumentsAdd(ref obj, ref obj, ref obj, ref obj);
documentActiveWindowSelectionWholeStory();
richTextBox1SelectAll();
ClipboardSetData(DataFormatsRtf, richTextBox1SelectedRtf);
documentActiveWindowSelectionPaste();
documentSaveAs(ref FileName, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj, ref obj);
}
finally
{
documentClose(ref obj, ref obj, ref obj);
applicationClassQuit(ref obj, ref obj, ref obj);
}
}
/// <summary>
/// 新建 *** 作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void 新建NToolStripMenuItem_Click(object sender, EventArgs e)
{
richTextBox1Clear();
saveName = "";
}
复制
写字板 *** 作设置
其他一系列doc加粗,倾斜,下划线,左中右对齐,字体型号颜色,查找(大小写,全字,正逆),其实本质上来说都是对richtextbox的一些属性的修改,注意多用DropDownOpening,DropDownItemClicked等 *** 作代替Click,使代码更加精简高效
这是一个MDI调整子窗体使用DropDownItemClicked的例子,高效优雅 = v =
private void 窗口WToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
string layout=eClickedItemText;
switch(layout)
{
case "水平平铺": LayoutMdi(MdiLayoutTileHorizontal);break;
case "垂直平铺": LayoutMdi(MdiLayoutTileVertical); break;
case "层叠": LayoutMdi(MdiLayoutCascade); break;
}
}
复制
MDI的使用,是为了让一个父窗体拥有许多个子窗体,进行更加简单有效的 *** 作
在父窗体new子窗体就行,记得一系列基本 *** 作,你也可以通过生成函数和属性进行快速高效设置
private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)
{
WritingBoard writingBoard = new WritingBoard();
writingBoardTopLevel = false;
writingBoardMdiParent = this;
writingBoardShow();
}
private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
{
WritingBoard writingBoard = new WritingBoard();
writingBoardTopLevel = false;
writingBoardMdiParent = this;
writingBoard父窗体打开Open(writingBoard);
writingBoardShow();
}
private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (WritingBoard writingBoard in MdiChildren) writingBoardClose();
ApplicationExit();
}
private void 窗口WToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
string layout=eClickedItemText;
switch(layout)
{
case "水平平铺": LayoutMdi(MdiLayoutTileHorizontal);break;
case "垂直平铺": LayoutMdi(MdiLayoutTileVertical); break;
case "层叠": LayoutMdi(MdiLayoutCascade); break;
}
}
复制
源码附上
传送门,我设置了分支,这样我就可以把不同内容相同属性的代码放在一起了,同时也可以拥有不同的md可以阅读,对于git 的整理也是不错的(`・ω・´)
发布者:全栈程序员栈长,转载请注明出处:>
以上就是关于VB考试教程:多窗体程序设计全部的内容,包括:VB考试教程:多窗体程序设计、用small basic,设计一个简单的人机对话程序、VC++中MDI(多重文旦)子框架窗口移动问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)