2016-09-24 2 views
0

Я прокручивал пользовательские окна с помощью API окон. В связи с этим я работал с Extended Layered Windows. У меня есть окно, и оно работает. Однако при изменении размера окна при вызове метода redraw/UpdateLayeredWindow (и UpdateLayeredWindowIndirect) появляется нечетное мерцание/сбой [(Снимок экрана)] [1]. Что-то я здесь делаю неправильно?Visual-C Win32 API Многоуровневое окно мерцания

void redrawBaseWindow(HWND window) { 
    RECT rect; 
    GetWindowRect(window, &rect); 
    int elipseDiam = ((rect.right - rect.left)+(rect.bottom-rect.top))/2*0.025; 
    HDC mainDC = GetDC(NULL); 
    POINT destination = { rect.left,rect.top }; 
    POINT zero = destination; 
    SIZE size = { rect.right - rect.left,rect.bottom - rect.top }; 
    BLENDFUNCTION bf; 
    bf.BlendOp = AC_SRC_OVER; 
    bf.BlendFlags = 0; 
    bf.AlphaFormat = 0; 
    bf.SourceConstantAlpha = 255; 
    HBRUSH brush = CreateSolidBrush(RGB(255, 0, 100)); 
    HBRUSH oldbrush = SelectObject(mainDC, brush); 
    HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); 
    HPEN oldPen = SelectObject(mainDC, pen); 
    HBITMAP bmp = CreateCompatibleBitmap(mainDC, size.cx,size.cy); 
    HBITMAP oldBmp = SelectObject(mainDC, bmp); 
    FillRect(mainDC, &rect, CreateSolidBrush(RGB(0, 0, 0))); 
    Rectangle(mainDC, rect.left, rect.top + elipseDiam/2, rect.right, rect.bottom - elipseDiam/2); 
    Rectangle(mainDC, rect.left + elipseDiam/2, rect.top, rect.right - elipseDiam/2, rect.bottom); 
    UPDATELAYEREDWINDOWINFO updated = { sizeof(UPDATELAYEREDWINDOWINFO), NULL, &destination, &size, mainDC, &zero, RGB(0,0,0),&bf, ULW_COLORKEY, &rect}; 
    UpdateLayeredWindowIndirect(window, &updated); 
    //BOOL error = UpdateLayeredWindow(window, NULL, &destination, &size, mainDC, &zero, RGB(0, 0, 0), &bf, ULW_COLORKEY); 
    SelectObject(mainDC, oldbrush); 
    SelectObject(mainDC, oldBmp); 
    SelectObject(mainDC, oldPen); 
    DeleteObject(brush); 
    DeleteObject(bmp); 
    DeleteObject(pen); 
} 

На всякий случай, сообщение Windows Proc.

long __stdcall WndProc(HWND window, unsigned int msg, WPARAM wp, LPARAM lp) { 
    PAINTSTRUCT ps; 
    HDC hdc; 
    TCHAR greeting[] = "Hello, World!"; 
    RECT rect_window; 
    GetWindowRect(window, &rect_window); 
    switch (msg) { 
    case WM_SYSKEYDOWN: 
     MessageBeep(MB_ICONERROR); 
    case WM_CREATE: 
    break; 
case WM_DESTROY: 
    PostQuitMessage(0); 
    break; 
case WM_NCHITTEST:; 
    int x = LOWORD(lp); 
    int y = HIWORD(lp); 
    if (x > rect_window.left && x<rect_window.right && y>rect_window.top && y < rect_window.top + 25) 
     return HTCAPTION; 
    if (x>=rect_window.left-3 && x<=rect_window.left+3) 
     return HTLEFT; 
    if (x >= rect_window.right - 3 && x <= rect_window.right + 3) 
     return HTRIGHT; 
    if (y >= rect_window.top - 3 && y <= rect_window.top + 3) 
     return HTTOP; 
    if (y >= rect_window.bottom - 3 && y <= rect_window.bottom + 3) 
     return HTBOTTOM; 
    break; 
case WM_LBUTTONDOWN: 
    break; 
case WM_SIZE: 
    redrawBaseWindow(window); 
    break; 
case WM_PAINT: 
    break; 
} 
return DefWindowProc(window, msg, wp, lp); 
} 

Редактировать: Gif of the glitch

Изменить 2: Используя значение CreateCompatibleDC в UpdateLayeredWindow [Кроме того, не работает]

void redrawBaseWindow(HWND window) { 
    RECT rect; 
    GetWindowRect(window, &rect); 
    int elipseDiam = ((rect.right - rect.left)+(rect.bottom-rect.top))/2*0.025; 
    HDC mainDC = GetDC(NULL); 
    HDC memDC = CreateCompatibleDC(mainDC); 
    POINT destination = { rect.left,rect.top }; 
    POINT zero = destination; 
    SIZE size = { rect.right - rect.left,rect.bottom - rect.top }; 
    BLENDFUNCTION bf; 
    bf.BlendOp = AC_SRC_OVER; 
    bf.BlendFlags = 0; 
    bf.AlphaFormat = 0; 
    bf.SourceConstantAlpha = 255; 
    HBRUSH brush = CreateSolidBrush(RGB(255, 0, 100)); 
    HBRUSH oldbrush = SelectObject(memDC, brush); 
    HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); 
    HPEN oldPen = SelectObject(memDC, pen); 
    HBITMAP bmp = CreateCompatibleBitmap(memDC, size.cx,size.cy); 
    HBITMAP oldBmp = SelectObject(memDC, bmp); 
    FillRect(memDC, &rect, CreateSolidBrush(RGB(0, 0, 0))); 
    Rectangle(memDC, rect.left, rect.top + elipseDiam/2, rect.right, rect.bottom - elipseDiam/2); 
    Rectangle(memDC, rect.left + elipseDiam/2, rect.top, rect.right - elipseDiam/2, rect.bottom); 
    Ellipse(memDC, rect.left + elipseDiam, rect.top + elipseDiam, rect.left, rect.top); //Top-Left 
    Ellipse(memDC, rect.right - elipseDiam, rect.top, rect.right, rect.top + elipseDiam); //Top-Right 
    Ellipse(memDC, rect.left, rect.bottom, rect.left + elipseDiam, rect.bottom - elipseDiam); //Bottom-Left 
    Ellipse(memDC, rect.right - elipseDiam, rect.bottom, rect.right, rect.bottom - elipseDiam); //Bottom-Right 
    UPDATELAYEREDWINDOWINFO updated = { sizeof(UPDATELAYEREDWINDOWINFO), NULL, &destination, &size, memDC, &zero, RGB(0,0,0),&bf, ULW_COLORKEY, &rect}; 
    UpdateLayeredWindowIndirect(window, &updated); 
    //BOOL error = UpdateLayeredWindow(window, NULL, &destination, &size, mainDC, &zero, RGB(0, 0, 0), &bf, ULW_COLORKEY); 
    SelectObject(memDC, oldbrush); 
    SelectObject(memDC, oldBmp); 
    SelectObject(memDC, oldPen); 
    DeleteObject(brush); 
    DeleteObject(bmp); 
    DeleteObject(pen); 
    ReleaseDC(NULL,mainDC); 
    ReleaseDC(NULL,memDC); 
} 

Редактировать 3: DeleteDC на CreateCompatibleDC устройстве, а также создание растрового изображения на экране DC, а не CompatibleDC

void redrawBaseWindow(HWND window) { 
    RECT rect; 
    GetWindowRect(window, &rect); 
    int elipseDiam = ((rect.right - rect.left)+(rect.bottom-rect.top))/2*0.025; 
    HDC mainDC = GetDC(NULL); 
    HDC memDC = CreateCompatibleDC(mainDC); 
    POINT destination = { rect.left,rect.top }; 
    POINT zero = destination; 
    SIZE size = { rect.right - rect.left,rect.bottom - rect.top }; 
    BLENDFUNCTION bf; 
    bf.BlendOp = AC_SRC_OVER; 
    bf.BlendFlags = 0; 
    bf.AlphaFormat = 0; 
    bf.SourceConstantAlpha = 255; 
    HBRUSH brush = CreateSolidBrush(RGB(255, 0, 100)); 
    HBRUSH oldbrush = SelectObject(memDC, brush); 
    HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); 
    HPEN oldPen = SelectObject(memDC, pen); 
    HBITMAP bmp = CreateCompatibleBitmap(mainDC, size.cx,size.cy); 
    HBITMAP oldBmp = SelectObject(memDC, bmp); 
    FillRect(memDC, &rect, CreateSolidBrush(RGB(0, 0, 0))); 
    Rectangle(memDC, rect.left, rect.top + elipseDiam/2, rect.right, rect.bottom - elipseDiam/2); 
    Rectangle(memDC, rect.left + elipseDiam/2, rect.top, rect.right - elipseDiam/2, rect.bottom); 
    Ellipse(memDC, rect.left + elipseDiam, rect.top + elipseDiam, rect.left, rect.top); //Top-Left 
    Ellipse(memDC, rect.right - elipseDiam, rect.top, rect.right, rect.top + elipseDiam); //Top-Right 
    Ellipse(memDC, rect.left, rect.bottom, rect.left + elipseDiam, rect.bottom - elipseDiam); //Bottom-Left 
    Ellipse(memDC, rect.right - elipseDiam, rect.bottom, rect.right, rect.bottom - elipseDiam); //Bottom-Right 
    UPDATELAYEREDWINDOWINFO updated = { sizeof(UPDATELAYEREDWINDOWINFO), NULL, &destination, &size, memDC, &zero, RGB(0,0,0),&bf, ULW_COLORKEY, &rect}; 
    UpdateLayeredWindowIndirect(window, &updated); 
    //BOOL error = UpdateLayeredWindow(window, NULL, &destination, &size, mainDC, &zero, RGB(0, 0, 0), &bf, ULW_COLORKEY); 
    SelectObject(memDC, oldbrush); 
    SelectObject(memDC, oldBmp); 
    SelectObject(memDC, oldPen); 
    DeleteObject(brush); 
    DeleteObject(bmp); 
    DeleteObject(pen); 
    DeleteDC(memDC); 
    ReleaseDC(NULL,mainDC); 
} 

Оригинальный мерцающий фиксированный. Спасибо [Jonathan Pottar] Другая ошибка однако: This

+0

Создайте анимированный скриншот gif, я не вижу проблемы с вашим изображением. – Lothar

+0

Будет делать только мгновение – UnknownRobotik

+1

Выбор другого растрового изображения в DC, полученный из 'GetDC', немного нечетный, и я не уверен, что поддерживается передача DC в' UpdateLayeredWindow'. Обычное использование - это выбрать ваш растровый рисунок в память DC, полученный из «CreateCompatibleDC», визуализировать его и обновить окно от него. У вас также есть утечка ресурсов GDI (не вызывающая 'ReleaseDC'). –

ответ

0
void redrawBaseWindow(HWND window) { 
RECT rect; 
GetWindowRect(window, &rect); 
int elipseDiam = ((rect.right - rect.left)+(rect.bottom-rect.top))/2*0.025; 
HDC mainDC = GetDC(NULL); 
HDC memDC = CreateCompatibleDC(mainDC); 
POINT destination = { rect.left,rect.top }; 
POINT zero = destination; 
SIZE size = { rect.right - rect.left,rect.bottom - rect.top }; 
BLENDFUNCTION bf; 
bf.BlendOp = AC_SRC_OVER; 
bf.BlendFlags = 0; 
bf.AlphaFormat = 0; 
bf.SourceConstantAlpha = 255; 
HBRUSH brush = CreateSolidBrush(RGB(255, 0, 100)); 
HBRUSH oldbrush = SelectObject(memDC, brush); 
HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); 
HPEN oldPen = SelectObject(memDC, pen); 
HBITMAP bmp = CreateCompatibleBitmap(mainDC, size.cx,size.cy); 
HBITMAP oldBmp = SelectObject(memDC, bmp); 
FillRect(memDC, &rect, CreateSolidBrush(RGB(0, 0, 0))); 
Rectangle(memDC, rect.left, rect.top + elipseDiam/2, rect.right, rect.bottom - elipseDiam/2); 
Rectangle(memDC, rect.left + elipseDiam/2, rect.top, rect.right - elipseDiam/2, rect.bottom); 
Ellipse(memDC, rect.left + elipseDiam, rect.top + elipseDiam, rect.left, rect.top); //Top-Left 
Ellipse(memDC, rect.right - elipseDiam, rect.top, rect.right, rect.top + elipseDiam); //Top-Right 
Ellipse(memDC, rect.left, rect.bottom, rect.left + elipseDiam, rect.bottom - elipseDiam); //Bottom-Left 
Ellipse(memDC, rect.right - elipseDiam, rect.bottom, rect.right, rect.bottom - elipseDiam); //Bottom-Right 
UPDATELAYEREDWINDOWINFO updated = { sizeof(UPDATELAYEREDWINDOWINFO), NULL, &destination, &size, memDC, &zero, RGB(0,0,0),&bf, ULW_COLORKEY, &rect}; 
UpdateLayeredWindowIndirect(window, &updated); 
//BOOL error = UpdateLayeredWindow(window, NULL, &destination, &size, mainDC, &zero, RGB(0, 0, 0), &bf, ULW_COLORKEY); 
SelectObject(memDC, oldbrush); 
SelectObject(memDC, oldBmp); 
SelectObject(memDC, oldPen); 
DeleteObject(brush); 
DeleteObject(bmp); 
DeleteObject(pen); 
DeleteDC(memDC); 
ReleaseDC(NULL,mainDC); 
} 

Это, к счастью, сосредоточил свой вопрос.

Смежные вопросы