Delphi-PRAXiS

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/)
-   -   Delphi Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird? (https://www.delphipraxis.net/215064-hintergrundform-abdunkeln-wenn-andere-form-modal-geoeffnet-wird.html)

NoGAD 30. Apr 2024 16:28

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

in den aktuellen Delphiversionen gibt es Alphablend, um eine Form und die Komponenten durchsichtig zu machen.


Ich suche eine Möglichkeit, um den Hintergrund abzudunkeln, wenn eine andere Form Modal geöffnet wird. Kann mir bitte jemand einen Tipp geben?

LG Mathias :-)

Michael II 30. Apr 2024 16:37

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Den ganzen Dekstop (maximiertes randloses Form mit Alphablend irgendwas anzeigen, z Order direkt hinter deinem modalen Fenster) - und wenn jemand dort klickt, Klick weitergeben und Verdunkelung aufheben (?)) abdunkeln oder nur deine anderen Appformulare?

NoGAD 30. Apr 2024 16:43

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Huhu. Nur eigene Forms.

LG

jaenicke 30. Apr 2024 16:49

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Ich habe dafür ein halbtransparentes Fenster verwendet, das ein ShowModal mit zwei Formularen als Parameter hat. Das erste wird zur Positionierung verwendet, das zweite zeigt es dann nach der Anzeige ebenfalls mit ShowModal an.

Uwe Raabe 30. Apr 2024 22:31

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Ich hatte das mal auf diese Weise implementiert:
Delphi-Quellcode:
function ShowModalDimmed(Form: TForm; ParentForm: TForm = nil; Centered: Boolean = true; SpaceBelow: Integer = 0):
    TModalResult;
var
  Back: TForm;
  below: Integer;
  P: TPoint;
begin
  Back := TForm.Create(nil);
  try
    Back.Position := poDesigned;
    Back.BorderStyle := bsNone;
    Back.AlphaBlend := true;
    Back.AlphaBlendValue := 192;
    Back.Color := clBlack;
    if ParentForm <> nil then
      Back.SetBounds(ParentForm.Left, ParentForm.Top, ParentForm.Width, ParentForm.Height)
    else
      Back.SetBounds(0, 0, Screen.Width, Screen.Height);
    Back.Show;
    if Centered then begin
      P := TPoint.Create((Back.ClientWidth - Form.Width) div 2, (Back.ClientHeight - Form.Height) div 2);
      below := Back.ClientHeight - (P.Y + Form.Height);
      if below < SpaceBelow then begin
        P.Y := P.Y - (SpaceBelow - below);
        if P.Y < 0 then
          P.Y := 0;
      end;
      P := Back.ClientToScreen(P);
      Form.Position := poDesigned;
      Form.Left := P.X;
      Form.Top := P.Y;
    end;
    result := Form.ShowModal;
    Back.Hide;
  finally
    Back.Free;
  end;
end;

Michael II 1. Mai 2024 01:02

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Das Dimmen mittels einer deckungsgleichen, leeren Form (wie von @jaenicke vorgeschlagen) sieht etwas ansprechender aus.

Falls die App gelegentlich mehrere Fenster anzeigt, wäre es wahrscheinlich am besten, eine TFormMitDim von TForm abzuleiten. Wenn dann ein Fenster modal angezeigt werden soll, werden alle zu dimmenden Fenster informiert.

Ich habe noch eine Frage: Die Form, die dimmt, kann auch farbig sein, aber die Titelleiste der Form wird (Methode deckungsgleiche Form) nicht eingefärbt.

Man kann eine Windows-Region (HRGN) definieren, die genau die Abmessungen der zu dimmenden Form hat, und dann einem ‘Panelwindow’ oder Ähnlichem (einer Delphi-Form mit BorderStyle=bsNone) diese Region zuordnen. (Zum Beispiel Uwes Dimmform.) Ich habe mit GetWindowRgn die Region des zu dimmenden Fensters ausgelesen und mit SetWindowRgn dem ‘Dimmfenster’ zugeordnet. Es wäre ein Zweizeiler, aber es will nicht funktionieren: Das Fenster wird mit nicht abgerundeten Ecken gezeichnet.

Man könnte über den Umweg ‘Screenshot(s) des Fensters’ eine HRGN ‘berechnen’ und dem Dimmfenster diese Region zuordnen. Gibt es einen besseren Weg?
Evt. könnte dies helfen: https://learn.microsoft.com/en-us/wi...ounded-corners

DaCoda 2. Mai 2024 19:29

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Die Function von Uwe Raabe finde ich gar nicht so schlecht, aber müsste (zumindest bei Windows 11) etwas angepasst werden, weil
der abgedunkelte Bereich größer ist wie das eigentliche Form (wegen dem Schatten und so, der zur Fenstergröße hinzu kommt)

Aber grundsätzlich sehr nützliche Sache, vielen Dank Uwe...

Michael II 2. Mai 2024 19:37

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

Zitat von DaCoda (Beitrag 1536317)
Die Function von Uwe Raabe finde ich gar nicht so schlecht, aber müsste (zumindest bei Windows 11) etwas angepasst werden, weil
der abgedunkelte Bereich größer ist wie das eigentliche Form (wegen dem Schatten und so, der zur Fenstergröße hinzu kommt)

Aber grundsätzlich sehr nützliche Sache, vielen Dank Uwe...

Für Windows 11 legst du einfach wie j vorschlägt eine typgleiche Form (ohne Titel, ohne "Inhalt") darüber mit Alphablend=true und AlphablendValue nicht 255, damit's durchscheint. Und der Form kannst du bei Bedarf auch noch eine Farbe spendieren. Dann sieht's in Windows 11 nicht so aus, als hätte jemand Akten geschwärzt ;-).

NoGAD 11. Mai 2024 11:19

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Hallo an euch alle.

Vielen Dank für die Ideen, ich war verhindert und konnte die Antworten erst jetzt abrufen.

Die Idee von Sebastian gefällt mir, auch wenn es den Anschein von "Frickelei" hat ;-)

Die Umsetzung von Uwe ist, wenn ich es richtig gelesen habe, eine ähnliche Variante - jedoch variabel gestaltet.

LG und ein schönes Wochenende :-)

TurboMagic 11. Mai 2024 21:13

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Hier ist auch noch eine Idee (geht in ähnliche Richtungen wie beschrieben,
nur evtl. mit anderer "Aktivierung"):

http://zarko-gajic.iz.hr/dim-out-the...-is-displayed/

NoGAD 11. Mai 2024 22:59

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Hallo nochmal :-)


Edit: Problem gelöst, siehe Anmerkungen im Code..


Den Code von Uwe habe ich versucht etwas zu erweiteren, was auch ganz gut klappt.
(Mir gefällt die Parameterliste in der Functionsübergabe noch nicht, das würde ich später als einen Type realiseren.)

Den Schatten der Form kann man auslesen (ein Beispiel habe ich hier gefunden: https://stackoverflow.com/questions/...rs-of-the-form, leider ergibt das bei mir aber Fehler: die Breiten/Höhen werden nicht korrekt ausgelesen.
Die entsprechende Form ist schon sichtbar, daran kann es wohl nicht liegen.


Delphi-Quellcode:

function ShowModalDimmed(Form: TForm; ParentForm: TForm = nil; aDimmed: Boolean = True; Centered: Boolean = True; SpaceBelow: Integer = 0; aAlphaBlendValue: Integer = 192; aBackColor: TColor = clBlack;
  aFadeIn: Boolean = True; aFadeOut: Boolean = True): TModalResult;
var
  Back: TForm;

  Dummy_Rect: TRect;

  targetAlpha: Integer;
  Dummy_Alpha_inc: Integer;
  alphaDiff: Integer;
begin
  (* Hintergrundform abdunkeln *)
  if not aDimmed then
  begin
    Result := Form.ShowModal;
    Exit;
  end;

  Back := TForm.Create(nil);
  try
    Back.Position := poDesigned; //poMainFormCenter; <- war ein Fehler von mir
    Back.AlphaBlend := True;

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

    if aFadeIn then
      Back.AlphaBlendValue := 1
    else
      Back.AlphaBlendValue := targetAlpha;
    Back.Color := aBackColor;
    Back.DoubleBuffered := True;
    Back.BorderStyle := bsNone;

    if ParentForm <> nil then
    begin
      Dummy_Rect := GetFormShadow(ParentForm);
      Back.SetBounds(ParentForm.Left + Dummy_Rect.Left, ParentForm.Top + Dummy_Rect.Top, ParentForm.Width - Dummy_Rect.Right, ParentForm.Height - Dummy_Rect.Bottom);
    end;
    if ParentForm = nil then
    begin
      Back.SetBounds(0, 0, Screen.Width, Screen.Height);
    end;
    Back.Show;
    if aFadeIn then
    begin
      Dummy_Alpha_inc := Back.AlphaBlendValue;
      while Back.AlphaBlendValue < targetAlpha do
      begin
        alphaDiff := targetAlpha - Back.AlphaBlendValue;
        Inc(Dummy_Alpha_inc, min(alphaDiff, 5));
        Back.AlphaBlendValue := Dummy_Alpha_inc;
        Application.ProcessMessages;
        Sleep(20);
      end;
      Back.AlphaBlendValue := aAlphaBlendValue;
    end;

    if Centered then
    begin
      Form.Position := poMainFormCenter; // Keine extra Berechnung notwendig; außerdem für mehrere Monitore geeignet
    end;

    Result := Form.ShowModal;

    if aFadeOut then
    begin
      while Back.AlphaBlendValue > 1 do
      begin
        Back.AlphaBlendValue := Back.AlphaBlendValue - 12;
        Application.ProcessMessages;
        Sleep(20);
      end;
    end;
    Back.Hide;
  finally
    Back.Free;
  end;
end;

function GetFormShadow(aForm: TForm): TRect;
(* uses: Winapi.DwmApi *)
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;

end;
Delphi-Quellcode:
(* Diese beiden Brechnungen waren nicht korrekt *)
      Result.Right := (R2.Right - R1.Right) + Result.Left; // Rechte Breite des Schattens
      Result.Bottom := (R2.Bottom - R1.Bottom) + Result.Top; // Untere Höhe des Schattens


Ich hoffe, das ist jetzt fehlerfrei :-)

LG Mathias

NoGAD 12. Mai 2024 01:09

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
(Eigener Thread, wegen neuem Code)

Delphi-Quellcode:

Type
  TDimmFormValues = record
    aForm: TForm;
    aParentForm: TForm;
    aDimmed: Boolean;
    aCentered: Boolean;
    aSpaceBelow: Integer;
    aAlphaBlendValue: Integer;
    aBackColor: TColor;
    aFadeIn: Boolean;
    aFadeOut: Boolean;

    class function Init(
      aDimmed: Boolean = True;
      aCentered: Boolean = True;
      aSpaceBelow: Integer = 0;
      aAlphaBlendValue: Integer = 192;
      aBackColor: TColor = clBlack;
      aFadeIn: Boolean = True;
      aFadeOut: Boolean = True): TDimmFormValues; static;
  end;

function ShowModalDimmed(const Dimm_Values: TDimmFormValues): TModalResult;
function GetFormShadow(aForm: TForm): TRect;

implementation

class function TDimmFormValues.Init(
  aDimmed: Boolean = True;
  aCentered: Boolean = True;
  aSpaceBelow: Integer = 0;
  aAlphaBlendValue: Integer = 192;
  aBackColor: TColor = 0;
  aFadeIn: Boolean = True;
  aFadeOut: Boolean = True): TDimmFormValues;
begin
  Result.aDimmed := aDimmed;
  Result.aCentered := aCentered;
  Result.aSpaceBelow := aSpaceBelow;
  Result.aAlphaBlendValue := aAlphaBlendValue;
  Result.aBackColor := aBackColor;
  Result.aFadeIn := aFadeIn;
  Result.aFadeOut := aFadeOut;
end;

function ShowModalDimmed(const Dimm_Values: TDimmFormValues): TModalResult;
var
  Back: TForm;

  Dummy_Rect: TRect;

  targetAlpha: Integer;
  Dummy_Alpha_inc: Integer;
  alphaDiff: Integer;
begin
  (* Hintergrundform abdunkeln *)
  if not Dimm_Values.aDimmed then
  begin
    Result := Dimm_Values.aForm.ShowModal;
    Exit;
  end;

  Back := TForm.Create(nil);
  try
    Back.Position := poDesigned; // poMainFormCenter;
    Back.AlphaBlend := True;

    targetAlpha := Dimm_Values.aAlphaBlendValue;
    if targetAlpha > 255 then
      targetAlpha := 255;
    if targetAlpha < 1 then
      targetAlpha := 1;

    if Dimm_Values.aFadeIn then
      Back.AlphaBlendValue := 1
    else
      Back.AlphaBlendValue := targetAlpha;
    Back.Color := Dimm_Values.aBackColor;
    Back.DoubleBuffered := True;
    Back.BorderStyle := bsNone;

    if Dimm_Values.aParentForm <> nil then
    begin
      Dummy_Rect := GetFormShadow(Dimm_Values.aParentForm);
      Back.SetBounds(Dimm_Values.aParentForm.Left + Dummy_Rect.Left, Dimm_Values.aParentForm.Top + Dummy_Rect.Top, Dimm_Values.aParentForm.Width - Dummy_Rect.Right, Dimm_Values.aParentForm.Height - Dummy_Rect.Bottom);
    end;
    if Dimm_Values.aParentForm = nil then
    begin
      Back.SetBounds(0, 0, Screen.Width, Screen.Height);
    end;
    Back.Show;
    if Dimm_Values.aFadeIn then
    begin
      Dummy_Alpha_inc := Back.AlphaBlendValue;
      while Back.AlphaBlendValue < targetAlpha do
      begin
        alphaDiff := targetAlpha - Back.AlphaBlendValue;
        Inc(Dummy_Alpha_inc, min(alphaDiff, 5));
        Back.AlphaBlendValue := Dummy_Alpha_inc;
        Application.ProcessMessages;
        Sleep(20);
      end;
      Back.AlphaBlendValue := Dimm_Values.aAlphaBlendValue;
    end;

    if Dimm_Values.aCentered then
    begin
      Dimm_Values.aForm.Position := poMainFormCenter; // Keine extra Berechnung notwendig
    end;

    Result := Dimm_Values.aForm.ShowModal;

    if Dimm_Values.aFadeOut then
    begin
      while Back.AlphaBlendValue > 1 do
      begin
        Back.AlphaBlendValue := Back.AlphaBlendValue - 12;
        Application.ProcessMessages;
        Sleep(20);
      end;
    end;
    Back.Hide;
  finally
    Back.Free;
  end;
end;

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;

end;

Falls nun viele Aufrufe von ShowModalDimmed im Code erfolgen, würde ich eine globale Variable nutzen, damit nicht jedes Mal eine neue Variable erstellt werden muss. Durch class function TDimmFormValues.Init kann diese wieder auf die Standardwerte zurück gesetzt werden.

Aufruf (z.B.):

Delphi-Quellcode:
{
[..]
}
var
 Dimm_Values: TDimmFormValues;
{
[..]
}
 Dimm_Values := Dimm_Values.Init();
 Dimm_Values.aForm := Form2;
 Dimm_Values.aParentForm := Form1;
 Dimm_Values.aBackColor := clInfoBk;
 ShowModalDimmed(Dimm_Values);

LG Mathias :-)

DaCoda 12. Mai 2024 06:05

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Hallo Mathias (NoGAD),
der Ansatz ist nicht schlecht, aber es gibt zumindest unter Windows 11 noch ein weiteres Problemchen.
Die Fensterecken können Rund sein, dein Bereich ist aber immer eckig und das sieht dann etwas komisch aus.

Ich habe noch zusätzlich in deinen Code eingefügt:
Code:
 
if aParentForm <> nil then
  Back.RoundedCorners := Dimm_Values.aParentForm.RoundedCorners;

Ansonsten gut gemacht :-)

LG
DaCoda™

NoGAD 12. Mai 2024 07:23

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

Zitat von DaCoda (Beitrag 1536600)

Ich habe noch zusätzlich in deinen Code eingefügt:
Code:
 
if aParentForm <> nil then
  Back.RoundedCorners := Dimm_Values.aParentForm.RoundedCorners;


Ich konnte es unter Windows 11 nicht testen, ist der Feier mit deinem zusätzlichen Code behoben?

LG Mathias

DaCoda 12. Mai 2024 07:51

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
[QUOTE=NoGAD;1536601]
Zitat:

Zitat von DaCoda (Beitrag 1536600)
Ich konnte es unter Windows 11 nicht testen, ist der Feier mit deinem zusätzlichen Code behoben?

LG Mathias

Ja, damit ist das behoben :-)

NoGAD 12. Mai 2024 08:49

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Vielen lieben Dank. :-D

Lieben Gruß Mathias

DaCoda 12. Mai 2024 09:02

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
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;

NoGAD 12. Mai 2024 12:15

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
TForm.RoundedCorners gibt es in Delphi 10.4 nicht. Daher kann ich es auch nicht einsetzen :-)

LG :-)

KodeZwerg 12. Mai 2024 19:19

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
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;

NoGAD 13. Mai 2024 07:40

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

Zitat von KodeZwerg (Beitrag 1536614)
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

KodeZwerg 13. Mai 2024 15:42

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

Zitat von NoGAD (Beitrag 1536619)
Danke. Das ist auch eine sehr schöne Variante.

Sehr gerne!
Zitat:

Zitat von NoGAD (Beitrag 1536619)
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.

NoGAD 14. Mai 2024 06:30

AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
 
Danke für die Erklärung. :-)

LG Mathias


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:10 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