一初級應用篇
資源文件一般為擴展名為res的文件在VC中資源文件用得非常普遍但Delphi在其聯機幫助中對資源文件沒作什麼介紹其實利用其自帶的資源編譯工具BRCCEXE(一般位於\Delphi\BIN目錄下)我們完全可以做出跟VC一樣效果的文件來
資源文件最大的好處是能將一些在必要時才調用的文件跟可執行文件一起編譯生成一個文件這樣做最大的好處就是使外部文件免遭破壞例如在一條程序中你要臨時調用一幅圖片一般作法是把圖片放在某一路徑下(通常是主程序所在路徑)但如果用戶路徑誤刪你的圖片文件則可能使程序找不到相應文件而出錯崩潰另外如果你想自己的程序界面美觀想用一些自定義光標也要用到資源文件
資源文件的使用步驟為
編寫rc腳本文本
用記事本或其它文本編輯器編寫一個擴展名為rc的文件例如
mycur cursor movecur //加入光標
mypic Bitmap WaterBMP //加入位圖
mywav WAVE happywav //加入聲音
myAVI AVI EPOENAVI //加入視頻
myIco ICON CJTICO //加入圖標
格式分別為在資源文件中的名稱>類型>實際文件名稱例如上面第一行定義一個名為mycur的光標實際名稱為加入光標movecur
將rc文件編譯成res資源文件
將腳本文件和實際文件拷到BrccEXE所在目錄執行DOS命令格式為Brcc 腳本文件(回車)例如有一名為myfirstrc的腳本文件則執行 Brcc myfirstrc(回車)即可如果你是懶人也可新建一批處理文件內容只有一行Brcc mufistrc(因為Delphi安裝後一般會在自動批處理文件中指明搜索路徑的)如果編譯成功則會生成一個結尾為res的文件這個文件就是我們需要的資源文件
在Delphi單元中加入資源文件
將生成的res資源文件拷貝到你所編程序的路徑下在單元文件{$R *DFM}後加上一句{$R mufirstres}則將res文件加入去編譯後資 源文件即已包含在可執行文件中了若你有多個資源文件也按上法依次加入
在Delphi程序中調用資源文件
資源文件在Delphi中的關鍵字為hinstance下面給出具體用法
<>光標的調用
首先在程序中定義一個值大於的常量因為Delphi本身用負來索引默認的光標所以我們制定的光標應從表面上開始索引然後在窗口的Oncreat事件中添加以下代碼
screencursor[]:=Loadcursor (hinstancemycur);
其中為大於的常量mycur為光標在資源文件中的名字如果希望在其他控件上使用定制光標例如Panel控件只需在程序的適當處加入以下代碼
Panelcursor:=;
<>位圖的調用
新建一項工程添加一Timage控件在需要顯示的地方寫以下代碼
Var mymap:Hbitmap;
begin
mymap:=LoadBitmap(hinstancemypic);
ImagepictureBitmapHandle:=mymap
end;
其中mypic為位圖資源文件中的名稱
〈〉AVI文件的調用
新建一工程添加一Animate控件在需要的地方加入
animaterresname:=myAVI;
animaterActive:=true;
其中myAVI為視頻文件在資源文件中的名稱
〈〉調用WAV文件
在uses中加入mmsystm單元以便在程序中播放WAV文件播放時Playsound(pchar(mywav)hinstancesndsync or snd_resource);其中mywav為聲音文件在資源中的名稱
〈〉加入光標
加入光標比較容易只要將res文件加入單元文件中即可但需注意名稱最好取WWW等使第一個字母盡量靠後以免與主程序的圖標順序顛倒這樣一來別人在使用你的程序時如果想選擇其它圖標就有很多選擇了
補充
資源類型除上述類型外還可以字體文件字符串文件等
資源文件不但可以在標准圖形界面下使用還可在控制台下使用
下面我們來試驗一下
新建一工程將唯一的一個Form刪除然後修改工程文件增加一句{$Apptype console}在uses子句中加入mmsystem並將其它引用單元刪掉將Begin和end之間語句刪掉至此我們就可和Turbo PASCAL下編程序一樣且還可以調用windows的API和資源將資源文件{$R myfistres}加入在Begin和end之間寫下
writeln(演示程序按任意鍵開始!);
readln;
playsound(pchar(mywav)hinstancesnd_sync or snd_resource);
writeln(演示結束!);
運行程序將彈出一個標准DOS窗口按任意鍵播放聲音文件是不是很COOL呢!我曾下載過一個播放器在其安裝目錄下我發現有一DOS程序用鼠標雙擊它便彈出一個DOS窗口顯示DOS時代特有的畫圖並有背景音樂!可能就是用這個方法做的
Delphi本身自帶了一個叫Image Editor的工具同樣可以編輯資源文本但和本文的方法比較可得出下表
Image Editor
Brcc
BMP
只支持位色
任意色
光標
黑白兩色
任意色
ICO
只支持位色
任意色
AVI
不支持
支持
WAV
不支持
支持
字體
字符串
其他
不支持
支持
上面說的是直接在程序本身的調用其實資源文件還有其它用法比如說在你的程序攜帶其它文件要用的時候釋放出來
例如: myexe exefile haexe//腳本文件
下面是自定義釋放函數ExtractRes本例中使用如下:
ExtractRes(exefilemyexec:\newexe);
就把haexe以newexe為名字保存到C盤根目錄下了
function TFormExtractRes(ResType ResName ResNewName: string): boolean;
var
Res: TResourceStream;
begin
try
Res := TResourceStreamCreate(Hinstance Resname Pchar(ResType));
try
ResSavetoFile(ResNewName);
Result := true;
finally
ResFree;
end;
except
Result := false;
end;
二中級應用篇
上面我們已經知道如何把一副BMP圖像從資源文件裡面讀出來但是BMP文件太大了JPG文件應用的相對較多那麼如何把JPG圖像讀出來呢?用資源文件加流方式即可具體方法如下:
()MyJpg JPEG MyJPG
()Var
Stream:TStream;
MyJpg:TJpegImage;
Begin
Stream=TResourceStreamCceat(HINSTANCEMyJpgJPEG);
Try
MyJpg:=TJpegImageCreate;
Try
MyJpgLoadfromStream(Stream);
ImagePictureAssignc(MyJpg);
Finally
MyJpgFree;
end;
Finally
StreamFree;
end;
end;
讀取其它圖片文件也是一樣的比如說gif動畫文件當然前提是你有一個gifpas這個單元很多站點都有的可以自己去找找實際應用中我還發現用上面的代碼可以直接顯示資源文件中的ICON和BMP
說到圖形處理實際上還可以用Delphi創建調用純圖標資源的DLL比如說你可以看看超級解霸目錄下的Dll很多就是純圖標資源而已具體方法如下:
():創建一個HiconRES文件這裡不再重復
():新建一文本文件Icondpr內容如下:
library Icon;
{$R IconRES}
begin
end
用Delphi打開編譯即可得到Icondll
():實際調用方法如下:
Private
Hinst:THANDLE;
Var Hicon:THANDLE;
begin
Hinst:=Loadlibrary(Icondll);
If Hinst= Then Exit
Hicon:=Loadicon(HinstPchar(EditText));
If Hicon<> Then ImagePictureIconHandle:=Hicon;
FreeLibrary(Hinst);
end;
如果你的程序想在國際上供使用不同語言的人使用的話用Dll來存放字符資源將是一個好方法因為Dll不象ini文件那樣可以被人隨便修改特別是有時侯如果想保存一些版權信息的話用Dll就再好不過了比如說你准備開發一個漢字簡繁體翻譯器軟件准備提供GbBig碼和英文三種語言菜單給用戶那麼你可以試試用Dll來保存字符資源
我們需要建立三個Dll第一步當然是寫Rc文件舉Gb碼為例內容如下:
/*MyScrc*/
#define IDS_MainForm_Caption
#define IDS_BtnOpen_Caption
#define IDS_BtnSave_Caption
#define IDS_BtnBig_Caption
#define IDS_BtnGb_Caption
#define IDS_BtnHelp_Caption
#define IDS_Help_Shelp
Stringtable
{
IDS_MainForm_Caption漢字簡繁體翻譯器
IDS_BtnOpen_Caption打開文件
IDS_BtnSave_Caption保存文件
IDS_BtnBig_Caption轉換成Big
IDS_BtnGb_Caption轉換成Gb
IDS_BtnHelp_Caption幫助
IDS_Help_Shelp輸入文字或打開文件後按需要點擊按鈕即可轉換!
}
第二步是Brcc編譯為Res文件後用上面的方法得到Dll文件另外兩個Dll用同樣的方法生成下面來應用一下:
新建一個工程放上五個Button:BtnOpenBtnSaveBtnBigBtnGb和BtnHelp還有一個TComboBox:CbSelect用來選擇語言種類的 具體代碼如下:
unit Unit;
interface
private
SHelp: string;
function SearchLanguagePack: TStrings;
procedure SetActiveLanguage(LanguageName: string);
{ Private declarations }
implementation
procedure TFormCbSelectChange(Sender: TObject);
begin
SetActiveLanguage(CbSelectText);//調用相應Dll文件讀取相應字符
end;
procedure TFormFormCreate(Sender: TObject);
begin
CbSelectItemsAddStrings(SearchLanguagePack);//搜索當前目錄下所有的Dll文件名稱
end;
function TFormSearchLanguagePack: TStrings;
var
ResultStrings: TStrings;
DosError: integer;
SearchRec: TsearchRec;
begin
ResultStrings := TStringListCreate;
DosError := FindFirst(ExtractFilePath(ParamStr()) + *dll faAnyFile SearchRec);
while DosError = do
begin
ResultStringsAdd(ChangeFileExt(SearchRecName ));
DosError := FindNext(SearchRec);
end;
FindClose(SearchRec);
Result := ResultStrings;
end;
procedure TFormSetActiveLanguage(LanguageName: string);
var
Hdll: Hmodule;
MyChar: array[] of char;
DllFileName: string;
begin
DllFileName := ExtractFilePath(ParamStr()) + LanguageName + dll;
if not FileExists(DllFileName) then Exit;
Hdll := loadlibrary(Pchar(DllFileName));
Loadstring(hdll MyChar );
SelfCaption := MyChar;
//讀取字符資源表示資源文件中定義的
Loadstring(hdll MyChar );
SelfCaption := MyChar;
Loadstring(hdll MyChar );
BtnOpenCaption := MyChar;
Loadstring(hdll MyChar );
BtnSaveCaption := MyChar;
Loadstring(hdll MyChar );
BtnBigCaption := MyChar;
Loadstring(hdll MyChar );
BtnGbCaption := MyChar;
Loadstring(hdll MyChar );
BtnHelpCaption := MyChar;
Loadstring(hdll MyChar );
SHelp := MyChar;
Freelibrary(hdll);
ApplicationTitle := SelfCaption;
//
BtnOpenVisible := True;
BtnSaveVisible := True;
BtnBigVisible := True;
BtnGbVisible := True;
BtnHelpVisible := True;
//
end;
procedure TFormBtnHelpClick(Sender: TObject);
begin
ApplicationMessageBox(Pchar(SHelp) Http://lovejingtaocom MB_ICONINFORMATION);
end;
end
可能你會說這種方法還不如我自己在程序中直接定義三種具體的值來的方便甚至我自己自定義一個結構好了用不著用DLL那麼麻煩的但是如果你的程序要用的字符很多呢?比如說Windows操作系統本身就有簡體中文繁體中文英文等等版本用Dll的話只要直接替換DLL即可而不用每發行一個版本就打開代碼來修改一次這樣一來可以大大減少工作量和出錯的機會說到這裡再多說一句:Windows系統本身很多Dll帶有了圖片等資源我們可以在程序中直接調用這樣一來我們的EXE也可以減少不少!當然最小的方法是實時生成技術老外曾經寫了一個KB的程序就是利用了這個方法感興趣的朋友可以到http://gocom/lovejingtao/haexe下載
三高級應用篇
Delphi是個很有效率的開發工具但是它有一個缺點就是生成的EXE文件太大一個程序就算只有一個空窗口體積也有KB如果直接用API來寫的話程序體積是小了但是又太繁瑣無法立即看到界面效果根本談不上是可視化開發其實並非魚與熊掌不可兼得利用資源文件我們就可以輕松達到這個目的
在開始之前我們需要一個可以編輯資源文件的工具這類工具很多比如說Resource WorkShop就是非常好的一個如果一時找不到利用VC的編輯器來也是可以的下面我們就以VC的為例示范如何創建一個窗口資源文件運行VC打開菜單File>New將出現一個多項選擇頁我們選擇Files>ResourceTemplate在右邊的File填上DemoLocation選擇保存路徑然後點擊按鈕OK返回VC開發環境
選擇菜單Insert>Resource將出現一個資源類型選擇框我們把鼠標移到Dialog上面不用展開點擊右邊的New即可這時候返回VC開發環境並出現一個只有關閉按鈕和兩個Button的窗體將鼠標選定窗體擊右鍵選擇最後一項Properties將出現一個設置窗口將ID改為MAINFORM(注意:跟下面添加的其它控件的屬性設置方法不同主窗口的ID必須把雙引號寫上去而且名稱必須為大寫否則程序將找不到資源程序會一運行就退出了)Caption改為安裝程序這時候可以立刻看到窗口的標題變成了安裝程序把Styles的Minimize box選上More Styles的Center勾上使程序運行時的位置居中當然你也可以設置它的坐標其它保留默認值即可回到開發環境在控件框裡面分別選擇一個Static Text一個Edit Box一個Button和一個Group Box添加到窗體上面把它們按照自己的愛好排列整齊然後逐個修改它們的屬性方法就是按照上面說的選定控件後擊右鍵選擇最後一項Properties在出現的屬性框裡面修改其中屬性如下:Group Box的Caption屬性清空Static Text的Caption屬性改為請選擇安裝目錄:Edit Box的ID改為第一個Button的ID為Caption屬性為選擇第二個Button的ID為Caption屬性為安裝第三個Button的ID為Caption屬性為退出為了使程序更加完美我們為它再添加一個菜單IDR_MENU選擇Insert>Resource>Menu我們這裡只簡單添加一項文件>退出其中退出的ID為然後在主窗口的屬性Menu設定為IDR_MENU即可
為了使程序更加美觀我們再添加一個小圖標同時這也將是我們程序的圖標選擇Insert>Resource>Icon>Import選擇一個圖標文件並將它的ID設置為MAINICON(注意:必須把雙引號寫上而且字母為大寫)為窗口添加一個Picture控件並設置它的屬性Type:IconImage下拉選擇剛才的圖標MainIcon即可
如果你想為程序在鼠標添加一些信息也是可以的選擇Insert>Resource>Version即可
到這裡我們已經完成了一個簡單的安裝程序的窗體設計實際上我們現在就可以在Delphi中調用它了我們先把勞動成果保存起來選擇File>Save As在文件類型裡選擇bit Resource File(res)保存為Demores文件大小大約為KB
新建一個擴展名為dpr的文本文件MyDemoDpr鍵入如下代碼:
Uses WindowsMessages;
{$R DemoRes}
function MainDialogProc(DlgWin:hWnd;DlgMessage:UINT;DlgWParam:WPARAM;DlgLParam:LPARAM):integer;stdcall;
begin
Result := ;
case DlgMessage of
WM_Close:
begin
PostQuitMessage();
Exit;
end;
end;
end;
begin
DialogBox(hInstance MAINFORM @MainDialogProc);
end
用Delphi打開它編譯一次即可產生一個大小為KB的EXE是不是很小!實際上你甚至只用一行代碼就把它Show出來不過程序無法關閉而已
Uses Windows;
{$R DemoRes}
function MainDialogProc: integer;
begin
Result := ;
end;
begin
DialogBox(hInstance MAINFORM @MainDialogProc);
end
上面的程序只不過是一個空窗口而已現在我們來寫代碼響應按下相應按鈕響應的事件完整代碼如下:
program MyDemo;
uses Windows Messages shlobj;
const
ID_Edit = ;
ID_Selet = ;
ID_Setup = ;
ID_Quit = ;
ID_Exit = ;
{$R DemoRes}
var
MainWin: HWND;
function My_Gettext: string;
var
Textlength: Integer;
Text: PChar;
s: string;
begin
TextLength := GetWindowTextLength(GetDlgItem(MainWin ID_Edit));
GetMem(Text TextLength + );
GetWindowText(GetDlgItem(MainWin ID_Edit) Text TextLength + );
s := text;
FreeMem(Text TextLength + );
Result := s;
end;
function Getmyname: string;
var
i j: integer;
begin
J := ;
for i := to length(ParamStr()) do
if ParamStr()[i] = \ then J := I;
Result := copy(ParamStr() J + length(ParamStr()) J);
end;
function SelectDirectory(handle: hwnd; const Caption: string; const Root:WideString;outDirectory:string): Boolean;
var
lpbi: _browseinfo;
buf: array[MAX_PATH] of char;
id: ishellfolder;
eaten att: cardinal;
rt: pitemidlist;
initdir: pwidechar;
begin
result := false;
lpbihwndOwner := handle;
lpbilpfn := nil;
lpbilpszTitle := pchar(caption);
lpbiulFlags := BIF_RETURNONLYFSDIRS + BIF_EDITBOX;
SHGetDesktopFolder(id);
initdir := pwchar(root);
idParseDisplayName( nil initdir eaten rt att);
lpbipidlRoot := rt;
getmem(lpbipszDisplayName MAX_PATH);
try
result := shgetpathfromidlist(shbrowseforfolder(lpbi) buf);
except
freemem(lpbipszDisplayName);
end;
if result then
begin
directory := buf;
if length(directory) <> then directory := directory + \;
end;
end;
function MainDialogProc(
DlgWin: hWnd;
DlgMessage: UINT;
DlgWParam: WPARAM;
DlgLParam: LPARAM
)
: integer; stdcall;
var
MyIcon: HICON;
Sdir: string;
begin
Result := ;
case DlgMessage of
WM_INITDIALOG:
begin
MyIcon := LoadIcon(hInstance MainIcon);
SetClassLONG(DlgWin GCL_HICON MyIcon);
MainWin := DlgWin;
end;
WM_Close:
begin
PostQuitMessage();
Exit;
end;
WM_COMMAND:
case LOWORD(DlgWParam) of
ID_Selet:
begin
if SelectDirectory(DlgWin 請選擇安裝目錄 Sdir)
then SendMessage(GetDlgItem(DlgWin ID_Edit) WM_SETTEXT lParam(pChar(Sdir)));
end;
ID_Setup:
begin
if My_Gettext = then
begin
MessageBox(DlgWin 請先選擇安裝文件夾! 信息 MB_ICONINFORMATION + MB_OK);
Exit;
end;
CopyFile(pchar(ParamStr()) pchar(My_Gettext + Getmyname) false);
MessageBox(DlgWin 安裝完畢! 信息 MB_ICONINFORMATION + MB_OK);
PostQuitMessage();
Exit;
end;
ID_Quit:
begin
PostQuitMessage();
EXIT;
end;
ID_Exit:
begin
if MessageBox(DlgWin 你點擊了菜單退出你確定退出程序嗎? 信息 MB_ICONQUESTION + MB_OKCANCEL) = IDOK then
PostQuitMessage();
Exit;
end;
end;
end;
end;
begin
DialogBox(hInstance MAINFORM @MainDialogProc);
end
From:http://tw.wingwit.com/Article/program/Delphi/201311/24946.html