Избегайте рисования над вложенными элементами управления - PullRequest
0 голосов
/ 24 марта 2010

Я пишу элемент управления в стиле панели инструментов и использую модуль ThemeServices, чтобы закрасить фон, необходимый для панели инструментов. Вот так:

ThemeServices.DrawElement(Canvas.Handle, 
  ThemeServices.GetElementDetails(trRebarRoot), ARect);

Затем я помещаю дочерние элементы управления на панель инструментов, и вуаля - мгновенная панель инструментов. За исключением того, что время от времени я замечаю, что вложенные (дочерние) элементы управления также не перерисовываются. Поэтому мой элемент управления закрашивает его фон, а дочерние элементы управления исчезают, пока вы не наведете на них мышь.

Некоторые элементы управления редактирования показывают свою клиентскую область (без границ), а некоторые из них просто исчезли.

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

Я продолжаю думать, что это должно быть очень легко вылечить, что, возможно, я каким-то образом предотвращаю попадание сообщения рисования в дочерние элементы управления или пропускаю переопределение, но я не смог понять это.

Ответы [ 3 ]

1 голос
/ 25 марта 2010

Чтобы это работало должным образом, чтобы вы не заканчивали перекрашивание дочерних элементов управления из WM_NCPaint, вы можете использовать функции области GDI региона в Window для создания области отсечения, исключающей области, которые вы не хотите рисовать. *

Вы можете сделать это, создав Регион с помощью функции CreateRectRgn (или аналогичной) с размером вашего фона.

Выберите этот регион для DC, который вы используете через функцию SelectClipRgn.

Затем переберите дочерние окна верхнего уровня на панели инструментов / панели и вызовите ExcludeClipRect с соответствующими координатами для каждого дочернего элемента.

Наконец, когда вы рисуете, будут окрашены только те области, которые не были исключены.

Также помните, что вам может потребоваться очистить свой регион (лучше всего обратитесь за помощью к GDI).

1 голос
/ 24 марта 2010

Это нормально для холста, который приходится перекрашивать, когда он покрыт другим элементом управления Windows.

Вы должны нарисовать панель инструментов в событии OnPaint элемента управления контейнера.

0 голосов
/ 25 марта 2010

ОК, я сам нашел проблему. Я рисовал фон в WM_NCPAINT, потому что это градиентный фон, который не может быть нарисован по крупицам. Я не осознавал, что WM_NCPAINT часто вызывается без перекрашивания клиентских элементов управления. Поэтому я все еще рисую фон в WM_NCPAINT, но также и в WM_PAINT. Последний уже обрезан, чтобы исключить границу и заставить первый обрезать клиентскую область, я назвал ExcludeClipRect.

Это работает как удовольствие.

...