Comment savoir si un contrôle Delphi est actuellement visible?
-
22-07-2019 - |
Question
J'ai besoin d'un moyen pour un contrôle personnalisé (dérivé de TCustomControl) pour savoir s'il est actuellement visible. Je ne parle pas de la propriété .Visible; Je veux dire si oui ou non cela est réellement affiché à l'écran pour le moment. Est-ce que quelqu'un sait comment faire cela?
La solution
Il y a quelques années, j'avais le même type de problème pour un formulaire: je cherchais un moyen de déterminer si un formulaire était réellement visible (même partiellement) par l'utilisateur.
En particulier quand elle était supposée être visible et que Showing était vrai, mais que la fenêtre était entièrement derrière une autre.
Voici le code, il pourrait être adapté pour un WinControl ...
{----------------------------------------------------------}
function IsMyFormCovered(const MyForm: TForm): Boolean;
var
MyRect: TRect;
MyRgn, TempRgn: HRGN;
RType: Integer;
hw: HWND;
begin
MyRect := MyForm.BoundsRect; // screen coordinates
MyRgn := CreateRectRgnIndirect(MyRect); // MyForm not overlapped region
hw := GetTopWindow(0); // currently examined topwindow
RType := SIMPLEREGION; // MyRgn type
// From topmost window downto MyForm, build the not overlapped portion of MyForm
while (hw<>0) and (hw <> MyForm.handle) and (RType <> NULLREGION) do
begin
// nothing to do if hidden window
if IsWindowVisible(hw) then
begin
GetWindowRect(hw, MyRect);
TempRgn := CreateRectRgnIndirect(MyRect);// currently examined window region
RType := CombineRgn(MyRgn, MyRgn, TempRgn, RGN_DIFF); // diff intersect
DeleteObject( TempRgn );
end; {if}
if RType <> NULLREGION then // there's a remaining portion
hw := GetNextWindow(hw, GW_HWNDNEXT);
end; {while}
DeleteObject(MyRgn);
Result := RType = NULLREGION;
end;
function IsMyFormVisible(const MyForm : TForm): Boolean;
begin
Result:= MyForm.visible and
isWindowVisible(MyForm.Handle) and
not IsMyFormCovered(MyForm);
end;
Autres conseils
Pourriez-vous attacher du code à l'événement OnPaint? C’est ce qu’on appelle très souvent, et je pense que cela n’est appelé que lorsque le contrôle va réellement être peint (par exemple, il est visible dans la façon dont vous voulez dire).
Je pense que c'est à cela que sert TWinControl.Showing. Je ne suis pas sûr de sa fiabilité.