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 tipoSystem.Windows.Forms.Control
; o qualificador deve ser do tipoTheProject.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: