Registriert seit: 22. Jan 2005
344 Beiträge
Delphi 2007 Professional
|
AW: Form in neuem Thread laufen lassen
23. Apr 2017, 02:58
Hallo,
naja, dann zeige ich mal, was ich bisher habe, viel ist es nicht und ich weiss nicht einmal, ob es überhaupt so richtig ist. Das Projekt besteht aus 2 Units. Habe das gesamte Projekt auch Zip Anhang angehängt.
Habe probeweise auf die Hauptunit folgende Unit1.pas ein Button, Memo und Progressbar draufgeklatscht.
Delphi-Quellcode:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,unit2, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
ProgressBar1: TProgressBar;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
DataThread: TDataThread;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i,j: Integer;
begin
for I := 0 to 100000 do
begin
for j := 0 to 100 do progressBar1.Position:=j;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DataThread := tDataThread.Create(' ');
end;
end.
In der folgenden Unit2.pas ist der Thread drin:
Delphi-Quellcode:
unit Unit2;
interface
uses classes, windows, Messages;
type
TDataThread = class(TThread)
private
hdlg: DWORD ;
protected
procedure Execute; override;
public
constructor Create( const Title: String); reintroduce;
end;
function dlgfunc(hwnd: hwnd; umsg: dword; wparam: wparam; lparam: lparam): bool; stdcall;
implementation
{$R main.res} //hier kommt die Vorlage rein
function dlgfunc(hwnd: hwnd; umsg: dword; wparam: wparam; lparam: lparam): bool; stdcall;
begin
result := true;
case umsg of
WM_CLOSE:
EndDialog(hWnd, 0);
WM_DESTROY:
PostQuitMessage(0);
WM_COMMAND:
if hiword(wparam) = BN_CLICKED then begin
case loword(wparam) of
IDOK:
begin
messagebox(hwnd, ' OK Button gedrückt', ' Meldung', 0);
sendmessage(hwnd, WM_CLOSE, 0, 0);
// PostQuitMessage(0);
end;
end;
end;
else result := false;
end;
end;
constructor TDataThread.Create( const Title: String);
begin
inherited Create(False);
hdlg := CreateDialog(HInstance, MAKEINTRESOURCE(100), Self.Handle, @DlgFunc);
ShowWindow(hdlg, SW_SHOW);
end;
procedure TDataThread.Execute;
var
Msg: TMsg;
begin
while not terminated do
begin
if GetMessage(msg,0,0,0) then
begin
if not(IsDialogMessage(hdlg, Msg)) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;
end;
end.
Das Formular im Thread enhält ein Button und eine Listbox wie folgt in main.rc definiert.
Code:
#define IDC_LIST 1002
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
100 DIALOGEX 6, 18, 264, 200
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Fenster-Caption"
FONT 8, "Arial"
BEGIN
PUSHBUTTON "OK", IDOK, 61, 65, 140, 14
LISTBOX IDC_LIST,7,25,138,106,LBS_NOINTEGRALHEIGHT |
LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
END
Der TDataThread ladet einfach per Windows API "CreateDialog" das Threaddialogfenster rein und mit "ShowWindow" wird es angezeigt. Wie man in Unit2.pas sieht, habe ich brutal im Thread eine Nachrichtenschleifen eingebaut. Das Threaddialogfenster reagiert sogar, wenn man auf den Button drückt. Ich muß zugeben, dass ich aber nicht weiß, ob es so überhaupt richtig ist, oder komplett auf dem Holzweg bin. Außerdem habe ich festgestellt, dass wenn ich in Unit1.pas auf Button1 klicke, womit der Hauptthread auf meinem Rechner kurzfristig überlastet wird, das Threaddialogfenster in dieser Zeit auch nicht mehr reagiert. Normalerweise sollte doch das Threaddialogfenster unabhängig vom Hauptfenster sein?
Bitte um Unterstützung.
lg,
jus
Geändert von jus (23. Apr 2017 um 03:20 Uhr)
|