Re[3]: Число созданий CompatibleBitmap под w98 сильно ограни
От: elich  
Дата: 22.01.04 21:48
Оценка:
Вот пример фунции, которая у меня дает сбой. Эту функцию построил на основании своей, которую немного сократил. Поэтому, в приведенном ниже коде минимум половина может показаться просто не нужной для достижения того же результата. Эту функцию я вызываю по таймеру через каждые 30 мс. Приходится жадть от 100 — до 140 секунд на моей машине. Еще более усугубляет ситуацию то, что w98 вылетает после появления сбоя, поэтому приходится каждый раз делать restart. Еще более ее усугубляет и то, что Visual C 7.0 под w98 поставить нельзя, поэтому приходится вместо отладчика использовать MessageBoxы и прочие пакости. В общей сложности на этот баг я потратил уже 2 дня. До сих пор не разобрался, по какой причине не работает. Блин, Вы не представляете, как бы я был Вам признателен, елси бы хотя бы малюсенькую зацепочку кто подсказал. Для тех, кто проявит интерес, гораздо более обычного, я могу выслать demo-проект, Visual C ++ 7.0. В нем этот сбой наглядно наблюдается — специально для этого делал диалог, в котором стоит таймер, статус вызова функции и т.п. Код хорошо прокомментирован, писал как раз для Вас. Все, что для этого надо — послать запрос мне по мылу: elich@ezmail.ru с указанием того, нужно ли exe файл, который чуть менее 200кб, или только исходник выслать. Обязуюсь выслать, очень скоро. Спецально для этого буду постонно проверять почту в течение 23 января, в надежде, что хоть кто-нибудь ответит на мой душевный крик. ВНИМАНИЕ: баг локализован. Т.е. известна строка, на которой происходит ошибка. Не известно лишь то, ПОЧЕМУ ОНА ПРОИСХОДИТ!!!. А вот и сама фукция для тех, кому не нужны мои старания...

int TestDraw1(CDC& dc, HBITMAP hbmPaint, CRect rcPaint)
{
    // Прозрачный цвет
    COLORREF clrTrans = RGB(255, 255, 255);

    // Создаем контекст в памяти
    CDC dcMem;
    dcMem.CreateCompatibleDC(&dc);
    if (!dcMem.m_hDC) return 1;
    
    // Создаем битмап для выбора в контесте и выбираем его
    CBitmap bmpSrc;
    if (bmpSrc.CreateCompatibleBitmap(&dc, bitmap.bmWidth, 
        bitmap.bmHeight) == FALSE) return 2;
    CBitmap* pOld = dcMem.SelectObject(&bmpSrc);

    // Получаем параметры битмапа, который необходимо отрисовать
    BITMAP bitmap;
    ::ZeroMemory(&bitmap, sizeof(bitmap));
    if (::GetObject(hbmPaint, sizeof(BITMAP), &bitmap) == FALSE) return 3;

    // Рисуем на холсте в памяти сначала, получаем прозрачный цвет
    if (dcMem.DrawState(CPoint(0, 0), 
        CSize(bitmap.bmWidth, bitmap.bmHeight), hbmPaint, 0) == FALSE) 
        return 4;

    // Рассчитываем прямоугольник отрисовки
    CRect rcBitmap(rcPaint.left, rcPaint.top, 
        rcPaint.left + bitmap.bmWidth, rcPaint.top + bitmap.bmHeight);
    
    // Вывод
    if (dc.TransparentBlt(rcBitmap.left, rcBitmap.top, 
        bitmap.bmWidth, bitmap.bmHeight, &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, clrTrans) == FALSE)
            return 5;

    // Освобождаем ресурсы
    dcMem.SelectObject(pOld);
    if (bmpSrc.DeleteObject() == FALSE)
        return 6;

    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.