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

API, COM et SDKs Delphi Discussion :

Intercepter WM_ENTERSIZEMOVE dans Twincontrol


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre éclairé
    Avatar de castorcharly
    Homme Profil pro
    Chef de projet
    Inscrit en
    Février 2009
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Dordogne (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2009
    Messages : 423
    Par défaut Intercepter WM_ENTERSIZEMOVE dans Twincontrol
    Bonjour,

    Je cherche le moyen d'intercepter les messages WM_ENTERSIZEMOVE et WM_EXITSIZEMOVE dans un TwinControl.
    Je suppose qu'ils sont envoyé exclusivement aux Tform et non diffusé aux controls enfants...

    WndProc de la form parent au Twincontrol, reçoit bien ces messages, mais je n'arrive pas à les recevoir dans mon Twincontrol.

    Bien sur, si je mets un Broadcast dans la gestion de ces messages dans la Tform, là je peux les intercepter, mais l'objectif est que le Twincontrol soit indépendant de la forme.

    Je me demande s'il ne serait pas possible dans le code de ce Twincontrol (autre que la form), de récupérer/intercepter ces messages ?

    Merci pour vos suggestion,

  2. #2
    Membre très actif
    Homme Profil pro
    libre
    Inscrit en
    Juin 2019
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Juin 2019
    Messages : 205
    Par défaut
    Je cherche le moyen d'intercepter les messages WM_ENTERSIZEMOVE et WM_EXITSIZEMOVE dans un TwinControl.
    Je suppose qu'ils sont envoyé exclusivement aux Tform et non diffusé aux controls enfants...
    Il existe plusieurs niveaux pour intercepter les messages .. individuellement on passe par WindowProc utilisé dans chaque wincontrol qui permet de contrôler la majorité des messages .
    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
     
    unit Unit2;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
     
    type
      TForm2 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
         OldProc:TWndMethod;
         procedure NewProc(var Message: TMessage);
      public
     
      end;
     
    var
      Form2: TForm2;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm2.FormCreate(Sender: TObject);
    begin
       OldProc:=WindowProc;
       WindowProc:=NewProc;
    end;
     
    procedure TForm2.NewProc(var Message: TMessage);
    begin
       OldProc(Message);
       if Message.Msg=WM_EXITSIZEMOVE then
         caption:=inttostr(random(1000));
    end;
     
    end.
    Il semble que le code ne fonctionne que pour la fiche principale pour les contrôles il faudrait utiliser le message WM_WINDOWPOSCHANGED

  3. #3
    Membre éclairé
    Avatar de castorcharly
    Homme Profil pro
    Chef de projet
    Inscrit en
    Février 2009
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Dordogne (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2009
    Messages : 423
    Par défaut
    Oui Wheel, c'est ce que j'ai vu, comme je le dis dans mon message, ces events ne sont pas diffusés aux Controls enfants.
    Seules les Tform les reçoivent.
    C'est pour ça que je demande s'il existe une possibilité d'intercepter les messages qui arrivent à une Form, à partir d'un Twincontrol.

    Mais merci d'avoir jeté un oeil,

    Castor

  4. #4
    Membre émérite
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Par défaut
    Bonjour,


    les messages WM_ENTERSIZEMOVE et WM_EXITSIZEMOVE ne sont pas diffusés aux contrôles enfants

    mais si tu rends ton contrôle déplaçable exemple un TPanel comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm3.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      ReleaseCapture;
      TControl(Sender).Perform(WM_SYSCOMMAND, SC_MOVE or HTCAPTION, 0);
    end;
    ces messages seront bien envoyés au panel
    pour intercepter le déplacement et le redimensionnement d'un contrôle enfant tu peux passer par WM_MOVE et WM_SIZE
    2 Méthodes testées ici:
    1 par WndProc
    1 par les messages directement

    ps: ne pas les activer ensemble pour les voir fonctionner ... l'un prend le pas sur l'autre
    Ex.
    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
      TPanel = class(ExtCtrls.TPanel)
      protected
        procedure WndProc(var Message: TMessage); override;
        procedure WMSize(var Msg: TMessage); message WM_SIZE;
        procedure WMMove(var Msg: TMessage); message WM_MOVE;
        procedure WMEnterSizeMove(var Msg: TMessage); message WM_ENTERSIZEMOVE;
        procedure WMExitSizeMove(var Msg: TMessage); message WM_EXITSIZEMOVE;
      end;
     
      TForm3 = class(TForm)
        Panel1: TPanel;
        procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
    ...
    implementation
     
    { TPanel }
     
    procedure TPanel.WMEnterSizeMove(var Msg: TMessage);
    begin
      Caption := Format('WMEnterSizeMove message %d', [random(1000)]);
    end;
     
    procedure TPanel.WMExitSizeMove(var Msg: TMessage);
    begin
      Caption := Format('WMExitSizeMove message %d', [random(1000)]);
    end;
     
    procedure TPanel.WMMove(var Msg: TMessage);
    begin
      Caption := Format('WMMove message %d', [random(1000)]);
    end;
     
    procedure TPanel.WMSize(var Msg: TMessage);
    begin
      Caption := Format('WMSize message %d', [random(1000)]);
    end;
     
     
    procedure TPanel.WndProc(var Message: TMessage);
    begin
      if Message.Msg = WM_ENTERSIZEMOVE then
        Caption := Format('WndProc WMEnterSizeMove message %d', [random(1000)]);
      if Message.Msg = WM_EXITSIZEMOVE then
        Caption := Format('WndProc WMExitSizeMove message %d', [random(1000)]);
      if Message.Msg = WM_SIZE then
        Caption := Format('WndProc WMSize message %d', [random(1000)]);
      if Message.Msg = WM_MOVE then
        Caption := Format('WndProc WMMove message %d', [random(1000)]);
      inherited;
    end;
    Cordialement,

    @+

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 921
    Par défaut
    Il y a toujours la possibilité de passer par un hook pour intercepter ces messages mais bien sûr une dll serait un peu lourde pour ça. Une autre façon de procéder est la surveillance des événements Windows.

    Une fiche avec un panel :
    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
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
     
    type
      TPanel = class(Vcl.ExtCtrls.TPanel)
      private
        class var WatchWnd :THandle;
        class var NotifyTo :TPanel;
        class procedure WinEventProc(hWinEventHook: THandle; aEvent: dword; aWnd: hWnd; aObject, aChild: cardinal; aEventThread, aEventTime: dword); static; stdcall;
      private
        Hook :THandle;
      protected
        procedure   SetParent(aParent :TWinControl); override;
        procedure   OnWindowMoveSizeStart;
        procedure   OnWindowMoveSizeEnd;
      public
        constructor Create(aOwner :TComponent); override;
        destructor  Destroy; override;
      end;
     
      TForm1 = class(TForm)
        Panel1: TPanel;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    { TPanel }
     
    constructor TPanel.Create(aOwner: TComponent);
    begin
      inherited;
     
      NotifyTo := Self;
      Hook     := SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART, EVENT_SYSTEM_MOVESIZEEND, 0, @WinEventProc, 0, GetCurrentThreadID, WINEVENT_OUTOFCONTEXT);
    end;
     
    destructor TPanel.Destroy;
    begin
      UnhookWinEvent(Hook);
     
      inherited;
    end;
     
    procedure TPanel.SetParent(aParent :TWinControl);
    begin
      inherited;
     
      if Assigned(aParent) then
        WatchWnd := GetAncestor(Handle, GA_ROOT);
    end;
     
    procedure TPanel.OnWindowMoveSizeEnd;
    begin
      Caption := 'End';
    end;
     
    procedure TPanel.OnWindowMoveSizeStart;
    begin
      Caption := 'Start';
    end;
     
    class procedure TPanel.WinEventProc(hWinEventHook: THandle; aEvent: dword; aWnd: hWnd; aObject, aChild: cardinal; aEventThread, aEventTime: dword);
    begin
      if aWnd = WatchWnd then
        case aEvent of
          EVENT_SYSTEM_MOVESIZESTART : NotifyTo.OnWindowMoveSizeStart;
          EVENT_SYSTEM_MOVESIZEEND   : NotifyTo.OnWindowMoveSizeEnd;
        end;
    end;
     
    end.
    J'ai dérivé un TPanel par simplification pour cette démo mais ça devrait être une classe particulière (dû aux class var), voire une classe spécialisée avec une liste fenêtre/contrôle à surveiller/notifier.

  6. #6
    Membre éclairé
    Avatar de castorcharly
    Homme Profil pro
    Chef de projet
    Inscrit en
    Février 2009
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Dordogne (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2009
    Messages : 423
    Par défaut
    Merci Cirec et merci andnotor,

    Je vais regarder attentivement ce que vous me proposez,
    je reviendrai vous dire ce qu'il en est.

    Merci encore

  7. #7
    Membre éclairé
    Avatar de castorcharly
    Homme Profil pro
    Chef de projet
    Inscrit en
    Février 2009
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Dordogne (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2009
    Messages : 423
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Il y a toujours la possibilité de passer par un hook pour intercepter ces messages mais bien sûr une dll serait un peu lourde pour ça. Une autre façon de procéder est la surveillance des événements Windows.
    AndNotOr,

    Je te confirme que ça fonctionne tip top ton code
    Une fois implémenté dans mon composant, c'est tout aussi nickel,
    me reste plus qu'a tester pour l'utilité finale.

    Merci infiniment,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Interception Evénement dans applic WPF lancé par WPF UserControl
    Par roxytbl dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 27/12/2010, 17h01
  2. Intercepter key dans un datagridviewcombo
    Par olibara dans le forum Windows Forms
    Réponses: 3
    Dernier message: 04/04/2010, 10h46
  3. Réponses: 2
    Dernier message: 28/07/2009, 08h15
  4. Intercepter message dans stringgrid
    Par CharleLéo dans le forum API, COM et SDKs
    Réponses: 0
    Dernier message: 14/02/2009, 11h29
  5. Comment intercepter WM_KEYDOWN dans un TPopupMenu ?
    Par lejert dans le forum Composants VCL
    Réponses: 4
    Dernier message: 12/11/2007, 09h44

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