Непонятное поведение функции BitBlt в Release версии моей программы
От: Melamed Россия  
Дата: 20.04.17 14:26
Оценка:
Ниже привожу код рисования BITMAN'a в моем окне, используя буферизацию изображения

void PaintOnPaint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC hDC = BeginPaint(hWnd, &ps);
    CBitmap *pBitmap = (CBitmap*)GetProp(hWnd, _T("BMP"));
    if (!pBitmap->IsEmpty())
    {
        RECT rc;
        GetClientRect(hWnd, &rc);
        HBITMAP hBmp = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
        HDC hMemDC = CreateCompatibleDC(hDC);
        HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
        HBRUSH hBrush = (HBRUSH)GetClassLong(hWnd, GCL_HBRBACKGROUND);
        if (hBrush != 0)
        {
            FillRect(hMemDC, &rc, hBrush);
        }
        int X = (rc.right - rc.left - pBitmap->GetWidth()) / 2;
        if (X < 0)
        {
            X = -GetScrollPos(hWnd, SB_HORZ);
        }
        int Y = (rc.bottom - rc.top - pBitmap->GetHeight()) / 2;
        if (Y < 0)
        {
            Y = -GetScrollPos(hWnd, SB_VERT);
        }
        if (GetDeviceCaps(hMemDC, RASTERCAPS) & RC_BITBLT)
        {
            pBitmap->Draw(hMemDC, X + g_dx, Y + g_dy);
        }
        if (GetDeviceCaps(hDC, RASTERCAPS) & RC_BITBLT)
        {
            BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY);
        }
        SelectObject(hMemDC, hOldBmp);
        DeleteDC(hMemDC);
        DeleteObject(hBmp);
    }
    EndPaint(hWnd, &ps);
}


Когда комментирую выделенную жирным шрифтом строку, следующая строка, где вызывается функция BitBlt работает с ошибкой в Release версии моей программы. Снимаю комментарий — все работает нормально. В Debug версии такого эффекта нет.
Среда разработки MVC++ 2015 Операционная система Windows 10
Re: Непонятное поведение функции BitBlt в Release версии моей программы
От: CEMb  
Дата: 21.04.17 02:35
Оценка:
Здравствуйте, Melamed, Вы писали:

M>Когда комментирую выделенную жирным шрифтом строку, следующая строка, где вызывается функция BitBlt работает с ошибкой в Release версии моей программы. Снимаю комментарий — все работает нормально. В Debug версии такого эффекта нет.

M>Среда разработки MVC++ 2015 Операционная система Windows 10

Т.е. если убрать условие, и просто вызвать GetDeviceCaps, даже намного раньше, тоже всё ок?
Re[2]: Непонятное поведение функции BitBlt в Release версии моей программы
От: Melamed Россия  
Дата: 21.04.17 17:33
Оценка:
Здравствуйте, CEMb, Вы писали:

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


M>>Когда комментирую выделенную жирным шрифтом строку, следующая строка, где вызывается функDция BitBlt работает с ошибкой в Release версии моей программы. Снимаю комментарий — все работает нормально. В Debug версии такого эффекта нет.

M>>Среда разработки MVC++ 2015 Операционная система Windows 10

CEM>Т.е. если убрать условие, и просто вызвать GetDeviceCaps, даже намного раньше, тоже всё ок?

Да все Ok. Я подозреваю, что производительность метода Draw класса СBitmap слишком высока, и для выполнения вызова функции BitBlt после вызова этого метода графическое устройство просто не готово. Вот и ошибка возникает.
Re[3]: Непонятное поведение функции BitBlt в Release версии моей программы
От: CEMb  
Дата: 28.04.17 02:31
Оценка:
Здравствуйте, Melamed, Вы писали:

CEM>>Т.е. если убрать условие, и просто вызвать GetDeviceCaps, даже намного раньше, тоже всё ок?

M>Да все Ok. Я подозреваю, что производительность метода Draw класса СBitmap слишком высока, и для выполнения вызова функции BitBlt после вызова этого метода графическое устройство просто не готово. Вот и ошибка возникает.

Не, а если GetDeviceCaps поставить до Draw?
На других операционках как?
BitBlt не может отработать раньше, чем Draw завершится. И никакого, например, кеша между Bitmap и HDC быть не может, чтобы ждать, когда данные в hMemDC попадут.
Есть подозр, GetDeviceCaps для получения данных как-то дополнительно инициализирует hDC.
Для тестов попробуй убрать GetDeviceCaps и вместо него сними данные с hMemDC, убедись, что там что-то есть/нет.
Потом тоже самое с GetDeviceCaps. Подозреваю, что там каждый раз будет одинаково, и всё дело в hDC.
Или, как вариант, просто в цикле зови BitBlt, пока оно не нарисует что-то Моя гипотеза: без GetDeviceCaps оно никогда ничего не нарисует.
Re: Непонятное поведение функции BitBlt в Release версии моей программы
От: Andrew S Россия http://alchemy-lab.com
Дата: 04.05.17 22:35
Оценка:
Какая ошибка возвращается?
Вообще, очень странный код — почему сразу из битмана не отрисовать на контекст устройства?

M>Ниже привожу код рисования BITMAN'a в моем окне, используя буферизацию изображения


M>
M>void PaintOnPaint(HWND hWnd)
M>{
M>    PAINTSTRUCT ps;
M>    HDC hDC = BeginPaint(hWnd, &ps);
M>    CBitmap *pBitmap = (CBitmap*)GetProp(hWnd, _T("BMP"));
M>    if (!pBitmap->IsEmpty())
M>    {
M>        RECT rc;
M>        GetClientRect(hWnd, &rc);
M>        HBITMAP hBmp = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
M>        HDC hMemDC = CreateCompatibleDC(hDC);
M>        HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
M>        HBRUSH hBrush = (HBRUSH)GetClassLong(hWnd, GCL_HBRBACKGROUND);
M>        if (hBrush != 0)
M>        {
M>            FillRect(hMemDC, &rc, hBrush);
M>        }
M>        int X = (rc.right - rc.left - pBitmap->GetWidth()) / 2;
M>        if (X < 0)
M>        {
M>            X = -GetScrollPos(hWnd, SB_HORZ);
M>        }
M>        int Y = (rc.bottom - rc.top - pBitmap->GetHeight()) / 2;
M>        if (Y < 0)
M>        {
M>            Y = -GetScrollPos(hWnd, SB_VERT);
M>        }
M>        if (GetDeviceCaps(hMemDC, RASTERCAPS) & RC_BITBLT)
M>        {
M>            pBitmap->Draw(hMemDC, X + g_dx, Y + g_dy);
M>        }
M>        if (GetDeviceCaps(hDC, RASTERCAPS) & RC_BITBLT)
M>        {
M>            BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY);
M>        }
M>        SelectObject(hMemDC, hOldBmp);
M>        DeleteDC(hMemDC);
M>        DeleteObject(hBmp);
M>    }
M>    EndPaint(hWnd, &ps);
M>}

M>


M>Когда комментирую выделенную жирным шрифтом строку, следующая строка, где вызывается функция BitBlt работает с ошибкой в Release версии моей программы. Снимаю комментарий — все работает нормально. В Debug версии такого эффекта нет.

M>Среда разработки MVC++ 2015 Операционная система Windows 10
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Непонятное поведение функции BitBlt в Release версии моей программы
От: CEMb  
Дата: 05.05.17 02:09
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Вообще, очень странный код — почему сразу из битмана не отрисовать на контекст устройства?


Дублирующая буферизация
И что значит "сразу из битмапа на контекст устройства"?
Re[3]: Непонятное поведение функции BitBlt в Release версии моей программы
От: Andrew S Россия http://alchemy-lab.com
Дата: 09.05.17 19:57
Оценка:
CEM>Здравствуйте, Andrew S, Вы писали:

AS>>Вообще, очень странный код — почему сразу из битмана не отрисовать на контекст устройства?


CEM>Дублирующая буферизация

CEM>И что значит "сразу из битмапа на контекст устройства"?

Например, SetDIBitsToDevice. Но это не суть — нам так и не ответили, что за ошибка возвращается.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Непонятное поведение функции BitBlt в Release версии моей программы
От: T4r4sB Россия  
Дата: 09.05.17 21:47
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Например, SetDIBitsToDevice.


А какая разница?
Re[5]: Непонятное поведение функции BitBlt в Release версии моей программы
От: Andrew S Россия http://alchemy-lab.com
Дата: 10.05.17 21:33
Оценка:
TB>А какая разница?

Разные механизмы. CBitmap — это gdi managed объект, в отличие от.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.