Вот пример фунции, которая у меня дает сбой. Эту функцию построил на основании своей, которую немного сократил. Поэтому, в приведенном ниже коде минимум половина может показаться просто не нужной для достижения того же результата. Эту функцию я вызываю по таймеру через каждые 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;
}