2009-03-14 5 views
8

J'ai besoin d'un moyen pour un contrôle personnalisé (descendant de TCustomControl) de dire s'il est actuellement visible. Je ne parle pas de la propriété .Visible; Je veux dire si oui ou non il est actuellement affiché à l'écran pour le moment. Est-ce que quelqu'un sait comment faire ça?Comment puis-je savoir si un contrôle Delphi est actuellement visible?

+0

Voulez-vous dire si oui ou non il est couvert par une autre fenêtre? –

+0

Je veux dire si cela attire ou non l'écran. Être couvert pourrait être une raison. Un autre pourrait être si il a été placé sur un formulaire qui a été créé mais pas encore montré. –

Répondre

15

Il y a quelques années, j'ai eu le même genre de problème pour un formulaire: je cherchais un moyen de déterminer si un formulaire est réellement visible (même partiellement) à l'utilisateur.
En particulier quand il était supposé être visible et Montrer était vrai mais la fenêtre était en réalité entièrement derrière une autre.
est ici le code, il pourrait être adapté pour une 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; 
+0

Merci! C'est exactement ce que je cherchais. –

2

Pourriez-vous joindre un code à l'événement OnPaint? Ceci est appelé très souvent et je pense qu'il n'est appelé que lorsque le contrôle va réellement être peint (par exemple, il est visible de la manière que vous voulez dire).

+0

J'irais avec cela comme un meilleur indicateur. Vous ne pouvez jamais être sûr car dans Vista toutes les applications dessinent sur un bitmap hors écran qui est ensuite composé dans la carte graphique avec les superpositions, etc. – mj2008

+0

Mais il est probable qu'il ne soit retiré de l'écran que s'il est affiché à l'écran pour le moment ? –

+1

Je ne pense pas qu'il soit sûr de supposer que WM_PAINT viendra seulement quand ces pixels sont sur le point de frapper l'écran. Avec Desktop Composition (http://msdn.microsoft.com/en-us/library/aa969540%28VS.85%29.aspx), Windows conserve un cache de fenêtres dessinées pour des effets tels que Windows Flip (http: // www. microsoft.com/windows/windows-vista/features/flip-3d.aspx) qui peut nécessiter * toutes * les fenêtres à la fois. À cause de cela, je m'attendrais à ce qu'il y ait des rafraîchissements d'arrière-plan. –

1

Je pense que c'est ce que TWinControl.Showing est pour. Je ne suis pas sûr de sa fiabilité.

+1

Cela ne fonctionne pas pour un formulaire par exemple. Une Forme peut être complètement derrière une autre et avoir toujours une Vraie Vraie. –

+0

Comme je l'ai dit, je n'avais aucune idée à quel point c'était complet. –

+2

L'affichage uniquement vous indique si tous les contrôles parents sont visibles. Il différencie certaines situations en mode design, où f.e. les composants non visibles sont visibles. Donc, il vous indique si le composant s'il est affiché pour le moment serait visible. –

Questions connexes