2011-01-05 2 views
0

Мне нужно определить некоторые wnds в моем приложении (объекты класса CMDIChildWnd). Для этого я использую таймер, чтобы нарисовать границу wnd с определенным цветом в качестве альтернативы, чтобы дать ощущение мигания. Это отлично работает на машинах WinXP, но страшно разочаровывает машины Win7; есть значительная задержка в рисовании выделенной границы.
Однако при переключении на оптимизируйте для лучшей производительности. настройка все работает ровно.Задержка при рисовании на окнах 7 ОС

Я использую метод CCLinetDC::Rectangle(), чтобы нарисовать границу. Есть ли известная проблема с этим API в Win7? Как я могу заставить его работать и с Win7?

+0

Что переключаясь "оптимизировать для лучшей производительности?" Это параметр компилятора или настройка ОС или? –

+0

Его настройка ОС Дэвида. Именно в настройках _Adjust Visual Effects_ из панели управления. – Hemant

ответ

1

Вы можете попробовать с отключением окраски NC-области.

Что-то, как показано ниже:

#include <dwmapi.h> 
... 

HRESULT hr = E_FAIL; 
if (IsVistaOrAbove()) 
{ 
    DWMNCRENDERINGPOLICY ncrp = DWMNCRP_DISABLED; 
    hr = ::DwmSetWindowAttribute(m_hWnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp)); 
    ASSERT(SUCCEEDED(hr)); 
} 

Но это также отключает Aero на окне.

Так что было бы проще показать мигание в клиентской области, а не на границе.

ОБНОВЛЕНО

Для XP совместимости, вы должны использовать API-интерфейсы DWM так:

typedef HRESULT (WINAPI *pfnDwmIsCompositionEnabled)(BOOL *pfEnabled); 
static pfnDwmIsCompositionEnabled s_DwmIsCompositionEnabled; 
typedef HRESULT (WINAPI *pfnDwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); 
static pfnDwmSetWindowAttribute s_DwmSetWindowAttribute; 
typedef HRESULT (WINAPI *pfnDwmGetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); 
static pfnDwmGetWindowAttribute s_DwmGetWindowAttribute; 


HMODULE hSysDll = LoadLibrary(_T("dwmapi.dll")); 
if(hSysDll) // Loaded dwmapi.dll success, must Vista or above 
{ 
    s_DwmIsCompositionEnabled = (pfnDwmIsCompositionEnabled)GetProcAddress(hSysDll, "DwmIsCompositionEnabled"); 
    s_DwmSetWindowAttribute = (pfnDwmSetWindowAttribute)GetProcAddress(hSysDll, "DwmSetWindowAttribute"); 
    s_DwmGetWindowAttribute = (pfnDwmGetWindowAttribute)GetProcAddress(hSysDll, "DwmGetWindowAttribute"); 
} 
... 
... 
bool IsAeroEnabled() 
{ 
    BOOL bAero = FALSE; 
    if(s_DwmIsCompositionEnabled) 
     s_DwmIsCompositionEnabled(&bAero); 
    return bAero != FALSE; 
} 
... 
... 
HRESULT ProxyDwmSetWindowAttribute(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) 
{ 
    if (s_DwmSetWindowAttribute) 
    { 
     return s_DwmSetWindowAttribute(hwnd, dwAttribute, pvAttribute, cbAttribute); 
    } 
    return E_FAIL; 
} 
+0

Один вопрос - будет ли это задано политика рендеринга NC в глобальном масштабе (т. Е. Для всех других приложений) или только для этого окна, специфичного для дескриптора? И Сбросить исходные настройки после того, как событие (идентификация окна) закончилось? – Hemant

+0

Кроме того, я рисую прямоугольник только в области клиента, а не в области ЧПУ. Для этого я использую 'CCLinetDC', что, безусловно, привлекает только клиентскую область. – Hemant

+0

@ Хемант А .. мои слова вводят в заблуждение. Во всяком случае, это может быть проблема, связанная с DWM. Вы можете проверить его, если проблема решена, если состав DWM отключен. Измените тему рабочего стола на не-Aero. – 9dan