托管C++程序开发Win表单的文档程序设计(上)

在Windows桌面程序中,应用程序类型通常有:对话框、单文档、多文档以及顶层显示的文档应用程序等。事实上,文档应用程序是最主要最有用的应用程序类型。Visual C++.NET新的MFC方式提供上述类型的应用程序向导。但在托管C++中,由于所开发的是Windows Forms应用程序,因而在构造方法、程序设计等方面均与MFC有着极大的区别。本篇首先讨论菜单、工具栏和状态栏的设计及其事件的映射等内容,然后讨论单文档/多文档应用程序的设计方法。

  一、菜单

  .NET框架中的Windows表单为菜单提供了Menu基类,这个基类不允许用户直接实例化,它有三个派生类:MainMenu、MenuItem和ContextMenu。MainMenu用来构造一个主菜单,所有菜单都是由MenuItem类的对象组成的,ContextMenu用来生成快捷菜单,即当用户右击鼠标时所弹出的上下文菜单。

  1、菜单项操作

  MenuItem类封装用户菜单所需的属性、事件和方法,下面就其属性和事件分别说明:

  (1) 菜单项属性

  使用过MFC菜单编辑器的用户都知道,MFC菜单项属性通常有菜单文本、标识、是否是分隔符、是否在菜单前有选中标记以及菜单的提示信息等。但在.NET框架中,菜单项属性最常用的有:菜单文本(Text)、菜单快捷键以及菜单命令的处理。例如下面的代码:

m_pFileMenuNew = new MenuItem();
m_pFileMenuNew->Text = S"打开(&O)";
m_pFileMenuNew->Shortcut = Shortcut::CtrlO;
m_pFileMenuNew->ShowShortcut = true; // 将快捷键显示在菜单文本之后
m_pFileMenuNew->Click += new EventHandler(this, &WinForm::OnFileOpen);
// 添加该菜单项的命令处理函数句柄

  当然,菜单项的这些属性也可直接在其MenuItem类构造函数中进行设置,如下列代码:

m_pFileMenuNew = new MenuItem(
S"打开(&O)",
new EventHandler(this, &WinForm::OnFileOpen),
Shortcut::CtrlO);
m_pFileMenuNew->ShowShortcut = true;


  除了上述属性外,还有IsParent(是否是父菜单项)、ShowShortcut(是否在菜单文本后面显示相应的快捷键内容)、Visible(菜单项是否可见)、Enabled(菜单是否激活)以及Checked(菜单项前有选中标记)和RadioCheck(菜单项带有单选标记)等。

  需要说明的是,如果想要将某菜单项变成一个分隔符(水平线),则只需将该菜单项的Text属性设为"-"即可。

  (2) 菜单事件及其处理

  MenuItem菜单项事件常用的主要有Click(选定菜单)和select(光标停在菜单项)。菜单事件的处理和控件一样,基本上都是通过EventHandler来映射一个事件处理函数。例如上面的“new EventHandler(this, &WinForm::OnFileOpen)”,在OnFileOpen中可以添加相关的用户代码:

void OnFileOpen(Object *sender, EventArgs *e)
{
OpenFileDialog *dlg = new OpenFileDialog();
dlg->Filter = S"所有文件|*.*";
dlg->ShowDialog();
}

2、创建多级菜单

  在应用程序窗口中,最上面的菜单栏的菜单是顶层菜单、每个顶层菜单项还有相应的下拉子菜单,每一个下拉子菜单项还有下一级的子菜单,......。实际上,在Win表单中,除了顶层菜单是用MainMenu来构造外,其余的菜单项都是用MenuItem来构造。若一个菜单项还包含由若干个菜单项组成的子菜单,那么在构造时既可以在其构造函数进行指定,或者通过MenuItems的Add方法来添加,例如下面的代码是构造一个如图1所示的多级菜单。

m_pFileMenuNew = new MenuItem( S"新建(&N)", new EventHandler(this, &WinForm::OnFileNew), Shortcut::CtrlN);
m_pFileMenuNew->ShowShortcut = true;
m_pFileMenuOpen = new MenuItem( S"打开(&O)", new EventHandler(this, &WinForm::OnFileOpen), Shortcut::CtrlO);
m_pFileMenuOpen->ShowShortcut = true;
m_pFileMenuExit = new MenuItem( S"退出(&X)", new EventHandler(this, &WinForm::OnFileExit));

MenuItem* rItems[] = new MenuItem *[3];
rItems[0] = m_pFileMenuNew;
rItems[1] = m_pFileMenuOpen;
rItems[2] = m_pFileMenuExit;

m_pFileMenu = new MenuItem( S"文件(&F)", rItems);

m_pEditMenuCut = new MenuItem( S"剪切(&X)");
m_pEditMenuCut->Shortcut = Shortcut::CtrlX;
m_pEditMenuCut->ShowShortcut = true;
m_pEditMenuCut->Enabled = false;
m_pEditMenuCopy = new MenuItem( S"复制(&C)");
m_pEditMenuCopy->Shortcut = Shortcut::CtrlC;
m_pEditMenuCopy->ShowShortcut = true;
m_pEditMenuCopy->Enabled = false;
m_pEditMenuPaste = new MenuItem( S"粘贴(&V)");
m_pEditMenuPaste->Shortcut = Shortcut::CtrlV;
m_pEditMenuPaste->ShowShortcut = true;
m_pEditMenuPaste->Enabled = false;

rItems[0] = m_pEditMenuCut;
rItems[1] = m_pEditMenuCopy;
rItems[2] = m_pEditMenuPaste;

m_pEditMenu = new MenuItem( S"编辑(&E)", rItems);

m_pViewMenuToolBar = new MenuItem( S"工具栏");
m_pViewMenuToolBar->Checked = true;
m_pViewMenuStatusBar = new MenuItem( S"状态栏");
m_pViewMenuStatusBar->Checked = true;

m_pViewMenu = new MenuItem( S"查看(&V)");
m_pViewMenu->MenuItems->Add(m_pViewMenuToolBar);
m_pViewMenu->MenuItems->Add(m_pViewMenuStatusBar);

m_pAboutMenu = new MenuItem( S"关于...(&A)");
m_pHelpMenu = new MenuItem( S"帮助(&H)");
m_pHelpMenu->MenuItems->Add(m_pAboutMenu);

rItems[0] = m_pFileMenu;
rItems[1] = m_pEditMenu;
rItems[2] = m_pViewMenu;

m_pMenu = new MainMenu(rItems);
m_pMenu->MenuItems->Add(m_pHelpMenu);




  3、为应用程序添加菜单的过程

  这个过程比较简单,首先,创建所需要的多级,然后创建顶层菜单(MainMenu),最后将窗口的Menu属性值设为该MainMenu即可:

  Menu = m_pMenu;

  4、使用快捷菜单

  在Win表单使用快捷菜单是极其方便的,只要将要显示的菜单按前面的方法构造好,然后设置相应的窗口ContextMenu属性即可,如下面的代码:

...//同上面的代码
MenuItem* cItems[] = new MenuItem *[3];
cItems[0] = m_pFileMenuNew;
cItems[1] = m_pFileMenuOpen;
cItems[2] = m_pFileMenuExit;

Windows::Forms::ContextMenu* pContextMenu = new Windows::Forms::ContextMenu(cItems);
ContextMenu = pContextMenu;

  需要说明的是,由于窗口的ContextMenu属性名与类名ContextMenu相同,因此需要像上面代码那样指明相应的具体名称空间。
 二、工具栏和状态栏

  工具栏(ToolBar)和状态栏(StatusBar)是Windows Forms两个控件,但它的构造方法和事件的处理与其他普通控件有所不同。下面分别加以讨论。

  1、使用工具栏的一般步骤

  在Windows Forms中使用工具栏通常遵循下列过程:

  (1) 创建一个ToolBar对象,如:

Toolbar *m_pToolBar = new ToolBar();

  (2) 由于工具栏上的按钮通常都会有相应的图像,因而要先构造由按钮图像组成的图像列表,并设置ToolBar对象的ImageList属性。例如下面的代码:

m_pImageList = new ImageList();
m_pImageList->ImageSize = System::Drawing::Size(16, 16);
m_pImageList->TransparentColor = System::Drawing::Color::Transparent;
m_pImageList->Images->Add(Image::FromFile(S"new.bmp"));
m_pImageList->Images->Add(Image::FromFile(S"open.bmp"));
m_pImageList->Images->Add(Image::FromFile(S"help.bmp"));

m_pToolBar = new ToolBar();
m_pToolBar->ImageList = m_pImageList;

  (3) 向工具栏添加按钮,例如下面的代码是添加一个“新建”按钮:

m_pNewButton = new ToolBarButton();
m_pNewButton->ImageIndex = 0;
m_pNewButton->ToolTipText = S"新建";
m_pNewButton->Text = S"新建"; // 设置按钮文本

m_pToolBar->Buttons->Add(m_pNewButton);

  (4) 设置工具栏属性,这些属性通常包括:外观(Appearance)、边框(BorderStyle)、下拉箭头(DropDownArrows)和文本放置(TextAlign)等。例如下面的代码:

m_pToolBar->Appearance = ToolBarAppearance::Flat; // 平面按钮
m_pToolBar->BorderStyle = BorderStyle::Fixed3D; // 3D外观
m_pToolBar->DropDownArrows = true; // 允许按钮有下拉箭头
m_pToolBar->TextAlign = ToolBarTextAlign::Underneath; // 按包钮文本处于图像下面
m_pToolBar->Divider = false; // 栏与栏之间不允许有分隔线

  (5) 处理工具栏事件

  工具栏包含两个常用的事件:ButtonClick和ButtonDropDown事件。前者是当用户单击工具栏按钮时产生时,而后者是当用户单击按钮旁边的下拉箭头时产生的。这两个事件的映射都是通过ToolBarButtonClickEventHandler来进行的。例如下面的代码框架:

m_pToolBar->ButtonClick += new ToolBarButtonClickEventHandler(this,&WinForm::OnToolButtonClick);
...
void OnToolButtonClick( Object* sender, ToolBarButtonClickEventArgs* e)
{
switch (m_pToolBar->Buttons->IndexOf(e->Button))
{
case 0:
// 当第一个工具按钮按下时
break;
case 1:
// 当第二个工具按钮按下时
break;
...
default:
break;
}
}


  2、使用状态栏的一般步骤

  在Windows Forms中使用状态栏要比工具栏简单,具体步骤如下:

  (1) 创建一个StatusBar对象,如:

StatusBar *m_pStatusBar = new StatusBar();

  (2) 为状态栏添加窗格

  例如下列代码:

m_pSBPanel1 = new StatusBarPanel();
m_pSBPanel1->Text = S"就绪";
m_pSBPanel1->BorderStyle = StatusBarPanelBorderStyle::None;
m_pSBPanel1->AutoSize = StatusBarPanelAutoSize::Spring;

m_pStatusBar->Panels->Add(m_pSBPanel1);

m_pSBPanel2 = new StatusBarPanel();
m_pSBPanel2->Text = S"另外一个窗格";
m_pSBPanel2->AutoSize = StatusBarPanelAutoSize::Spring;

m_pStatusBar->Panels->Add(m_pSBPanel2);

  (3) 设置状态栏属性并添加到窗口的Controls集合中

m_pStatusBar->ShowPanels = true; // 显示所有的窗格
Controls->Add(m_pStatusBar);


  需要说明的是,状态栏也有相应的事件,如PanelClick(用户单击状态栏的窗格)等,但这些事件一般很少用到。

  三、综合示例

  这里给出一个菜单栏、工具栏和状态栏的综合示例程序,其结果如图2所示。


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值