Метод переопределения C # во время выполнения

У меня есть два вопроса.

1) Я нашел небольшую жемчужину кода для как сделать плавную прокрутку управления .

Отлично. Но он переопределяет метод WndProc, поэтому для его использования мне пришлось вырвать FlowLayoutPanel I ' Я поместил в форму во время разработки подкласс FlowLayoutPanel, а затем, наконец, создал экземпляр моего нового класса, создал все свойства вручную и изменил все ссылки на элемент управления на this.Controls ["ControlName"]. (Или, я думаю, я мог бы создать переменную уровня класса, которая по сути была бы тем же, чем изначально был элемент управления, хотя как они позволяют вам использовать intellisense для него, когда он нигде не объявлен?)

Так что теперь мне просто интересно, есть ли на самом деле это был способ выполнения.

Могу ли я сделать что-то простое, как это, где MainPanel - это имя элемента управления:

MainPanel = (SmoothScrollingFlowLayoutPanel)MainPanel

Это не может быть так просто, не так ли? Несмотря на это, это раздражает, потому что у меня все еще должен быть подкласс (который может быть хорошим дизайнерским решением, но я хотел бы свободы, чтобы исключить его). Поэтому можно ли поместить код в родительский элемент FlowLayoutPanel примерно так:

private Delegate void WndProcHandler(ref Message m);
private WndProcHandler w;

public void SomeCode() {
   w = MainPanel.WndProc; // get reference to existing wndproc method
   MainPanel.WndProc = WndProcSmoothScroll; //replace with new method
}

private void WndProcSmoothScroll(ref Message m) { // make smooth scrolling work
   if (
      (m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL)
      && (((int)m.WParam & 0xFFFF) == 5)
   ) {
      m.WParam = (IntPtr)(((int)m.WParam & ~0xFFFF) | 4);
   }
   if (w != null) { w(); }
   base.WndProc(ref m);
  }

Я понимаю, что это, вероятно, довольно наивно. Я отношусь к методу WndProc как к событию, а не к нему.

2) Итак, мой второй вопрос: если бы WndProc был событием, а не методом, как бы я сделал то же самое - сохранить копию оригинального списка обработчиков для события, сначала установить собственный обработчик событий, а затем вызвать все оригинальные обработчики событий?

ВКУСНЫЕ БИТЫ

На случай, если кому-то будет интересно, я заметил оптимизацию возможно в коде с плавной прокруткой:

//m.WParam = (IntPtr)(((int)m.WParam & ~0xFFFF) | 4);
m.WParam = (IntPtr)((int)m.WParam ^ 1);

Так как мы хотим повернуть последние 16 битов с 5 на 4, мы можем просто перевернуть последний бит (XOR) вместо AND, а затем OR.

5
задан Undo 6 May 2013 в 22:13
поделиться