Подтвердить что ты не робот

Я не могу вырваться из своего ClipRectangle, и я хочу заплакать

При переопределении метода OnPaint настраиваемого элемента управления мне предоставляется PaintEventArgs, который содержит объект Graphics и ClipRectangle. ClipRectangle слишком мал для моих вкусов, поэтому я хочу либо расширить его, скажем, на 100 пикселей, либо полностью игнорировать его.

Независимо от того, что я делаю, я не могу вырваться из ClipRectangle. До сих пор я пробовал:

e.ClipRectangle.Inflate(100, 0);
e.Graphics.ResetClip();
e.Graphics.SetClip(new Rectangle(x, y, w, h));

Родительский элемент управления вызывает Invalidate (true) (для принудительной отмены всех дочерних элементов дочерних элементов).

Я также сделал некоторые поисковые запросы и посмотрел сайт bob powell, но не смог найти nuffin.

ResetClip сбрасывает область отсечения для объекта Graphics на бесконечно большой прямоугольник, но объект Graphics бодро продолжает использовать предоставленный ClipRectangle.

Справка.

4b9b3361

Ответ 1

Recap: похоже, что у вас есть дочерний элемент управления с пользовательским методом рисования. Вы хотите нарисовать элемент управления в области, которая больше, чем границы управления. Например, если вы разместите свой контроль на (10, 10, 100, 100), вы хотите нарисовать область (0, 10, 110, 100).

Вы не можете это сделать, контрольный HDC, который передается методу рисования, предназначен для управления дескриптором собственного окна. Он обрезается ОС и AFAIK, нет возможности рисовать вне него с помощью HDC, заданного методу рисования.

Что вы можете сделать: одним из вариантов является переопределение метода создания родительского окна и удаление стиля окна WS_CLIPCHILDREN (0x02000000), а затем рисование дочернего элемента в методе родительской краски.

Другой вариант - просто расширить область дочернего окна, чтобы он охватывал область, которую вы хотите рисовать. Если вы также переопределите метод OnPaintBackground вашего элемента управления, вы можете предотвратить очистку фоновой краски от родительского рендеринга. Это проблематично, так как родитель будет обрезать область дочернего элемента и не обновлять его. Таким образом, вам все равно нужно удалить родительский WS_CLIPCHILDREN, чтобы он работал.

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

Ответ 2

Rectangle - это структура, а не класс - она ​​передается как значение, поэтому вызов e.ClipRectangle.Inflate(100, 0); не может даже теоретически.

Следующее, что вам нужно знать, это то, что e.Graphics связан с контекстом аппаратного устройства, поэтому Windows не позволит вам расширить область рисования. Решение состоит в том, чтобы получить контекст устройства родительского окна и затем рисовать там, где вы хотите. Вот как это сделать:

[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("User32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

IntPtr dcPtr = GetDC(this.ParentForm.Handle);
Graphics g = Graphics.FromHdc(dcPtr);

// your code here

// don't forget to release it
g.Dispose();
ReleaseDC(this.ParentForm.Handle, dcPtr);