線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3219
推到 Plurk!
推到 Facebook!

用C++ Builder3 製作NotePad(記事本)

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-09-27 22:20:23 IP:61.70.xxx.xxx 未訂閱
此為轉貼資料    http://hanlin.hbu.edu.cn/personal/star/program/bcb/viewpage.asp?ID=131    用C++ Builder3 製作NotePad(記事本)      ?動C++ Builder3後,在File功能表中選New APPlication來建立一個新程式。這時,顯示在螢幕中間的視窗的標題是Form1,這個視窗是程式的主表單(就是主視窗的意恩),它將在程式?動時自動顯示。而以後再創建的表單(Form)一般需要用Show()方法(Method)來顯示。和元件一樣,系統?第一個表單起名?Form1,以後的表單起名?Form2、Form3等等,標題(Caption)也是如此。    當然,你可以將它們改成你喜歡的名字。我們先來把Form1的名字(Name)屬性設?MainForm,把MainForm的標題(Caption)屬性設?“Untited.txt--我的記事本”。接著可以用滑鼠拖動視窗的位置和改 變窗口的大小。以上的這些工作,幾乎每個程式都需要如法炮製一番。    隨後,我們要開始NotePad的編程工作了。知己知彼,百戰不殆,先來分析一下MicroSoft NotePad的結構。其實NotePad是附件裏最簡單的程式了,它的主視窗中只包含一個佔據全部用戶區域(Client Area)的多行的編輯控制(Edit)。由於編輯控制最多容納64KB文字(Windows95),所以NotePad只能打開小於64KB的文件。好,我們來依樣畫葫蘆,選擇Standard中的多行編輯(Memo)元件(而不是單行編輯元件)。    放入表單中,將多行編輯Memo1的Align屬性設?alClient,這時Memo1撐滿了整個視窗,Memo1中顯示的是Memo1。選擇Memo1的Lines屬性,[TString]後面出現了一個按鈕。    單擊該按鈕,將出現一個設置Lines屬性的對話方塊,其中第一行便是“Memo1”。多行編輯(Memo)元件的Lines屬性在設計時(Design Time)設定的內容將在該視窗創建時自動顯示。由於我們不需要顯示什?,所以把“Memo1”擦掉,選OK退出。你一定想看看目前的效果,運行一下吧。編譯……連接……?動程式……怎 ?樣,是不是和NotePad一模一樣,能打字、刪字、刪行,還能使用右鍵功能表來複製(copy)和粘貼(paste)。    本來就是嘛,用一樣的編輯控制,不一樣才怪呢。哎,不對,好像字體小了點,而且沒有捲軸。沒有關 系,關閉程式回到C++ Builder3中,先修改Memo1的字體(Font)屬性,選擇system字體(當然你愛選什?字 體都可以),然後設置捲軸(ScrollBars)屬性,選擇ssBoth(兩根捲軸都要)。在這些改動之後,先別急著運行,windows的程式沒功能表是不行的。在C++ Builder中,功能表也是元件之一。選擇Standard中的主功能表(MainMenu)元件放入表單中。主功能表(MainMenu)元件顯示?一個圖示。順便提一句功能表,對話方塊或系統功能之類元件屬於非可視元件(nonvisual components),它們的工作基本不是用來滿足視覺的,或者在程式運行時根本就看不見(相對於介面上可視元件來說),因此你可以將非可視元件放在表單中的任意位置。    接下來的工作是製作功能表,雙擊主功能表MainMenu1的圖表,會彈出功能表編輯視窗,開始時是一個空功能表。按右鍵會彈出一個功能表(不是我們要做的功能表),其中: Insert(添加一個功能表項,按Insert鍵完成相同的功能) Delete(刪除一個功能表項,按Delete鍵完成相同的功能) Create SubMenu(添加一個子功能表,按Ctrl + →鍵完成相同的功能) Select Menu(選擇一個功能表,用來關閉當前編輯的功能表並選擇另一個功能表來編輯) Save as Template(將當前功能表保存?模板,供以後使用) Insert From Template(將已有的功能表模板加入當前功能表) Delete Template(刪除功能表模板) Insert From Resource(從資源檔案中取得功能表加入當前功能表)    製作“我的記事本”的功能表有一種偷懶的方法,就是照抄Microsoft記事本的功能表。你可以用BC5.02的IDE打開Notepad.exe(先把打開文件對話方塊中的Viewer設?Edit Resource,再把文件類型設?Exe cutable(*.exe),這樣才是以編輯資源的方式打開EXE文件,否則默認的打開方式是Debug調試程式),將裏面的功能表導出以RC(資源腳本)方式存檔,然後用Insert From Resource導入該功能表;一共用不了2分鐘。    還有一種方法就是自己一項一項慢慢地做。當然,不管你用什?方法,最後都要做出功能表來才能繼續下面的工作。下面附上從Windows NT4.0中Notepad導出的功能表的資源腳本menu.rc,把下面的文件以menu.rc存檔就能用C++ Builder3來導入了: 1 MENU { POPUP "文件(&F)"   { MENUITEM "新建(&N)", 9     MENUITEM "打開(&O)...", 10     MENUITEM "保存(&S)", 1     MENUITEM "另存?(&A)...", 2     MENUITEM SEPARATOR     MENUITEM "頁面設置(&T)...", 32     MENUITEM "列印(&P)", 14     MENUITEM SEPARATOR     MENUITEM "退出(&X)", 28   }   POPUP "編輯(&E)"   { MENUITEM "撤消(&U)\tCtrl+Z", 25     MENUITEM SEPARATOR     MENUITEM "剪切(&T)\tCtrl+X", 768,GRAYED     MENUITEM "複製(&C)\tCtrl+C", 769, GRAYED     MENUITEM "粘貼(&P)\tCtrl+V", 770,GRAYED     MENUITEM "刪除(&L)\tDel",771, GRAYED     MENUITEM SEPARATOR     MENUITEM "全部選定(&A)", 7     MENUITEM "時間/日期(&D)\tF5",12     MENUITEM SEPARATOR     MENUITEM "自動換行(&W)", 27     MENUITEM "設置字體(&F)...", 37   }   POPUP "搜索(&S)"   { MENUITEM "查找(&F)...", 3     MENUITEM "查找下一個(&N)\tF3", 8     MENUITEM "替換(&R)"', 40   }   POPUP "幫助(&H)"   { MENUITEM "幫助主題(&H)", 5     MENUITEM SEPARATOR     MENUITEM "關於記事本(&A)...",11   } } 關於功能表,還有兩點要提: 1.一般沒有必要去改動功能表項的Name屬性,使用系統給出的默認名就可以了。 2.以“-”?標題的功能表項即是功能表分割條,而功能表項的Break屬性提供的分割則是一種很奇怪的樣子--“垂直分害條”(群山笑:這個名詞是我自已加上的)。    OK,到此?止,介面部分的工作已經全部完成了,接下來便是代碼部分的編寫。首先要做的就是打開文件和存檔的工作。我們來建立一個char *UserFileName的總體變數來存放檔案名。按工具條上的Toggle Form/Uint將工作窗口切換到代碼編輯區。這個按鈕用於表單編輯區和代碼編輯區的相互切換,按F11顯示物件觀察器。在“TMainForm *MainForm;”下加語句: char *UserFileName="untitled.txt";//默認檔案名Untitled.txt BOOL If_saved=TRUE;//表示文件存檔與否 char title_buf[256];//標題的內容    接著,我們再切換回表單編輯區,從Dialogs元件條中選SaveDialog元件放入表單中。    SaveDialog元件就是用來顯示Save As對話方塊的,當然用Windows API也能實現此功能,這裏將使用SaveDialog元件。將SaveDialog1的DefaultExt(默認的副檔名)屬性設?.txt,這表示如果用戶沒有加副檔名,系統會自動加上“.txt”。按Filter屬性後的[…]按鈕,在彈出的對話方塊中輸入“文字檔案”“*.txt”“所有文件”“*.*”。另外再雙擊Options屬性,將展開後其中的ofOverwritePrompt(文件覆蓋提醒)屬性設?true。接著在表單編輯區的功能表中選功能表項“另存?(A)...”,這時C++ Builder3會自動切換到代碼編輯區,而游標停在一個函數的開頭。在該例中功能表項“另存?(A)…”的名字屬性是A1,所以這個函數的名字是A1Click(TObject * Sender),表示用戶選擇(Click)這個功能表項而執行的函數。我們所要做的是彈出Save As對話方塊來獲得用戶輸入的檔案名,並將這個文件存檔。所以在這個函數里加如下的語句: if(!SaveDialog1->Execute()) return; //如果用戶選擇了取消,我們就return UserFileName = SaveDialog1 -> FileName.c_str(); / * FileName保存了用戶輸入的檔案名,但是AnsiString類型的,用其中的c_str()方法可以將其轉換成字串*/ Memo1 ->Lines->SaveToFile(UserFlleName); If_saved=TRUE; //已經存檔 sprintf(title_buf,"% s - 我的記事本”, UserFileName); /* 設置窗口的標題,記得要加上include  * / Caption=title_buf; / * Memo中的Lines屬性即是編輯控制中的內容,Lines屬性是Strings類型的,用其中提供的SaveToFile方法可以方便地將編輯控制中的內容存檔 */ 類似地,我們再來處理打開文件的工作。首先,在表單中放置一個OpenDialog元件,DefaultExt和Filter 屬性同SaveDialog1,將Options屬性中的ofFileMustExist(文件必須存在)設?true。然後在表單編輯區中 的功能表中選功能表項“打開(O)...”,在代碼編輯區中輸入如下語句。 if(!if_saved) if(Application ->MessageBox("文件還未保存,是否要保存?","我的記事本", MB_OKCANCEL MB_DEFBUTTON1 MB_ICONWARNING)==ID_OK) S1Click(NULL); / * 如果文件沒有保存,我們得先徵求用戶是否要保存文件。s1Click()是“保存(s)”功能表項的處理函數(就是接下來處理的功能表項),“保存(S) ”功能表項的工作就是將文件存檔,所以我們沒有必要寫重復的代碼,而只要直接調用該函數就可以了。注意,如果你的“保存(S)”功能表項的名字屬性不是S1而是其他,那?這個函數的名字也會有所不同,但總是“名字” Click() */ if(!OpenDialog1->Execute())return; UserFileName=OpenDialog1->FileName.c_str(); Memo1->Lines->LoadFromFile(UserFileName); sprintf(title_buf,"% s - 我的記事本", UserFileName); Caption = title_buf; (?節省篇幅,以下凡是重復的操作描述省略) 處理“保存(S)”功能表項,輸入: Memo1->Lines->SaveToFile(UserFileName); If_saved=TRUE; sprintf(title_buf,"% s - 我的記事本", UserFileName)"; Caption = title_buf; 處理“新建(N)”功能表項,輸入如下語句: lf(!If_saved) if(Application ->MessageBox ("文件還未保存,是否要保存?","我的記事本", MB_OKCANCEL MB_DEFBUTTON1 MB_ICONWARNING)==ID_OK)S1Click(NULL); sprintf(UserFileName,"Untitled.txt"); sprintf(title_buf, "% s - 我的記事本-未存檔",UserFileName); Caption=title_buf; Memo1->Lines->Clear(); //將編輯控制中的內容清空 隨後,我們要處理Memo1的OnChange事件(Events)。一旦編輯控制中的內容有改變,Memo1就將?生OnChange事件,這時需要將If_saved置?FALSE,表示文件已經改動過了,並在標題上顯示“未存檔”。在物件觀察器中選Memo1,再單擊下面的Events,將列出許多事件,第一個就是OnChange,雙擊後面的編輯框,後面的操作和處理功能表項是一樣的(其實前面處理的功能表項就是處理功能表的OnClick事件),輸入: If_saved=FALSE; sprintf(title_buf,"% s -我的記事本-未存檔", UserFileName); Caption=title_buf; 隨後處理MainForm的OnClose事件,輸入: //OnClose事件在關閉視窗時?生,需要做一些收尾工作 if(!If_saved) if(application->MessageBox("文件還未保存,是否要保存?","我的記事本", MB_OKCANCEL MB_DEFBUTTON1 MB_ICONWARNING)==ID_OK)S1Click(NULL); 最後,處理“退出(X)”功能表項,輸入如下語句: if(!If_saved) if(application->MessageBox("文件還未保存,是否要保存?","我的記事本", MB_OKCANCEL MB_DEFBUTTON1 MB_ICONWARNING)==ID_OK)S1Click(NULL); Application->Terminate(); //程式結束 到此?止,終於小功告成了,快把專案保存下來吧。在File功能表中選Save Project As…,首先彈出的對 話框要求輸入表單的檔案名(不能和表單的名字屬性相同),我們就輸入Main。隨後彈出的對話方塊才是要求輸入專案(Project)的檔案名,該檔案名也就是exe文件的名字,我們輸入NotePad。保存後再選Project功能表 裏的Make NotePad,或按Ctrl F9,就會?生一個NOtePad.exe,這就是我們自己做的記事本,目前它已經能打開文件、編輯並保存。你一定發現功能表中還有許多功能尚未實現,這就是我只說小功告成的原因,不過 下次我們會完成它。 附件中除了記事本(NotePad),還有一個寫字板(WordPad)。它們最大的區別在於前者使用的是編輯 控制(Edit),而後者使用的是Rich Edit控制(有些書翻譯成豐富文本控制)。與編輯控制相比,Rich Edit除了能給文本加上各種修飾,還支援簡單的物件鏈結和嵌入技術(Object Linking and Embedding)。 此外,Microsoft Win32 SDK的文檔中說Rich Edit控制能接受的文本大小將只受記憶體大小的限制,這比 編輯控制的64KB強多了。當然,效率又是另一個問題。我曾試圖用寫字板(WordPad)打開一個15MB的文件,硬碟讀了10多分鐘還沒結果,只能按Reset重新?動了(我可有64MB記憶體哦)。自然使用Rich Edit控制也比編輯控制難的多。在以後講到RichEdit元件時,詳細講述它的用法。
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-04-26 2:57:36
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!