RedrawWindow () проблема в дочерних окнах - PullRequest
1 голос
/ 21 апреля 2011

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

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

После этого я скрываю окно фотошопа (установите непрозрачность равным 0) и вместо этого захватываю его содержимое контекста устройства в созданное мной растровое изображение и рисую это растровое изображение в своем окне. Для этого я установил таймер, который срабатывает каждые 16 миллисекунд (60 Гц). Это таймер:

void CALLBACK drawProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
{
    updateFrames();

    RECT r;
    GetClientRect( hwnd, &r );

    //Erase background
    HBRUSH eraseBrush = CreateSolidBrush( RGB( 255, 255, 255 ) );
    FillRect( bbHDC, &r, eraseBrush );
    DeleteObject( eraseBrush );

    //Draw frames
    drawFrames( bbHDC );    

    RedrawWindow( hwnd, 0, 0, RDW_INVALIDATE | RDW_NOCHILDREN );
}

Проблема в том, что это замедляет работу фотошопа (и некоторых других приложений). Комментируя строки, я узнал, что redrawWindow вызывает это. Я подумал, что перерисовка главного окна может привести к тому, что Photoshop также перерисовывает его содержимое, поэтому я добавил RDW_NOCHILDREN, но медлительность сохраняется.

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

Спасибо.

1 Ответ

3 голосов
/ 21 апреля 2011

Я даже не собираюсь комментировать, почему это странная вещь:)

Почему это медленно:

RedrawWindow, вероятно, заставляет перекрашивать каждый раз, когда вы звоните.В конце концов, вы делаете недействительным все окно.Это будет дорогостоящая операция - обычно в приложении Windows вы рисуете только тогда, когда знаете, что вам нужно (путем аннулирования прямоугольника или области, что является очень дешевой операцией, и в какой-то момент обрабатывает сообщение WM_PAINT, и когдаобработка этой картины только недействительной областью, которая является минимально возможной работой.)

Стоит прочитать о рисование и рисование в Windows , особенно , когда рисовать в окне.

Теперь, чтобы попытаться ответить на ваш вопрос:

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

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

Следующее предложение, я не пробовал, но оно должно работать.В Windows уже есть встроенная инфраструктура, поэтому приложение знает, когда ему нужно рисовать: сообщение WM_PAINT будет присутствовать в его очереди сообщений.Вы можете заглянуть в очередь сообщений окна и посмотреть, какие сообщения там есть, не удаляя их, используя PeekMessage .Это скажет вам, когда нужно покрасить окно: перекрасьте тогда.В качестве альтернативы, перехватывает функцию сообщения или , подклассирует окно и, когда сообщение WM_PAINT получено, передает его в исходную функцию сообщения, а затем перерисовывает.Вы можете использовать GetUpdateRect, чтобы увидеть, какая область будет окрашена, а затем, после завершения обработки WM_PAINT, скопировать эту область только в свое собственное окно.И т.д.

Это общий ответ: попробуйте некоторые из этих вещей и посмотрите, что произойдет.Помните, что если у вас есть проблемы с определенными деталями, вы можете отправить еще один вопрос!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...