程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++ Builder中MDI應用程序的設計

C++ Builder中MDI應用程序的設計

編輯:關於C++

MDI(多文檔界面)應用程序是指用戶可以同時打開多個文檔,每一個文檔顯示在應用程序主窗口客戶區的獨立窗口中。如字處理程序Word就是一個典型的MDI應用程序,你可以在Word中同時打開和使用多個文檔,PowerPoint中你也可以同時創建和打開多個幻燈片應用程序,電子表格中也允許用戶同時對多個圖表進行編輯。MDI應用程序一般包括三類窗口:

* 框架窗口:框架窗口與應用程序的主窗口類似,有可改變大小的邊框、標題欄、系統菜單等。應用程序必須為框架窗口注冊一個窗口類。一個MDI應用程序一般只有一個框架窗口,框架窗口控制著其它各類窗口。

* 客戶窗口:客戶窗口提供對下屬MDI子窗口的管理,每一個MDI應用程序有一個客戶窗口。

* 子窗口:當用戶打開或創建一個文檔時,客戶窗口便為該文檔創建一個子窗口。每個子窗口都有可以改變大小的邊框、標題欄、系統菜單、最小最大化按鈕等。任何時刻只有一個子窗口是活動的。子窗口不能超出客戶窗口的范圍。

用一般的開發工具開發MDI應用程序相當麻煩:你必須注冊框架窗口和子窗口類、創建框架窗口和客戶窗口、寫消息循環和回調函數、創建子窗口等等,其中的每一步都不是什麼輕而易舉之事。但是在Borland C++ Builder(以下簡稱CB)中實現MDI應用程序卻相對簡單,你只需設置一下窗體的屬性FormStyle即可:把框架窗口的FormStyle設為fsMDIForm,子窗口的FormStyle設為fsMDIChild。另外CB本身也提供了MDI程序模板,選擇File|New|Projects|MDI Application,如下圖所示:

CB就會產生一個MDI應用程序框架。直接編譯運行該程序,就可以看到該程序已經具有一個MDI程序的基本特征了。

我們利用這個模板設計一個MDI應用程序。該程序是一個支持多文本格式和普通文本格式的多文檔編輯器,且同時支持工具欄快捷按鈕和打印輸出。下面我們就來談一談其具體開發過程:

(1) 選擇File|New|Projects|MDI Application,產生MDI程序框架。

(2) 把主框架窗口另存為MDIMain.cpp,子窗口另存為MDIChild.cpp,工程名另存為MDI。

(3) 轉到主框架窗口FrameForm,設置其Caption為“ MDI演示程序---可打開多文件的文本編輯器”,在Object Inspector中觀察FrameForm的屬性,可看到其FormStyle為fsMDIForm。改變主框架窗口FrameForm上的控件(Component).

(4)點擊菜單控件,改變菜單項和菜單項的OnClick事件如下,使之適合自己的要求:

菜單項 菜單項的OnClick事件

文件:新建 New1Click

打開 Open1Click

退出 Exit1Click

窗口:層疊 Tile1Click

平鋪 Cascade1Click

排列圖標 Arrangeicons1Click

(5) 改變SpeedPanel上的TSpeedButton控件和事件響應,並在其屬性Glyph中裝入相應的位圖圖像:

快捷按鈕名稱 事件響應

SpeedButton1 New1Click

SpeedButton2 Open1Click

SpeedButton3 Exit1Click

(6)修改原有的OpenDialog文件打開對話框控件的屬性:

單擊Filter屬性,彈出Filter Editor對話框,輸入:

Rich Text Format(*.rtf) *.rtf

Text Files(*.txt) *.txt

All Files(*.*) *.*

(7) 選擇View|Project Manager,在Project Manager中單擊MDIChild一欄的ChildForm,就可以查看該子窗體的FormStyle屬性為fsMDIChild。設置窗體的事件響應:

OnClick FormClick

OnClose FormClose

OnCloseQuery FormCloseQuery

OnCreate FormCreate

拖動控件到ChildForm之上。

(8) 設置ChildForm上菜單控件的菜單項名稱和菜單項的OnClick事件:

菜單項 菜單項的OnClick事件

文件:新建 New1Click

打開 Open1Click

關閉 Close1Click

保存 Save1Click

另存為 Saveas1Click

打印 Print1Click

打印設置 Printersetup1Click

退出 Exit1Click

編輯:剪切 Cut1Click

復制 Copy1Click

粘貼 Paste1Click

刪除 Delete1Click

全選 Selectall1Click

其他:靠左 Left1Click

靠右 Left1Click

居中 Left1Click

自動換行 Wordwrap1Click

字體 Font1Click

(9) 從Dialogs控件板選取對話框控件到ChildForm上,並設置其屬性:

* SaveDialog

Name SaveFileDialog

單擊Filter屬性,彈出Filter Editor對話框,輸入:

Rich Text Format(*.rtf) *.rtf

Text Files(*.txt) *.txt

All Files(*.*) *.*

* PrintDialog

Name PrintDialog1

* PrinterSetupDialog

Name PrinterSetupDialog1

* FontDialog

Name FontDialog1

(10) 然後從Win32控件板中選擇RichEdit控件,放在ChildForm上,設置其屬性:

Align alClient

Name doc

點擊Lines屬性,彈出String list editor,清空裡面的內容。

(11) 最後,在程序中加入程序源代碼。運行該程序,然後打開兩個文檔(該程序在C++ Builder 3.0和Windows 95下調試通過):

附源程序清單:

(這兒略去大部分系統自己加進去的程序代碼部分):

//-------- MDIMain.cpp--------
#include "MDIMain.h"
#include "MDIChild.h"
__fastcall TFrameForm::TFrameForm(TComponent* Owner)
: TForm(Owner)
{ }
void __fastcall TFrameForm::Exit1Click(TObject *Sender)
{Close();//應用程序退出}
void __fastcall TFrameForm::Tile1Click(TObject *Sender)
{Tile();//窗口層疊}
void __fastcall TFrameForm::Cascade1Click(TObject *Sender)
{Cascade();//窗口平鋪}
void __fastcall TFrameForm::Arrangeicons1Click(TObject *Sender)
{ ArrangeIcons();//排列圖標}
//新建文檔
void __fastcall TFrameForm::New1Click(TObject *Sender)
{ ChildForm = new TChildForm(this); }
//打開文件
void __fastcall TFrameForm::Open1Click(TObject *Sender)
{
if(OpenFileDialog->Execute()){
ChildForm=new TChildForm(this);
ChildForm->Open(OpenFileDialog->FileName);
}
}
//----------MDIChild.cpp-------------
#include "MDIChild.h"
#include "MDIFrame.h"
TChildForm *ChildForm;
//定義缺省文件名為Untitled
const AnsiString DefaultFileName = AnsiString("Untitled");
__fastcall TChildForm::TChildForm(TComponent* Owner)
: TForm(Owner)
{ }
//文件打開函數
void __fastcall TChildForm::Open(const AnsiString AFileName)
{
PathName = AFileName;
Caption = ExtractFileName(AFileName);
doc->Lines->LoadFromFile(PathName);
doc->SelStart = 0;
doc->Modified = false;
}
void __fastcall TChildForm::New1Click(TObject *Sender)
{ FrameForm->New1Click(Sender); //新建文件}
void __fastcall TChildForm::Open1Click(TObject *Sender)
{ FrameForm->Open1Click(Sender);//打開文件 }
void __fastcall TChildForm::Close1Click(TObject *Sender)
{ Close();//關閉打開的文件}
void __fastcall TChildForm::Exit1Click(TObject *Sender)
{ FrameForm->Exit1Click(Sender);//退出應用程序 }
//保存打開或創建的文檔
void __fastcall TChildForm::Save1Click(TObject *Sender)
{
if(Caption == DefaultFileName){
Saveas1Click(Sender);
}
else{
doc->Lines->SaveToFile(PathName);
doc->Modified = false;
} }
//另存打開或創建的文檔
void __fastcall TChildForm::Saveas1Click(TObject *Sender)
{
SaveFileDialog->FileName = PathName;
if (SaveFileDialog->Execute() ){
PathName= SaveFileDialog->FileName;
Caption = ExtractFileName(PathName);
Save1Click(Sender);
} }
//文檔打印
void __fastcall TChildForm::Print1Click(TObject *Sender)
{
if (PrintDialog1->Execute()){
try {
doc->Print(PathName);
}
catch(...){
Printer()->EndDoc();
throw;
} } }
void __fastcall TChildForm::Printersetup1Click(TObject *Sender)
{ PrinterSetupDialog1->Execute();//打開打印機設置對話框進行打印機設置}
void __fastcall TChildForm::Cut1Click(TObject *Sender)
{doc->CutToClipboard();//文檔剪切到剪貼板}
void __fastcall TChildForm::Copy1Click(TObject *Sender)
{ doc->CopyToClipboard();//文檔拷貝到剪貼板}
void __fastcall TChildForm::Paste1Click(TObject *Sender)
{ doc->PasteFromClipboard();//從剪貼板粘貼文檔}
void __fastcall TChildForm::Delete1Click(TObject *Sender)
{ doc->ClearSelection();//刪除選中的文檔}
void __fastcall TChildForm::Selectall1Click(TObject *Sender)
{ doc->SelectAll();//文檔全選}
//文檔向左、向右、居中等各種對齊方式響應函數
void __fastcall TChildForm::Left1Click(TObject *Sender)
{
Left1->Checked = false;
Right1->Checked = false;
Center1->Checked = false;
if( dynamic_cast<TMenuItem *>(Sender) !=0)
dynamic_cast <TMenuItem *>(Sender) ->Checked = true;
{
if (Left1->Checked )
doc->Paragraph->Alignment = taLeftJustify;
else if (Right1->Checked)
doc->Paragraph->Alignment= taRightJustify;
else if (Center1->Checked)
doc->Paragraph->Alignment = taCenter;
} }
//文檔自動換行
void __fastcall TChildForm::Wordwrap1Click(TObject *Sender)
{
doc->WordWrap = !doc->WordWrap; //toggle word wrapping
if (doc->WordWrap)
doc->ScrollBars = ssVertical;
else
doc->ScrollBars = ssBoth;
Wordwrap1->Checked = doc->WordWrap; // set menu item check
}
//設置選中文檔的字體
void __fastcall TChildForm::Font1Click(TObject *Sender)
{FontDialog1->Font= doc->Font;
if (FontDialog1->Execute())
doc->SelAttributes->Assign(FontDialog1->Font);
}
//子窗口鼠標單擊響應函數
void __fastcall TChildForm::FormClick(TObject *Sender)
{
bool HasSelection;
Paste1->Enabled = Clipboard()->HasFormat(CF_TEXT);
HasSelection = doc->SelLength > 0;
Cut1->Enabled = HasSelection;
Copy1->Enabled = HasSelection;
Delete1->Enabled = HasSelection;
}
//子窗口關閉時事件響應
void __fastcall TChildForm::FormClose(TObject *Sender, TCloseAction &Action)
{Action=caFree; }
//子窗口關閉時詢問事件響應
void __fastcall TChildForm::FormCloseQuery(TObject *Sender,
bool &CanClose)
{
if (doc->Modified)
{
TMsgDlgButtons temp_set;
temp_set<< mbYes<<mbNo <<mbCancel;
String buffer = "Save changes to " + PathName;
switch(MessageDlg(buffer, mtConfirmation,temp_set,0))
{
case mrYes:
Save1Click(this);
break;
case mrCancel:
CanClose=false;
break;
} }}
void __fastcall TChildForm::FormCreate(TObject *Sender)
{ PathName = DefaultFileName; }
//---------MDIChild.h------------
class TChildForm : public TForm
{
private:  // User declarations
AnsiString PathName;//文檔文件和路徑名定義
public:    // User declarations
void __fastcall Open(const AnsiString AFileName);//文檔打開函數聲明
virtual __fastcall TChildForm(TComponent* Owner);
};

另外,你自己也可以根據上述開發思路來開發出各種各樣的MDI程序,比如,你可以在文檔中利用OLE加入圖片,聲音等多媒體因素,使你的文檔更加豐富多彩!

(全文完)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved