none
Visual Studio.Рисование в Graphics, инверсия цвета. RRS feed

  • Вопрос

  • Доброе время суток!

    Наверное глупый вопрос,но..:
    рисую "ручками" на панели при этом использую двойную буферизацию, чтоб не мерцало...хотя это не важно, 
    основная проблема в том, что никак не могу  сообразить как/в каком режиме нужно рисовать вторую линию, чтобы проинвертировать точку пересечения?
    т.е. где и как нужно/и можно ли включить режим рисования Xor ?

    Простой пример:

    private: void DrawToBuffer(Graphics ^ g)
    {
    System::Drawing::Pen ^ Pcursor=gcnew Pen(Color::Black);

    g->DrawLine(Pcursor, 0,100,200,100);  //горизонтальная линия 
    g->DrawLine(Pcursor, 50,0,50,500); // вертикальная линия
    }

    Подскажите пожалуйста!

    + еще: Панель, в которой рисую располагается на другой панели (с включенным AutoScroll), при манипуляции ScrollBar-ом обрабатываю событие Scroll (внутри которого просто вызываю Refrash), так при этом наблюдается такой эффект как-будто сначала происходит перемещение панели рисования, а потом только прорисовка. Так ли это? Есть ли событие, которое "опережает" Scroll?

    Заранее благодарен за любой совет.

     

    19 февраля 2011 г. 19:08

Ответы

  • т.е. где и как нужно/и можно ли включить режим рисования Xor ?

    К сожалению, в GDI+ такого режима нет. Вам нужно либо рисовать четыре линии, если нужна прозрачность, или ставить точку цвета фона в месте пересечения, если прозрачность не требуется. Также посмотрите метод ControlPaint.DrawReversibleLine , возможно, он Вам подойдет.

     

    + еще: Панель, в которой рисую располагается на другой панели (с включенным AutoScroll), при манипуляции ScrollBar-ом обрабатываю событие Scroll (внутри которого просто вызываю Refrash), так при этом наблюдается такой эффект как-будто сначала происходит перемещение панели рисования, а потом только прорисовка. Так ли это? Есть ли событие, которое "опережает" Scroll?
    Это из-за того, что Refresh не вызывает перерисовку, а всего лишь добавляет событие WM_PAINT в очередь событий, в которой уже находится несколько событий скроллинга. Все события в очереди равноправны и выполняются в порядке их поступления. Единственный способ избежать этого — помещать уже отрисованное изображение внутрь Panel.
    • Помечено в качестве ответа Makarov_Vitaliy 20 февраля 2011 г. 18:56
    19 февраля 2011 г. 20:46

Все ответы

  • т.е. где и как нужно/и можно ли включить режим рисования Xor ?

    К сожалению, в GDI+ такого режима нет. Вам нужно либо рисовать четыре линии, если нужна прозрачность, или ставить точку цвета фона в месте пересечения, если прозрачность не требуется. Также посмотрите метод ControlPaint.DrawReversibleLine , возможно, он Вам подойдет.

     

    + еще: Панель, в которой рисую располагается на другой панели (с включенным AutoScroll), при манипуляции ScrollBar-ом обрабатываю событие Scroll (внутри которого просто вызываю Refrash), так при этом наблюдается такой эффект как-будто сначала происходит перемещение панели рисования, а потом только прорисовка. Так ли это? Есть ли событие, которое "опережает" Scroll?
    Это из-за того, что Refresh не вызывает перерисовку, а всего лишь добавляет событие WM_PAINT в очередь событий, в которой уже находится несколько событий скроллинга. Все события в очереди равноправны и выполняются в порядке их поступления. Единственный способ избежать этого — помещать уже отрисованное изображение внутрь Panel.
    • Помечено в качестве ответа Makarov_Vitaliy 20 февраля 2011 г. 18:56
    19 февраля 2011 г. 20:46
  • Спасибо большое за ответ! По поводу линий понял, метод ( ControlPaint.DrawReversibleLine ) глянул, эксперимент провел, - пока, правда, не думая (ctrl+C -> ctrl+V), - понял что использует глобальные координаты экрана, а не control-а и прорисовка слегка странновата(вызывал в обработчике On_Paint, а точнее при подготовке буфера).  

    А насчет второго: идея проста (как казалось)- рисую график на всю Panel, здесь же - оси координат, Panel - двигаем, а оси пересчитав и переместив (с учетом положения ScrollBara перерисовываем), по-видимому выбросив из On_Paint  эту строчку buff->Render(e->Graphics);

    private: System::Drawing::BufferedGraphics^        buff;

    private: System::Void GraphPanel_Paint(System::Object^ /*sender*/, System::Windows::Forms::PaintEventArgs^  e)

    {
    DrawToBuffer( buff->Graphics );

    buff->Render(e->Graphics);

    }

    (как я понял уже непосредственный вывод на экран) и поставив ее в обработчик событий Scroll проблему решу (наверное), но тогда эту строку придется множить и множить....еще много куда. Возможно ли другое решение?

    Спасибо за помощь!

    19 февраля 2011 г. 22:02
  • Не до конца понял часть задачи про оси, но, возможно для этого подойдет элемент PictureBox . Если поместить его в панель и рисовать непосредственно в нем (а не поверх элемента в событии OnPaint), то, возможно, получится решить Вашу задачу.
    19 февраля 2011 г. 22:58
  • Спасибо, посмотрю на этот элемент, возможно, Вы правы.
    20 февраля 2011 г. 14:07