Передача сообщений в точку входа DLL - PullRequest
0 голосов
/ 13 октября 2011

У меня есть 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, похоже, не получает сообщение. Вы случайно не знаете почему?

Если это плохой метод, и у вас есть другое решение, пожалуйста, дайте мне знать.

Ответы [ 3 ]

2 голосов
/ 13 октября 2011

Вы не должны использовать DLLMain для этого.Просто экспортируйте свою собственную функцию инициализации и вызовите ее вручную.

2 голосов
/ 13 октября 2011

Это довольно извилистый подход. Вы должны делать как можно меньше в функции DllMain. Каноническое решение заключается в создании выделенной функции для выполнения инициализации. Организуйте, чтобы приложение хоста вызывало функцию инициализации перед вызовом чего-либо еще.

Наиболее вероятная причина сбоя вашей версии - множество окон с таким именем класса. Каждое окно, созданное AllocHwnd, имеет это имя класса. FindWindow, вероятно, просто находит неправильный.


С другой стороны, вы случайно упомянули в комментарии, что эта DLL вставлена! В этом случае вы можете заставить свой метод работать, используя уникальное имя класса или присвоив окну уникальный заголовок, чтобы вы могли его найти.

Наконец, вызов ProcessMessages выглядит бесполезным.

1 голос
/ 13 октября 2011

Сначала убедитесь, что внедренная DLL действительно создает ваш дескриптор окна.WinSight или Spy ++ должны помочь вам в этом.Как только вы узнаете, что окно действительно существует, убедитесь, что FindWindow находит ваш дескриптор окна, а не другой с тем же именем класса.IIRC, даже сама Delphi IDE создает дескрипторы окон, используя это имя класса.

...