2009-11-02 5 views
1

J'essaie de dessiner sur l'ensemble de l'écran en utilisant la toile de bureau et de peindre directement. Le problème est que je ne peux pas effacer cette toile de bureau. J'ai essayé de placer le canvas.pen.style à psNotXOR et de dessiner sur l'ancienne image mais malheureusement, ce n'est pas assez fiable et quelques restes sont toujours présents dans certaines conditions.Dessiner et effacer la toile de bureau avec Delphi

Mon besoin est de dessiner un rectangle de sélection autour d'une fenêtre/commande lorsque la souris est dessus.

Répondre

5

Vous n'écrivez pas sur quel OS vous avez des problèmes avec les artefacts après l'effacement. Au moins avec la composition du bureau activée, c'est une très mauvaise idée de dessiner directement sur le bureau et de faire de la peinture XOR (voir "Dessiner et lire depuis l'écran - Baaaad!" Dans this blog post). Mis à part les conséquences négatives sur les performances, vous ne pouvez pas être sûr que les autres peintures se produisent en même temps et quels effets et animations modifient le contenu affiché, un simple XOR peut donc ne pas suffire à tout effacer complètement.

Une façon possible de l'implémenter serait une fenêtre de superposition transparente de taille de bureau, et de dessiner votre sélecteur de bande élastique par-dessus. Invalider toute la fenêtre si les changements de taille devraient suffire, pas besoin d'effacer l'ancienne ligne de sélection. Si la superposition est supprimée, la ligne sera également supprimée. La composition du bureau assurera qu'aucun scintillement ne se produira. Cependant, changer d'application en sélectionnant une zone sera problématique, vous devez l'attraper et annuler immédiatement la sélection.

Edit:

Je viens de tester avec Delphi 2009, et avec l'application de test suivant:

  • un formulaire avec FormStyle ensemble à fsStayOnTop et AlphaBlend ensemble à True
  • avec une méthode CreateParams() surchargée pour ajouter le drapeau de style étendu WS_EX_TRANSPARENT

Je peux passer tous les clics de souris aux fenêtres sous-jacentes tout en étant capable de dessiner dans une fenêtre au-dessus d'eux. Cela devrait vous aider à démarrer.

+0

Je pensais à ce sujet mais le problème est que Windows ne me rendra pas le contrôle derrière la souris alors. Ou le sera-t-il? Venez y penser, si la toile est transparente, cela pourrait faire l'affaire. Je vais essayer ça. Merci pour la réponse très détaillée et utile. – jonjbar

+0

Eh bien, la sélection ne fonctionne pas et la fenêtre de niveau supérieur est toujours celle derrière la souris. – jonjbar

+0

Désolé, je ne comprends pas. Commencez-vous la sélection en cliquant avec la souris sur le bureau et commencez à la faire glisser? Si oui, comment l'attraper avec un hook de souris global (bas niveau)? Ou créez-vous la superposition (dans un mode de sélection spécial) et démarrez la sélection en cliquant dessus? Peut-être pourriez-vous développer votre question avec plus de détails. – mghie

0

J'ai fait des choses comme ça dans le passé et je n'ai jamais trouvé de solution acceptable. Après avoir réfléchi à ce sujet, vous pouvez envoyer une commande d'invalidation au bureau HWND.

Parce que le bureau est un contrôle ListView modifié, vous devriez pouvoir utiliser quelque chose comme

procedure InvalidateDesktop; 
begin 
    RedrawWindow(GetDesktopWindow, 0, 0, RDW_INVALIDATE); 

    //if that doesn't work then try this: 
    //Sendmessage(GetDesktopWindow, wm_setredraw, 1, 0); 
end; 

Cela pourrait faire ce que vous voulez, je ne l'ai pas testé comme je l'ai juste frappé vers le haut pour l'exemple .

+0

La listview visible est juste un enfant du 'HWND' retourné par' GetDesktopWindow() ', donc cela ne fonctionnera probablement pas tel quel. – mghie

+0

J'ai dit que je ne l'avais pas testé.

+0

Comme mghie prévu, cela ne fonctionne pas malheureusement. Merci pour la réponse, Ryan. – jonjbar

-2

Voici comment nous le faisons dans notre application:

FBitmap.Canvas.Brush.Color := clWhite; 
    FBitmap.Canvas.FillRect(FBitmap.Canvas.ClipRect); 
+0

-1 ce n'est pas la "compensation" demandée par le PO. Au lieu de cela, il peint un rectangle blanc. – jpfollenius

+0

Ah, chéri. N'a pas lu la question correctement. –

0

le problème est que Windows ne me retourner le contrôle derrière la souris

Je pense vous devez accrocher les messages d'événement de la souris pour cela - le message accroché vous donne alors le handle de fenêtre que la souris est terminée.

Recherchez SetWindowsHookEx (WH_MOUSE ,,,) et MOUSEHOOKSTRUCT.

+0

Je suis déjà en train d'utiliser un hook de souris global pour récupérer le handle de la fenêtre mais quand je crée une fenêtre de haut niveau, même si elle est transparente, Windows sélectionne toujours son handle :( – jonjbar

Questions connexes