G->Clear(Color::White);
//Дальше идет рисование фигур
G — Объект Graphics, полученый методом CreateGraphics() конрола.
Все рисуется нормально, только очень сильно мерцает.
Конрол самопальный, установка Style
Попробуй переопределить OnPaintBackground и оставить его пустым. Это событие генерируется для прорисовки фона и закрашивает контрол цветом фона, а вот после этого ты уже рисуешь свое, поэтому и мерцание
Чем вызвана необходимость рисовать из другого потока? В какой момент времени вы это делаете? Обработка-то WM_PAINT происходит в основном потоке…
Как и в какой момент времени вы получаете Graphics? Как начинаете рисовать?
OK>Конрол самопальный, установка Style
Ещё бы!
OK>Пробовал рисовать в битмап, потом выводить — сильно тормозит.
Как рисовали? В отдельном потоке? А как потом "выводили"?
OK>У кого какие есть мысли по этому поводу?
Сначала надо разобраться, что же мешает рисовать в основном потоке?
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Рисование из другого потока без мерцания
От:
Аноним
Дата:
23.09.08 06:58
Оценка:
Здравствуйте, flenov, Вы писали:
F>Попробуй переопределить OnPaintBackground и оставить его пустым. Это событие генерируется для прорисовки фона и закрашивает контрол цветом фона, а вот после этого ты уже рисуешь свое, поэтому и мерцание
Ок.
Программа просчитывает гравитационное взаимодействие двух и более тел. В дополнительном потоке просчитывается изменение координат и выводится результат на конрол.
Здравствуйте, ObKo, Вы писали:
OK>Программа просчитывает гравитационное взаимодействие двух и более тел. В дополнительном потоке просчитывается изменение координат и выводится результат на конрол.
В смысле, расчёты долгие и каждый раз при отрисовке их делать тяжело?
Тогда делается так: отдельный поток рассчитывает данные и сообщает потоку GUI о том, что надо отрисоваться, например через SynchronizationContext. Поток GUI вызывает по наступлению этого события Invalidate, затем в обработчике OnPaint(…) по рассчитанным данным производится отрисовка. Остаётся только не забыть о синхронизации.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Сначала надо разобраться, что же мешает рисовать в основном потоке?
А, собственно говоря, что изменится от рисования в основном потоке ? Я вообще-то особенного криминала в рисовании в другом потоке не вижу — если, конечно, их не 10 и они не пытаются одновременно рисовать. . А так — пожалуйста. Если основной поток сейчас не рисует, а рисует другой — на здоровье. Здесь WM_PAINT и не пахнет.
Тут, похоже, иное. Что за самопальный контрол и не генерирует ли он WM_PAINT (InvalidateRect) каждую секунду или около того ? Вот если так — неудивительно. Один рисует, другой перерисовывает...
Здравствуйте, _FRED_, Вы писали:
_FR>А вот о практике или опыте рисования из разных потоков мне как-то раньше слышать ничего хорошего не прихдилось
Хм. Можем мы рисовать из разных место одного потока ? Например, на WM_LBUTTONDOWN некое рисование делается тут же, без Invalidate. Естественно, надо куда-то добавить новую фигуру для возможного WM_PAINT, но в самой такой идее нет решительно ничего криминального. Более того, если WM_PAINT медленный, то это наилучшее решение. Да что там WM_LBUTTONDOWN — по таймеру ведь рисуют!
А теперь это же, но из другого потока. И что ? То же получение HDC окна , то же рисование. Честно говоря, не вижу разницы. Скажу больше — а как на десктопе рисуют ? Он-то уж точно не окно моего потока
Вот если 2 потока одновременно рисовать начнут — тогда точно ничего хорошего не выйдет
Здравствуйте, Pavel Dvorkin, Вы писали:
_FR>>А вот о практике или опыте рисования из разных потоков мне как-то раньше слышать ничего хорошего не прихдилось
PD>Хм. Можем мы рисовать из разных место одного потока?
Рисовать можем. Я хотел бы знать, что в этом может быть хорошего?
PD>Например, на WM_LBUTTONDOWN некое рисование делается тут же, без Invalidate.
Где такая техника применяется?
PD>Естественно, надо куда-то добавить новую фигуру для возможного WM_PAINT, но в самой такой идее нет решительно ничего криминального.
В я не вижу смысла, и потому она кажется криминальной: ну нарисуем мы что-нибудь, а потом свёрнём-развернём окно. И кто нам заново что-то отрисует? Что значит "куда-то добавить новую фигуру"? Можно нарисовать, например, в битмап, а из WM_PAINT рисовать уже с этого битмапа. Так рисование в битмап и рисование на окне — две разные вещи. В картинку можно рисовать не только из другого потока, но и из другого процесса, не важно. Рисовать же в окне нужно из WM_PAINT.
PD>Более того, если WM_PAINT медленный, то это наилучшее решение.
Что значит "WM_PAINT медленный" Я могу понять "GDI\GDI+ медленный". А скорость WM_PAINT такая, как мы её сделаем. Если рисовать быстро не получается, значит, надо что-то думать над тем, как бы ускорить WM_PAINT, а не над тем, где бы ещё порисовать. Конечно, если кто-то всё окно на каждый WM_PAINT перересовывает, то может быть медленно. Или инвалидирует, что бы хорошо не думать, так же всё целиком, то будет не быстро. Но ведь так можно и подругому: посчитал данные, потом посчитал, в какой части экрана они отображаются, и заинвалидировал этот региончик. В обработчике рисования (там известен квадрат, в котором надо рисовать) посчитал, где те данные, которые надо перерисовать, и перерисовал только их. Эти расчёты будут намного быстрее перерисовываний, дело за хорошо подобранной моделью данных.
PD>Да что там WM_LBUTTONDOWN — по таймеру ведь рисуют!
По таймеру рисуют так: в обработчике таймера рассчитывают данные. Затем рассчитывают регион, данные которого поменялись и инвалидируют регион. Всё: остальное сделает винда, выставив WM_PAINT. Скажу больше: именно под такую схему и подобраны (назначены) приоритеты сообщений WM_TIMER и WM_PAINT в потрохах винды. Отойти от этой схемы опять же не мешает ничто, кроме незнания и недоверия общепринятой практике.
PD>А теперь это же, но из другого потока. И что ? То же получение HDC окна , то же рисование. Честно говоря, не вижу разницы. Скажу больше — а как на десктопе рисуют ? Он-то уж точно не окно моего потока
Ага, это вот как раз и есть special case, который нужно применять очень осторожно на свой страх и риск (рисование на чёжом окне). Между прочим, что мешает от окна засабклассится и рисовать из его WM_PAINT? И, кстати, можно пример серьёзного (не поделки) приложения, которое рисует на десктопе?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Рисовать можем. Я хотел бы знать, что в этом может быть хорошего?
Я хотел бы знать, что в этом может быть плохого ?
PD>>Например, на WM_LBUTTONDOWN некое рисование делается тут же, без Invalidate.
_FR>Где такая техника применяется?
Сплошь и рядом в Win32. Банальный, заурядный прием, из учебника. GetDC и т.д.
_FR>В я не вижу смысла, и потому она кажется криминальной: ну нарисуем мы что-нибудь, а потом свёрнём-развернём окно. И кто нам заново что-то отрисует?
Обработчик WM_PAINT.
>Что значит "куда-то добавить новую фигуру"? Можно нарисовать, например, в битмап, а из WM_PAINT рисовать уже с этого битмапа.
Да.
>Так рисование в битмап и рисование на окне — две разные вещи. В картинку можно рисовать не только из другого потока, но и из другого процесса, не важно. Рисовать же в окне нужно из WM_PAINT.
Ну это далеко не так. По WM_PAINT не рисуют, а отрисовывают инвалидную область. А рисовать можно где угодно. Естественно, при этом надо принять меры, чтобы в случае появления инвалидной области обработчик WM_PAINT нарисовал то же, отрисовал, иными словами. Но это еще может быть, очень нескоро будет.
PD>>Более того, если WM_PAINT медленный, то это наилучшее решение.
_FR>Что значит "WM_PAINT медленный"
Обработчик медленный. Много рисовать, и без битовой карты.
> Я могу понять "GDI\GDI+ медленный". А скорость WM_PAINT такая, как мы её сделаем. Если рисовать быстро не получается, значит, надо что-то думать над тем, как бы ускорить WM_PAINT, а не над тем, где бы ещё порисовать.
Какое это имеет отношение к вопросу ?
>Конечно, если кто-то всё окно на каждый WM_PAINT перересовывает, то может быть медленно. Или инвалидирует, что бы хорошо не думать, так же всё целиком, то будет не быстро. Но ведь так можно и подругому: посчитал данные, потом посчитал, в какой части экрана они отображаются, и заинвалидировал этот региончик. В обработчике рисования (там известен квадрат, в котором надо рисовать) посчитал, где те данные, которые надо перерисовать, и перерисовал только их. Эти расчёты будут намного быстрее перерисовываний, дело за хорошо подобранной моделью данных.
Нет. Если мне надо новый эллипс, вписанный в окно, нарисовать, то никакие прямоугольнички не получатся. Тут проще именно эллипс напрямую нарисовать, а на битовую карту его тоже положить. Это быстрее будет, чем делать копирование всей битовой карты для каждого эллипса. Последнее оставим для WM_PAINT, там никуда не денешься, придется всю картинку выводить. А здесь лишь эллипс.
PD>>Да что там WM_LBUTTONDOWN — по таймеру ведь рисуют!
_FR>По таймеру рисуют так: в обработчике таймера рассчитывают данные. Затем рассчитывают регион, данные которого поменялись и инвалидируют регион. Всё: остальное сделает винда, выставив WM_PAINT.
Сделает. Только медленно это будет.
>Скажу больше: именно под такую схему и подобраны (назначены) приоритеты сообщений WM_TIMER и WM_PAINT в потрохах винды. Отойти от этой схемы опять же не мешает ничто, кроме незнания и недоверия общепринятой практике.
Ты просто, видимо, с этой методикой не знаком. Честное слово, вполне стандартная методика в Win32.
PD>>А теперь это же, но из другого потока. И что ? То же получение HDC окна , то же рисование. Честно говоря, не вижу разницы. Скажу больше — а как на десктопе рисуют ? Он-то уж точно не окно моего потока
_FR>Ага, это вот как раз и есть special case, который нужно применять очень осторожно на свой страх и риск (рисование на чёжом окне). Между прочим, что мешает от окна засабклассится и рисовать из его WM_PAINT?
Сабклассить можно только окна своего процесса. Или хук вешай.
>И, кстати, можно пример серьёзного (не поделки) приложения, которое рисует на десктопе?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Попробовал сейчас
PD>
PD> public partial class Form1 : Form
PD> {
PD> public bool stop;
PD> public void DoWork()
PD> {
PD> Graphics g = CreateGraphics();
PD> Pen pen = new Pen(Color.Blue);
PD> for (int i = 0; i < 10000; i++)
PD> {
PD> Thread.Sleep(10);
PD> if (stop)
PD> return;
PD> g.DrawEllipse(pen, new Rectangle(0, 0, i, i));
PD> }
PD> }
PD> public Form1()
PD> {
PD> InitializeComponent();
PD> stop = false;
PD> }
PD> private void button1_Click(object sender, EventArgs e)
PD> {
PD> ThreadStart threadDelegate = new ThreadStart(DoWork);
PD> Thread newThread = new Thread(threadDelegate);
PD> newThread.Start();
PD> }
PD> private void Form1_FormClosing(object sender, FormClosingEventArgs e)
PD> {
PD> stop = true;
PD> }
PD> }
PD>
PD>Ничего криминального не вижу и ничего не мигает. Естественно, при WM_PAINT рисунок не восстановится
PD>Сорри за некорректные действия с переменной stop — лень было писать как следует.
Re[6]: Рисование из другого потока без мерцания
От:
Аноним
Дата:
23.09.08 11:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Попробовал сейчас
PD>Ничего криминального не вижу и ничего не мигает. Естественно, при WM_PAINT рисунок не восстановится
PD>Сорри за некорректные действия с переменной stop — лень было писать как следует.
В том и проблема, что мне нужно очищать перед перересовкой!
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, _FRED_, Вы писали:
_FR>>Рисовать можем. Я хотел бы знать, что в этом может быть хорошего? PD>Я хотел бы знать, что в этом может быть плохого ?
Да вообще-т _FRED_ привел пример, что плохого. Никакой WM_PAINT ничего нам не отрисует, если мы банальным GetDC чего-то накалякаем из другого потока.
В любом случае, обращаться к контролам и их ресурсам рекомендуется только в том же потоке, где контрол создается.
Нарушать эту рекомендацию, значит вступать в противоречие с поведением ОС.
PD>>>Например, на WM_LBUTTONDOWN некое рисование делается тут же, без Invalidate. _FR>>Где такая техника применяется? PD>Сплошь и рядом в Win32. Банальный, заурядный прием, из учебника. GetDC и т.д.
Я правильно понимаю, что в этом случае в WM_PAINT и в WM_LBUTTONDOWN все-таки один и тот же код рисует?
_FR>>В я не вижу смысла, и потому она кажется криминальной: ну нарисуем мы что-нибудь, а потом свёрнём-развернём окно. И кто нам заново что-то отрисует? PD>Обработчик WM_PAINT. >>Что значит "куда-то добавить новую фигуру"? Можно нарисовать, например, в битмап, а из WM_PAINT рисовать уже с этого битмапа. PD>Да. >>Так рисование в битмап и рисование на окне — две разные вещи. В картинку можно рисовать не только из другого потока, но и из другого процесса, не важно. Рисовать же в окне нужно из WM_PAINT.
PD>Ну это далеко не так. По WM_PAINT не рисуют, а отрисовывают инвалидную область. А рисовать можно где угодно. Естественно, при этом надо принять меры, чтобы в случае появления инвалидной области обработчик WM_PAINT нарисовал то же, отрисовал, иными словами. Но это еще может быть, очень нескоро будет.
Я еще не пробовал, но вроде WPF от данной проблемы избавляет. Правда ни о каких WM_PAINT'ах, GetDC и пр. там речи не идет.
>>И, кстати, можно пример серьёзного (не поделки) приложения, которое рисует на десктопе? PD>Visual Studio при старте. И другие.
Серьезно?
Здравствуйте, Pavel Dvorkin, Вы писали:
_FR>>Рисовать можем. Я хотел бы знать, что в этом может быть хорошего? PD>Я хотел бы знать, что в этом может быть плохого ?
Большие проблемы в поддержке.
PD>>>Например, на WM_LBUTTONDOWN некое рисование делается тут же, без Invalidate. _FR>>Где такая техника применяется? PD>Сплошь и рядом в Win32. Банальный, заурядный прием, из учебника. GetDC и т.д.
Какого учебника? Давайте конкретнее. А ещё лучше, на софт. это использующий.
_FR>>В я не вижу смысла, и потому она кажется криминальной: ну нарисуем мы что-нибудь, а потом свёрнём-развернём окно. И кто нам заново что-то отрисует? PD>Обработчик WM_PAINT. >>Что значит "куда-то добавить новую фигуру"? Можно нарисовать, например, в битмап, а из WM_PAINT рисовать уже с этого битмапа. PD>Да. >>Так рисование в битмап и рисование на окне — две разные вещи. В картинку можно рисовать не только из другого потока, но и из другого процесса, не важно. Рисовать же в окне нужно из WM_PAINT. PD>Ну это далеко не так. По WM_PAINT не рисуют, а отрисовывают инвалидную область.
Извините, но вы выдумываете: покажите-ка мне где-либо в профессиональной литературе по данному вопросу термин "отрисовка" в контексте различия с "рисованием"?
PD>А рисовать можно где угодно. Естественно, при этом надо принять меры, чтобы в случае появления инвалидной области обработчик WM_PAINT нарисовал то же, отрисовал, иными словами. Но это еще может быть, очень нескоро будет.
Я же сам сказал — что рисовать можно что угодно и где угодно, но если это не будет сделано в WM_PAINT, то толку от этого нет. Рисование в картинку в любом потоке не отменяем рисование каринки в WM_PAINT.
PD>>>Более того, если WM_PAINT медленный, то это наилучшее решение. _FR>>Что значит "WM_PAINT медленный" PD>Обработчик медленный. Много рисовать, и без битовой карты.
Ага, а с битовой картой обработчик получается быстрым? Значит, я прав-таки, говоря, что скорость обработчика зависит от того, как его реализовать?
>>Конечно, если кто-то всё окно на каждый WM_PAINT перересовывает, то может быть медленно. Или инвалидирует, что бы хорошо не думать, так же всё целиком, то будет не быстро. Но ведь так можно и подругому: посчитал данные, потом посчитал, в какой части экрана они отображаются, и заинвалидировал этот региончик. В обработчике рисования (там известен квадрат, в котором надо рисовать) посчитал, где те данные, которые надо перерисовать, и перерисовал только их. Эти расчёты будут намного быстрее перерисовываний, дело за хорошо подобранной моделью данных.
PD>Нет. Если мне надо новый эллипс, вписанный в окно, нарисовать, то никакие прямоугольнички не получатся. Тут проще именно эллипс напрямую нарисовать, а на битовую карту его тоже положить. Это быстрее будет, чем делать копирование всей битовой карты для каждого эллипса. Последнее оставим для WM_PAINT, там никуда не денешься, придется всю картинку выводить. А здесь лишь эллипс.
А если у вас тысяса элипсов, то всю тысячу перерисовывать будете? Я бы не перересрвывал. еденица рисование — не пиксел, а примитив. До него и надо "округлять".
>>Скажу больше: именно под такую схему и подобраны (назначены) приоритеты сообщений WM_TIMER и WM_PAINT в потрохах винды. Отойти от этой схемы опять же не мешает ничто, кроме незнания и недоверия общепринятой практике. PD>Ты просто, видимо, с этой методикой не знаком. Честное слово, вполне стандартная методика в Win32.
Возможно. Покажите-ка описание этой методики?
>>И, кстати, можно пример серьёзного (не поделки) приложения, которое рисует на десктопе? PD>Visual Studio при старте.
Ага, а Spy++ запустить не пробовали?
Резюмируя: если вы знаете, что есть некая методика рисования не в обработчике WM_PAINT (именно рисования на окне, а не в буфере), то не могли бы дать мне с ней ознакомиться? Интересно, как следуя такой методике повышается скорость и появляются прочие бенефиты. Методика, о которой говорю я описана как в MSDN (Painting and Drawing), так и у Рихтера.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, MxKazan, Вы писали:
MK>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Здравствуйте, _FRED_, Вы писали:
_FR>>>Рисовать можем. Я хотел бы знать, что в этом может быть хорошего? PD>>Я хотел бы знать, что в этом может быть плохого ? MK>Да вообще-т _FRED_ привел пример, что плохого. Никакой WM_PAINT ничего нам не отрисует, если мы банальным GetDC чего-то накалякаем из другого потока.
Слушай. я же ясно там написал, что надо обеспечить, чтобы по WM_PAINT отрисовывалось то же.
MK>В любом случае, обращаться к контролам и их ресурсам рекомендуется только в том же потоке, где контрол создается. MK>Нарушать эту рекомендацию, значит вступать в противоречие с поведением ОС.
PD>>>>Например, на WM_LBUTTONDOWN некое рисование делается тут же, без Invalidate. _FR>>>Где такая техника применяется? PD>>Сплошь и рядом в Win32. Банальный, заурядный прием, из учебника. GetDC и т.д. MK>Я правильно понимаю, что в этом случае в WM_PAINT и в WM_LBUTTONDOWN все-таки один и тот же код рисует?
Нет. Простейший пример, первое задание, что я даю студентам. По WM_LBUTTONDOWN рисовать прямоугольники, а по WM_RBUTTONDOWN эллипсы. С backbuffer они еще не знакомы, поэтому список фигур
2 варианта
1. Рисуем по WM_?BUTTONDOWN и добавляем в список. По WM_PAINT отрисовываем весь список.
2. По WM_?BUTTONDOWN добавляем в список и InvalidateRect
В первом случае рисуется только одна фигура на нажатие кнопки. Весь список будет отрисовываться только когда будет инвалидная область. А она, мб, еще не скоро появится.
Во втором случае рисуется весь список. Всегда.
При 10-100 фигурах разницы в скорости нет. При тысячах — есть.
Естественно, в дальнейшем я их знакомлю с offscreen и битовыми картами, так что список выкидывается.
Но, конечно, рисовать они должны так, чтобы все сошлось. То есть WM_PAINT должен отрисовать список по тем же координатам и т.д, что и все WM_?BUTTONDOWN, вместе взятые.
Честно говоря, удивлен, что это надо объяснять. Это стандартная методика, еще раз говорю. Одна из двух.
MK>Я еще не пробовал, но вроде WPF от данной проблемы избавляет. Правда ни о каких WM_PAINT'ах, GetDC и пр. там речи не идет.
WPF избавляет . Он от много избавляет, в том числе от знания базовых принципов Win32. Не обижайся
>>>И, кстати, можно пример серьёзного (не поделки) приложения, которое рисует на десктопе? PD>>Visual Studio при старте. И другие. MK>Серьезно?
Абсолютно. Приложения, которые выводят стартовую картинку, рисуют на десктопе. GetDC(NULL). Это тоже общеизвестно. Вот, пожалуйста
А, пардон, где им еще рисовать ? Окна-то своего еще нет.
И кстати, характерный эффект. Если картинка висит достаточно долго, и за это время ее успеет перекрыть и уйти откуда-то взявшееся постороннее окно, то вместо картинки мы видим порой белый прямоугольник. Замечал такое ? В обычном окне такого не бывает — на то WM_PAINT есть. А тут просто рисование.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет. Простейший пример, первое задание, что я даю студентам. По WM_LBUTTONDOWN рисовать прямоугольники, а по WM_RBUTTONDOWN эллипсы. С backbuffer они еще не знакомы, поэтому список фигур
А, помню я такую книжку по МФЦ: там тоже в графическом редакторе рисовали гужки по левой кнопке. Но только вот это же учебник был: в следующей главе кружки уже сохранялись и рисовались в WM_PAINT.
>>>>И, кстати, можно пример серьёзного (не поделки) приложения, которое рисует на десктопе? PD>>>Visual Studio при старте. И другие. MK>>Серьезно? PD>Абсолютно. Приложения, которые выводят стартовую картинку, рисуют на десктопе. GetDC(NULL). Это тоже общеизвестно. Вот, пожалуйста PD>http://img.meta.ua/rsdnsearch/?q=%F0%E8%F1%EE%E2%E0%F2%FC+%E4%E5%F1%EA%F2%EE%EF&mode=rank&group=N PD>А, пардон, где им еще рисовать ? Окна-то своего еще нет. PD>И кстати, характерный эффект. Если картинка висит достаточно долго, и за это время ее успеет перекрыть и уйти откуда-то взявшееся постороннее окно, то вместо картинки мы видим порой белый прямоугольник. Замечал такое ? В обычном окне такого не бывает — на то WM_PAINT есть. А тут просто рисование.
Только вот как объяснить то, что можно навести сверху чужое окно, потом убрать, и оно отрисуется-таки?
Help will always be given at Hogwarts to those who ask for it.
Ну, повеселились и хватит...
PD>Здравствуйте, MxKazan, Вы писали:
MK>>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Здравствуйте, _FRED_, Вы писали:
_FR>>>>Рисовать можем. Я хотел бы знать, что в этом может быть хорошего? PD>>>Я хотел бы знать, что в этом может быть плохого ? MK>>Да вообще-т _FRED_ привел пример, что плохого. Никакой WM_PAINT ничего нам не отрисует, если мы банальным GetDC чего-то накалякаем из другого потока. PD>Слушай. я же ясно там написал, что надо обеспечить, чтобы по WM_PAINT отрисовывалось то же.
MK>>В любом случае, обращаться к контролам и их ресурсам рекомендуется только в том же потоке, где контрол создается. MK>>Нарушать эту рекомендацию, значит вступать в противоречие с поведением ОС. PD>>>>>Например, на WM_LBUTTONDOWN некое рисование делается тут же, без Invalidate. _FR>>>>Где такая техника применяется? PD>>>Сплошь и рядом в Win32. Банальный, заурядный прием, из учебника. GetDC и т.д. MK>>Я правильно понимаю, что в этом случае в WM_PAINT и в WM_LBUTTONDOWN все-таки один и тот же код рисует? PD>Нет. Простейший пример, первое задание, что я даю студентам. По WM_LBUTTONDOWN рисовать прямоугольники, а по WM_RBUTTONDOWN эллипсы. С backbuffer они еще не знакомы, поэтому список фигур PD>Честно говоря, удивлен, что это надо объяснять. Это стандартная методика, еще раз говорю. Одна из двух.
Хаааа. Клааасс.. Я так и думал, что будет нечто подобное приведено. Ага, ага... только правильнее скорее описать, что это не способ рисования в Win32, а вообще просто методика рисования. И мы здесь всё же знакомы с битовыми картами
MK>>Я еще не пробовал, но вроде WPF от данной проблемы избавляет. Правда ни о каких WM_PAINT'ах, GetDC и пр. там речи не идет. PD>WPF избавляет . Он от много избавляет, в том числе от знания базовых принципов Win32. Не обижайся
Ага, не обижаюсь. Ведь на самом деле WPF использует прицнип в чем то схожий с тем, что приведен тобой выше На даёт мне забыть! Спасибо ей
>>>>И, кстати, можно пример серьёзного (не поделки) приложения, которое рисует на десктопе? PD>>>Visual Studio при старте. И другие. MK>>Серьезно? PD>Абсолютно. Приложения, которые выводят стартовую картинку, рисуют на десктопе. GetDC(NULL). Это тоже общеизвестно. Вот, пожалуйста
PD>http://img.meta.ua/rsdnsearch/?q=%F0%E8%F1%EE%E2%E0%F2%FC+%E4%E5%F1%EA%F2%EE%EF&mode=rank&group=N PD>А, пардон, где им еще рисовать ? Окна-то своего еще нет.
PD>И кстати, характерный эффект. Если картинка висит достаточно долго, и за это время ее успеет перекрыть и уйти откуда-то взявшееся постороннее окно, то вместо картинки мы видим порой белый прямоугольник. Замечал такое ? В обычном окне такого не бывает — на то WM_PAINT есть. А тут просто рисование.
Окно то там вполне себе есть. А нет там стандартного message loop'а, поэтому при показе картинки, окно отрисовывают "насильно", а дальше перерисовывать уже некому, потому что приложение занято запуском.