Eventos de passagem do mouse para o controle pai

Ambiente: .NET Framework 2.0, VS 2008.

Eu estou tentando criar uma subclass de determinados controles do .NET (label, painel) que passará por determinados events de mouse ( MouseDown , MouseMove , MouseUp ) para seu controle pai (ou alternativamente para o formulário de nível superior). Eu posso fazer isso criando manipuladores para esses events em instâncias dos controles padrão, por exemplo:

 public class TheForm : Form { private Label theLabel; private void InitializeComponent() { theLabel = new Label(); theLabel.MouseDown += new MouseEventHandler(theLabel_MouseDown); } private void theLabel_MouseDown(object sender, MouseEventArgs e) { int xTrans = eX + this.Location.X; int yTrans = eY + this.Location.Y; MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta); this.OnMouseDown(eTrans); } } 

Não posso mover o manipulador de events para uma subclass do controle, porque os methods que elevam os events no controle pai são protegidos e não tenho um qualificador para o controle pai:

Não é possível acessar membro protegido System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs) por meio de um qualificador do tipo System.Windows.Forms.Control ; o qualificador deve ser do tipo TheProject.NoCaptureLabel (ou derivado dele).

Eu estou olhando para replace o método WndProc do controle na minha subclass, mas espero que alguém possa me dar uma solução mais limpa.

Sim. Depois de muita pesquisa, eu encontrei o artigo “Controles flutuantes, estilo de dica de ferramenta” , que usa WndProc para alterar a mensagem de WM_NCHITTEST para HTTRANSPARENT , tornando o Control transparente para events de mouse.

Para conseguir isso, crie um controle herdado de Label e simplesmente adicione o seguinte código.

 protected override void WndProc(ref Message m) { const int WM_NCHITTEST = 0x0084; const int HTTRANSPARENT = (-1); if (m.Msg == WM_NCHITTEST) { m.Result = (IntPtr)HTTRANSPARENT; } else { base.WndProc(ref m); } } 

Eu testei isso no Visual Studio 2010 com o .NET Framework 4 Client Profile.

Você precisa escrever um método público / protegido em sua class base, o que aumentará o evento para você. Em seguida, chame esse método da class derivada.

OU

É isso que voce quer?

 public class MyLabel : Label { protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); //Do derived class stuff here } } 

O estilo de janela estendida WS_EX_TRANSPARENT realmente faz isso (é o que as dicas de ferramentas locais usam). Você pode querer considerar a aplicação desse estilo em vez de codificar muitos manipuladores para fazer isso por você.

Para fazer isso, substitua o método CreateParams :

 protected override CreateParams CreateParams { get { CreateParams cp=base.CreateParams; cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT return cp; } } 

Para mais informações: