您当前位置:闸机网 >> 相关资源 >> delphi >> 浏览文章      |关键词: SendMessage delphi

封装应用程序的资源(3)

2011-10-31 16:03:59 互联网 未知 【字体:

   三、高级应用篇
   Delphi是个很有效率的开发工具,但是它有一个缺点就是生成的EXE文件太大。一个程序就算只有一个空窗口
体积也有286KB。如果直接用API来写的话程序体积是小了,但是又太繁琐,无法立即看到界面效果,根本谈不上是
可视化开发。其实并非“鱼与熊掌不可兼得”,利用资源文件我们就可以轻松达到这个目的。
   在开始之前,我们需要一个可以编辑资源文件的工具。这类工具很多,比如说Resource WorkShop就是非常好
的一个。如果一时找不到,利用VC的编辑器来也是可以的。下面我们就以VC的为例示范如何创建一个窗口资源文
件。
   运行VC,打开菜单“File/New”,将出现一个多项选择页。我们选择“Files/Resource Template”,在右边
的File填上Demo,Location选择保存路径,然后点击按钮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改为10001,第一个Button的ID为10002,Caption属
性为“选择”,第二个Button的ID为10003,Caption属性为“安装”,第三个Button的ID为10004,Caption属性为
“退出”。
   为了使程序更加完美,我们为它再添加一个菜单IDR_MENU1。选择“Insert/Resource/Menu”,我们这里只简
单添加一项“文件/退出”,其中“退出”的ID为10005。然后在主窗口的属性Menu设定为IDR_MENU1即可。
   为了使程序更加美观,我们再添加一个小图标,同时这也将是我们程序的图标。选择
“Insert/Resource/Iconv/Import”,选择一个图标文件,并将它的ID设置为"MAINICON"(注意:必须把双引号写
上而且字母为大写),为窗口添加一个Picture控件并设置它的属性Type:Icon,Image下拉选择刚才的图标MainIcon
即可。
   如果你想为程序在鼠标添加一些信息也是可以的。选择“Insert/Resource/Version”即可。到这里我们已经
完成了一个简单的“安装程序”的窗体设计,实际上我们现在就可以在Delphi中调用它了。我们先把“劳动成果”
保存起来,选择“File/Save As”,在文件类型里选择“32-bit Resource File(.res)”保存为“Demo.res”,文
件大小大约为2.65KB。
   新建一个扩展名为dpr的文本文件MyDemo.Dpr,键入如下代码:
   Uses Windows,Messages;
   {$R Demo.Res}
   function MainDialogProc(
    DlgWin: hWnd;
    DlgMessage: UINT;
    DlgWParam: WPARAM;
    DlgLParam: LPARAM
    )
    : integer; stdcall;
   begin
    Result := 0;
   case DlgMessage of
    WM_Close:
      begin
       PostQuitMessage(0);
       Exit;
      end;
    end;
   end;
   begin
    DialogBox(hInstance, 'MAINFORM', 0, @MainDialogProc);
   end.
   用Delphi打开它编译一次即可产生一个大小为19KB的EXE。是不是很小?!实际上,你甚至只用一行代码就把
它Show出来,不过程序无法关闭而已:
   Uses Windows;
   {$R Demo.Res}
   function MainDialogProc: integer;
   begin
    Result := 0;
   end;
   begin
    DialogBox(hInstance, 'MAINFORM', 0, @MainDialogProc);
   end.
   上面的程序只不过是一个空窗口而已,现在我们来写代码响应按下相应按钮响应的事件。完整代码如下:
   program MyDemo;
   uses Windows, Messages, shlobj;
   const
    ID_Edit = 10001;
    ID_Selet = 10002;
    ID_Setup = 10003;
    ID_Quit = 10004;
    ID_Exit = 10005;
   {$R Demo.Res}
   var
    MainWin: HWND;
  
   function My_Gettext: string;
   var
    Textlength: Integer;
    Text: PChar;
    s: string;
   begin
    TextLength := GetWindowTextLength(GetDlgItem(MainWin, ID_Edit));
    GetMem(Text, TextLength + 1);
    GetWindowText(GetDlgItem(MainWin, ID_Edit), Text, TextLength + 1);
    s := text;
    FreeMem(Text, TextLength + 1);
    Result := s;
   end;
  
   function Getmyname: string;
   var
    i, j: integer;
   begin
    J := 3;
    for i := 1 to length(ParamStr(0)) do
     if ParamStr(0)[i] = '' then J := I;
    Result := copy(ParamStr(0), J + 1, length(ParamStr(0)) - J);
   end;
  
   function SelectDirectory(handle: hwnd; const Caption: string; const Root: WideString; out
Directory: string): Boolean;
   var
    lpbi: _browseinfo;
    buf: array[0..MAX_PATH] of char;
    id: ishellfolder;
    eaten, att: cardinal;
    rt: pitemidlist;
    initdir: pwidechar;
   begin
    result := false;
    lpbi.hwndOwner := handle;
    lpbi.lpfn := nil;
    lpbi.lpszTitle := pchar(caption);
    lpbi.ulFlags := BIF_RETURNONLYFSDIRS + BIF_EDITBOX;
    SHGetDesktopFolder(id);
    initdir := pwchar(root);
    id.ParseDisplayName(0, nil, initdir, eaten, rt, att);
    lpbi.pidlRoot := rt;
    getmem(lpbi.pszDisplayName, MAX_PATH);
    try
     result := shgetpathfromidlist(shbrowseforfolder(lpbi), buf);
    except
     freemem(lpbi.pszDisplayName);
    end;
    if result then
     begin
      directory := buf;
      if length(directory) <> 3 then directory := directory + '';
     end;
   end;
  
   function MainDialogProc(
    DlgWin: hWnd;
    DlgMessage: UINT;
    DlgWParam: WPARAM;
    DlgLParam: LPARAM
    )
    : integer; stdcall;
   var
    MyIcon: HICON;
    Sdir: string;
   begin
    Result := 0;
    case DlgMessage of
     WM_INITDIALOG:
      begin
       MyIcon := LoadIcon(hInstance, 'MainIcon');
       SetClassLONG(DlgWin, GCL_HICON, MyIcon);
       MainWin := DlgWin;
      end;
     WM_Close:
      begin
       PostQuitMessage(0);
       Exit;
      end;
     WM_COMMAND:
      case LOWORD(DlgWParam) of
  
       ID_Selet:
        begin
         if SelectDirectory(DlgWin, '请选择安装目录', '', Sdir)
          then SendMessage(GetDlgItem(DlgWin, ID_Edit), WM_SETTEXT, 0, lParam(pChar
(Sdir)));
        end;
       ID_Setup:
        begin
         if My_Gettext = '' then
          begin
           MessageBox(DlgWin, '请先选择安装文件夹!', '信息', MB_ICONINFORMATION + MB_OK);
           Exit;
          end;
         CopyFile(pchar(ParamStr(0)), pchar(My_Gettext + Getmyname), false);
         MessageBox(DlgWin, '安装完毕!', '信息', MB_ICONINFORMATION + MB_OK);
         PostQuitMessage(0);
         Exit;
        end;
       ID_Quit:
        begin
         PostQuitMessage(0);
         EXIT;
        end;
       ID_Exit:
        begin
         if MessageBox(DlgWin, '你点击了菜单“退出”,你确定退出程序吗?', '信息',
MB_ICONQUESTION + MB_OKCANCEL) = IDOK then
          PostQuitMessage(0);
         Exit;
        end;
      end;
    end;
   end;
   begin
    DialogBox(hInstance, 'MAINFORM', 0, @MainDialogProc);
   end.
 
 

相关栏目:

网友评论: