AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Form in neuem Thread laufen lassen

Ein Thema von Hobbycoder · begonnen am 17. Apr 2017 · letzter Beitrag vom 27. Jul 2017
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.981 Beiträge
 
Delphi 12 Athens
 
#1

AW: Form in neuem Thread laufen lassen

  Alt 18. Apr 2017, 09:54
Hm....klinkt verlockend. Aber ich nehme mal an, du möchtest das nicht hier posten?
Darf ich leider nicht...
Aber da steckt eigentlich nicht viel dahinter, wenn man es richtig macht.

Das Fenster selbst steckt ja in einer Ressource. Das schöne ist nun, dass nach der Anzeige eines solchen Fensters dessen Controls ja alle da sind. Man findet die also direkt.

Die Klasse für solch einen Dialog ist nun von TThread abgeleitet. Beim Start des Threads zeigt der das Fenster mit ShowWindow an. Danach findet man mit EnumChildWindows die Controls, wobei als Userpointer einfach der eigene Dialog angegeben ist. So bekommt die Threadinstanz einen Methodenaufruf pro gefundenem Control.

Mit GetClassName bekommt man nun den Typ des Controls heraus und erstellt eine passende Wrapperklasse, alle abgeleitet von einer Basisklasse. Die Instanz kann man sich dann direkt merken um über die ID an die entsprechende Wrapperinstanz zu kommen.

Das Basiscontrol braucht sich nur das Fensterhandle usw. zu merken. Und ein Wrapper für ein Edit-Control muss eine property Text haben, die auf WM_GETTEXT, SetDlgItemText usw. geht.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#2

AW: Form in neuem Thread laufen lassen

  Alt 18. Apr 2017, 10:10
Du könntest eine zweite Instanz deiner Anwendung starten, die auf Grund eines Parameters nur das Scroll-Window erzeuugt und steuert. Damit sparrst du dir eine zusätzliche Exe und brauchst nicht auf die VCL verzichten.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
1.002 Beiträge
 
#3

AW: Form in neuem Thread laufen lassen

  Alt 18. Apr 2017, 10:42
Darf ich leider nicht....
Dachte ich mir schon.


Aber da steckt eigentlich nicht viel dahinter, wenn man es richtig macht.

Das Fenster selbst steckt ja in einer Ressource. Das schöne ist nun, dass nach der Anzeige eines solchen Fensters dessen Controls ja alle da sind. Man findet die also direkt.

Die Klasse für solch einen Dialog ist nun von TThread abgeleitet. Beim Start des Threads zeigt der das Fenster mit ShowWindow an. Danach findet man mit EnumChildWindows die Controls, wobei als Userpointer einfach der eigene Dialog angegeben ist. So bekommt die Threadinstanz einen Methodenaufruf pro gefundenem Control.

Mit GetClassName bekommt man nun den Typ des Controls heraus und erstellt eine passende Wrapperklasse, alle abgeleitet von einer Basisklasse. Die Instanz kann man sich dann direkt merken um über die ID an die entsprechende Wrapperinstanz zu kommen.

Das Basiscontrol braucht sich nur das Fensterhandle usw. zu merken. Und ein Wrapper für ein Edit-Control muss eine property Text haben, die auf WM_GETTEXT, SetDlgItemText usw. geht.
Ich habe mir das schon mal in Luckie's Tutorial angesehen. So in der Theorie klingt das alles nicht so schwer. Allerdings in der Praxis sieht das dann doch etwas anders aus
ich werde mich da mal dran versuchen. Wenn man sich erst mal so eine Wrapperklasse zusammengestrickt hat, kann man die ja auch ganz nett weiterverwenden. Mal schauen wie weit ich komme

Du könntest eine zweite Instanz deiner Anwendung starten, die auf Grund eines Parameters nur das Scroll-Window erzeuugt und steuert. Damit sparrst du dir eine zusätzliche Exe und brauchst nicht auf die VCL verzichten.
Das wär dann Plan B.
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
350 Beiträge
 
Delphi 2007 Professional
 
#4

AW: Form in neuem Thread laufen lassen

  Alt 20. Apr 2017, 18:15
Darf ich leider nicht....
Dachte ich mir schon.


Aber da steckt eigentlich nicht viel dahinter, wenn man es richtig macht.

Das Fenster selbst steckt ja in einer Ressource. Das schöne ist nun, dass nach der Anzeige eines solchen Fensters dessen Controls ja alle da sind. Man findet die also direkt.

Die Klasse für solch einen Dialog ist nun von TThread abgeleitet. Beim Start des Threads zeigt der das Fenster mit ShowWindow an. Danach findet man mit EnumChildWindows die Controls, wobei als Userpointer einfach der eigene Dialog angegeben ist. So bekommt die Threadinstanz einen Methodenaufruf pro gefundenem Control.

Mit GetClassName bekommt man nun den Typ des Controls heraus und erstellt eine passende Wrapperklasse, alle abgeleitet von einer Basisklasse. Die Instanz kann man sich dann direkt merken um über die ID an die entsprechende Wrapperinstanz zu kommen.

Das Basiscontrol braucht sich nur das Fensterhandle usw. zu merken. Und ein Wrapper für ein Edit-Control muss eine property Text haben, die auf WM_GETTEXT, SetDlgItemText usw. geht.
Ich habe mir das schon mal in Luckie's Tutorial angesehen. So in der Theorie klingt das alles nicht so schwer. Allerdings in der Praxis sieht das dann doch etwas anders aus
ich werde mich da mal dran versuchen. Wenn man sich erst mal so eine Wrapperklasse zusammengestrickt hat, kann man die ja auch ganz nett weiterverwenden. Mal schauen wie weit ich komme

Du könntest eine zweite Instanz deiner Anwendung starten, die auf Grund eines Parameters nur das Scroll-Window erzeuugt und steuert. Damit sparrst du dir eine zusätzliche Exe und brauchst nicht auf die VCL verzichten.
Das wär dann Plan B.
@Hobbycoder:
Ja das Thema würde mich aktuelle auch interessieren. Vielleicht könnten wir uns da mal was austauschen. Ich benötige aktuell wie der jaenicke einsetzt eine einfache Windowsanzeige, der Statusmeldungen und Progressbar in einem Thread unabhändig vom Haupthread anzeigt.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.981 Beiträge
 
Delphi 12 Athens
 
#5

AW: Form in neuem Thread laufen lassen

  Alt 21. Apr 2017, 05:54
Würde denn Interesse bestehen an dem bestehenden Quelltext weiterzuarbeiten? Das ist nicht viel bisher, nur was ich geschildert habe ausprogrammiert und nur Wrapper für einen Button, ein Edit und ein Memo (mehr brauchten wir bisher nicht ). Alle 5 Units zusammen umfassen nur rund 350 Zeilen. Aber es funktioniert so wie es ist.

Es gibt vielleicht die Möglichkeit das ganze unter GPL/LGPL/MPL Triple Lizenz zur Verfügung zu stellen sofern Interesse besteht gemeinsam daran zu arbeiten. Das müsste ich dann bei uns klären.
// EDIT: Die Möglichkeit bestünde, wenn sich noch andere finden, die an dem Projekt mitarbeiten möchten.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (21. Apr 2017 um 11:52 Uhr)
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
350 Beiträge
 
Delphi 2007 Professional
 
#6

AW: Form in neuem Thread laufen lassen

  Alt 22. Apr 2017, 22:14
Würde denn Interesse bestehen an dem bestehenden Quelltext weiterzuarbeiten? Das ist nicht viel bisher, nur was ich geschildert habe ausprogrammiert und nur Wrapper für einen Button, ein Edit und ein Memo (mehr brauchten wir bisher nicht ). Alle 5 Units zusammen umfassen nur rund 350 Zeilen. Aber es funktioniert so wie es ist.

Es gibt vielleicht die Möglichkeit das ganze unter GPL/LGPL/MPL Triple Lizenz zur Verfügung zu stellen sofern Interesse besteht gemeinsam daran zu arbeiten. Das müsste ich dann bei uns klären.
// EDIT: Die Möglichkeit bestünde, wenn sich noch andere finden, die an dem Projekt mitarbeiten möchten.
@jaenicke:
Danke fürs Angebot, Interesse ja, aber ich weiss nicht, ob es nicht für mich zu steil ist, da mit zu arbeiten.

lg,
jus
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
350 Beiträge
 
Delphi 2007 Professional
 
#7

AW: Form in neuem Thread laufen lassen

  Alt 23. Apr 2017, 01: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
Angehängte Dateien
Dateityp: zip thread_non_vcl.zip (3,7 KB, 6x aufgerufen)

Geändert von jus (23. Apr 2017 um 02:20 Uhr)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Form in neuem Thread laufen lassen

  Alt 23. Apr 2017, 08:18
Erzeuge alles im execute, das create ist noch im hauptthread, du musst das Window in dem Tread erzeugen in dem es benutzt werden soll.
Fritz Westermann
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#9

AW: Form in neuem Thread laufen lassen

  Alt 22. Apr 2017, 22:53
Würde denn Interesse bestehen an dem bestehenden Quelltext weiterzuarbeiten? Das ist nicht viel bisher, nur was ich geschildert habe ausprogrammiert und nur Wrapper für einen Button, ein Edit und ein Memo (mehr brauchten wir bisher nicht ). Alle 5 Units zusammen umfassen nur rund 350 Zeilen. Aber es funktioniert so wie es ist.

Es gibt vielleicht die Möglichkeit das ganze unter GPL/LGPL/MPL Triple Lizenz zur Verfügung zu stellen sofern Interesse besteht gemeinsam daran zu arbeiten. Das müsste ich dann bei uns klären.
// EDIT: Die Möglichkeit bestünde, wenn sich noch andere finden, die an dem Projekt mitarbeiten möchten.
Ich lese diese Diskussion auch mit. Soweit ich das verstehe, besteht die Möglichkeit, Formulare (ob nun VCL oder eher doch nicht) in Nicht-VCL-Threads zu nutzen. Daran bin auch ich interessiert, denn sogar ein schödes Showmessage oder auch nur die Änderung einer VCL-Formulartitelleiste, ja sogar einfache Pieptöne auszugeben, alles ist in Extra-Threads nur unter umständlich-verrenkter Benutzung der Synchronisation möglich. Das würde sich mit einem solchen Projekt anscheinend ändern. Also, Interesse ja, aber ob meine Kenntnisse ausreichen, bei der Erstellung mitzuwirken, halte ich für fraglich, leider.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
1.002 Beiträge
 
#10

AW: Form in neuem Thread laufen lassen

  Alt 23. Apr 2017, 00:38
Was ich bisher in Luckie Tutorial gelesen habe, sollte das ganze mehr oder weniger problemlos aus dem Tutorial abzuleiten sein. Das ganze könnte man sicherlich gut in eine/mehrere Klassen verpacken und eben wie schon Jaenicke sagt einen schicken Wrapper erstellen, so dass man sich damit dann leicht hier und da ein nonVCL-Dialog ganz nach den verschiedenen Ansprüchen erstellen kann.
Sicherlich hat jeder hier, der Interesse bekundet, etwas andere Anforderungen.

Natürlich ist es nicht ganz so mal eben gemacht, aber ein interessantes Thema.
Wenn Jaenicke seinen Wrapper zur Verfügung stellt, dann müsste jeder auch erst mal schauen, in wie weit er damit klar kommt, bzw. ob die darin enthaltenen Möglichkeiten für sein Vorhaben bereits ausreicht.

Ich muss mir Luckie's Tutorial mal ausdrucken (kann besser Papier lesen, als am Bildschirm). Und dann fange ich einfach mal an.
Ein Fenster mit 2 Buttons hat schon mal ganz gut geklappt. Leider hatte ich in den letzten Tage nicht die Zeit, mich damit weiter ausgiebig zu beschäftigen. Werde ich aber zeitnah nachholen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz