庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>程序设计>汇编语言>技巧教程>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

使用DLL中的资源

 作者:本站收集   日期:2005-8-1 15:50:32
字号选择〖 〗/ 双击滚屏 单击停止   

   本文相关的例子:请这里下载

    长久以来,把界面的信息单独存为一个DLL一直是很多商业软件的作法,比如VC、InstallShield等等,这样做的好处是,如果要做多语言版本,只要写出不同的DLL来,在主程序中使用时调用不同的DLL就行,当然现在还有一种流行的方法是使用INI,读存也非常方便。最近在网上转了转,发现竟没有一篇关于如何读取DLL中资源的文章,虽然Iczelion的Win32ASM教程中第26课"Splash Screen"讲到了读取DLL中的图片,但不知是这种问题太简单了还是其它什么原因,Iczelion没有讲解这段代码的意思,于是乎决定写一篇关于DLL资源读取的文章,望大家不要$%@%@^%@%。
  我们看一下这些函数:
  HBITMAP LoadBitmap(HINSTANCE hInstance,LPCTSTR lpBitmapName)
  HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName)
  HMENU LoadMenu(HINSTANCE hInstance,LPCTSTR lpMenuName)
  int LoadString(HINSTANCE hInstance,UINT uID,LPTSTR lpBuffer,int BufferMax)

  int DialogBoxParam(
    HINSTANCE hInstance,   // handle to application instance
    LPCTSTR lpTemplateName,   // identifies dialog box template
    HWND hWndParent,   // handle to owner window
    DLGPROC lpDialogFunc,   // pointer to dialog box procedure  
    LPARAM dwInitParam    // initialization value
   );

  HWND CreateDialogParam(
    HINSTANCE hInstance,   // handle to application instance
    LPCTSTR lpTemplateName,   // identifies dialog box template
    HWND hWndParent,   // handle to owner window
    DLGPROC lpDialogFunc,   // pointer to dialog box procedure  
    LPARAM dwInitParam    // initialization value
   );
  这些都是常用的读取资源的函数,它们都有一个共同点:第一个参数需要的是要读取的包含资源的程序的模块句柄,那么,关键就在这个句柄,因为我们在读取本身程序资源的时候,肯定是提供用GetModuleHandle函数获得的句柄,这个句柄就是当前程序的实例句柄,如果要读取DLL中的资源,很显然的,我们需要提供DLL的句柄,那么这个DLL句柄怎么得到呢?很简单,我们在使用LoadLibrary函数时,返回的值就是读取的DLL的句柄,于是,我们读取DLL中的资源,只需要这样:
  invoke LoadLibrary,DLL_FILENAME
  mov DLL_HANDLE,eax
  invoke LoadBitmap,DLL_HANDLE,BITMAP_ID
  invoke LoadIcon,DLL_HANDLE,ICON_ID
  invoke LoadMenu,DLL_HANDLE,MENU_ID
  invoke LoadString,DLL_HANDLE,STRING_ID,StrBuffer,sizeof StrBuffer
  invoke DialogBoxParam,DLL_HANDLE,DLG_NAME,hParent,DlgProc,lParam
  其它的函数就不多说,着重讲一下DialogBoxParam与CreateDialogParam,因为其它函数不需要回调函数,读取之后句柄可以一直到程序结束才释放。我们讨论的就是DialogBoxParam与CreateDialogParam回调函数的方法。
  我曾上过当,把DialogBoxParam与CreateDialogParam的回调函数写在主程序中,相信有很多的朋友也是写在主程序中,然后直接把回调过程地址传给DialogBoxParam与CreateDialogParam,其实,这是一种错误的方法,正确的方法是,我们必须把回调函数写在对话框资源本身的DLL中,在主程序用DialogBoxParam与CreateDialogParam显示对话框时提供DLL中的回调函数地址,当然,对纯提供资源的DLL,它们不同的只是界面语言文字,这个把回调函数写在主程序中更加好,如果是插件呢?如果主程序使用了很多的DLL呢?对于插件而言,回调函数是必须在DLL中的,主程序使用很多DLL时,把回调函数都写在主程序中,就算能正常运行,但是DLL有变动,就算是一个小修改,也不得不重新更改主程序,所以,我的建议是:除了纯资源DLL,编写DLL时,对话框的回调函数一定要写在DLL本身中。
  可是,如果在主程序中就这样子使用DLL对话框,那么,DLL对话框的回调函数就必须引出,这样主程序才能获得回调函数地址,就像这样:
  invoke GetProcAddress,DLL_HANDLE,DlgProcName
  invoke DialogBoxParam,DLL_HANDLE,DLG_NAME,hWnd,eax,NULL
  ;DlgProcName就是DLL中引出的回调函数
  这段代码看起来非常简洁,也完全能正常工作,可是想一想,如果在程序其它的地方要不停的使用DLL中的对话框,不仅上述工作很烦人,更烦的是,我们必须把所有的回调函数全部引出,其实我们完全可以这样做:
  在DLL中编写一个函数LoadDialog,如下:
  LoadDialog proc hInstance,hWnd,ID
    .if ID==100
      mov eax,offset DlgProc0
    .elseif ID==101
      mov eax,offset DlgProc1
    .elseif ID==102
      mov eax,offset DlgProc2
    .elseif ID==103
      mov eax,offset DlgProc3
    .end if
    invoke DialogBoxParam,hInstance,ID,hWnd,eax,NULL
   ret
  LoadDialog endp
  ;DlgProc0、DlgProc1、DlgProc2、DlgProc3都是DLL中的回调函数
那么,我们在主程序中调用时就只需这样:
  invoke GetProcAddress,DLL_HANDLE,DlgProcName ;DlgProcName="LoadDialog"
  mov LoadDialog,eax
  push ID
  push hWnd
  push DLL_HANDLE
  call [LoadDialog]
  只需在程序开头获取到LoadDialog的地址后,在任何地方调用不同的对话框只需要提供不同的ID即可,就像这样:
  push 101
  push hWnd
  push DLL_HANDLE
  call [LoadDialog]
  这样做,不仅DLL中的回调函数不需要引出,在主程序中使用时也比每次读回调函数地址方便得多。

上一篇:MASM的反反汇编技术    下一篇:API参数说明符前缀详解  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-8-1 15:50:32
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿