{*------------------------------------------------------------------------------ Unité permettant de désactiver une form lorsqu'elle appelle un showmodal pour en afficher une autre(Avec différentes méthodes : griser, assombrir, eclaircir) @Author tiki06 (Avec l'aide de Sub0) @Version 02-août-2006 Version initiale @Version 04-août-2006 Changement complet dans la manière de griser les fenêtres @Version 07-août-2006 Correction pour le problème des scrollBar quand il y a une StatusBar sur la Form. Ajout de différente méthodes pour désactiver la Form : Griser, Assombrir, Eclaircir @Version 09-août-2006 Ajout d'un test lors d'appel de la fonction avec une Form=nil -------------------------------------------------------------------------------} Unit UDisableForm; Interface Uses Windows, Forms, Types, Graphics, ExtCtrls, SysUtils, Controls, Math; const PIXELCOUNTMAX = 32768; WS_EX_LAYERED = $80000; FRAME_NAME = 'DisableFrame'; DEFAULT_PERCENT = 40; type pRGBArray = ^TRGBArray; TRGBArray = ARRAY[0..PIXELCOUNTMAX-1] OF TRGBTriple; TFormToDisable = (FdCurrentWindow, FdAllWindows); TDisableMethod = (DmGrayscaleForm, DmDarkForm, DmLightForm); Procedure ChangerCouleursPixels(Var PixelAChanger:TRGBTriple; DisableMethod:TDisableMethod; Pourcentage: Integer); Procedure GriserFenetre(FenetreAGriser: TForm; DisableMethod:TDisableMethod; Pourcentage: Integer); Procedure ReactiverFenetreNormal(FenetreAReactiver: TForm); Function CustomShowModal(Fenetre: TForm; FormToDisable: TFormToDisable = FdCurrentWindow; DisableMethod:TDisableMethod = DmGrayscaleForm; Pourcentage : Integer = DEFAULT_PERCENT):integer; implementation var bVertScrl, bHorzScrl : Boolean; {*------------------------------------------------------------------------------ procedure pour changer la couleur d'un pixel passé en paramètre @param PixelAChanger Pixel sur lequel il faut changer la couleur @param DisableMethod Méthode pour désactiver la Form : Griser : DmGrayscaleForm Assombrir : DmDarkForm Eclaircir : DmLightForm @param Pourcentage Pourcentage pour les méthodes Assombrir et Eclaircir -------------------------------------------------------------------------------} Procedure ChangerCouleursPixels(Var PixelAChanger:TRGBTriple; DisableMethod:TDisableMethod; Pourcentage: Integer); Var icolor : integer; r,g,b : byte; begin Case DisableMethod of DmGrayscaleForm: /// Griser la Form begin r:=PixelAChanger.rgbtRed; g:=PixelAChanger.rgbtGreen; b:=PixelAChanger.rgbtBlue; icolor:=(r+g+b) div 3; PixelAChanger.rgbtRed := icolor; PixelAChanger.rgbtGreen := icolor; PixelAChanger.rgbtBlue := icolor; end; DmDarkForm: /// Assombrir la Form begin r:=PixelAChanger.rgbtRed; g:=PixelAChanger.rgbtGreen; b:=PixelAChanger.rgbtBlue; PixelAChanger.rgbtRed := Max(Min(Round(r*Pourcentage/100), 255), 0); PixelAChanger.rgbtGreen := Max(Min(Round(g*Pourcentage/100), 255), 0); PixelAChanger.rgbtBlue := Max(Min(Round(b*Pourcentage/100), 255), 0); end; DmLightForm: /// Eclaircir la Form begin r:=PixelAChanger.rgbtRed; g:=PixelAChanger.rgbtGreen; b:=PixelAChanger.rgbtBlue; PixelAChanger.rgbtRed := Round(R*Pourcentage/100) + Round(255 - Pourcentage/100*255); PixelAChanger.rgbtGreen := Round(G*Pourcentage/100) + Round(255 - Pourcentage/100*255); PixelAChanger.rgbtBlue := Round(B*Pourcentage/100) + Round(255 - Pourcentage/100*255); end; end; end; {*------------------------------------------------------------------------------ procedure pour griser la fenêtre passé en paramètre @param FenetreAGriser Form a griser @param DisableMethod Méthode pour désactiver la Form : Griser : DmGrayscaleForm Assombrir : DmDarkForm Eclaircir : DmLightForm @param Pourcentage Pourcentage pour les méthodes Assombrir et Eclaircir -------------------------------------------------------------------------------} Procedure GriserFenetre(FenetreAGriser: TForm; DisableMethod:TDisableMethod; Pourcentage: Integer); var WindowHandle : THandle; deviceContext : HDC; BitmapForm : Tbitmap; iheight,iwidth : integer; RowOriginal : pRGBArray; FrameGrise : TFrame; begin if (FenetreAGriser.FindComponent(FRAME_NAME)=nil) then begin bHorzScrl:=FenetreAGriser.HorzScrollBar.Visible; bVertScrl:=FenetreAGriser.VertScrollBar.Visible; FenetreAGriser.HorzScrollBar.Visible:=False; FenetreAGriser.VertScrollBar.Visible:=False; WindowHandle:= FenetreAGriser.Handle; deviceContext:= GetDC(WindowHandle); try BitmapForm := Tbitmap.Create; BitmapForm.PixelFormat := pf24bit; BitmapForm.Width := FenetreAGriser.ClientWidth; BitmapForm.Height := FenetreAGriser.ClientHeight; BitBlt(BitmapForm.Canvas.Handle, 0, 0, BitmapForm.Width, BitmapForm.Height, deviceContext, 0, 0, SRCCOPY); finally ReleaseDC(WindowHandle, deviceContext); end; for iHeight := 0 to BitmapForm.height-1 do begin RowOriginal := pRGBArray(BitmapForm.Scanline[iHeight]); for iWidth := 0 to BitmapForm.width-1 do begin ChangerCouleursPixels(RowOriginal[iWidth],DisableMethod,Pourcentage); end; end; with TFrame.Create(FenetreAGriser) do begin Visible:=False; Name:=FRAME_NAME; Parent:=FenetreAGriser; Left:=0; Top:=0; Width:=FenetreAGriser.ClientWidth; Height:=FenetreAGriser.ClientHeight; HorzScrollBar.Visible:=False; VertScrollBar.Visible:=False; BringToFront; FrameGrise:=(FenetreAGriser.FindComponent(FRAME_NAME) as TFrame); with TImage.Create(FenetreAGriser) do begin Align:=alClient; Parent:=FrameGrise; Picture.Bitmap.Assign(BitmapForm); end; Visible:=True; end; end; end; {*---------------------------------------------------------------------------- procedure pour réactiver une fenêtre grisé @param FenetreAReactiver Form a réactiver -----------------------------------------------------------------------------} Procedure ReactiverFenetreNormal(FenetreAReactiver: TForm); var FrameGrise:TFrame; begin FenetreAReactiver.HorzScrollBar.Visible:=bHorzScrl; FenetreAReactiver.VertScrollBar.Visible:=bVertScrl; FrameGrise:=(FenetreAReactiver.FindComponent(FRAME_NAME) as TFrame); if FrameGrise<>nil then FreeAndNil(FrameGrise); end; {*---------------------------------------------------------------------------- Fonction pour afficher une fenêtre en showmodal et griser soit toutes les fenêtres affichées, soit juste celle qui appelle le showmodal @param Fenetre Form a afficher en Showmodal @param FormToDisable Paramètre optionnel pour déterminer si on grise toutes les fenêtres (FdAllWindows) ou seulement celle qui appelle le showmodal (FdCurrentWindow) @param DisableMethod Méthode pour désactiver la Form : Griser : DmGrayscaleForm Assombrir : DmDarkForm Eclaircir : DmLightForm @param Pourcentage Pourcentage pour les méthodes Assombrir et Eclaircir -----------------------------------------------------------------------------} Function CustomShowModal(Fenetre: TForm; FormToDisable: TFormToDisable; DisableMethod:TDisableMethod; Pourcentage : Integer):integer; var i : integer; bAppliMdi : Boolean; begin Result:=0; if Fenetre<>nil then begin bAppliMdi:=Screen.ActiveForm.FormStyle=fsMDIChild; if FormToDisable=FdCurrentWindow then GriserFenetre(Screen.ActiveForm,DisableMethod,Pourcentage) else begin if bAppliMdi then GriserFenetre(Application.MainForm,DisableMethod,Pourcentage) else begin for i:=0 to Screen.FormCount-1 do begin if (Screen.Forms[i]<>nil) and (Screen.Forms[i]<>Fenetre) and (Screen.Forms[i].Visible) and (Screen.Forms[i].FormStyle in [fsNormal,FsStayOnTop]) then GriserFenetre(Screen.Forms[i],DisableMethod,Pourcentage) end; end; end; Result:=Fenetre.ShowModal; if FormToDisable=FdCurrentWindow then ReactiverFenetreNormal(Screen.ActiveForm) else begin if bAppliMdi then ReactiverFenetreNormal(Application.MainForm) else begin for i:=0 to Screen.FormCount-1 do begin if (Screen.Forms[i]<>nil) and (Screen.Forms[i]<>Fenetre) and (Screen.Forms[i].Visible) and (Screen.Forms[i].FormStyle in [fsNormal,FsStayOnTop]) then ReactiverFenetreNormal(Screen.Forms[i]) end; end; end; end; end; End.