AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

Ein Thema von NoGAD · begonnen am 30. Apr 2024 · letzter Beitrag vom 27. Mai 2025
Antwort Antwort
DaCoda

Registriert seit: 21. Jul 2006
Ort: Hamburg
172 Beiträge
 
Delphi 12 Athens
 
#1

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

  Alt 12. Mai 2024, 09:02
Ich habe mich aber entschieden den Code bzw. Aufruf von Uwe Raabe seinem Basiscode zu verwenden und das "Faden" nicht zu nutzen.
Damit ist der Aufruf aus meiner Sicht schöner/einfacher.

Aufrufbeispiele:
Code:
  ShowModalDimmed(Form, nil);

  ShowModalDimmed(Form, ParentForm);

  ShowModalDimmed(Form, ParentForm, Alphablend, BackColor, Centered);
Function:
Code:
function ShowModalDimmed(aForm: TForm; aParentForm: TForm; AlphaBlendValue: Integer = 100; BackColor: TColor = clGray; Centered: Boolean = True): TModalResult;
var
  Back: TForm;

  Dummy_Rect: TRect;

  targetAlpha: Integer;
  Dummy_Alpha_inc: Integer;
  alphaDiff: Integer;
begin
  Back := TForm.Create(nil);
  try
    Back.AlphaBlend := True;

    targetAlpha := AlphaBlendValue;
    if targetAlpha > 255 then
      targetAlpha := 255;
    if targetAlpha < 1 then
      targetAlpha := 1;

    Back.AlphaBlendValue := targetAlpha;
    Back.Color := BackColor;
    Back.DoubleBuffered := True;
    Back.BorderStyle := bsNone;

    if aParentForm <> nil then begin
      Back.Position := aParentForm.Position;
      Back.RoundedCorners := aParentForm.RoundedCorners;
      Dummy_Rect := GetFormShadow(aParentForm);
      Back.SetBounds(aParentForm.Left + Dummy_Rect.Left, aParentForm.Top + Dummy_Rect.Top, aParentForm.Width - Dummy_Rect.Right, aParentForm.Height - Dummy_Rect.Bottom);
    end else begin
      Back.SetBounds(0, 0, Screen.Width, Screen.Height);
    end;
    Back.Show;

    if Centered then begin
      aForm.Position := poMainFormCenter;
    end;

    Result := aForm.ShowModal;
    Back.Hide;
  finally
    Back.Free;
  end;
end;
Und die Function von Mathias (NoGAD):
Code:
function GetFormShadow(aForm: TForm): TRect;
var
  R1, R2: TRect;
begin
  (* Breite eines Schattens einer TForm *)
  Result := default (TRect);
  if (Win32MajorVersion >= 6) and DwmCompositionEnabled then
  begin
    if DwmGetWindowAttribute(aForm.Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1)) = S_OK then
    begin
      R2 := aForm.BoundsRect;
      Result.Left := R2.Left - R1.Left; // Linke Breite des Schattens
      if Result.Left < 0 then
        Result.Left := Result.Left * -1;
      Result.Right := (R2.Right - R1.Right) + Result.Left; // Rechte Breite des Schattens
      if Result.Right < 0 then
        Result.Right := Result.Right * -1;
      Result.Top := R2.Top - R1.Top; // Obere Höhe des Schattens
      if Result.Top < 0 then
        Result.Top := Result.Top * -1;
      Result.Bottom := (R2.Bottom - R1.Bottom) + Result.Top; // Untere Höhe des Schattens
      if Result.Bottom < 0 then
        Result.Bottom := Result.Bottom * -1;
    end;
  end;
Debuggers don’t remove bugs, they only show them in slow-motion.

Geändert von DaCoda (12. Mai 2024 um 09:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

  Alt 12. Mai 2024, 12:15
TForm.RoundedCorners gibt es in Delphi 10.4 nicht. Daher kann ich es auch nicht einsetzen

LG
Mathias
Ich vergesse einfach zu viel.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

  Alt 12. Mai 2024, 19:19
Hier ein Auszug wie ich es mache:
Delphi-Quellcode:
  private
    fHiddenWnd: HWND;
    fHiddenClass: ATOM;
Delphi-Quellcode:
procedure TfrmMain.DestroyHidden;
begin
  if (fHiddenWnd <> 0) then
    DestroyWindow(fHiddenWnd);
  if (fHiddenClass <> 0) then
    Winapi.Windows.UnregisterClass(MakeIntResource(fHiddenClass), HInstance);
  fHiddenWnd := 0;
  fHiddenClass := 0;
  BringToFront;
  Application.ProcessMessages;
end;

procedure TfrmMain.CreateHidden(const Color: TColor = COLOR_WINDOW; const AlphaBlend: Boolean = True; const AlphaBlendValue: Integer = 127; const Transparent: Boolean = True; const ExcludeBorder: Boolean = True);
  function HiddenProc(fWnd: HWND; fMsg: UINT; fWParam: WPARAM; fLParam: LPARAM): LRESULT; stdcall;
  begin
    Result := DefWindowProc(fWnd, fMsg, fWParam, fLParam);
  end;
var
  WndClass: TWndClass;
  S: string;
  BorderWidth: Integer;
  hMenuHandle: HMENU;
  dwExStyle: DWORD;
begin
  if ((fHiddenClass <> 0) or (fHiddenWnd <> 0)) then
    DestroyHidden;
  BorderWidth := 0;
  if (ExcludeBorder) then
    BorderWidth := BorderWidth + GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYEDGE) + GetSystemMetrics(SM_CYBORDER);
  FillChar(WndClass, SizeOf(WndClass), 0);
  WndClass.style := CS_NOCLOSE or CS_VREDRAW or CS_HREDRAW;
  WndClass.lpfnWndProc := @HiddenProc;
  WndClass.cbClsExtra := 0;
  WndClass.cbWndExtra := 0;
  WndClass.hInstance := HInstance;
  WndClass.hIcon := LoadIcon(0, IDI_APPLICATION);
  WndClass.hCursor := LoadCursor(0, IDC_APPSTARTING);
  if (Color < 31) then
    WndClass.hbrBackground := GetSysColorBrush(Color)
    else
    WndClass.hbrBackground := GetSysColorBrush(COLOR_WINDOW);
  WndClass.lpszMenuName := '';
  S := Format('%s@%x', [ExtractFileName(Application.ExeName), GetCurrentThreadId]);
  WndClass.lpszClassName := PChar(S);
  fHiddenClass := Winapi.Windows.RegisterClass(WndClass);
  Sleep(1);
  dwExStyle := WS_EX_TOOLWINDOW;
  if (Transparent) then
    dwExStyle := dwExStyle or WS_EX_TRANSPARENT;
  if (AlphaBlend) then
    dwExStyle := dwExStyle or WS_EX_LAYERED;
  if (fHiddenClass = 0) then
    Exit
  else
    fHiddenWnd := CreateWindowEx(dwExStyle,
                          MakeIntResource(fHiddenClass),
                          PChar(S),
                          WS_POPUP or WS_VISIBLE or WS_CLIPSIBLINGS or WS_CLIPCHILDREN,
                          Self.Left + BorderWidth, Self.Top {+ GetSystemMetrics(SM_CYCAPTION) + BorderWidth},
                          Self.Width - (BorderWidth * 2), Self.Height - BorderWidth {- BorderWidth - GetSystemMetrics(SM_CYCAPTION)},
                          Self.Handle, 0, HInstance, nil);
  if (fHiddenWnd <> 0) then
    begin
      if AlphaBlend then
        Winapi.Windows.SetLayeredWindowAttributes(fHiddenWnd, 0, AlphaBlendValue, LWA_ALPHA or ULW_ALPHA);
      EnableWindow(fHiddenWnd, LongBool(not Transparent));
      hMenuHandle := GetSystemMenu(fHiddenWnd, False);
      if (hMenuHandle <> 0) then
        begin
          DeleteMenu(hMenuHandle, SC_SIZE, MF_BYCOMMAND);
          DeleteMenu(hMenuHandle, SC_MAXIMIZE, MF_BYCOMMAND);
          DeleteMenu(hMenuHandle, SC_MINIMIZE, MF_BYCOMMAND);
          DeleteMenu(hMenuHandle, SC_RESTORE, MF_BYCOMMAND);
          DeleteMenu(hMenuHandle, SC_MOVE, MF_BYCOMMAND);
          DeleteMenu(hMenuHandle, SC_CLOSE, MF_BYCOMMAND);
          DeleteMenu(hMenuHandle, 0, MF_BYCOMMAND);
          CloseHandle(hMenuHandle);
        end;
    end;
  Application.ProcessMessages;
end;
Beispiel:
Delphi-Quellcode:
procedure TfrmMain.Click(Sender: TObject);
begin
  CreateHidden(Random(30));
  with TfrmOptions.Create(nil) do
    begin
      try
        Icon := Self.Icon;
        ShowModal;
      finally
        Release;
      end;
    end;
  DestroyHidden;
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

  Alt 13. Mai 2024, 07:40
Hier ein Auszug wie ich es mache:
Danke. Das ist auch eine sehr schöne Variante.

Leider verstehe ich nicht, warum die Fensterfarbe immer in einem Grauton erscheint, selbst wenn ich

Delphi-Quellcode:
  if (Color < 31) then
    WndClass.hbrBackground := GetSysColorBrush(Color)
  else
    WndClass.hbrBackground := GetSysColorBrush(COLOR_WINDOW);
in

Delphi-Quellcode:
    WndClass.hbrBackground := Color;


{ Aufruf }
  CreateHidden(clBlack, True, 192, False, False);
umwandle.


LG Mathias
Mathias
Ich vergesse einfach zu viel.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

  Alt 13. Mai 2024, 15:42
Danke. Das ist auch eine sehr schöne Variante.
Sehr gerne!
Leider verstehe ich nicht, warum die Fensterfarbe immer in einem Grauton erscheint, selbst wenn ich ... clBlack
Weil clBlack keine SystemFarbe ist.
Du kannst von 0 bis 30 oder verfolge wo COLOR_WINDOW definiert ist um vielleicht noch andere Möglichkeiten zu finden. Im jetzigen zustand muss es eine Systemfarbe sein.
Zum "abdunkeln" wird sicherlich eine passen.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von NoGAD
NoGAD

Registriert seit: 31. Jan 2006
Ort: Weimar
345 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

  Alt 14. Mai 2024, 06:30
Danke für die Erklärung.

LG Mathias
Mathias
Ich vergesse einfach zu viel.
  Mit Zitat antworten Zitat
Bodenseematze

Registriert seit: 10. Jul 2023
76 Beiträge
 
#7

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?

  Alt 26. Mai 2025, 10:24
Auch wenn der Thread schon etwas älter ist...
...ich hänge mich mal an

Die Lösungen hier im Thread gehen immer davon aus, dass man das abdunkelnde Fenster selber erzeugt und zerstört, weil eine andere Form von der eigenen aus ShowModal angezeigt wird.

Ich möchte die Logik gerne umdrehen - d.h. ich möchte in meiner Form darauf reagieren, wenn irgendein anderer Dialog in meiner Applikation von irgendwoher ShowModal gesetzt wird.
Wenn das erkannt wird, soll die eigene Form abgedunkelt werden (d.h. das abdunkelnde Zusatz-Fenster erzeugt / angezeigt werden).

Aber wie erkenne ich das am Besten (ohne total kompliziert zu werden)?
Über Application.OnModalBegin?
Ist dort sicher, dass der Sender das Fenster ist, das modal geschaltet wird/wurde?
Und wie leite ich das dann an alle meine sichtbaren Forms weiter (sind alle von einer Basisklasse abgeleitet, d.h. prinzipiell machbar)?
Sollte auch funktionieren, wenn ein Standard-Dialog (z.B. MessageBox) modal aufgeschaltet wurde...

EDIT: inzwischen habe ich herausgefunden, dass die Verwendung des TMessageManager gut geeignet wäre - aber ich bin noch bei Delphi7 und da gibt's dennoch nicht - und auch keine 3rdParty Implementierung eines EventBus o.ä. , oder?

Geändert von Bodenseematze (26. Mai 2025 um 11:11 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 09:26 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