Delphi-PRAXiS
Seite 18 von 20   « Erste     8161718 1920      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   FireMonkey Sammelthread (https://www.delphipraxis.net/162660-firemonkey-sammelthread.html)

stahli 4. Mai 2013 15:36

AW: FireMonkey Sammelthread
 
Eigentlich müssten nur "focused handler" und "change focus" getauscht werden.
Dann könnte man Key auf 0 setzen wenn man vkTab selbst behandeln will.

Wenn das in XE4 noch nicht geändert ist werde ich mal einen QC-Eintrag schreiben.
Delphi-Quellcode:
procedure TCommonCustomForm.KeyDown(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState);
var
  List: TInterfaceList;
  i, CurIdx: Integer;
  TabDirection : Integer;
  FocusObj: TFmxObject;
  Done: boolean;
  FocusPopup: TCustomPopupMenu;
  lIsDialog: boolean;
  NewFocus: IControl;
  procedure TraverseChildren(Container: TFmxObject);
  var I: integer;
  begin
    if (Container is TControl) and
       (not TControl(Container).Enabled) then Exit;
    for I := 0 to Container.ComponentCount - 1 do
      if (Container.Components[I] is TCustomActionList) and
         (TCustomActionList(Container.Components[I]).DialogKey(Key, Shift)) then
      begin
        Done := True;
        Exit;
      end;
    if (Container.ChildrenCount > 0) then
      for I := 0 to Container.ChildrenCount - 1 do
      begin
        TraverseChildren(Container.Children[I]);
        if Done then
          Exit;
      end;
  end;
  procedure OtherForms(IsMain: boolean);
  var I, J: integer;
      F: TCommonCustomForm;
  begin
    if Done then Exit;
    for I := 0 to Screen.FormCount - 1 do
    if (Screen.Forms[I] <> self) and
       (Screen.Forms[I].Visible) and
       (IsMain xor (Screen.Forms[I] <> Application.MainForm)) then
    begin
      F := Screen.Forms[I];
      for J := F.ChildrenCount - 1 downto 0 do
      begin
        if F.Children[J] is TMainMenu then
          TMainMenu(F.Children[J]).DialogKey(Key, Shift);
        if Key = 0 then
        begin
          Done := True;
          Exit;
        end;
      end;
      TraverseChildren(F);
      if Done then Exit;
    end;
  end;
begin
  { dialog key }
  FocusPopup := nil;
  lIsDialog := False;
  IsDialogKey(Key, KeyChar, Shift, lIsDialog);
  try
    if lIsDialog then
    begin
      Done := False;
      // 1. perform key in Focus Control
      if Assigned(FFocused) then
      begin
        FFocused.DialogKey(Key, Shift);
        if Key = 0 then
          Exit;
        FocusObj := FFocused.GetObject;
      end
      else
        FocusObj := nil;
      // 2. perform key in PopupMenu of Focus Control
      if (FocusObj is TControl) then
      begin
        FocusPopup := TControl(FocusObj).PopupMenu;
        if FocusPopup is TPopupMenu then
        begin
          TPopupMenu(FocusPopup).DialogKey(Key, Shift);
          if Key = 0 then
            Exit;
        end
        else
          FocusPopup := nil;
      end;
      // 3. perform key in other Menus
      for i := ChildrenCount - 1 downto 0 do
      if Children[i] <> FocusPopup then
      begin
        if Children[i] is TMainMenu then
          TMainMenu(Children[i]).DialogKey(Key, Shift)
        else if Children[i] is TPopupMenu then
          TPopupMenu(Children[i]).DialogKey(Key, Shift);
        if Key = 0 then
          Exit;
      end;
      // 4. perform key in other, no focus controls
      for i := ChildrenCount - 1 downto 0 do
      if Children[i] <> FocusObj then
      begin
        if Children[i].IsIControl then
          Children[i].AsIControl.DialogKey(Key, Shift);
        if Key = 0 then
          Exit;
      end;
      // 5. perform key in all ActionLists in Childrens
      TraverseChildren(self);
      // 6. perform key in all main menus and ActionLists in other forms
      OtherForms(True);
      OtherForms(False);
      if Done then Exit;
    end;

    { change focus } // DANN DAS ******************************************************
    if (Key = vkTab) then
    begin
      NewFocus := nil;
      Key := 0;
      List := TInterfaceList.Create;
      try
        GetTabOrderList(List, True);
        if ssShift in Shift then
          TabDirection := -1
        else
          TabDirection := 1;

        CurIdx := List.IndexOf(FFocused);
        for i := 0 to List.Count-1 do
        begin
          Inc(CurIdx, TabDirection);
          if (TabDirection > 0) and (CurIdx >= List.Count) then
            CurIdx := 0
          else
          if (TabDirection < 0) and (CurIdx < 0) then
            CurIdx := List.Count - 1;

          if IControl(List[CurIdx]).CheckForAllowFocus then
          begin
            NewFocus := IControl(List[CurIdx]);
            break;
          end;
        end;
      finally
        FreeAndNil(List);
      end;
      if Assigned(NewFocus) then
        NewFocus.SetFocus;
      Exit;
    end;

    { focused handler }  // ERST DAS *****************************************************
    if ((Key <> 0) or (KeyChar <> #0)) then
    begin
      if Assigned(FFocused) then
        FFocused.KeyDown(Key, KeyChar, Shift);
      if Assigned(FOnKeyDown) then
        FOnKeyDown(Self, Key, KeyChar, Shift);
    end;
  finally
    Application.FLastKeyPress := Now;
    Application.FLastUserActive := Application.FLastKeyPress;
  end;
end;

Thom 4. Mai 2013 20:41

AW: FireMonkey Sammelthread
 
Oder so. :thumb:

Darlo 5. Mai 2013 15:57

AW: FireMonkey Sammelthread
 
Entweder stelle ich mich ziemlich an oder das mit den Gesten ist nicht ganz durchdacht.

An sich ganz simpeler Programmablauf.

Tabcontrol mit paar Tabitems und jeweils einer TabChangeAction.
Die entsprechenden Actions zum Einblenden des richtigen Tabs sollen per link/rechts wischen ausgeführt werden.
Soweit so gut. Jetzt kam ich aber auf die absurde Idee sowohl TSwitche wie TTRackbars zu verwenden ;-)
Wenn man diese bedient wird leider die Action zur Navigation ausgeführt.
Bei Switch konnte ich das über eine Funktion die im MouseDown und MouseUp gesteuert wird umgehen. Wie soll man das aber bitte bei einer Trackbar machen????

stahli 10. Jul 2013 23:16

AW: FireMonkey Sammelthread
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich erzeuge aus der Datenschicht AniIndicators auf gebundenen GUI-Controls um eine längere Beschäftigung anzuzeigen.

Sichtbar werden diese erst durch Application.ProcessMessages. Und dann wird nix animiert, solange die Anwendung beschäftigt ist.
Zu laufen beginnen sie wenn der Prozess fertig ist und ich die AniIndicators nicht zerstöre.

Gibt es dazu Tipps?

Mann, Mann, Mann, da denkt man, man hat eine schöne tolle neue und leistungsfähige GUI...

Delphi-Quellcode:
procedure TssCtrl.StartAniIndicator;
begin
  if Owner is TControl then
  begin
    fAniIndicator := TAniIndicator.Create(Owner);
    fAniIndicator.Align := TAlignLayout.alCenter;
    fAniIndicator.Parent := (Owner as TControl);
    fAniIndicator.Enabled := True;
    RefreshData;
    Application.ProcessMessages;
  end;
end;

procedure TssCtrl.EndAniIndicator;
begin
  FreeAndNil(fAniIndicator);
  RefreshData;
end;

Thom 11. Jul 2013 04:05

AW: FireMonkey Sammelthread
 
Ist doch ganz "einfach": :-D
Delphi-Quellcode:
type
  TFormHelper = class helper for TForm
    procedure PaintRects(const UpdateRects: array of TRectF);
  end;

procedure TFormHelper.PaintRects(const UpdateRects: array of TRectF);
begin
  inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Time: Cardinal;
begin
  AniIndicator1.Visible:=true;
  AniIndicator1.Enabled:=true;
  try
    Time:=TThread.GetTickCount;
    while TThread.GetTickCount-Time<=5000 do //<- 5 Sekunden Blockierung des Hauptthreads
    begin
      Sleep(100);
      if Assigned(AniThread)
        then AniThread.OnTimer(nil); //<- Animation(en) am Leben erhalten
      PaintRects([AniIndicator1.ParentedRect]); //<- Indikator neu darstellen
    end;
  finally
    AniIndicator1.Visible:=false;
    AniIndicator1.Enabled:=false;
  end;
end;
Natürlich ist wieder alles so verpackt (im Implementationteil deklarierte Objekte, im protected-Abschnitt versteckte Methoden), daß man auf "normalem" Weg nicht richtig herankommt. Und (T)AniThread ist unter Windows selbstverständlich kein Thread (wäre ja auch sehr naiv, so etwas aus dem Namen zu schlußfolgern), sondern ein normaler Timer, der logischerweise nicht funktioniert, wenn die Nachrichtenschleife blockiert ist.

Wenn ich dann so was
Delphi-Quellcode:
destructor TAniIndicator.Destroy;
begin
  if Assigned(FFill) then
    FreeAndNil(FFill);
  inherited;
end;
und so was
Delphi-Quellcode:
var
  [...]
  AniThread: TTimer;
sehe, weiß ich wieder, wo das durchdachte Design herkommt... :lol:

stahli 11. Jul 2013 11:44

AW: FireMonkey Sammelthread
 
@Thom
Danke! Das schaue ich mir heute Abend mal an.

Da kommt mir wieder der Vergleich zu einer Spieleentwicklung in den Sinn (http://www.delphipraxis.net/175033-f...-schlecht.html). Wenn da ein Alientreffer verarbeitet würde bleiben doch die anderen Kugeln auch nicht ein paar Sekunden unbewegt in der Luft hängen. Echt zum :kotz:

Eine flüssige Progressbar braucht ja wohl auch entsprechende Klimmzüge. (Es gab mal einen Hinweis dazu, finde ich aber gerade nicht auf die Schnelle.)


...man sollte halt wohl doch auf den FireDog warten, der den Affen auf den Baum jagt... :cry:

Das schlimme ist ja, wenn man allein hier aus der DP ein paar Leute zusammensuchen könnte würde ein ähnliches aber vernünftig umgesetztes Konzept echt Spaß bringen.

Sobald ich im Lotto gewinne miete ich eine Garage...
(Alternative zu den LB habe ich ja schon. :) )

greenmile 11. Jul 2013 12:01

AW: FireMonkey Sammelthread
 
Offtopic: Ich habe meine Firemonkey Entwicklungen erstmal auf Eis gelegt; bis das Teil endlich rund läuft. Ich denke, mit XE5 (oder halt Android) aktiviere ich es wieder, aber bis dahin kann und will ich mich leider nicht mehr damit rumschlagen. Schade, aber selbst meine Mac Projekte laufen nur mehr schlecht als recht und mit sehr sehr viel Gepfusche :(

stahli 12. Jul 2013 15:44

AW: FireMonkey Sammelthread
 
Als TIdleIndicator würde das Ding (TAniIndicator) andererseits perfekt arbeiten.
Es rödelt nämlich sofort los, wenn die Anwendung gerade nix tut.
:wall:

Darlo 12. Jul 2013 22:12

AW: FireMonkey Sammelthread
 
Zitat:

Zitat von stahli (Beitrag 1221605)
Als TIdleIndicator würde das Ding (TAniIndicator) andererseits perfekt arbeiten.
Es rödelt nämlich sofort los, wenn die Anwendung gerade nix tut.
:wall:

:thumb:

cookie22 13. Jul 2013 12:52

AW: FireMonkey Sammelthread
 
Zitat:

Zitat von greenmile (Beitrag 1221459)
...Ich denke, mit XE5 (oder halt Android) aktiviere ich es wieder, aber bis dahin kann und will ich mich leider nicht mehr damit rumschlagen...

Wenn mit XE5 dann Android kommen sollte, musst du aber noch mindestens bis XE8 warten um es produktiv nutzen zu können. :P


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:22 Uhr.
Seite 18 von 20   « Erste     8161718 1920      

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