У меня два вопроса.
1) Я нашел небольшую жемчужину кода для , как сделать плавную прокрутку управления .
Отлично. Но он переопределяет метод WndProc, поэтому для его использования мне пришлось вырвать FlowLayoutPanel, который я сбросил на форму во время разработки, создать подкласс FlowLayoutPanel, а затем, наконец, создать экземпляр моего нового класса и создать все свойства вручную и изменить все ссылки к элементу управления, чтобы быть этим. 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) вместо И, затем ИЛИ.