全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:13728
推到 Plurk!
推到 Facebook!

VCL How To - 內部物件篇

 
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-08-09 22:32:40 IP:163.32.xxx.xxx 未訂閱
類別名稱:Tstrings 文件版本:for Delphi 文件作者:bruce0211 1999.01 具有類別型態為 Tstrings 的元件: Memo 之 Lines 屬性 RichEdit 之 Lines 屬性 StringGrid 之 Cols 及 Rows 屬性 ListBox 之 Items 屬性 ComboBox 之 Items 屬性 等等... ●清空Tstrings 之內容:Clear <方法> 例:Memo1.Lines.Clear; RichEdit.Lines.Clear; ListBox.Items.Clear; ComboBox.Items.Clear; ●加入一筆資料到Tstrings 之方法:Add(‘字串’) <方法> 例:Memo1.Lines.Add('加入一行字串'); RichEdit.Lines.Add('加入一行字串'); ListBox.Items.Add('加入一行字串'); ComboBox.Items.Add('加入一行字串'); ●取出Tstrings 字串列數:Count <屬性> 例:I:=Memo1.Lines.Count; I:=RichEdit.Lines.Count; I:=ListBox.Items.Count; I:=ComboBox.Items.Count; ●刪除Tstrings 字串列中某一字串列號:Delete(列號) <方法> 例:Memo1.Lines.Delete(1); RichEdit.Lines.Delete(1); ListBox.Items.Delete(1); ComboBox.Items.Delete(1); □ 若要同時刪除多個列號時需由後往前刪(即由列號大者往列號小者) 因為假設要同時刪 1,3,5 列號 , 當刪完列號 1 時 , 列號 2 以後會往前遞補,所以再刪列號 3 及 5 時 , 已非原先之列號 3 及 5 ●求出Tstrings 字串列中某一列號之字串值:Strings[列號] <屬性> 例:tt:=Memo1.Lines.Strings[1]; tt:=RichEdit.Lines.Strings[1]; tt:=ListBox.Items.Strings[1]; tt:=ComboBox.Items.Strings[1]; ●將Tstrings 字串列全部內容存檔:SaveToFile(‘檔名’) <方法> 例:Memo1.Lines.SaveToFile(‘C:\TEMP.TXT’); RichEdit.Lines.SaveToFile(‘C:\TEMP.TXT’); ListBox.Items.SaveToFile(‘C:\TEMP.TXT’); ComboBox.Items.SaveToFile(‘C:\TEMP.TXT’); ●將Tstrings 字串列全部內容從檔案中取出:LoadFromFile(‘檔名’) <方法> 例:Memo1.Lines.LoadFromFile(‘C:\TEMP.TXT’); RichEdit.Lines.LoadFromFile(‘C:\TEMP.TXT’); ListBox.Items.LoadFromFile(‘C:\TEMP.TXT’); ComboBox.Items.LoadFromFile(‘C:\TEMP.TXT’); ●求出一字串值是在目前Tstrings 字串列中哪一個列號上:IndexOf('你要找的字串值') 例:I:=FileListBox1.Items.IndexOf('COMMAND.COM'); FileListBox1.ItemIndex:=I; {當FileListBox一開啟時,反白焦點即會停在'COMMAND.COM'上} 發表人 - bruce0211 於 2002/08/10 11:40:58
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-08-09 22:40:01 IP:163.32.xxx.xxx 未訂閱
物件名稱:TStringList 文件版本:for BCB 文件作者:bruce0211 2002/05 ●前言 TStringList 為一獨立物件 , 類似 ListBox 用法 , 但為一不可視的內部物件 , 使用者使用時需自行建立它 ●應用 如果程式需要抓取一堆文字檔來處理,可使用現成的 FileListBox 元件並將元件之Directory屬性指向目標目錄位址,我們要找的文字檔就會出現在 FileListBox 中了,利用修改其 ItemIndex 屬性值,就可逐筆取出 FileListBox1->FileName 傳回之檔案名稱;FileListBox 元件還有個好處,那就是它還可利用 Mask 屬性過濾副檔名,我們可以要求只列出某一目錄中副檔名為 *.TXT (可同時選擇多種不同副檔名)的檔案;但如果程式是一個無 Form 的不可視程式,或程式的 Form 中沒有地方放這個 FileListBox 元件, 而我們卻需要其「列出檔案清單」的功能,在背景做一些檔案處理的動作(如一直偵測某一目錄發現收到文字檔後 , 做轉資料庫的動作) 但畫面上卻不需要上插入 FileListBox 這個元件,那該如何做呢? 1.以程式碼建立一個 TstringList 物件(非可視物件) 2.利用 FindFirst() 函式收集檔案名稱,放入這個 TstringList 物件中 3.TstringList 物件的使用方法類似 ListBox 或 FileListBox 元件 4.用完要自行釋放這個 TstringList 物件 void __fastcall TForm1::Button1Click(TObject *Sender) { String Dir; String FileName; TSearchRec SearchRec; int iAttributes = 0; iAttributes |= faAnyFile * true; //偵測 c:\ 底下有無 *.tot 這個類型的檔案 //有的話則收集到 TempList 這個區域物件中 , 用完即釋放掉 Dir=("C:\\"); TStringList *TempList = new TStringList; // declare the list try { //use the string list TempList->Clear(); //搜集 *.tot if (FindFirst(Dir "*.tot", iAttributes, SearchRec) == 0) { do { if ((SearchRec.Attr & iAttributes) == SearchRec.Attr) { TempList->Add(SearchRec.Name); } } while (FindNext(SearchRec) == 0); FindClose(SearchRec); } for ( int i = 0; i <= (TempList->Count-1); i ) { FileName=(Dir TempList->Strings[i]); //本迴圈可抓出所有符合條件之檔名至 FileName 變數中 //.......................... //可將後續運用程式碼寫在這裡 //.......................... } } __finally { delete TempList; // destroy the list object ProgressBar2->Position=100; Label2->Visible=true; } } 發表人 - bruce0211 於 2002/08/10 11:42:45
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-08-09 22:42:42 IP:163.32.xxx.xxx 未訂閱
文件名稱:Set (集合型態) 的使用方法 文件版本:for BCB 文件作者:bruce0211 2002/05 ●前言 Set (集合型態) 是 Object Pascal 特有型態 , 在 BCB 中是用一個名為 Set 的類別來模擬Set 型態 , 由於在 VCL 元件中有許多屬性都會利用到 Set 型態 , 所以在此介紹其使用方法 ●加入集合元素 語法 : 集合型態原型 << 元素一 [<< 元素二] [<< 元素二] [...] 舉例 : 1. 在 MessageDlg 談出示對話盒中 , 若需要有兩個按鈕 "YES" & "NO" 則使用 TMsgDlgButtons() << mbYes << mbNo 完整範例如 if (MessageDlg("Delete Record?", mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrYes) DataModule3->Table1->Delete(); 2. 我們要將某一元件之字型設為粗體 , 使用物件檢視器(Object Inspector)來設定很簡單 , 只要在 Font 屬性中展開 Style 次屬性 , 再將 fsBold 設為 true 即可 但在程式碼中如何做到以上動作呢 ? (以設定 Edit1 字型為粗體為例) Edit1->Font->Style = TFontStyles() << fsBold; 若要同時設定其字型為粗體加底線 : Edit1->Font->Style = TFontStyles() << fsBold << fsUnderline; ●判斷是否含有集合元素 □ 判斷 Edit1 目前是否為粗體字型 if (Edit1->Font->Style.Contains(fsBold)) ShowMessage("true"); else ShowMessage("false"); □ 判斷 KeyDown 事件中是否帶有 Shift void __fastcall TFm_POS1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if (Shift.Contains(ssShift)) { ...... ...... } } □ 在做 StringGrid 變色特效時 , 判斷當在固定列或選擇列(藍色光棒列)則不于變色 void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State) { // 如果是固定列或選擇列(藍色光棒列)則不于變色 if (State.Contains(gdFixed) || State.Contains(gdSelected)) return; if (ARow==2) StringGrid1->Canvas->Font->Color=clRed; //字型變色 if (ACol==3) StringGrid1->Canvas->Brush->Color=clLime ; // 垂直 cell 背景變色 if (ARow==3) StringGrid1->Canvas->Brush->Color=clYellow; // 水平 cell 背景變色 // output the text StringGrid1->Canvas->TextRect (Rect, Rect.Left, Rect.Top,StringGrid1->Cells[ACol][ARow]); } □ 註 : 根據測試 Contains() 中好像無法同時塞入兩個集合元素值 ... ●移除集合元素 同 "加入集合元素" 語法 , 但只要將 "<<" 改為 ">>" 即可 if (Edit1->Font->Style.Contains(fsBold)) Edit1->Font->Style = TFontStyles() >> fsBold;
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2002-08-09 22:47:37 IP:163.32.xxx.xxx 未訂閱
物件名稱:TIniFile (INI 檔處理) 文件版本:for BCB 文件作者:bruce0211 2002/05 ●前言 INI 檔應用的歷史從 Windows 3.1就已存在,雖然它也是文字檔的一種,但它利用「節區(Section)」及「識別字(KeyWord)」觀念,類似資料庫的索引,所以用來當作少量變數資料的儲存器非常適合,除變數管理容易外尚可做程式流程控制,市售套裝軟體有用 ini 檔來控制其軟體版本例子,其主執行檔可能只有一個,但依 INI 檔設定可開放其全功能版(豪華版)與非全功能版;INI檔案 Size 雖然有 64k的限制,但已足夠存放上百個變數資料;在 32 位元系統上,正統取代 INI 機能的方法為使用 Windows Regist,但為了儲存Windows 作業系統本身的資訊,Regist已夠龐大,如果我們每個應用程式又去 Regist內挖一塊空間當作自己儲藏變數或參數的地方,會讓 Regist變得更龐大更複雜,所以筆者還是建議每個程式都使用自己的INI檔來儲存自己的變數,況且 INI檔不會被淘汰,連 Linux Kylix 下都看得到其蹤影 ●應用實例 假設程式中需要紀錄目前發票號碼(invo_no)、交易序號(tran_no),而每次交易完都要將這兩個變數值加1,若程式從頭到尾都不關機,那沒有問題,程式會記錄目前的發票號碼及交易序號已排到幾號;但若程式中途有關機後,下次開機,程式怎知發票號碼及交易序號已排到幾號?所以除了將變數資料存於資料庫中外,更簡單的方法就是使用INI檔來記錄變數值,在程式重新啟動時再將變數值取回,所以該INI檔內容可能長得如下: [Varible] invo_no=00000005 tran_no=3 其中,用中括號刮起來的Variable就是「節區(Section)」名稱(可自訂),而其內的 INVO_NO、TRAN_NO則稱為「識別字(KeyWord)」(可自訂);不可有相同名稱的兩個節區(Section),但不同的節區中可有相同名稱的識別字(KeyWord),取用時按節區(Section)索引分開取用,如下圖: [Varible] invo_no=00000005 tran_no=3 [Varible_2] invo_no=00000007 tran_no=5 ●程式實例 接下來我們介紹使用 INI 檔來儲存或取回變數的方法,在程式中要使用 INI 檔有幾個步驟: 1.程式開頭必須 #include "inifiles.hpp" 2.程式中首先需建立一個 TIniFile 物件以對應實際的 INI 檔,不用時再釋放這個 TIniFile 物件,通常 INI 檔實 體與主執行檔存在同一路徑,甚至檔名也和主執行檔相同,但副檔名則為 *.ini 3.使用 INI 物件的某些方法(Method)來存取變數,取用的方法依變數型態有下列幾種方法(假設這個 TIniFile 物件名為 MyIni) MyIni->ReadInteger(節區名,識別字,整數Default值); MyIni->ReadString(節區名,識別字,字串Default值); MyIni->ReadBool(節區名,識別字,布林Default值) 4.寫入的方法依變數型態也有下列幾種方法 MyIni->WriteInteger(節區名,識別字,欲寫入之整數變數值); MyIni->WriteString(節區名,識別字,欲寫入之字串變數值); MyIni->WriteBool(節區名,識別字,欲寫入之布林變數值) 以下為一完整使用INI程式碼的範例 //------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" #include "inifiles.hpp" //要 include 這個東西才有 TIniFile 類別 //------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; TIniFile *MyIni; //------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { //建立 TIniFile 物件及實體存放路徑 MyIni = new TIniFile(ChangeFileExt( Application->ExeName, ".ini" ) ); //讀取變數(若變數值不存在則用自動使用 Default 值) Left=MyIni->ReadInteger( "Form","Left",100); Caption=MyIni->ReadString( "Form","Caption","Default Caption"); } //------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { //將變數寫入 ini 物件 MyIni->WriteInteger("Form","Left",Left); MyIni->WriteString("Form","Caption",Caption); // 釋放 ini 物件 delete MyIni; } //------------------------------------------------------- ●TIniFile 物件的生命週期 在上面的程式碼中,可以看見我們把 TIniFile 物件的建立寫在 FormCreate 事件中,而釋放 TIniFile 物件則寫在 FormClose 事件中;事實上,變數真正寫到實體檔案中,是在TIniFile 物件釋放的時候(也就是類似關閉檔案動作);平常則只是暫存於記憶體中,如此可減少磁碟 I/O 動作,但若程式不正常關閉,則TIniFile 物件來不及將暫存於記憶體中的變數存檔,會導致欲存檔的變數遺失;所以為保險起見,我們可在準備寫入變數的時候才去建立 TIniFile 物件,存入後馬上釋放 TIniFile 物件以確保寫入實體檔案中,但這樣卻會增加磁碟I/O讀寫頻繁,其中的斟酌端看應用方向的特性。 //------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { TIniFile *MyIni; MyIni = new TIniFile(ChangeFileExt( Application->ExeName, ".ini" ) ); MyIni->WriteInteger("Form","Left",Left); MyIni->WriteString("Form","Caption",Caption); delete MyIni; } //------------------------------------------------------- 發表人 - bruce0211 於 2002/08/09 22:49:18
系統時間:2024-11-21 17:13:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!