2011-10-12 113 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函數並手動調用它。