| Profile冰峰魔焰的世界PhotosBlogLists | Help |
|
|
November 10 创建一个虚幻的层窗口(Win2000/XP)procedure TForm1.FormCreate(Sender: TObject); 试试,在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 DotNET Framework 2.0 SDK Beta 1 x86 - 229M Visual Web Developer 2005 Express Edition Beta - 43.4M SQL Server 2005 Express Edition Beta - 36M Visual C# 2005 Express Edition Beta - 28.9 Visual Basic 2005 Express Edition Beta - 34.1M Visual C++ 2005 Express Edition Beta - 65.3M Visual J# 2005 Express Edition Beta - 32.3M |
|
|