2015-05-26 7 views
1

Я пишу настраиваемый элемент управления в .NET Windows Forms. Рассмотрим следующий код:Capture Window Messages (WM) в WinForms Designer с использованием WndProc

protected override void WndProc(ref Message m) 
{ 
    base.WndProc(ref m); 
    switch(m.Msg) 
    { 
     case WM_LBUTTONDOWN: // Yes, it's defined correctly. 
      MessageBox.Show("Left Button Down"); 
      break; 
    } 
} 

Это работает во время работы, но мне нужно его для работы в дизайнере. Как я могу это достичь?

Примечание:

Я думаю, кто-то может сказать, что «Вы не можете обнаружить щелчки в конструкторе, потому что дизайн поверхности захватывает их и обрабатывает их как часть процесса проектирования»

... Возьмем, например, TabControl. Когда вы добавляете новую вкладку, вы можете щелкнуть, чтобы перемещаться по вкладкам, а затем щелкнуть по назначаемой области вкладки, чтобы начать разработку содержимого вкладки. Как это работает?

+0

Возможно, я что-то пропустил, но как это будет работать? Ваша программа не работает, пока вы смотрите на дизайнера. – Octopoid

+0

@Octopoid. Ваш код по-прежнему работает даже в режиме разработки - определенные сообщения разрешены через цикл WndProc, но, как и в моем комментарии, я думаю, что клики обрабатываются до того, как они достигнут самого элемента управления. (см. обновление) – series0ne

+0

Достаточно честно, я не очень сильно использую конструктора - что происходит, когда вы перемещаете 'base.WndProc (ref m);' до конца метода после обработки вашего события? – Octopoid

ответ

1

Ну, дизайнер ест некоторые из сообщений. Если вы хотите, чтобы все сообщения отправлялись на адрес Control, вам необходимо создать собственный конструктор и отправить его в элемент управления.

См ControlDesigner.WndProc

public class CustomDesigner : ControlDesigner 
{ 
    protected override void WndProc(ref Message m) 
    { 
     DefWndProc(ref m);//Passes message to the control. 
    } 
} 

Затем примените DesignerAttribute к пользовательскому элементу управления.

[Designer(typeof(CustomDesigner))] 
public partial class MyUserControl : UserControl 
{ 
    public MyUserControl() 
    { 
     InitializeComponent(); 
    } 

    protected override void WndProc(ref Message m) 
    { 
     base.WndProc(ref m); 
     const int WM_LBUTTONDOWN = 0x0201; 
     switch (m.Msg) 
     { 
      case WM_LBUTTONDOWN: // Yes, it's defined correctly. 
       MessageBox.Show("Left Button Down"); 
       break; 
     } 
    } 
} 

Перетащите элемент управления в Form, нажмите на нее. Теперь вы также должны увидеть окно сообщения в дизайнере :)

+0

Вы гений! Большое спасибо :-) – series0ne