精华内容
下载资源
问答
  • 用于解决I社游戏卡慢的问题,其它的类型的游戏也可以,但是个人建议用在I社的游戏上
  • __declspec(dllexport)与__declspec(dllimport) : DLL内的关键字,即导出与导入。他们是将DLL内部的类与函数以及数据导出与导入时使用的。
    • __declspec(dllexport)与__declspec(dllimport)
      使用DLL的关键字,即导出与导入。他们是将DLL内部的类与函数以及数据导出与导入时使用的。(一般有第三方提供的dll时会使用如上关键字)
    展开全文
  • lucene的应用程序扩展

    2010-08-09 09:45:35
    这里是我搜集的一些关于asp.net 所需要的 lucene.net 的一些*.dll 应用程序扩展
  • 在“应用程序扩展”中,可以设定对特定扩展名的请求的处理方式,比如.aspx,.ascx,.asmx,.ashx这几个都设定为由“c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll”来处理。我们可以添加一个新的...

    在“应用程序扩展”中,可以设定对特定扩展名的请求的处理方式,比如.aspx,.ascx,.asmx,.ashx这几个都设定为由“c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll”来处理。我们可以添加一个新的扩展名,如.happy,也将它交给“c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll”来处理。

    在“应用程序扩展”中,添加新的映射时,扩展名一栏不能直接填“.*”,而只能填写形如“.aspx”之类具体的扩展名,这就是“通配符应用程序映射”的用处了。插入一个“通配符应用程序映射”后,比如,插入“c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll”,则所有扩展名的请求都会由“c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll”来处理。

    当我们在“应用程序扩展”中添加了对应于.happy扩展名的映射,或者干脆直接添加了“通配符应用程序映射”后,在地址栏中直接输入形如“http://localhost/WebApplication1/haha.happy”的请求时,还是会报错,因为“c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll”默认也没有提供对.happy这种请求的处理,所以,我们还需要在web.config文件中添加用来处理.happy请求的handler,比如:<httpHandlers><add verb="*" path="*.happy" validate="false" type="WebApplication1.MyHandler, WebApplication1"/> </httpHandlers>当然,其中的WebApplication1.MyHandler这个类是需要我们自己写的,实现IHttpHandler接口即可。

    转载于:https://www.cnblogs.com/TSPWater/archive/2013/01/16/2863055.html

    展开全文
  • d3d8应用程序扩展

    2010-01-09 17:41:50
    d3d8.dll,Microsoft Direct3D DLL for DirectX。d3d8.dll是DirectX的3D显示部分控制模块,在DirectX 中被安装。
  • windows mobile 部署应用程序 之 setupdll.dll 扩展cab 的行为 1,我们发布windows mobile 程序时,一般要制作*.cab 去在设备安装我们应用程序,那如何在安装时去做一些特殊的行为呢 e.g. 拷贝程序的快捷...

    windows mobile 部署应用程序 之  setupdll.dll 扩展cab 的行为



    1,我们发布windows mobile 程序时,一般要制作*.cab 去在设备安装我们应用程序,那如何在安装时去做一些特殊的行为呢
         e.g.   拷贝程序的快捷方式去多个目录, 修改文件名称,创建日志文件 etc.
        cab 文件运行时,首先从cab文件中解压出所要安装的文件,如果文件中有setupdll.dll  则setupdll.dll会被隐式的加载,并调用Install_Init,Install_Exit,Uninstall_Init,Uninstall_Exit  etc. 函数, 我们可以在编写自己的setupdll.dll 在

    Install_Init,Install_Exit,Uninstall_Init,Uninstall_Exit   函数体中实现自己的特殊操作。

    下面是托管和本地代码的实现
    C#:

       using System.Configuration.Install;

     

     


        public partial class CustomInstaller : Installer
       {
            public CustomInstaller()
             {
                InitializeComponent();
                this.BeforeInstall +=
                 new InstallEventHandler(CustomInstaller_BeforeInstall);
               }
            void CustomInstaller_BeforeInstall(object sender, InstallEventArgs e)
             {
             //这里写自己的特殊操作
             }
        }
    C++:
    // Function Name: Install_Init
    //
    // Purpose: processes the push message.
    //
    // Arguments:
    //    IN HWND hwndParent  handle to the parent window
    //    IN BOOL fFirstCall  indicates that this is the first time this function is being called
    //    IN BOOL fPreviouslyInstalled  indicates that the current application is already installed
    //    IN LPCTSTR pszInstallDir  name of the user-selected install directory of the application
    //
    // Return Values:
    //    codeINSTALL_INIT
    //    returns install status
    //
    // Description: 
    //    The Install_Init function is called before installation begins.
    //    User will be prompted to confirm installation.
    // **************************************************************************
    SETUP_API codeINSTALL_INIT Install_Init(
        HWND        hwndParent,
        BOOL        fFirstCall,     // is this the first time this function is being called?
        BOOL        fPreviouslyInstalled,
        LPCTSTR     pszInstallDir
        )
    {
    //这里写自己的特殊操作
    }

    转载于:https://www.cnblogs.com/sea918/archive/2010/03/03/1677371.html

    展开全文
  • Delphi插件创建、调试与使用应用程序扩展 翻译 : MiracleZ 有没有使用过Adobe Photoshop?如果用过,你就会对插件的概念比较熟悉。对外行人来说,插件仅仅是从外部提供给应用程序的代码块而已(举个例子来说,在一...

    Delphi插件创建、调试与使用应用程序扩展

    翻译 : MiracleZ
      有没有使用过Adobe Photoshop?如果用过,你就会对插件的概念比较熟悉。对外行人来说,插件仅仅是从外部提供给应用程序的代码块而已(举个例子来说,在一个DLL中)。一个插件和一个普通DLL之间的差异在于插件具有扩展父应用程序功能的能力。例如,Photoshop本身并不具备进行大量的图像处理功能。插件的加入使其获得了产生诸如模糊、斑点,以及其他所有风格的奇怪效果,而其中任何一项功能都不是父应用程序自身所具有的。
    对于图像处理程序来说这很不错,可是为什么要花偌大的力气去完成支持插件的商业应用程序呢?假设,我们举个例子,你的应用程序要产生一些报表。你的客户肯定会一直要求更新或者增加新的报表。你可以使用一个诸如Report Smith的外部报表生成器,这是个不怎么样的解决方案,需要发布附加的文件,要对用户进行额外的培训,等等。你也可以使用QuickReport,不过这会使你身处版本控制的噩梦之中——如果每改变一次字体你就要Rebuild你的应用程序的话。
      然而,只要你把报表做到插件中,你就可以使用它。需要一个新的报表吗?没问题,只要安装一个DLL,下次应用程序启动时就会看见它了。另外一个例子是处理来自外部设备(比如条形码扫描器)的数据的应用程序,为了给用户更多的选择,你不得不支持半打的各种设备。通过将每种设备接口处理例程写成插件,不用对父应用程序作任何变动就可以获得最大程度的可伸缩性。
     
    入门

     
      在开始写代码之前最重要的事情就是搞清楚你的应用程序到底需要扩展哪些功能。这是因为插件是通过一个特定的接口与父应用程序交互的,而这个接口将根据你的需要来定义。在本文中,我们将建立3个插件,以便展示插件与父应用程序相交互的几种方式。
      我们将把插件制作成DLL。不过,在做这项工作之前,我们得先制作一个外壳程序来载入和测试它们。图1显示的是加载了第一个插件以后的测试程序。第一个插件没有完成什么大不了的功能,实际上,它所做的只是返回一个描述自己的字符串。不过,它证明了很重要的一点——不管有没有插件应用程序都可以正常运行。如果没有插件,它就不会出现在已安装的插件列表中,但是应用程序仍然可以正常的行使功能。
     
    图1:插件测试外壳程序


      我们的插件外壳程序与普通应用程序之间的唯一不同就在于工程源文件中出现在uses子句中的Sharemem单元和加载插件文件的代码。任何在自身与子DLL之间传递字符串参数的应用程序都需要Sharemem单元,它是DelphiMM.dll(Delphi提供该文件)的接口。要测试这个外壳,需要将DelphiMM.dll文件从Delphi\Bin目录复制到path环境变量所包含的路径或者应用程序所在目录中。发布最终版本时也需要同时分发该文件。
      插件通过LoadPlugins过程载入到这个测试外壳中,这个过程在主窗口的FormCreate事件中调用,见图2。该过程使用FindFirst和FindNext函数在应用程序所在目录中查找插件文件。找到一个文件以后,就使用图3所示的LoadPlugins过程将其载入。
    { 在应用程序目录下查找插件文件 }
    procedure TfrmMain.LoadPlugins;
    var

      sr: TSearchRec;
      path: string;

      Found: Integer;
    begin

      path := ExtractFilePath(Application.Exename);
      try

      Found := FindFirst(path + cPLUGIN_MASK, 0, sr);
      while Found = 0 do begin
      LoadPlugin(sr);

      Found := FindNext(sr);
      end;

      finally
      FindClose(sr);

      end;
    end;

     
    图 2: 寻找插件

    { 加载指定的插件 DLL. }
    procedure TfrmMain.LoadPlugin(sr: TSearchRec);
    var

      Description: string;
      LibHandle: Integer;

      DescribeProc: TPluginDescribe;
    begin

      LibHandle := LoadLibrary(Pchar(sr.Name));
      if LibHandle <> 0 then
      begin

      DescribeProc := GetProcAddress(LibHandle,
      cPLUGIN_DESCRIBE);

      if Assigned(DescribeProc) then
      begin

      DescribeProc(Description);
      memPlugins.Lines.Add(Description);
      end

      else
      begin

      MessageDlg('File "' + sr.Name +
    '" is not a valid plug-in.',
      mtInformation, [mbOK], 0);
      end;

      end
      else

      MessageDlg('An error occurred loading the plug-in "' +
      sr.Name + '".', mtError, [mbOK], 0);
    end;

     
    图 3: 载入插件

      LoadPlugin方法展示了插件机制的核心。首先,插件被写成DLL。其次,通过LoadLibrary API它被动态的加载。一旦DLL被加载,我们就需要一个访问它所包含的过程和函数的途径。API调用GetProcAddress提供这种机制,它返回一个指向所需例程的指针。在我们这个简单的演示中,插件仅仅包含一个名为DescribePlugin的过程,由常数cPLUGIN_DESCRIBE指定(过程名的大小写非常重要,传递到GetProcAddress的名称必须与包含在DLL中的例程名称完全一致)。如果在DLL中没有找到请求的例程,GetProcAddree将返回nil,这样就允许使用Assigned函数测定返回值。
      为了以一种易用的方式存储指向一个函数的指针,有必要为用到的变量创建一个特定的类型。注意,GetProcAddress的返回值被存储在一个变量中,DescribeProc,属于TpluginDescribe类型。下面是它的声明:
    type

      TPluginDescribe = procedure(var Desc: string); stdcall;
      由于过程存在于DLL内部,它通过标准调用转换编译所有导出例程,因此需要使用stdcall指示字。这个过程使用一个var参数,当过程返回的时候它包含插件的描述。
      要调用刚刚获得的过程,只需要使用保存地址的变量作为过程名,后面跟上任何参数。就我们的例子而言,声明:
    DescribeProc(Description)

    将会调用在插件中获得的描述过程,并且用描述插件功能的字符串填充Description变量。
     
    构造插件

     
      我们已经创建好了父应用程序,现在该轮到创建我们希望加载的插件了。插件文件是一个标准的Delphi DLL,所以我们从Delphi IDE中创建一个新DLL工程,保存它。由于导出的插件函数将用到字符串参数,所以要在工程的uses子句中把Sharemen单元放在最前面。图4列出的就是我们这个简单插件的工程源文件。
    uses

      Sharemem, SysUtils, Classes,
      main in 'main.pas';

     
    {$E plg.}

     
    exports

      DescribePlugin;
     

    begin
     

    end.
     
    图 4: 简单插件的工程源文件
      虽然插件是一个DLL文件,但是没有必要一定要给它一个.DLL的扩展名。实际上,一个原因就足以让我们有理由改变扩展名:当父应用程序寻找要加载的文件时,新的扩展名可以作为特定的文件掩模。通过使用别的扩展名(我们的例子使用了*.plg),你可以在一定程度上确信应用程序只会载入相应的文件。编译指示字$X可以实现这个改变,也可以通过Project Options对话框的Application页来设置扩展名。
      第一个例子插件的代码是很简单的。图5显示了包含在一个新单元中的代码。注意,DescribePlugin原型与外壳应用程序中的TpluginDescribe类型相一致,使用附加的export保留字指定该过程将被导出。被导出的过程名称也将会出现在主工程源代码的exports段中(在图4中列出)。
    unit main;

     
    interface

     
      procedure DescribePlugin(var Desc: string);
      export; stdcall;

     
    implementation

     
    procedure DescribePlugin(var Desc: string);
    begin

      Desc := 'Test plugin v1.00';
    end;

     
    end.

     
    图 5: 例子插件的主程序

      在测试这个插件之前,要先把它复制到主应用程序的路径下。最简单的办法就是在主目录的子目录下创建插件,然后把输出路径设置为主路径(Project Options对话框的Directories/Conditionals也可以作这个设置)。
     
    调试

     
      现在介绍一下Delphi 3中一个较好的功能:从IDE中调试DLL的能力。在DLL工程中可以通过Run paramaters对话框指定某程序为宿主应用程序,这就是指向将调用DLL的应用程序的路径(在我们这个例子中,就是刚刚创建的测试外壳程序)。然后你就可以在DLL代码中设置断点并且按F9运行它——就像在一个普通应用程序中做的那样。Delphi会运行指定的宿主程序,并且,通过编译带有调试信息的DLL,把你指引到DLL代码内的断点处。
     
    延伸父应用

     
    这个简单的插件不错,不过它不能做什么有用的事情。第二个例子就是纠正这个问题。这个插件的目标就是在父应用程序的主菜单中加入一个项目。这个菜单项目,当被单击时,就会执行插件内的一些代码。图6显示外壳程序的改进版,两个插件都已经加载。在这个版本的外壳程序中,一个名为Plug-in的新菜单项目,被添加到主菜单中。插件会在运行时加入一个菜单项。

    图6:加载了两个插件的外壳程序的改进版
     
      为了实现这个目的,我们必须在插件DLL中定义第二个接口。现有的DLL只导出了一个过程,DescribePlugin。第二个插件将声明一个叫做InitPlugin的过程。不过,在这个过程可以在主应用程序中看到以前,必须修改LoadPlugin来配合它。
    图7所示的代码展示了改进的过程。
    procedure TfrmMain.LoadPlugin(sr: TSearchRec);
    var

      Description: string;
      LibHandle: Integer;

      DescribeProc: TPluginDescribe;
      InitProc: TPluginInit;
    begin

      LibHandle := LoadLibrary(Pchar(sr.Name));
      if LibHandle <> 0 then
      begin

      // 查找 DescribePlugin.
      DescribeProc := GetProcAddress(LibHandle,
      cPLUGIN_DESCRIBE);

      if Assigned(DescribeProc) then
      begin

      // 调用 DescribePlugin.
      DescribeProc(Description);
      memPlugins.Lines.Add(Description);
      // 查找 InitPlugin.

      InitProc := GetProcAddress(LibHandle, cPLUGIN_INIT);
      if Assigned(InitProc) then
      begin

      // 调用 InitPlugin.
      InitProc(mnuMain);

      end;
      end

      else
      begin

      MessageDlg('File "' + sr.Name +
      '" is not a valid plugin.',
      mtInformation, [mbOK], 0);
      end;

      end
      else

      begin
      MessageDlg('An error occurred loading the plugin "' +
      sr.Name + '".', mtInformation, [mbOK], 0);
      end;

    end;
    图 7: 改进过的LoadPlugin方法
      如你所见,当GetProcAddress第一次查找调用描述过程之后,又调用了一次GetProcAddress。这一次,我们要寻找的是常量cPLUGIN_INIT,定义如下:
    const

      cPLUGIN_INIT = 'InitPlugin';
    返回值存储在TpluginInit类型的变量中,定义如下:
    type

      TPluginInit = procedure(ParentMenu: TMainMenu); stdcall;
    当InitPlugin方法被执行时,父应用程序的主菜单被当作一个参数传递给它。这个过程可以按照自己的意愿修改菜单。由于所有GetProcAddress的返回值都用assigned测试,新版本的LoadPlugin过程仍然会加载不包含InitPlugin过程的第一个插件。在这个过程中第一次调用寻找DescribePlugin方法会通过,第二次寻找InitPlugin会无响应失败。
      现在新的接口已经定义好了,可以为新的InitPlugin方法编写代码了。像原先一样,新插件的实现代码存在于一个单独的单元中。图8显示了修改过的包含InitPlugin方法的main.pas。
    unit main;

     
    interface

     
    uses Dialogs, Menus;

     
    type

      THolder = class
      public

      procedure ClickHandler(Sender: TObject);
      end;

     
      procedure DescribePlugin(var Desc: string);
      export; stdcall;

      procedure InitPlugin(ParentMenu: TMainMenu);
      export; stdcall;

     
    var

      Holder: THolder;
     

    implementation
     

    procedure DescribePlugin(var Desc: string);
    begin

      Desc := 'Test plugin 2 - Menu test';
    end;

     
    procedure InitPlugin(ParentMenu: TMainMenu);
    var

      i: TMenuItem;
    begin

      // 创建新菜单项.
      i := NewItem('Plugin &Test', scNone, False, True,
      Holder.ClickHandler, 0, 'mnuTest');
      ParentMenu.Items[1].Add(i);
    end;

     
    procedure THolder.ClickHandler;
    begin

      ShowMessage('Clicked!');
    end;

     
    initialization

      Holder := THolder.Create;
     

    finalization
      Holder.Free;

     
    end.

    图 8: 第二个插件的代码
      很明显,对原始插件的第一个改变就是增加了InitPlugin过程。像原先一样,带有export关键字的原型被加入到单元顶端的列表中,过程名也被加入到工程源代码的exports子句列表中。这个过程使用NewItem函数创建一个新的菜单项,返回值是TmenuItem对象。新菜单项通过下列语句被加入到应用程序主菜单中:
    ParentMenu.Items[1].Add(I);
      在测试外壳主菜单上的Items[1]是菜单项Plug-in,所以这个语句在Plugin菜单条上添加一个叫Plug-in Test的菜单项。
      为了处理对新菜单项的响应,作为它的第五个参数,NewItem可以接受一个TNotifyEvent类型的过程,这个过程将在菜单项被点击时调用。不幸的是,按照定义,这种类型的过程是一个对象方法,然而在我们的插件中并没有对象。如果我们想用通常的指针来指向函数,那么得到的将只会是Delphi编译器的抱怨。所以,唯一的解决办法就是创建一个处理菜单点击的对象。这就是Tholder类的用处。它只有一个方法,是一个叫做ClickHandler的过程。一个叫做Holder的全局变量,在修改过的main.pas的var段中被声明为Tholder类型,并且在单元的initialization段中被创建。现在我们就有一个对象了,我们可以拿它的方法(Holder.ClickHandler)当作NewItem函数的参数。
      搞了这一通,ClickHandler除了显示一个“Clicked!”消息对话框以外什么以没干。也许这不怎么有趣,不过它仍然证明了一点:插件DLL成功的修改了父应用的主菜单,表现了它的新用途。并且如同第一个例子一样,不管这个插件在不在应用程序都能执行。
      由于我们创建了一个对象来处理菜单点击,那么在不再需要这个插件时,就要释放这个对象。修改后的单元中会在finalization段中处理这件事情。Finalization端时与initialization段相对应的,如果前面有一个initialization段,那么在应用程序终止时finalization段一定会得到执行。把下面的语句
    Holder.Free

    加到finalization段中,以确保Holder对象会被正确的释放。
      显而易见,虽然这个插件只是修改了外壳应用的主菜单,但是它可以轻易地操纵传递到InitPlugin过程中的任何其他对象。如果有必要,插件也可以打开自己的对话框,向列表框(List boxes)和树状视图(tree views)中添加项目,或者在画布(canvas)中绘画。
     
    事件驱动的插件

     
      到现在为止我们所描述的技术可以产生一种通用的扩展应用程序的方法。通过增加新菜单、窗体和对话框,就可以实现全新的功能而不必对父应用做任何修改。不过仍然有一个限制:这只是一种单侧(one-sided)机制。正如所看到的,系统依赖用户的某些操作才能启动插件代码,比如点击菜单或者类似的动作。代码运行起来以后,又要依靠另外一个用户动作来停止它,例如,关闭插件可能已经打开的窗体。克服这种缺陷的一种可行的方法就是使插件可以响应父应用中的动作——模仿在Delphi中工作地很好的事件驱动编程模型的确有效。
    在最后一个例子插件中,我们将创建一种机制,插件可以藉此响应父应用中产生的事件。通常情况下,可以通过判定需要触发哪些事件、在父应用中为每个事件创建一个Tlist对象来实现。然后每个Tlist对象都被传递到插件的初始化过程中,如果插件想在某个事件中执行动作,它就把负责执行的函数地址加入到对应的TList中。父应用在适当的时刻循环这些函数指针的列表,按次序调用每个函数。通过这种方法,就为多个插件在同一事件中执行动作提供了可能。
    应用程序产生的事件完全依赖于程序已确定的功能。例如,一个TCP/IP网络应用程序可能希望通过TclientSocket的onRead事件通知插件数据抵达,而一个图形应用程序可能对调色板的变化更感兴趣。
      为了说明事件驱动的插件应答的概念,我们将创建一个用于限制主窗口最小尺寸的插件。这个例子有点儿造作,因为把这个功能做到应用程序里边会比这简单的多。不过这个例子的优点在语容易编码而且易于理解,而这正是本文想要做到的。
      很明显,我们要做的第一件事情就是决定到底要产生哪些事件。在本例中,答案很简单:要限制一个应用程序窗口的尺寸,有必要捕获并且修改Windows消息WM_GETMINMAXSINFO。因此,要创建一个完成这项功能的插件,我们必须捕获这个消息并且在这个消息处理器中调用插件例程。这就是我们要创建的事件。
      接下来我们要创建一个TList来处理这个事件。在主窗体的initialization段中将会创建lstMinMax对象,然后,创建一个消息处理器来捕获Windows消息WM_GETMINMAXINFO。图9中的代码显示了这个消息处理器。
    { 捕获 WM_GETMINMAXINFO. 为每个消息调用插件例程. }
    procedure TfrmMain.MinMaxInfo(var msg: TMessage);
    var

      m: PMinMaxInfo; file://在 Windows.pas 中定义.
      i: Integer;

    begin
      m := pointer(msg.Lparam);
      for i := 0 to lstMinMax.count -1 do begin
      TResizeProc(lstMinMax[i])(m.ptMinTrackSize.x,
      m.ptMinTrackSize.y);
      end;

    end;
    图 9: WM_GETMINMAXINFO 的消息处理器
      外壳应用的LoadPlugin过程必须再次修改以便调用初始化例程。这个新初始化函数把我们的TList当作参数接受,在其中加入修改消息参数的函数地址。图10显示了LoadPlugin过程的最终版本,它可以执行到目前为止所讨论的全部几个插件的初始化工作。
    { 加载指定的插件DLL. }

    procedure TfrmMain.LoadPlugin(sr: TSearchRec);
    var

      Description: string;
      LibHandle: Integer;

      DescribeProc: TPluginDescribe;
      InitProc: TPluginInit;
      InitEvents: TInitPluginEvents;
    begin

      LibHandle := LoadLibrary(Pchar(sr.Name));
      if LibHandle <> 0 then
      begin

      // 查找 DescribePlugin.
      DescribeProc := GetProcAddress(LibHandle,
      cPLUGIN_DESCRIBE);

      if Assigned(DescribeProc) then
      begin

      // 调用 DescribePlugin.
      DescribeProc(Description);
      memPlugins.Lines.Add(Description);
      file://查找InitPlugin.
      InitProc := GetProcAddress(LibHandle, cPLUGIN_INIT);
      if Assigned(InitProc) then
      begin

      file://调用InitPlugin.
      InitProc(mnuMain);

      end;
      // 为第三方插件查找 InitPluginEvents
      InitEvents := GetProcAddress(LibHandle,
      cPLUGIN_INITEVENTS);
      if Assigned(InitEvents) then
      begin

      // 调用 InitPlugin.
      InitEvents(lstMinMax);
      end;

      end
      else

      begin
      MessageDlg('File "' + sr.Name +
      '" is not a valid plugin.',
      mtInformation, [mbOK], 0);
      end;

      end
      else

      begin
      MessageDlg('An error occurred loading the plugin "' +
      sr.Name + '".', mtInformation, [mbOK], 0);
      end;

    end;
    图 10: LoadPlugin 的最终版本
      最后一步是创建插件自身。如同前面的几个例子,插件展示一个标志自身的描述过程。它也带有一个初始化例程,在本例中只是接受一个TList作为参数。最后,它还包含一个没有引出(Export)的历程,叫做AlterMinTrackSize,它将修改传递给它的数值。图11显示了最终插件的完整代码。
    unit main;

     
    interface

     
    uses Dialogs, Menus, classes;
     

      procedure DescribePlugin(var Desc: string);
      export; stdcall;

      procedure InitPluginEvents(lstResize: TList);
      export; stdcall;

      procedure AlterMinTrackSize(var x, y: Integer); stdcall;
     

    implementation
     

    procedure DescribePlugin(var Desc: string);
    begin

      Desc := 'Test plugin 3 - MinMax';
    end;

     
    procedure InitPluginEvents(lstResize: TList);
    begin

      lstResize.Add(@AlterMinTrackSize);
    end;

     
    procedure AlterMinTrackSize(var x, y: Integer);
    begin

      x := 270;
      y := 220;

    end;
     

    end.
    图 11: 最终插件的代码

      InitPluginEvents过程是这个插件的初始化例程。它接受一个TList作为参数。这个TList就是在父应用程序中创建的保存相应函数地址的列表。下面的语句:
    lstResize.Add(@AlterMinTrackSize);
      把AlterMinTrackSize函数的地址加入到了这个列表中。它被声明为类型stdcall以便与其他过程相配,不过用不着export指示字。由于函数被直接通过它的地址调用,所以也就没有必要按照通常的方式把它从DLL中引出。
    所以,事件序列如下所列:

    1、 在应用程序初始化时,创建一个TList对象。
    2、 在启动时这个列表被传递到插件的初始化过程InitPluginEvents中。
    3、 插件过程把一个过程的地址加入到列表中。
    4、 每次窗口大小改变时所产生的Windows消息WM_GETMINMAXINFO被我们的应用程序所捕获。
    5、 该消息被我们的消息处理器TfrmMain.MainMaxInfo所处理,见图10。
    6、 消息处理器遍历列表并调用它所包含的函数,把当前的X和Y最小窗口尺寸作为参数传递。要注意,TList类只是存储指针,所以如果想用保存的地址做些什么事情的话,我们必须把指针转换成所需要的类型——在本例中,要转换成TresizeProc。
    TResizeProc = procedure (var x, y: Integer); stdcall;
    7、 插件过程AlterMinTrackSize(列表中的指针所指向的),接受X和Y值作为可变的var参数并且修改它们。
    8、 控制权返回到父应用的消息处理器,按照最小窗口尺寸的新值继续运行下去。
    9、 应用程序退出时TList会在主代码的finalization段被释放。
    结论

     
      使用该体系结构时,可能利用Delphi提供的package功能是个不错的主意。在通常情况下,我不是一个分割运行时模块的狂热爱好者,但是当你认为任一包含大量代码的Delphi DLL超过200KB时,它就开始变得有意义了。
      这篇文章应该还是有些用处的,至少它可以让你思考一些程序设计方面的问题,比如如何让它变得更加灵活。我知道如果我在以前的应用程序中使用一些这种技术的话,我就可以省掉在修改程序方面的好多工作。我并不想把插件作为一种通用的解决方案。很明显,有些情况下额外的复杂度无法验证其正确性,或者应用程序压根儿就不打算把自身搞成几块可扩展的单元。还有一些其它的方法也可以达成同样的效果。Delphi自身提供了一个接口来创作能集成到IDE中的模块,比起我所说明的技术这种方法更加面向对象(或者说更“干净”),而我也确信你可以在自己的应用中模仿这一技术。在运行时加载Delphi包也不是做不到的。探索一下这种可能性吧。
      [本文所介绍的技术在Delphi 4下工作的很好。实际上,Delphi 4增加了工程选项,使这类应用程序加强DLL(application-plus-DLL)的开发变得更加容易了。]

    转载于:https://www.cnblogs.com/shangdawei/p/4058461.html

    展开全文
  • N卡下卡驱动所需要的一个文件,文件名称是nvcod.dll
  • FFMPEG扩展应用DLL

    2014-08-09 15:51:23
    FFMPEG扩展应用DLL库 源程序销售 产品销售 2014-08-09 15:49:41| 分类: 公司产品推销 | 标签: |字号大中小 订阅 FFMPEG扩展应用DLL库 1.2.0.9000 - RMB:商谈 FFMPEG扩展应用DLL库 本公司开发...
  • 使用DLL封装应用程序的资源 程序在BDS2006下编译通过。 笔者有些懒,理论说明文档就引用网上的。 笔者的代码应该来说是写得比较简单的。 谈Delphi编程中资源文件的应用  一、初级应用篇  资源文件一般为...
  • Delphi插件创建、调试与使用应用程序扩展 有没有使用过Adobe Photoshop如果用过,你就会对插件的概念比较熟悉。对外行人来说,插件仅仅是从外部提供给应用程序的代码块而已(举个例子来说,在一个DLL中)。一个插件...
  • 言:在编写MFC程序的时候,通常需要编写...本部分共上下两篇文章,本文为上篇,MFC DLL应用程序类型分为以下三种: (1)使用共享MFC DLL的规则DLL (2)带静态链接MFC的规则DLL (3)MFC扩展DLL 下面重点
  • 一个插件和一个普通DLL之间的差异在于插件具有扩展应用程序功能的能力。例如,Photoshop本身并不具备进行大量的图像处理功能。插件的加入使其获得了产生诸如模糊、斑点,以及其他所有风格的奇怪效果,而其中任何一...
  • 本部分共上下两篇文章,本文为上篇,MFC DLL应用程序类型分为以下三种: (1)使用共享MFC DLL的规则DLL (2)带静态链接MFC的规则DLL (3)MFC扩展DLL 下面重点解释一下这些DLL的含义区别: 一,规则...
  • IIS 5.1 在第一次添加PHP php5isapi.dll 应用程序扩展名映射时," 确定 "按钮不可用. 解决办法: 先添加一次PHP目录中可执行文件任意一个 .exe. 输入扩展名,当 " 确定 " 按钮可用后,再重新添加 php5isapi.dll ...
  • 一个插件和一个普通DLL之间的差异在于插件具有扩展应用程序功能的能力。例如,Photoshop本身并不具备进行大量的图像处理功能。插件的加入使其获得了产生诸如模糊、斑点,以及其他所有风格的奇怪效果,而其中任何一...
  • 引言:在编写MFC程序的时候,...本部分共上下两篇文章,本文为上篇,MFC DLL应用程序类型分为以下三种: (1)使用共享MFC DLL的规则DLL (2)带静态链接MFC的规则DLL (3)MFC扩展DLL 下面重点解释一下这些DLL的含义区
  • 引言:在编写MFC程序的时候,...本部分共上下两篇文章,本文为上篇,MFC DLL应用程序类型分为以下三种: (1)使用共享MFC DLL的规则DLL (2)带静态链接MFC的规则DLL (3)MFC扩展DLL 下面重点解释一下这些DLL的含义区
  • 我们在添加aspnet_isapi.dll后,移动到下面后那个框会变成 c:/windows/.../aspnet_isapi.dll 这样确定是灰色的,你把鼠标移动到框里点一下就出来完整路径 下面的确定就可以了
  • 、Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出的函数一般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用。 b、Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的。...
  • 一个运行很好的QT可执行的exe程序,需要被其他的程序调用,并且使调用者和...2.修改输出文件名称,扩展名改为dll 3.添加导出符号定义头文件XXX_global.h,并且添加到程序中: #pragma once #include <QtCore/qg...
  • 能够被所有支持dll的编程语言所写的应用程序使用,当然也包括使用MFC创建的应用程序。在这种动态链接库中包含一个从CWinApp中继承而来的类,DllMain函数也被隐藏在其中了。  规则DLL包含俩类——静态链接到MFC上和...
  • 请问如何在扩展 DLL 中创建应用程序框架?如何在DLL中创建窗体(SDI/MDI)?非常急!!!!!!!
  • MFC扩展DLL

    千次阅读 2018-06-06 17:28:07
     6.1概论 MFC扩展DLL与MFC规则DLL的相同点在于在两种DLL的内部都可以使用MFC类库,其不同点在于MFC扩展DLL应用程序的接口可以是MFC的。MFC扩展DLL的含义在于它是MFC的扩展,其主要功能是实现从现有MFC库类中派...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,602
精华内容 640
关键字:

dll应用程序扩展