¿Cómo proporcionar animación en un elemento de menú dibujado por el propietario?
-
25-10-2019 - |
Pregunta
Mi aplicación está en C# 3.5, Winforms, pero esto probablemente requerirá P/Invoke de todos modos, por lo que no está tan estrictamente vinculado a .NET.
He creado elementos de menú dibujados por el propietario a través de ContextMenu
y MenuItem
clases. Todo funciona bien, pero para algunos elementos me gustaría crear una pequeña animación (que demuestra que hay un proceso en ejecución, asociado con el elemento). Desafortunadamente, las dos clases mencionadas anteriormente no proporcionan un Invalidate()
método o cualquier cosa similar.
Mi mejor idea hasta ahora es p/invoque WindowFromDC()
En el primer OnDraw, guarde el mango resultante y luego llame periódicamente InvalidateRect()
en el mango, hasta que el menú esté cerrado.
Sin embargo, esto parece un poco hackish, aún no lo he intentado, y me pregunto si hay una manera más elegante.
Solución
En lugar de usar WindowFromDC
, Podría sugerir llamar al GetMenuItemRect
función Para recuperar el rectángulo delimitador para un elemento de menú en particular. Entonces, puedes pasar el estructura rectangular llena por esa función al InvalidateRect
función.
Estoy de acuerdo en que esta solución tiene una sensación de "hackish", pero sospecho que eso se debe a que los menús proporcionados por la API de Windows no fueron diseñados para ser animados. Las clases de envoltura de menú proporcionadas por .NET Framework no incluyen un Invalidate
Funciona porque este es un caso de uso relativamente raro. En general, es suficiente que los elementos del menú dibujados por el propietario cambien cada vez que se muestra el menú emergente (manejando el WM_INITMENUPOPUP
mensaje). Hasta donde yo sé, la propuesta anterior es la forma más "correcta" que existe para hacer lo que desea.
Si realmente necesitas tanto control sobre los menús de dibujo, podrías ser una de las pocas personas para quienes los cursis MenuStrip
/ContextMenuStrip
Las clases son realmente mejores. Dado que se implementan completamente en el código administrado, el ToolStripItem
La clase proporciona un funcionamiento Invalidate
método.