Profile冰峰魔焰的世界PhotosBlogLists Tools Help

Blog


    November 10

    创建一个虚幻的层窗口(Win2000/XP)

    procedure TForm1.FormCreate(Sender: TObject);
    var
      ExSty:DWORD;
    begin
      ExSty:=GetWindowLong(Handle,GWL_EXSTYLE);
      ExSty:=ExSty or WS_EX_TRANSPARENT or WS_EX_LAYERED;
      SetWindowLong(Handle,GWL_EXSTYLE,ExSty);
      SetLayeredWindowAttributes(Handle,cardinal(clBtnFace),125,LWA_ALPHA);
      MoveWindow(Handle,Screen.Width-Self.Width,0,Self.Width,Self.Height,false);
    end;

    试试,在Win2000\XP下有效果.

    November 05

    制作无输出函数名的 DLL 文件

    用 Delphi 用长了,总是发现,有些和 MS 不同的地方。例如,MS 的公开库中,常常隐藏了许多重要函数,这些函数在系统中常常有起着非常巨大的作用。一旦知道如何调用,可以给自己的应用程序提供很强的功能和很大的灵活性。但,这些函数通常又没有函数名(即使用 ExeScope 查看 DLL 文件的导出表也看不出函数意义),仅仅只有一个序号来表示。有时候我又自己想,为什么我在写程序的时候不能学学 MS 隐藏一些自己不希望公开的函数呢?
     
    其实用 Delphi 写 DLL 的时候,使用简单的技巧就可以实现隐藏函数名的效果。让我们来看看下面这个 DLL 源码:
     
    library proDll;
     
    uses
      Windows;
     
    {$R *.res}
     
    procedure ShowMessageA(hWnd: HWND); stdcall;
    begin
      MessageBox(hWnd, '您调用的是 ShowMessageA 函数', 'DLL 函数信息',
        MB_ICONINFORMATION);
    end;
     
    procedure ShowMessageB(hWnd: HWND); stdcall;
    begin
      MessageBox(hWnd, '您调用的是 ShowMessageB 函数', 'DLL 函数信息',
        MB_ICONINFORMATION);
    end;
     
    exports
      ShowMessageA index 1 name '',
      ShowMessageB index 2 name '';
     
    begin
    end.
     
    注意看 exports 部分,用 index 关键字指定输出函数的序号,后面紧跟一个 name 关键字指明输出函数名称。关键就在这里,name 后面是一个空字符串,这样就给函数生成了一个空字符串名。实际效果既是隐藏了输出函数的名称。是不是很容易呢?
     
    那么我们怎样调用这样的输出函数呢?由于没有了函数名,我们调用起来会显得和以前不一样。其实也不用担心,调用同样非常简单。我下面就静态调用和动态调用制作了两个工程,源码如下:
     
    静态调用例子:
     
    unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.dfm}
    procedure ShowMessageA(hWnd: HWND); stdcall; external 'proDll.dll' index 1;
    procedure ShowMessageB(hWnd: HWND); stdcall; external 'proDll.dll' index 2;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowMessageA(Handle);
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      ShowMessageB(Handle);
    end;
    end.
     
    动态调用的例子:
     
    unit Unit2;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    type
      TForm2 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    var
      Form2: TForm2;
    implementation
    {$R *.dfm}
    type
      TDllShowMessageFunc = procedure (hWnd: HWND); stdcall;
    var
      hDllHandle: THandle;
      ShowMessageA, ShowMessageB: TDllShowMessageFunc;
    procedure LoadFuncDll;
    begin
      if hDllHandle = 0 then
      begin
        hDllHandle := LoadLibrary('proDll.dll');
        if hDllHandle = 0 then
          raise Exception.Create('proDll.dll 加载失败');
        try
          {
          lpProcName: the second argument of function GetProcAddress
            Points to a null-terminated string containing the function name,
            or specifies the function's ordinal value. If this parameter is
            an ordinal value, it must be in the low-order word; the high-order
            word must be zero.
          }
          @ShowMessageA := GetProcAddress(hDllHandle, Pointer(HiWord(0) or LoWord(1)));
          if @ShowMessageA = nil then
            raise Exception.Create('proDll.dll 中没有输出 ShowMessageA 函数');
          @ShowMessageB := GetProcAddress(hDllHandle, Pointer(HiWord(0) or LoWord(2)));
          if @ShowMessageB = nil then
            raise
    Exception.Create('proDll.dll 中没有输出 ShowMessageB 函数');
        except
          FreeLibrary(hDllHandle);
          hDllHandle := 0;
          raise;
        end;
      end;
    end;
    procedure FreeFuncDll;
    begin
      if
    hDllHandle <> 0 then
      begin
        FreeLibrary(hDllHandle);
        hDllHandle := 0;
        @ShowMessageA := nil;
        @ShowMessageB := nil;
      end;
    end;
    procedure TForm2.Button1Click(Sender: TObject);
    begin
      if
    @ShowMessageA = nil then LoadFuncDll;
      ShowMessageA(Handle);
    end;
    procedure TForm2.Button2Click(Sender: TObject);
    begin
      if
    @ShowMessageB = nil then LoadFuncDll;
      ShowMessageB(Handle);
    end;
    initialization
      // do nothing
    finalization
      FreeFuncDll;
    end.
     
    呵呵,好了,让我们也来隐藏 DLL 里面的函数吧!!!
    April 19

    通过窗口句柄获得 IWebBrowser2 接口源码

    function GetIEFromHWND(WHandle: HWND; var IE: IWebbrowser2): HRESULT;
    var
      hInst: HWND;
      lRes: Cardinal;
      MSG: Integer;
      pDoc: IHTMLDocument2;
      ObjectFromLresult: TObjectFromLresult;
    begin
      hInst := LoadLibrary('Oleacc.dll');
      @ObjectFromLresult := GetProcAddress(hInst, 'ObjectFromLresult');
      if @ObjectFromLresult <> nil then begin
        try
          MSG := RegisterWindowMessage('WM_HTML_GETOBJECT');
          SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes);
          Result := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
          if Result = S_OK then
            (pDoc.parentWindow as IServiceprovider).QueryService(IWebbrowserApp, IWebbrowser2, IE);
        finally
          FreeLibrary(hInst);
        end;
      end;
    end;
    January 14

    今天试装 Visual Studio 2005 Express BETA1

    装上感觉变化很大, 我是指外观部分, 不过毕竟我很少用 VS 很多方面不太会使用. 另外, 感觉启动速度比 Delphi 2005 要好点. 有兴趣的朋友可以下载组包单独安装 VS 2005.

    整个Visual Studio 2005 Express Beta Products所有的完整安装包。

    地址分别如下,累计大小约在510M左右:

    DotNET Framework Version 2.0 Redistributable Package Beta 1 (x86) - 24M
    http://go.microsoft.com/fwlink/?linkid=30093&clcid=0x409

    DotNET Framework 2.0 SDK Beta 1 x86 - 229M
    http://www.microsoft.com/downloads/details.aspx?familyid=916EC067-8BDC-4737-9430-6CEC9667655C&displaylang=en

    Visual Web Developer 2005 Express Edition Beta - 43.4M
    http://go.microsoft.com/fwlink/?linkid=30092&clcid=0x409

    SQL Server 2005 Express Edition Beta - 36M
    http://go.microsoft.com/fwlink/?linkid=31760&clcid=0x409

    Visual C# 2005 Express Edition Beta - 28.9
    http://go.microsoft.com/fwlink/?linkid=30090&clcid=0x409

    Visual Basic 2005 Express Edition Beta - 34.1M
    http://go.microsoft.com/fwlink/?linkid=30088&clcid=0x409

    Visual C++ 2005 Express Edition Beta - 65.3M
    http://go.microsoft.com/fwlink/?linkid=30089&clcid=0x409

    Visual J# 2005 Express Edition Beta - 32.3M
    http://go.microsoft.com/fwlink/?linkid=30091&clcid=0x409