【发布时间】:2013-03-05 21:48:23
【问题描述】:
我有一个加载我的自定义 dll 的多线程应用程序。
在这个 dll 中,我需要创建一个窗口。
我通过创建新线程来做到这一点,并在其中尝试创建此窗口,但我收到错误消息告诉我:EInvalidOperation - Canvas does not allow drawing。
通过在网上搜索,我发现我需要为该线程自定义消息泵。
所以,我的问题是,如何正确地做到这一点?
我现在要做的是:
- 外部应用程序正在加载 dll
- 比单独线程中的这个应用程序从 dll 调用 Init 函数
- Init 函数创建线程
- TMyThread 声明为:
type
TMyThread = class(TThread)
private
Form: TMyForm;
FParentHWnd: HWND;
FRunning: Boolean;
protected
procedure Execute; override;
public
constructor Create(parent_hwnd: HWND); reintroduce;
end;
constructor TMyThread.Create(parent_hwnd: HWND);
begin
inherited Create(False); // run after create
FreeOnTerminate:=True;
FParentHWnd:=parent_hwnd;
FRunning:=False;
end;
procedure TMyThread.Execute;
var
parent_hwnd: HWND;
Msg: TMsg;
XRunning: LongInt;
begin
if not Terminated then begin
try
try
parent_hwnd:=FParentHWnd;
Form:=TMyForm.Create(nil); // <-- here is error
Form.Show;
FRunning:=True;
while FRunning do begin
if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then begin
if Msg.Message <> WM_QUIT then
Application.ProcessMessages
else
break;
end;
Sleep(1);
XRunning:=GetProp(parent_hwnd, 'XFormRunning');
if XRunning = 0 then
FRunning:=False;
end;
except
HandleException; // madExcept
end;
finally
Terminate;
end;
end;
end;
异常EInvalidOperation - Canvas does not allow drawing 在线程到达我现有的消息泵代码之前被触发。
我做错了什么或者让它发挥作用的正确方法是什么?
感谢您的帮助。
要在 DLL 中创建第二个 GUI 线程,我必须完全按照标准应用程序中的方式进行操作。
谁能证实我的想法?
在我做的 DLL begin...end. 部分:
begin
Application.CreateForm(THiddenForm, HiddenForm);
Application.Run;
end.
在TMyThread.Execute我必须这样做:
procedure TMyThread.Execute;
begin
if not Terminated then begin
try
try
Application.CreateForm(TMyForm, Form);
???? how to make a thread that has remained in this place until you close this window ???
except
HandleException; // madExcept
end;
finally
Terminate;
end;
end;
end;
这是正确的方法吗?就这么简单吗?
【问题讨论】:
-
嗯.. DLL 有自己的 TApplication 实例吗? IIRC,这是实现您似乎想要的唯一方法 - 一个具有两个 GUI 线程的进程。我以前做过,只是不记得细节了:(
-
我想是的,当它使用 Forms.pas 时会这样。
-
@MartinJames:也许你还记得我必须在哪里以及如何创建这两个 GUI 线程吗?或者也许你有一些代码来说明这一点。
标签: forms delphi dll messaging delphi-2006