2011-10-12 74 views
0

我有一个DLL,其在它的入口点exectues一些代码,即现在传递消息到DLL的入口点

procedure MainDLL(Reason: Integer); 
begin 
    { ... Code here ... } 
end; 

begin 
    DLLProc := @MainDLL; 
end. 

,我想从外部应用程序传递一些值到DLL的入口点。我曾尝试创建DLL里面隐藏的窗口,这样的:

const 
    WM_JAJCO = WM_USER + 1024; 

type 
    TWnd = class(TObject) 
    class procedure DLLWndProc(var Msg: TMessage); 
    end; 

{ ... } 

class procedure TWnd.DLLWndProc(var Msg: TMessage); 
var 
    Tmp: DWORD; 
begin 
    if (Msg.Msg = WM_JAJCO) then 
    begin 
    PNewHandle := Msg.LParam; 
    CreateThread(nil, 0, @Starter, nil, 0, Tmp); 

    Msg.Result := 0; 
    end else 
    Msg.Result := DefWindowProc(MyHnd, Msg.Msg, Msg.WParam, Msg.LParam); 
end; 

// in the entry point 
MyHnd := AllocateHWND(TWnd.DLLWndProc); 

然后,之后我在调用者的应用程序初始化DLL,我用:

SendMessage(FindWindow('TPUtilWindow', nil), WM_USER + 1024, 0, wi.WndHandle); 
Application.ProcessMessages(); 

但DLL中创建的窗口似乎没有收到消息。你碰巧知道为什么?

如果这是一个不好的方法,你有不同的解决方案,请让我知道。

+0

为什么不从DLL中导出一个函数,并通过'GetModuleHandle','GetProcAddress'和对获得的指针的调用将参数传递给这个导出的函数? –

+0

但是,我调用'LoadLibrary'后就会执行入口点,不是吗?我不明白你的意思。 – Pateman

回答

1

首先确保注入的DLL确实创建了窗口句柄。 WinSight或Spy ++应该可以帮助你。一旦你知道窗口确实存在,确保FindWindow找到你的窗口句柄,而不是另一个具有相同类名的窗口。 IIRC,即使是Delphi IDE本身也会使用这个类名创建窗口句柄。

+0

你是对的,但问题在于别的地方。请检查我对David Heffernan的答案的最新评论。 – Pateman

2

这是一个相当曲折的方法。您应该在DllMain函数中尽可能少地执行操作。规范的解决方案是创建一个专用函数来执行初始化。安排主机应用程序在调用其他任何东西之前调用初始化函数。

你的版本失败的最可能的原因是有很多窗口与该类名称。 AllocHwnd创建的每个窗口都有该类名称。 FindWindow可能只是找到了错误的一个。


另一方面,你在传递注释中提到这个DLL被注入!在这种情况下,您可以通过使用唯一的类名称或给窗口一个唯一的标题使您的方法工作,以便您可以找到它。

最后,对ProcessMessages的调用看起来是无偿的。

+0

问题在于DLL被注入到另一个进程中,并且我不知道如何在注入进程后调用该DLL的导出函数。 – Pateman

+0

谢谢,我会试试看。 – Pateman

+0

那么改变的事情!看我的编辑。 –

2

您不应该为此使用DLLMain。只需导出自己的init函数并手动调用它。