Как обеспечить анимацию в нарисованном владельцем пункте меню? - PullRequest
3 голосов
/ 27 января 2011

Мое приложение в C # 3.5, Winforms, но для этого, скорее всего, все равно потребуется P / Invoke, так что оно не так строго привязано к .NET.

Я создал нарисованные владельцем пункты меню через ContextMenu и MenuItem классы.Все работает хорошо, но для некоторых элементов я бы хотел создать небольшую анимацию (показывающую, что запущен процесс, связанный с элементом).К сожалению, вышеупомянутые два класса не предоставляют метод Invalidate() или что-либо подобное.

На данный момент моя лучшая идея - P / Invoke WindowFromDC() на первом OnDraw, сохранить полученный дескриптор, а затем периодическизвоните InvalidateRect() на ручку, пока меню не закроется.

Это кажется довольно хакерским, я еще не пробовал, и задаюсь вопросом, есть ли более элегантный способ.

1 Ответ

3 голосов
/ 27 января 2011

Вместо использования WindowFromDC я мог бы предложить вызвать функцию GetMenuItemRect , чтобы получить ограничивающий прямоугольник для определенного пункта меню. Затем вы можете передать прямоугольную структуру , заполненную этой функцией, в InvalidateRect функцию .

Я согласен, что это решение выглядит как "хакерское", но я подозреваю, что это потому, что меню, предоставляемые Windows API, не были предназначены для анимации. Классы обертки меню, предоставляемые .NET Framework, не включают функцию Invalidate, потому что это относительно редкий случай использования. Обычно достаточно, чтобы нарисованные владельцем пункты меню менялись при каждом отображении всплывающего меню (путем обработки сообщения WM_INITMENUPOPUP ). Насколько я знаю, вышеприведенное предложение - самый «правильный» способ сделать то, что вы хотите.

Если вам действительно нужен такой большой контроль над меню рисования, вы можете быть одним из немногих людей, для которых классы MenuStrip / ContextMenuStrip на самом деле лучше. Так как они полностью реализованы в управляемом коде, класс ToolStripItem предоставляет рабочий Invalidate метод .

...