Re[10]: Рисование из другого потока без мерцания
От: Pavel Dvorkin Россия  
Дата: 24.09.08 01:30
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А, помню я такую книжку по МФЦ: там тоже в графическом редакторе рисовали гужки по левой кнопке. Но только вот это же учебник был: в следующей главе кружки уже сохранялись и рисовались в WM_PAINT.


Совершенно верно. 2 варианта, какой из них лучше — можно долго обсуждать, а если коротко — зависит от ситуации.

PD>>И кстати, характерный эффект. Если картинка висит достаточно долго, и за это время ее успеет перекрыть и уйти откуда-то взявшееся постороннее окно, то вместо картинки мы видим порой белый прямоугольник. Замечал такое ? В обычном окне такого не бывает — на то WM_PAINT есть. А тут просто рисование.


_FR>Только вот как объяснить то, что можно навести сверху чужое окно, потом убрать, и оно отрисуется-таки?


А черт его знает. Мне самому это не совсем понятно. Еще во аремена W95 я попробовал как-то сделать InvalidateRect(GetDesktopWindow(), ...). Никакого эффекта. В общем, десктоп — это , конечно, окно, но уж больно специфическое.

Посмотрел сейчас на него с помощью Spy++. Оказывается, оно WS_POPUP А также WS_VISIBLE (интересно, что будет, если ему сделать ShowWindow(hWnd, SW_HIDE) ?
With best regards
Pavel Dvorkin
Re[10]: Рисование из другого потока без мерцания
От: Pavel Dvorkin Россия  
Дата: 24.09.08 01:33
Оценка:
Здравствуйте, MxKazan, Вы писали:

PD>>Честно говоря, удивлен, что это надо объяснять. Это стандартная методика, еще раз говорю. Одна из двух.

MK>Хаааа. Клааасс.. Я так и думал, что будет нечто подобное приведено. Ага, ага... только правильнее скорее описать, что это не способ рисования в Win32, а вообще просто методика рисования. И мы здесь всё же знакомы с битовыми картами

Способ рисования, методика рисования... Слова, слова, слова. Называй хоть горшком, только в печь не сажай.

MK>>>Я еще не пробовал, но вроде WPF от данной проблемы избавляет. Правда ни о каких WM_PAINT'ах, GetDC и пр. там речи не идет.

PD>>WPF избавляет . Он от много избавляет, в том числе от знания базовых принципов Win32. Не обижайся
MK>Ага, не обижаюсь. Ведь на самом деле WPF использует прицнип в чем то схожий с тем, что приведен тобой выше На даёт мне забыть! Спасибо ей

Ну ин так

MK>Окно то там вполне себе есть.


Доказательства ?
With best regards
Pavel Dvorkin
Re[8]: Рисование из другого потока без мерцания
От: Pavel Dvorkin Россия  
Дата: 24.09.08 02:16
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>Рисовать можем. Я хотел бы знать, что в этом может быть хорошего?

PD>>Я хотел бы знать, что в этом может быть плохого ?

_FR>Большие проблемы в поддержке.


_FR>Какого учебника? Давайте конкретнее. А ещё лучше, на софт. это использующий.


Ну софт я искать не буду, нет времени, а вот учебник — пожалуйста

Петцольд. Programming Windows 95. Классика из классик. Все мы из этой книги вышли.

///////////////////////////////////////////////////////////////////////////////////////////////////

Getting a Device Context Handle: Method Two

Although it is best to structure your program so that you can update the entire client area during the WM_PAINT message, you may also find it useful to paint part of the client area while processing messages other than WM_PAINT. Or you may need a device context handle for other purposes, such as obtaining information about the device context.
...
Generally, you'll use the GetDC and ReleaseDC calls in response to keyboard messages (such as in a word processing program) or mouse messages (such as in a drawing program). This allows the program to draw on the client area in prompt reaction to the user's keyboard or mouse input without deliberately invalidating part of the client area to generate WM_PAINT messages. However, even if you paint during messages other than WM_PAINT, your program must still accumulate enough information to be able to update the display whenever you do receive a WM_PAINT message.


///////////////////////////////////////////////////////////////////////////////////////////////////

Кстати, могу привести еще пример, когда эта методика является не одной из двух возможных, а единственно возможной. Это рисование резинового контура. Суть, я думаю, ты помнишь — на WM_MOUSEMOVE рисуем 2 раза в режиме SetROP2 (R2_NOT или R2_XORPEN), второй вызов восстанавливает прежнее изображение, то есть то, что было под контуром. Так вот, тут делать каждый раз InvalidateRect с WM_PAINT попросту бессмысленно, это лишь трата времени. Все действия делаются прямо на WM_MOUSEMOVE. У Петцольда есть пример





void DrawBoxOutline (HWND hwnd, POINT ptBeg, POINT ptEnd)
     {
     HDC hdc ;

     hdc = GetDC (hwnd) ;

     SetROP2 (hdc, R2_NOT) ;
     SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
     Rectangle (hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y) ;

     ReleaseDC (hwnd, hdc) ;
     }


          case WM_MOUSEMOVE :
               if (fBlocking)
                    {
                    SetCursor (LoadCursor (NULL, IDC_CROSS)) ;

                    DrawBoxOutline (hwnd, ptBeg, ptEnd) ;

                    ptEnd.x = LOWORD (lParam) ;
                    ptEnd.y = HIWORD (lParam) ;

                    DrawBoxOutline (hwnd, ptBeg, ptEnd) ;
                    }
               return 0 ;


Кстати, и в учебнике по .Net такое же есть. Тот же Петцольд, но теперь книга по .Net.


protected override void OnMouseMove(MouseEventArgs mea)
{
Graphics grfx = CreateGraphics();
DrawWeb(grfx, BackColor, ptMouse);
ptMouse = new Point(mea.X, mea.Y);
DrawWeb(grfx, ForeColor, ptMouse);
grfx.Dispose();
}
protected override void OnPaint(PaintEventArgs pea)
{
DrawWeb(pea.Graphics, ForeColor, ptMouse);
}
void DrawWeb(Graphics grfx, Color clr, Point pt) // код опустил




_FR>Извините, но вы выдумываете: покажите-ка мне где-либо в профессиональной литературе по данному вопросу термин "отрисовка" в контексте различия с "рисованием"?


Тот же Петцольд. Надеюсь, не будете спорить, что это профессиональная литература Одна глава так и называется — "Painting and Repainting". Цитаты выше — из нее.

_FR>Я же сам сказал — что рисовать можно что угодно и где угодно, но если это не будет сделано в WM_PAINT, то толку от этого нет. Рисование в картинку в любом потоке не отменяем рисование каринки в WM_PAINT.


Разумееется.

_FR>Ага, а с битовой картой обработчик получается быстрым? Значит, я прав-таки, говоря, что скорость обработчика зависит от того, как его реализовать?


Быстрее, да. Но не всегда. Если в окне рисуется один круг, то быстрее без битовой карты .
Битовую карту обычно по двум причинам применяют. Во-первых, и это главное, она позволяет "закрыть" WM_ERASEBKGND, тем самым убрав очистку и мигание. Во-вторых, это действительно быстрее (но не всегда, например, если изображение меняется по таймеру, то это может оказаться медленнее)

А скорость чего угодно зависит от того, как его реализовать

_FR>А если у вас тысяса элипсов, то всю тысячу перерисовывать будете? Я бы не перересрвывал. еденица рисование — не пиксел, а примитив. До него и надо "округлять".


При чем тут пиксель — не понял. Эллипс как раз и есть примитив, а как тут округлять — тоже не понял.
А если нет битовой карты — придется- таки перерисовывать всю тысячу. Предложите иной способ

>>>Скажу больше: именно под такую схему и подобраны (назначены) приоритеты сообщений WM_TIMER и WM_PAINT в потрохах винды. Отойти от этой схемы опять же не мешает ничто, кроме незнания и недоверия общепринятой практике.

PD>>Ты просто, видимо, с этой методикой не знаком. Честное слово, вполне стандартная методика в Win32.

_FR>Возможно. Покажите-ка описание этой методики?


См. выше, цитату из Петцольда.

_FR>Резюмируя: если вы знаете, что есть некая методика рисования не в обработчике WM_PAINT (именно рисования на окне, а не в буфере), то не могли бы дать мне с ней ознакомиться? Интересно, как следуя такой методике повышается скорость и появляются прочие бенефиты. Методика, о которой говорю я описана как в MSDN (Painting and Drawing), так и у Рихтера.


Если речь идет о книге Рихтера для .Net — да, конечно, там именно это. В книгах же по Win32 он вообще о графике не говорит. Но Рихтер, прямо скажу, не есть большой авторитет в плане GDI. Вот в том, что касается ядра и т.д — другое дело, там он классик. А поскольку методика, о которой я говорю, относится к Win32, а в .Net не то чтобы очень популярна , то неудивительно, что Рихтер ее обходит вниманием.

А вообще, если есть желание узнать про скорость и получить всякие бенефиты — настойчиво рекомендую книгу Фень Юаня. Вот там действительно узнаешь все, что надо.
With best regards
Pavel Dvorkin
Re[9]: Рисование из другого потока без мерцания
От: _FRED_ Черногория
Дата: 24.09.08 06:56
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

_FR>>Какого учебника? Давайте конкретнее. А ещё лучше, на софт. это использующий.

PD>Ну софт я искать не буду, нет времени, а вот учебник — пожалуйста
PD>Петцольд. Programming Windows 95. Классика из классик. Все мы из этой книги вышли.

Хорошо, а теперь назовите главу, в которой рекомендуется так делать из чужого потока.

_FR>>Возможно. Покажите-ка описание этой методики?

PD>См. выше, цитату из Петцольда.

Нет, там (и в ваших) очень узкий пример: реакция на мышь. Понятно, что пока мы что-то рисуем над мышью, перекрыть это будет сложно. И, опять же, помните, с чего начался спор: Я говорю "Не рисуй из чужого пока", а вы: "А чего плохого"? А вот теперь выяснилось, что "рисование из чужого потока" по-вашему не отменяет рисование (или отрисовку, разница, как я вижу, лишь в том, что отрисовка — это рисование уже подготовленной картинки, я прав?).

Я утверждал (и продолжаю, ибо Петцольд не противоречит) что на окне надо рисовать из WM_PAINT. Ваши примеры — лишь очень редкие и частные случаи того, как можно делать. Я знаю только пару мест, в которых так поступают (рисование прямоугольника выделения в ListView да DragDrop) но не вижу, при чём тут многопоточность.

_FR>>Резюмируя: если вы знаете, что есть некая методика рисования не в обработчике WM_PAINT (именно рисования на окне, а не в буфере), то не могли бы дать мне с ней ознакомиться? Интересно, как следуя такой методике повышается скорость и появляются прочие бенефиты. Методика, о которой говорю я описана как в MSDN (Painting and Drawing), так и у Рихтера.


PD>Если речь идет о книге Рихтера для .Net — да, конечно, там именно это. В книгах же по Win32 он вообще о графике не говорит. Но Рихтер, прямо скажу, не есть большой авторитет в плане GDI. Вот в том, что касается ядра и т.д — другое дело, там он классик. А поскольку методика, о которой я говорю, относится к Win32, а в .Net не то чтобы очень популярна , то неудивительно, что Рихтер ее обходит вниманием.


Я говорю о книге по "Создание эффективных WIN32-приложений с учетом специфики 64-разрной версии Windows" в разделе сообщений windows просто говорится о приоритетах, и причинах того, что приоритет WM_PAINT ниже приоритета WM_TAIMER. Кстати, у Петцольд есть такой же (как вы описывали) пример рисования по таймеру?
Help will always be given at Hogwarts to those who ask for it.
Re[11]: Рисование из другого потока без мерцания
От: _FRED_ Черногория
Дата: 24.09.08 06:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

MK>>Окно то там вполне себе есть.

PD>Доказательства ?

Я запустил Spy++ и узнал, что класс этого окна VSSplash.
Help will always be given at Hogwarts to those who ask for it.
Re[10]: Рисование из другого потока без мерцания
От: Pavel Dvorkin Россия  
Дата: 24.09.08 07:56
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Хорошо, а теперь назовите главу, в которой рекомендуется так делать из чужого потока.


Этого я не назову. Но напомню то, с чего начал. Я сказал, что не вижу никакого криминала в этом. Если Вы можете объяснить, в чем здесь криминал — я готов отказаться от своих слов. Но не раньше.

_FR>Нет, там (и в ваших) очень узкий пример: реакция на мышь. Понятно, что пока мы что-то рисуем над мышью, перекрыть это будет сложно.


Разумеется, не отменяет. Само собой. Где я говорил, что отменяет ?
Что же касается того, что это очень узкий пример — ну знаете, так можно долго дискутировать. Вот вам еще один пример — рисование по таймеру (см. внизу) Я еще помню пример с фракталами, но, увы, текст привести не могу, он из старой книги по Win16, по которой я когда-то изучал программирование для Windows, и диска там не было. Но заверяю честным словом, рисование там шло так же. На это Вы, конечно, можете ответить, что и это узкий пример — но так Вы с меня будете требовать пример за примером, я не могу этим заниматься .

_FR>И, опять же, помните, с чего начался спор: Я говорю "Не рисуй из чужого пока", а вы: "А чего плохого"? А вот теперь выяснилось, что "рисование из чужого потока" по-вашему не отменяет рисование (или отрисовку, разница, как я вижу, лишь в том, что отрисовка — это рисование уже подготовленной картинки, я прав?).


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

_FR>Я утверждал (и продолжаю, ибо Петцольд не противоречит) что на окне надо рисовать из WM_PAINT. Ваши примеры — лишь очень редкие и частные случаи того, как можно делать. Я знаю только пару мест, в которых так поступают (рисование прямоугольника выделения в ListView да DragDrop) но не вижу, при чём тут многопоточность.


У нас тут 2 вопроса получились, так вот, давайте отдельно.
Первое — можно ли рисовать (в смысле, что я выше привел) вне WM_PAINT ? Ответ — можно, и Вы с этим согласны, хотя и считаете, что это очень редкие случаи. Я этого не считаю, но это уже спор, который не стоит продолжать.
Второе — можно ли это делать из другого потока. Здесь см. мое замечание в начале этого постинга.


_FR>Я говорю о книге по "Создание эффективных WIN32-приложений с учетом специфики 64-разрной версии Windows" в разделе сообщений windows просто говорится о приоритетах, и причинах того, что приоритет WM_PAINT ниже приоритета WM_TAIMER.


Да, знаком, конечно , на лекции рассказываю. Но из этого следует только, что только при данной расстановке приоритетов вариант с InvalidateRect будет корректен. Если приоритеты поставить иначе, он может быть просто некорректным. Однако из этого не следует ничего в отношении второго варианта.

>Кстати, у Петцольд есть такой же (как вы описывали) пример рисования по таймеру?


Да. Но чуть более хитрый. Да простит меня модератор за цитирование не по профилю форума



// в Winmain

hwnd = CreateWindow(szAppName, "Beeper2 Timer Demo",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
while(!SetTimer(hwnd, ID_TIMER, 1000,(TIMERPROC) TimerProc))


Таймер создается с отдельной callback функцией TimerProc


VOID CALLBACK TimerProc(HWND hwnd, UINT iMsg, UINT iTimerID, DWORD dwTime)
{
static BOOL fFlipFlop = FALSE;
HBRUSH hBrush;
HDC hdc;
RECT rc;
MessageBeep(0);
fFlipFlop = !fFlipFlop;
GetClientRect(hwnd, &rc);
hdc = GetDC(hwnd);
hBrush = CreateSolidBrush(fFlipFlop ? RGB(255,0,0) : RGB(0,0,255));
FillRect(hdc, &rc, hBrush);
ReleaseDC(hwnd, hdc);
DeleteObject(hBrush);
}

В общем, флип-флоп :-)
With best regards
Pavel Dvorkin
Re[12]: Рисование из другого потока без мерцания
От: Pavel Dvorkin Россия  
Дата: 24.09.08 07:59
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Я запустил Spy++ и узнал, что класс этого окна VSSplash.


Доказательство принято.
With best regards
Pavel Dvorkin
Re[11]: в дополнение
От: Pavel Dvorkin Россия  
Дата: 24.09.08 08:16
Оценка:
Кстати, посмотрел еще раз в книге Петцольда по C#. Там примеров с рисованием вне Onpaint не так уж мало. Хинт — поиск по слову CreateGraphics.

Вот твои часы (аналоговые, правда)


//-------------------------------------------
// AnalogClock.cs c 2001 by Charles Petzold
//-------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsWithCSharp;

class AnalogClock: Form
{
     ClockControl clkctl;

     public static void Main()
     {
          Application.Run(new AnalogClock());
     }
     public AnalogClock()
     {
          Text = "Analog Clock";
          BackColor = SystemColors.Window;
          ForeColor = SystemColors.WindowText;

          clkctl = new ClockControl();
          clkctl.Parent    = this;
          clkctl.Time      = DateTime.Now;
          clkctl.Dock      = DockStyle.Fill;
          clkctl.BackColor = Color.Black;
          clkctl.ForeColor = Color.White;

          Timer timer    = new Timer();
          timer.Interval = 100;
          timer.Tick    += new EventHandler(TimerOnTick);
          timer.Start();
     }
     void TimerOnTick(object obj, EventArgs ea)
     {
          clkctl.Time = DateTime.Now;
     }
}

Здесь ставится свойство Time и вот что этот сеттер делает


[c#]
     public DateTime Time
     {
          set 
          { 
               Graphics grfx = CreateGraphics();
               InitializeCoordinates(grfx);

               Pen pen = new Pen(BackColor);

               if (dt.Hour != value.Hour)
               {
                    DrawHourHand(grfx, pen);
               }
               if (dt.Minute != value.Minute)
               {
                    DrawHourHand(grfx, pen);
                    DrawMinuteHand(grfx, pen);
               }
               if (dt.Second != value.Second)
               {
                    DrawMinuteHand(grfx, pen);
                    DrawSecondHand(grfx, pen);
               }
               if (dt.Millisecond != value.Millisecond)
               {
                    DrawSecondHand(grfx, pen);
               }          
               dt  = value;
               pen = new Pen(ForeColor);

               DrawHourHand(grfx, pen);
               DrawMinuteHand(grfx, pen);
               DrawSecondHand(grfx, pen);

               grfx.Dispose();
          }
     }


Убедил ?
With best regards
Pavel Dvorkin
Re[11]: Рисование из другого потока без мерцания
От: _FRED_ Черногория
Дата: 24.09.08 08:51
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

_FR>>Хорошо, а теперь назовите главу, в которой рекомендуется так делать из чужого потока.


PD>Этого я не назову. Но напомню то, с чего начал. Я сказал, что не вижу никакого криминала в этом. Если Вы можете объяснить, в чем здесь криминал — я готов отказаться от своих слов. Но не раньше.


В ковырянии в носу так же нет никакого криминала, однако в некоторых местах это просто… не считается хорошей практикой (аргументом тому может служить отсутствие статей и примеров уважаемых специалистов).

_FR>>Нет, там (и в ваших) очень узкий пример: реакция на мышь. Понятно, что пока мы что-то рисуем над мышью, перекрыть это будет сложно.


PD>Разумеется, не отменяет. Само собой. Где я говорил, что отменяет ?

PD>Что же касается того, что это очень узкий пример — ну знаете, так можно долго дискутировать. Вот вам еще один пример — рисование по таймеру (см. внизу) Я еще помню пример с фракталами, но, увы, текст привести не могу, он из старой книги по Win16, по которой я когда-то изучал программирование для Windows, и диска там не было.

Это чисто учебные и экзотические примеры: не станете же вы утверждать, что это мэйнстрим. Например, если изменять размер окна или таскать его туда-сюда, пока таймер его рисует, то можно будет заметить неприятные артефакты. Для студентов сойдёт.

PD>Но заверяю честным словом, рисование там шло так же. На это Вы, конечно, можете ответить, что и это узкий пример — но так Вы с меня будете требовать пример за примером, я не могу этим заниматься .


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

PD>Первое — можно ли рисовать (в смысле, что я выше привел) вне WM_PAINT ? Ответ — можно, и Вы с этим согласны, хотя и считаете, что это очень редкие случаи. Я этого не считаю, но это уже спор, который не стоит продолжать.

PD>Второе — можно ли это делать из другого потока. Здесь см. мое замечание в начале этого постинга.

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

C#, например, позволяет работать c неуправляемыми указателями. Единственно упоминание их в соседнем, наверное, самом посещаемом в рунете форуме, в этюдах nikov-а. Я думаю, это о многом говорит, но на это, при желании, можно и не обращать внимание.

_FR>>Я говорю о книге по "Создание эффективных WIN32-приложений с учетом специфики 64-разрной версии Windows" в разделе сообщений windows просто говорится о приоритетах, и причинах того, что приоритет WM_PAINT ниже приоритета WM_TAIMER.


PD>Да, знаком, конечно , на лекции рассказываю. Но из этого следует только, что только при данной расстановке приоритетов вариант с InvalidateRect будет корректен. Если приоритеты поставить иначе, он может быть просто некорректным. Однако из этого не следует ничего в отношении второго варианта.


Из этого следует, что о рисовании из таймера подумали зазработчики ОС, а так же то, какое решение они для данного случая нашли.

>>Кстати, у Петцольд есть такой же (как вы описывали) пример рисования по таймеру?


Выше я про него рассказал. Для студента или поделки, быть может, и сойдёт. Для мэйнстрима — нет.
Help will always be given at Hogwarts to those who ask for it.
Re[12]: в дополнение
От: _FRED_ Черногория
Дата: 24.09.08 08:58
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Кстати, посмотрел еще раз в книге Петцольда по C#. Там примеров с рисованием вне Onpaint не так уж мало. Хинт — поиск по слову CreateGraphics.

PD>Вот твои часы (аналоговые, правда)

И не сомневаюсь — он показывает "как можно", а не "как надо". Вот можете ли вы аналитически сказать, тем показанный пример лучше того, чем вызов Invalidate и обработка WM_PAINT?

PD>Убедил ?


Нет, ибо наличие примера не показывает того, что он описывает правильную практику. Сомневаюсь, что автор говорит о том, почему указанный пример _нельзя_ делать по-другому (то есть, почему другое решения является неправильным).
Help will always be given at Hogwarts to those who ask for it.
Re[12]: Рисование из другого потока без мерцания
От: Pavel Dvorkin Россия  
Дата: 24.09.08 09:17
Оценка:
Здравствуйте, _FRED_, Вы писали:


_FR>В ковырянии в носу так же нет никакого криминала, однако в некоторых местах это просто… не считается хорошей практикой (аргументом тому может служить отсутствие статей и примеров уважаемых специалистов).


Я же не о том, хорошая практика это или нет, а о том, что в этом криминала нет, писал. А о том, хорошая ли это практика или нет — спорить не буду, так как за такой метод вовсе не стою горой. Я лишь утверждаю, что криминала в этом нет.



_FR>Это чисто учебные и экзотические примеры: не станете же вы утверждать, что это мэйнстрим. Например, если изменять размер окна или таскать его туда-сюда, пока таймер его рисует, то можно будет заметить неприятные артефакты. Для студентов сойдёт.


Ну вот, пожалуйста. Сначала Вы просите ссылки на учебник. Я их даю, с цитированием, из книги классика и по Win32, и по .Net. Теперь оказывается, что это чисто учебные примеры (а какие еще вы в учебнике хотите ? )

Дело не в студентах и не в таймере. Дело в том, что в принципе такое возможно и допустимо.. Это все, что я заявляю. Хорошо это или плохо — зависит от ситуации. Что касается мэйнстрим это или нет — это мне попросту неинтересно. В конкретной ситуации я буду решать, какой из двух вариантов ей больше подходит, и мне не важно, какой из них мэйнстрим, а какой нет. вот если бы второй вариант был технически ошибочен и мог привести к неправильной работе — тогда другое дело.

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

Кстати, что за проблема возникнет при перетаскивании окна ? При этом WM_PAINT не шлют. Вот при изменении размера — шлют, и то не всегда, а если стоят CS_HREDRAW и/или CS_VREDRAW в стилях класса.

_FR>Я просил пример реального приложения, которое нельзя было бы назвать поделкой и не получил. Вместо этого получил главы из _учебника_, целью которого является "показать как можно", а не "как надо".


Так. Извиняюсь, но вынужден цитировать

>Какого учебника? Давайте конкретнее. А ещё лучше, на софт. это использующий


http://www.rsdn.ru/forum/message/3113396.1.aspx
Автор: _FRED_
Дата: 23.09.08


Я и дал конкретнее некуда. А искать исходники программ и смотреть, где и как рисуют, у меня времени нет. Извините, но этим заниматься не буду.


_FR>Потоки так же можно завершать через TerminateThread


Можно. Не рекомендуется, но при соблюдении определенных требований — вполне безопасно.

>а с памятью работать с помощью голых указателей.


Ну это за пределами .Net обычная практика

>Но первое, несмотря на то, что существует, повсеместно признано неверным


Не рекомендуемым. Утверждать, что это всегда неверно — неверно. Функции, вызов которых всегда недопустим, не имеют права на существование. Функции, вызова которых надо избегать до последней возможности, а если уж вызываешь — детально проанализировать, какие неприятные последствия от этого могут быть и предупредить их — возможны.

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


+1. Я бы так сказал — надо проанализировать, стоит ли ей пользоваться, какие преимущества мы можем получить. Истина всегда конкретна.

_FR>C#, например, позволяет работать c неуправляемыми указателями. Единственно упоминание их в соседнем, наверное, самом посещаемом в рунете форуме, в этюдах nikov-а. Я думаю, это о многом говорит, но на это, при желании, можно и не обращать внимание.


Нет, не могу я не обращать внимание на эти неуправляемые указатели. Потому что программа моя, которую я сделал — это просто GUI к некоторой неуправляемой DLL, которая меня именно этими неуправляемыми указателями и кормит. Так что я на них свою зарплату получаю. И в этом плане большое спасибо MS, что они их сделали доступными.


PD>>Да, знаком, конечно , на лекции рассказываю. Но из этого следует только, что только при данной расстановке приоритетов вариант с InvalidateRect будет корректен. Если приоритеты поставить иначе, он может быть просто некорректным. Однако из этого не следует ничего в отношении второго варианта.


_FR>Из этого следует, что о рисовании из таймера подумали зазработчики ОС


Верно. Не допустили ошибки. Или вовремя исправили

>а так же то, какое решение они для данного случая нашли.


Неверно. Они просто расставили приоритеты. К тому, что не относится к вопросу приоритетов, это решения отношения не имеет. они не могли сделать иначе, так как пришлось бы отвечать на вопрос — что делать, если таймер работает быстрее, чем окно перерисовывается путем InvalidateRect, и ответа бы не было. А дать ответ — не используйте для этой цели InvalidateRect — нельзя, почему это его я не могу использовать когда хочу, что за исключение из правил ?

_FR>Выше я про него рассказал. Для студента или поделки, быть может, и сойдёт. Для мэйнстрима — нет.


With best regards
Pavel Dvorkin
Re[13]: в дополнение
От: Pavel Dvorkin Россия  
Дата: 24.09.08 09:35
Оценка: 1 (1)
Здравствуйте, _FRED_, Вы писали:

_FR>И не сомневаюсь — он показывает "как можно", а не "как надо". Вот можете ли вы аналитически сказать, тем показанный пример лучше того, чем вызов Invalidate и обработка WM_PAINT?


Да, конечно. На каждый тик таймера здесь меньше рисуется. К примеру, не перерисовывается окружность часов — незачем. А если по Invalidate всерьез делать — надо битовую карту и BitBlt. А это намного медленнее, чем несколько стрелок (линий) нарисовать.

PD>>Убедил ?


_FR>Нет, ибо наличие примера не показывает того, что он описывает правильную практику. Сомневаюсь, что автор говорит о том, почему указанный пример _нельзя_ делать по-другому (то есть, почему другое решения является неправильным).


А кто сказал, что нельзя по-другому ? Можно. Но и так можно.

Я не думаю, что автор признанного учебника стал бы рекомендовать то, что делать не стоит. Его бы давно высмеяли, а его вместо этого классиком считают. Мы с Вами давно не студенты, а поэтому можем сранивать оба варианта со знанием дела. А ведь студенты, только приступающие к изучению предмета, воспринимают учебник как рекомендацию того, что делать можно. Как-то странно было бы, если бы учебник рекомендовал порочную практику, не так ли ? Да еще лучший в мире учебник.

Не обижайтесь, но мое мнение очень простое. Вы столкнулись с подходом решения задачи, решение которой Вам хорошо известно, но другим подходом. Теперь этот другой подход вызывает у Вас реакцию "доказать, что он неверен". Ничего в этой реакции особенного нет, я , наверное, так же поступил бы. Психологически это вполне объяснимо. Но не стоит дальше искать эти доказательства. Этот подход существует, он вполне возможен, но я вовсе не призываю Вас забыть все, что Вы знали раньше. Просто примите спокойно как факт. что вот такое возможно, и совсем не обязательно так делать.

Кстати, если бы в форуме по Win32 я бы начал с таким усердием доказывать, что это возможно, меня бы просто не поняли — чего он в открытую дверь ломится, нашел что доказывать

За сим, как говорили в старину, примите и проч., а я свое участие в этой дискуссии прекращаю. Аргументы обеих сторон высказаны, новых у них нет, так что дальше продолжать не стоит ИМХО.
With best regards
Pavel Dvorkin
Re[11]: Рисование из другого потока без мерцания
От: MxKazan Португалия  
Дата: 24.09.08 09:51
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, MxKazan, Вы писали:


MK>>Окно то там вполне себе есть.


PD>Доказательства ?


"Честно говоря, удивлен, что это надо объяснять. Это стандартная методика, еще раз говорю."
Re: Рисование из другого потока без мерцания
От: TK Лес кывт.рф
Дата: 24.09.08 14:47
Оценка:
Здравствуйте, ObKo, Вы писали:

OK>G — Объект Graphics, полученый методом CreateGraphics() конрола.

OK>Все рисуется нормально, только очень сильно мерцает.
OK>Конрол самопальный, установка Style

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