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

請問關於resourcestring

尚未結案
rowater
一般會員


發表:11
回覆:19
積分:6
註冊:2004-08-30

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-07-20 22:40:16 IP:211.23.xxx.xxx 未訂閱
各位大大 我使用了resourcestring implementation uses REAbout, RichEdit, ShellAPI, ReInit; resourcestring KKsSaveChanges = 'Save changes to %s?'; 請問有沒有function是可傳回resourcestring的 如 String A := 'KK' 'sSaveChanges'; Label1.Caption := Getresourcestring(A); 這樣的東西? 謝謝~~
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-07-21 10:12:56 IP:218.163.xxx.xxx 未訂閱
SysUtils Unit 的 LoadStr Function Windows Unit 的 LoadString Function 是你要的嗎 ?
rowater
一般會員


發表:11
回覆:19
積分:6
註冊:2004-08-30

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-07-25 09:55:40 IP:211.23.xxx.xxx 未訂閱
可否給個例子呢 謝謝~~
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-07-26 15:54:14 IP:203.69.xxx.xxx 未訂閱
由 ResourceString 宣告的常數 不須 Function 就可以在程式中引用. Label1.Caption := KKsSaveChanges; 因為程式 compiler 後 這些 ResourceString 常數 會被放入程式執行檔之中 (可以用 Resouce Hacker 看看) 發表人 - malanlk 於 2005/07/26 17:07:08
rowater
一般會員


發表:11
回覆:19
積分:6
註冊:2004-08-30

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-07-26 18:00:44 IP:211.23.xxx.xxx 未訂閱
To malanlk : KKsSaveChanges由字串組成 所以要使用Function傳回 Mickey大大的答案似乎是我要的 可是找網路的例子我都看不太懂~~
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-07-26 18:42:38 IP:203.69.xxx.xxx 未訂閱
如果用 resourcestring 宣告, 就是將字串由 compiler 自動幫你編號, 所以就沒辦法如你願 用字串識別找出來, 必須另外用 .RES 檔的方式做出你要的東西, 先看這篇 http://delphi.ktop.com.tw/topic.php?topic_id=18030
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-07-27 01:59:41 IP:61.219.xxx.xxx 未訂閱
參考    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tools/tools/rcdata_resource.asp    將下列文字存入檔案 MyData.rc
MYDATA RCDATA
{
   "[Test]\n",
   "AA=Here is an ANSI string AA\n",
   "BB=Here is an ANSI string BB\n" 
}
在命令提示列下 執行 C:\Program Files\Borland\Delphi7\Bin\Brcc32 MyData.rc 執行後會產生 MyData.res 參考下列程式
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;    type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;    var
  Form1: TForm1;    implementation    {$R *.dfm}
{$R MyData.res} // 引用先前產生的 resource file    procedure TForm1.Button1Click(Sender: TObject);
var
  reshandle: THandle;
  hglobal: THandle;
  ressize: dword;
  ptr: pointer;
  TempStream : TMemoryStream;
begin
  reshandle := FindResource(hinstance,'MYDATA',PChar(RT_RCDATA)); // 紅色的 MYDATA 是 MyData.rc 檔案裡建立的 RCDATA
  hglobal := LoadResource(hinstance,reshandle);
  Ressize := SizeOfResource(hinstance,reshandle);
  ptr := LockResource(hglobal);
  TempStream := TMemoryStream.Create;
  try
    TempStream.SetSize(Ressize);
    TempStream.Write(ptr^,Ressize);
    TempStream.Position := 0;
    Memo1.Lines.Clear;
    Memo1.Lines.LoadFromStream(TempStream);
  finally
    TempStream.Free;
  end;
end;    end.
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-07-31 20:34:36 IP:61.64.xxx.xxx 未訂閱
如果你是要存取別的程式的 資源字串 才需要 LoadString 對自己的程式使用 LoadString ,不是脫褲子放屁嗎? 如 malanlk 所說 直接使用 Label1.Caption := KKsSaveChanges; 除非你將字串放在 res 內,如果是這樣,又何必用 resourcestring 來宣告? 所以 1. 用 resourcestring 來宣告 就直接使用 Label1.Caption := KKsSaveChanges; 不須再用 LoadString,脫褲子放屁 2. 而用 {$R xxx.res} 就必需使用 LoadString 之類的函式來取得
rowater
一般會員


發表:11
回覆:19
積分:6
註冊:2004-08-30

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-08-03 08:55:40 IP:211.23.xxx.xxx 未訂閱
我就是有這樣的需求呀 如用 resourcestring 來宣告 不知有沒有簡單一點的方法達到我的需求
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-08-03 11:46:53 IP:203.69.xxx.xxx 未訂閱
就是用 Name=Value 字串列的方式達成你的需求啊 把 Name=Value 放進 .res 內, 當你如程式所示範由 resource 讀入 Memo1.Lines 後就可以用 aStr := Memo1.Lines.Values[Memo1.Lines.IndexOfName('A' 'A')]; 可將 AA 對應的字串讀出....
wameng
版主


發表:31
回覆:1336
積分:1188
註冊:2004-09-16

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-08-03 12:07:40 IP:61.222.xxx.xxx 未訂閱
如果您這樣的用意是要方便管理訊息。 建議使用 StringTable 方式,可定義字串代號。 如: 123, "Hello..."    當然我們可以透過 TResStringRec 資源結構 Showmessage(inttostr(PResStringRec(@KKsSaveChanges)^.Identifier)); 可以顯示該訊息的編號。 通常是以 65346 開始的。    因此在 LoadStr(65346) 就會等於 KKsSaveChanges內容 如:
var
  Ident : Integer;
begin
  Ident := PResStringRec(@KKsSaveChanges)^.Identifier;
  Showmessage(LoadStr(Ident));
end;
個人仍建議您使用 StringTable 的方式。 不過就是要建立 Rc 檔 STRINGTABLE { 1, "...." 2, "..." .... } 參考 ~~~~~~~~~~~ 難得聰明,常常糊塗。 ~~~~~~~~~~~
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-08-03 18:39:18 IP:61.64.xxx.xxx 未訂閱
引言: 我就是有這樣的需求呀 如用 resourcestring 來宣告 不知有沒有簡單一點的方法達到我的需求
是的,大家都很清楚你的需求 但是你已經進入一個程式設計的牛角尖了 這樣只會讓你的程式碼表面上看起來很方便記憶與使用,但是卻是不然,久了,你還是會忘記,然後看似方便的東西,就不方便了 更不用說,增加程式碼的複雜度,效率會打折 方法: 1. 用 resourcestring 來宣告 就直接使用 Label1.Caption := KKsSaveChanges; 不須再用 LoadString,脫褲子放屁 2. 而用 {$R xxx.res} 就必需使用 LoadString 之類的函式來取得 如果你硬要用 if xxx then kk := yyy else if aaa then kk := zzz else ... S := 'kk' 'sSaveChanges' 這樣跟 if xxx then S := 001sSaveChanges; else if aaa then S := 002sSaveChanges; else ... 並沒有什麼不同 因為當你訊息一多,你在寫程式時,看到 kksSaveChanges ,並無法直接知道該訊息的意義,反而會降低你程式寫作的速度,同時也會增加你將訊息誤放的機率 這樣並不會比較好 使用 resourcestring 就是要簡化訊息使用,集中訊息位置,並同時使程式能在編譯時就先將需要在 run time 所花費的處理時間,在 complie time 就先計算處理掉 所以我們都會用容易記憶的方式來表達 resourcestring 如 error_file_nor_found = '找不到檔案'; error_drive_not_ready = '磁碟未就緒'; 而盡量不會去用 err_001 = 'xxxx'; err_002 = 'xxxx'; 如果你硬宣告 resourcestring 然後再由 loadstr 去存取,將會在執行時多負擔一些定址計算與存取的時間浪費,而這種時間可以在編譯時就節省掉,讓 Delphi 為你編處最佳效率的程式碼,為什麼不要?反而要浪費時間去 call API ? 那何時要使用 {$R xxx.res} 比較好 ? 因為有些資源不適合直接 Keyin ,如 Binary Data,圖形,像這種使用 res 是最好的,也是最方便的方式 這都是 Delphi 所提供的想法與方便之處,因為最後 resourcestring 還不是編到 '資源 ' 內,都是一樣的地方,只是提供你一個較有效率的方式,程式也較省時,不然又何必多個 resourcestring 來多此一舉 當然如果你硬要在 resourcestring 內宣告,然後在用 loadstr 來取得,當然也是可以,只是繞了個彎 不過,如你所說,你有需要,只要你確定你繞這個彎的花費可以幫你省下更多的花費,這個彎還是值的繞的 你也可以將所有的 resourcestring 集中在單一的 units 內,然後再引入(uese 或 include),這樣檔案就不會太多字串在開頭,或是直接使用 res 編輯 string table 要怎麼做都行,單看你所需 反正結果可以出來就是正確的程式,那怕你的程式檔較大,執行較慢,累贅一堆,只要你喜歡,能接受就好,那怕大家都喜歡效率好、檔案小,你的程式由你編譯,別人也干預不了,頂多給你建議,當然,不能跑、有 bug ,也是你的事囉~ 只是程式設計是固定的,某些東西最簡單就是那樣,一味追求最簡單,甚至到了鑽牛角尖的地步,將會適得其反
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-08-03 21:34:41 IP:220.228.xxx.xxx 未訂閱
哈哈...也曾想過...寫個例子...    只是構想時...突然不知為何需要這樣麻煩....所以寫不下去.
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-08-04 00:47:41 IP:61.219.xxx.xxx 未訂閱
Mickey大所言, 正是我寫前面範例的心聲, 我還是"忍著"寫完了... 是不是請發問者說清楚 來龍去脈, 也許就會..... "喔! 原來如此, 你這樣這樣更好....."
rowater
一般會員


發表:11
回覆:19
積分:6
註冊:2004-08-30

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-08-04 02:12:35 IP:211.23.xxx.xxx 未訂閱
不好意思 小弟真正用Delphi寫軟體才三個月 對於開發程式的觀念可能有錯誤 承蒙這個網站和各位大大的不吝分享讓我穫益不少 希望各位大大能多指導 我想用ResourceString的原因是因為我想做一個資料字典 我原本是放在資料庫 去對應資料表名稱和欄位名稱,用locate資料表的方式去把dataset上Tfield 的Displaylabel設上中文名 像這樣 SetDisplaylabel(Tablename,Tclientdataset), 可是隨著Tbale越來越多 Form開啟的速度也好像有點頓頓的 我怕Table越開越多 會變的難以忍受 所以又改了clientdataset抓XML減少資料庫傳輸時間(不想用BDE抓paradox) 如果用ResourceString而不用資料庫會不會在速度上更快點 因為欄位很多 不想一個Dataset就寫很多行欄位對應 所以想寫成Function傳入Dataset並自動設上Displaylabel 所以才會有此需求 我是新手 所以想法需求可能都有點天馬行空怪怪的 讓各位見笑了 如果各位大大對於Displaylabel的資料管理有任何高見 或資料字典的規劃有任何想法或意見 可否提出討論分享 謝謝~~~
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-08-04 08:59:54 IP:61.64.xxx.xxx 未訂閱
引言: 不好意思 小弟真正用Delphi寫軟體才三個月 對於開發程式的觀念可能有錯誤 承蒙這個網站和各位大大的不吝分享讓我穫益不少 希望各位大大能多指導 我想用ResourceString的原因是因為我想做一個資料字典 我原本是放在資料庫 去對應資料表名稱和欄位名稱,用locate資料表的方式去把dataset上Tfield 的Displaylabel設上中文名 像這樣 SetDisplaylabel(Tablename,Tclientdataset), 可是隨著Tbale越來越多 Form開啟的速度也好像有點頓頓的 我怕Table越開越多 會變的難以忍受 所以又改了clientdataset抓XML減少資料庫傳輸時間(不想用BDE抓paradox) 如果用ResourceString而不用資料庫會不會在速度上更快點 因為欄位很多 不想一個Dataset就寫很多行欄位對應 所以想寫成Function傳入Dataset並自動設上Displaylabel 所以才會有此需求 我是新手 所以想法需求可能都有點天馬行空怪怪的 讓各位見笑了 如果各位大大對於Displaylabel的資料管理有任何高見 或資料字典的規劃有任何想法或意見 可否提出討論分享 謝謝~~~
你這樣不算是觀念錯誤 只是想法奇特(有時想法奇特是不錯的) 你有沒有想過,最後反而是直接使用 record 結構 檔案讀寫最快呢? 資料庫也是需要檔案讀寫,但是同時還需要加上一層網路處理機制,或資料轉換機制 (ODBC or somethink alike),這些額外的機制都需要CPU時間來處理,結果最快的是自己寫(XML 理論上會比 Database 快一點,至於會不會比 call API 的 resourcestring 快,這就不知道了) 但自己寫,往往是最麻煩,因為工作量落在自己身上,不過程式效率最好 我的話,可以在編譯時期就解決的東西,我就盡量在編譯時期解決,不會希望留到執行時期在使用CPU時間來處理,增加效率、節省時間,因為現在已經不像以前,以前 Ram 有限制,就盡量用 Disk ,現在沒這問題,就盡量將東西編死在 Disk 上,載入記憶體就可以用,不需要再做處理,計算位址後才再載入 的確大量的 Label 設定,是很 恩,不 是非常煩人的 但是要是有更好的方式,相信 Borland 或其他第三方一定地會有相應的新方法供我們使用,但目前沒有,如果你可以找到更好、更方便的方式有效率的處理程式,相信將來 Borland Delphi 的 about Borland 中會有你的名字
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#17 引用回覆 回覆 發表時間:2005-08-04 09:47:15 IP:203.69.xxx.xxx 未訂閱
syntax大大所說的沒錯, 觀念是對的.... 如果你早點說清楚, 會得到更多的建議.... 不過採用 syntax 大大作法之前, 你是否有試過問題可能是出在資料庫使用的問題上, 比如說 你用 locate, 那我就要問 1. 你的 Table 有 Index 嗎? Index 對存取速度影響很大的.. 2. 有必要 ㄧ開始就把所有資料表的 DisplayName 都設上去嗎? 用到才設就可以把時間分散...這階段有許多技巧可以用... 3. 到 資料庫程式設計區去發問, 說清楚你的問題, 你會得到更多的幫助... 當然, 如果可以的話先做1,2 也許就解決了....據我經驗, 在區域網路內抓經過索引的 2000 筆資料字典通常不會超過 1 秒, 也許時間是花在連接資料庫上...
rowater
一般會員


發表:11
回覆:19
積分:6
註冊:2004-08-30

發送簡訊給我
#18 引用回覆 回覆 發表時間:2005-08-04 12:53:38 IP:211.23.xxx.xxx 未訂閱
我想到這裡應該結案了 感謝各位的寶貴意見 很可惜 分數只能給一個人 所以把分數給寫了程式的malanlk
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#19 引用回覆 回覆 發表時間:2005-08-04 23:39:14 IP:61.64.xxx.xxx 未訂閱
引言: 我想到這裡應該結案了 感謝各位的寶貴意見 很可惜 分數只能給一個人 所以把分數給寫了程式的malanlk
分數不是重點,重要的是大家都經由討論,學到了東西
系統時間:2024-03-29 17:33:58
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!