IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Transparence partielle de Form


Sujet :

Delphi

  1. #1
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut Transparence partielle de Form
    Bonjour,

    Pour la transparence de la zône "client" de Form1, pas de problème.
    Par exemple le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    procedure TForm1.FormResize(Sender: TObject);
    var
      R1, R2 : HRGN;
      ClientLeft, ClientTop:integer;
    begin
         if ClientTransparent=true then
         begin
              ClientLeft:=clientOrigin.X-Left;
              Clienttop:=clientOrigin.Y-Top;
              R1 := CreateRectRgn(Clientleft,ClientTop,ClientLeft+ClientWidth,ClientTop+ClientHeight);
              R2 := CreateRectRgn(0,0,width, height);
              CombineRgn(R1, R1, R2, RGN_XOR);
              SetWindowRgn(handle, R1, true);
              DeleteObject(R1);
              DeleteObject(R2);
         end;
    end;
    Avec ce code, si le boolean "ClientTransparent" est mis à true, la zône client est transparente et les bordures de From1 restent visibles. On voit donc l'image d'écran dans cette zône.
    Je me demande comment il serait possible de réaliser une transparence partielle. C'est à dire pour qu'il apparaisse, dans la zône client de Form1, un mixte de l'image d'écran et du canvas de Form1. Ceci avec un taux de transparence partielle fixé.
    Merci à l'avance pour vos idées et/ou des informations sur des réalisations de ce genre dans des codes déjà existants.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    euh pourquoi ne pas utilise AlphaBlend et AlphaBlendValue, dispo depuis au moins D6 et W2K ! Quoi qu'en relisant ton sujet, tu veux conserver les Bordures, hum, ce que je ne fais pas AlphaBlend !

    Tu peux aussi utiliser ClientRect plus pratique clientOrigin !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ClientTransparent=true then
    c'est rigolo, il existe plus simple !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ClientTransparent then
    Sinon, tu peux récupérer le contenu du Bureau dans un BitMap, après tu as doit pouvoir jouer avec les API pour trouver une variante de BitBlt avec gestion du Alpha, ou le faire à la main, c'est juste

    Pourcent = 0.00 à 1.00
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CanalDest := (CanalForm * Pourcent + CanalDeskTop * (1 - Pourcent)
    C'est globalement pareil si tu préfère un Alpha de 0 à 255
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CanalDest := (CanalForm * Alpha div 255 + CanalDeskTop * ((255 - Alpha) div 255)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    procedure TFrmWindowsRegions.PaintBoxDesktopPaint(Sender: TObject);
    var
      hDesktopWindow: HWND;
      hDesktopWindowDC: HDC;
      hWindowDC: HDC;
    begin
      // GetDesktopWindow() fourni le Handle du Bureau
      // GetWindowDC(...) si tu lui fourni le Handle du Bureau, tu obtiens une sorte de Canvas pour dessiner dessus
      // ReleaseDC(...) Comme d'habitude, on laisse la place propre ...
     
      hDesktopWindow := GetDesktopWindow();
      hDesktopWindowDC := GetWindowDC(HDesktopWindow);
      if hDesktopWindowDC > 0 then
      begin
        BitBlt(PaintBoxDesktop.Canvas.Handle, 0, 0, PaintBoxDesktop.Width, PaintBoxDesktop.Height, hDesktopWindowDC, 0, 0, SRCCOPY);
     
        ReleaseDC(hDesktopWindow, hDesktopWindowDC);
      end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Merci je vais faire des essais selon plusieurs variantes.
    En tout cas cela donne des idées... à tester.

  4. #4
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Bonjour,
    Résultat : Echec de toutes mes tentatives !
    tu peux récupérer le contenu du Bureau dans un BitMap, après tu as doit pouvoir jouer avec les API pour trouver une variante de BitBlt avec gestion du Alpha, ou le faire à la main,
    "Récupérer dans un BitMat (BitMap1) une région rectangulaire du bureau : OK, je sais faire (à condition que Form1 ne soit pas devant la région choisie).
    "Mixer BitMap1 avec le BitMap du canevas de Form1" : je sais faire et le mettre dans BitMap2 : OK.
    "Afficher l'image de BitMap2 sur Form1" : OK, je sais faire.
    Sauf que tout cela ne sert à rien : ce qui est obtenu est une apparence de transparence de Form1 par rapport à la région du bureau choisie, mais qui n'est pas la région du bureau située derrière Form1.
    Si la région du bureau choisie est bien celle située derrière Form1, alors BitMap1 correspond à Form1 et non pas à ce qui est derrière. On n'obtient donc pas une transparence partielle de Form1 comme il était souhaité.
    Merci d'avoir donné suite à ma question (qui reste ouverte).

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Si ça ne te dérange pas de passer par 2 fiches, tu pourrais t'inspirer de ceci.

  6. #6
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Si ça ne te dérange pas de passer par 2 fiches, tu pourrais t'inspirer de ceci.
    Malheureusement ça ne répond pas vraiment au souhait d'avoir la Form1 partiellement transparente par rapport à ce qu'elle cache habituellement.
    Néanmoins, le lien est intéressant en tant qu'exemples et idées pour traiter d'autres problèmes. C'est très instructif.

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Je pense que oui

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    unit Unit8;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
    TBackgroundForm = class(TForm)
      protected
        procedure DoClose(var Action: TCloseAction); override;
        procedure Refresh;
        procedure WMWindowPosChanged(var Message :TMessage); message WM_WINDOWPOSCHANGED;
      public
        constructor CreateNew(AOwner: TComponent; Dummy: Integer  = 0); override;
      end;
     
      TTopForm = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
      private
        BkForm :TBackgroundForm;
      public
        constructor Create(aOwner :TComponent); override;
      end;
     
    var
      TopForm: TTopForm;
     
    implementation
     
    {$R *.dfm}
     
    constructor TTopForm.Create(aOwner: TComponent);
    begin
      inherited;
     
      //Fiche transparente
      BorderStyle           := bsNone;
      TransparentColorValue := Color;
      TransparentColor      := TRUE;
     
      //Fond
      BkForm := TBackgroundForm.CreateNew(Self);
    end;
     
    { TBackgroundForm }
     
    procedure TBackgroundForm.DoClose(var Action: TCloseAction);
    begin
      TForm(Owner).Close;
    end;
     
    constructor TBackgroundForm.CreateNew(AOwner: TComponent; Dummy: Integer);
    begin
      inherited;
      AlphaBlend      := TRUE;
      AlphaBlendValue := 200;
      BoundsRect      := TControl(Owner).BoundsRect;
      Caption         := TForm(Owner).Caption;
      Show;
      Refresh;
    end;
     
     
    procedure TBackgroundForm.WMWindowPosChanged(var Message: TMessage);
    begin
      inherited;
     
      if not (csDestroying in ComponentState) then
        TForm(Owner).BoundsRect := BoundsRect;
    end;
     
    procedure TBackgroundForm.Refresh;
    var
      i  :integer;
      R1, R2 :hRgn;
    begin
      //Découpe les zones où doivent apparaître les Controls
      R1 := CreateRectRgn(0, 0, Width, Height);
     
      with TForm(Owner) do
        for i := 0 to ControlCount -1 do
          with Controls[i].BoundsRect do
        begin
          R2 := CreateRectRgn(Left, Top, Right, Bottom);
          CombineRgn(R1, R1, R2, RGN_XOR);
          DeleteObject(R2);
        end;
     
      SetWindowRgn(handle, R1, TRUE);
      DeleteObject(R1);
    end;
     
    end.
    Il y aurait bien sûr encore quelques événements à rediriger sur la fiche principale (ou inversement), mais le principe est là.

  8. #8
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Salut Andnotor,

    je ne mets pas en doute que ça marche, du moins chez toi ! Et je dis bravo !
    Mais chez moi, il y a des difficultés. Des tas d'erreur à la compilation...
    Certain qu'il me manque quelque chose, quelque part. Disons carrément que je m'y prends comme un pied. Mais avec encore un peu plus d'attention et de travail, cela devrait s'arranger.
    Le problème est que j'ai maintenant beaucoup à faire par ailleurs, en plus urgent et que je suis obligé de laisser de coté cette question de "transparence", qui est secondaire mais très utile à ma formation personnelle.
    J'y reviendrais plus tard et par temps calme.
    Merci pour tout.

    Au fait, si je pouvais avoir l'exécutable, rien que pour voir ce que cela donne, ça renforcerait la motivation à persévérer !

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 420
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 420
    Points : 1 325
    Points
    1 325
    Par défaut
    Bonjour à toutes et à tous,

    @ 5x J, Le code de l'ami AndNotOr, fonctionne correctement sur D6 et Seven 64bits.

    Tu dois forcément nommer ta fiche principale "TopForm" et recopier le reste tout simplement.

    J'ajouterai que la gestion de déplacement des Fiches n'est pas inclue, car si tu déplaces la fiche principale, tu retrouves l'autre derrière.

    @ AndNotOr, toujours à la pointe du progrès

    @+,

    Cincap

Discussions similaires

  1. [ImageMagick] Transparence sur une forme
    Par Woodgate dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 10/02/2007, 01h20
  2. Transparence d'une forme dans une MDIChild
    Par Sub13 dans le forum Delphi
    Réponses: 2
    Dernier message: 14/12/2006, 09h50
  3. Transparence partielle sur IE
    Par speedev dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 23/06/2006, 11h29
  4. [VB6] transparence d'une form
    Par Vesta dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 13/06/2006, 23h05
  5. Comment annuler la transparence d'une Form ?
    Par bubulemaster dans le forum Composants VCL
    Réponses: 3
    Dernier message: 24/10/2005, 19h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo