Tengo dos preguntas.C# Método de anulación en tiempo de ejecución
1) Encontré una pequeña joya de código para how to make a control scroll smoothly.
Genial. Pero anula el método WndProc, así que para usarlo, tuve que arrancar el FlowLayoutPanel que había dejado caer en el formulario en el momento del diseño, la subclase FlowLayoutPanel, y finalmente crear una instancia de mi nueva clase y crear todas las propiedades de forma manual y cambiar todas las referencias al control ser esto. Controles ["ControlName"]. (O supongo que podría hacer una variable de nivel de clase que es esencialmente lo que originalmente era el control, aunque ¿cómo te permiten usar intellisense cuando no está declarado en ninguna parte?)
Así que ahora solo me pregunto si de hecho, había una manera de ejecutarlo para hacerlo.
¿Puedo hacer algo simple como este, donde MainPanel es el nombre del control:
MainPanel = (SmoothScrollingFlowLayoutPanel)MainPanel
No puede ser tan fácil, ¿verdad? Aun así, es molesto porque todavía tengo que tener la subclase (lo que puede ser una buena decisión de diseño, pero me gustaría tener la libertad de hacerlo de manera única). Así sería posible poner el código en la matriz de la FlowLayoutPanel algo como esto:
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);
}
Comprendo que esto es probablemente bastante ingenua. Estoy tratando el método WndProc como si fuera un evento, y no lo es.
2) Así que mi segunda pregunta es, si WndProc era un evento en lugar de un método, ¿cómo iba a hacer lo mismo que la tienda una copia de la lista original de los manipuladores para un evento, instalar mi propio evento controlador para ejecutar primero, luego llamar a todos los controladores de eventos originales?
BITS SABROSOS
En caso de que alguien está interesado me di cuenta de una optimización posible en el código desplazamiento suave:
//m.WParam = (IntPtr)(((int)m.WParam & ~0xFFFF) | 4);
m.WParam = (IntPtr)((int)m.WParam^1);
Dado que queremos convertir los últimos 16 bits de 5 a 4, que puede simplemente voltear el último bit (XOR) en lugar de Y luego O.
Gracias Zach, pero ya he logrado que mis ventanas se desplacen sin problemas. Solo odiaba cómo tenía que quitarle el control al diseñador y hacer todo de forma dinámica. – ErikE
@Emtucifor: No hay problema, solo quería hacerle saber que no tenía que heredar de 'FlowLayoutPanel' para anular su' WndProc'. –
Oh, ahora lo entiendo. Gracias. Confieso que no leí tan cuidadosamente como debería haberlo hecho. ¡Esto es útil! De hecho, estás 100% en lo cierto, es la respuesta que estaba buscando. (golpea la frente) – ErikE