![]() |
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: ![]() 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 |
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 :-) |
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™ |
AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
Zitat:
Ich konnte es unter Windows 11 nicht testen, ist der Feier mit deinem zusätzlichen Code behoben? LG Mathias |
AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
[QUOTE=NoGAD;1536601]
Zitat:
|
AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
Vielen lieben Dank. :-D
Lieben Gruß Mathias |
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:
Function:
ShowModalDimmed(Form, nil);
ShowModalDimmed(Form, ParentForm); ShowModalDimmed(Form, ParentForm, Alphablend, BackColor, Centered);
Code:
Und die Function von Mathias (NoGAD):
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;
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; |
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 :-) |
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:
Beispiel:
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;
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; |
AW: Hintergrundform abdunkeln, wenn andere Form Modal geöffnet wird?
Zitat:
Leider verstehe ich nicht, warum die Fensterfarbe immer in einem Grauton erscheint, selbst wenn ich
Delphi-Quellcode:
in
if (Color < 31) then
WndClass.hbrBackground := GetSysColorBrush(Color) else WndClass.hbrBackground := GetSysColorBrush(COLOR_WINDOW);
Delphi-Quellcode:
umwandle.
WndClass.hbrBackground := Color;
{ Aufruf } CreateHidden(clBlack, True, 192, False, False); LG Mathias |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:36 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