Кстати, на кодегуру прямого примера нет точно, а то что есть о том как рисовать прозрачные штучки — не то.
Valery Boronin
A 1 Нужно для каждой картинки, входящей в анимацию, делать для окна специальный регион, который включал бы в себя точки, принадлежащие изображению и не включал все остальные. Это можно сделать так (source ниже) : Создать пустой регион, выбрать картинку (bitmap), выбрать прозрачный цвет, проитись по bitmap и для каждого непрозрачного участка в каждой строке bitmap создать регион высотой 1 пиксел и прикомбинировать его к исходному региону. В конце операции установить получившийся регион окну.
void MakeBitmapRegion(HWND hwnd, int int bmp_id) {
COLORREF back_color;
CBitmap bmp;
if (!bmp.LoadBitmap (bmp_id)) return;
BITMAP bmp_o;
bmp.GetObject(sizeof(BITMAP), (LPSTR)&bmp_o);
int w = bmp_o.bmWidth;
int h = bmp_o.bmHeight;
HDC wnd_dc = GetDC(hwnd);
if (hwnd == NULL) return;
if (wnd_dc == NULL) return;
HDC hdc_bmp = CreateCompatibleDC(wnd_dc);
SelectObject(hdc_bmp, HBITMAP(bmp));
back_color = GetPixel(hdc_bmp, 0, 0);
int x, x0, y;
HRGN tmp_rgn, wnd_rgn;
wnd_rgn = CreateRectRgn(0,0,0,0);
x = y = 0;
for (y; y < h; y++) {
while (x < w-1) {
while(GetPixel(hdc_bmp, x, y) == back_color && x < w) x++;
if (x != w) {
x0 = x;
while(GetPixel(hdc_bmp, x, y) != back_color && x < w) x++;
tmp_rgn = CreateRectRgn(x0, y, x, y+1);
CombineRgn(wnd_rgn, wnd_rgn, tmp_rgn, RGN_XOR);
}
}
x = 0;
}
DeleteObject(tmp_rgn);
DeleteDC(hdc_bmp);
SetWindowRgn(hwnd, wnd_rgn, TRUE);
DeleteObject(wnd_rgn);
}
Сергей Егоров
A 2 Как сделать полностью прозрачное окно, которое не тащит за собою кусок фона – понятно. Нужно просто перехватить сообщение WM_WINDOWPOSCHANGING и сказать системе, чтобы она не копировала содержимое окна. Для этого в структуре WINDOWPOS, указатель на которую передаётся в функцию окна, предусмотрен флаг SWP_NOCOPYBITS. В MFC обработчик может выглядеть примерно так:
void CMyWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) {
lpwndpos->flags |= SWP_NOCOPYBITS;
CWnd::OnWindowPosChanging(lpwndpos);
}
Другой вопрос, что этого явно не достаточно для реализации прозрачного окна. Ведь полностью пустое окно мало кого заинтересует, а если нарисовать в нём что-то, а затем сдвинуть окно, за ним потянется шлейф с нарисованным изображением.
Если прозрачные области в окне статические, то есть способ лучше – воспользоваться SetWindowRgn. Об этой функции писалось в 7-м выпуске рассылки. Но если требуется организовать анимацию на фоне рабочего стола, то, вероятно, не обойтись без сохранения фона с его последующим восстановлением. Дело в том, что многие программы очень медленно перерисовывают свои окна, и поручать им обновление фона под нашим окном не представляется возможным.
Alexander Shargin ( rudankort@mail.ru)
ОБРАТНАЯ СВЯЗЬ
К прошлому выпуску:
У меня есть два меленьких примечания к теме "Три способа подключения DLL":
1. При неявном подключении .lib файл можно добавить к проекту с помощью меню "Project\Add to project\Files", выбрав тип файлов *.lib. Об этом все, наверное, знают, но про это не было упоминания в статье.
2.По поводу отложенной загрузки. К сожалению, как сказано в MSDN, такое подключение не позволяет импортировать данные: "Imports of data cannot be supported. A workaround is to explicitly handle the data import yourself using LoadLibrary (or GetModuleHandle after you know the delay-load helper has loaded the DLL) and GetProcAddress.".
Sergey Kuryata
По поводу проблемы, описанной в конце статьи прошлого выпуска:
я не проделывал данных действий, но у меня всё слинковалось и заработало
обычная линковка
#pragma comment(lib, "Delayimp.lib")
проходит, может потому, что установлен SP для MSVC 6.0
Max Stepanov
В ПОИСКАХ ИСТИНЫ
Q. Возникла проблема… Существует sdi-приложение с CFormView-базированным видом. Существует несколько форм также основанных на CFormView. Необходимо динамически изменять основной вид на другие формы в процессе работы программы. Я так понимаю существует два пути. Первый – в OnCreate CMainFrame создавать все формы и потом сортировать их меняя z-порядок и второй – по мере необходимости создавать формы динамически.А вот с реализацией – :(. Или может я не прав? Заранее спасибо.
olegich
Это все на сегодня. Пока!
Алекс Jenter jenter@mail.ru Красноярск, 2000.
Программирование на visual C++
Выпуск №24 от 19 ноября 2000 г.
Всем привет!
СТАТЬЯ
Как бороться с мерцанием
Вот наконец настал момент, когда работа над программой уже как бы закончена, все вылизано и подчищено, и шедевр вроде не глючит и даже заказчик кажется довольным. И все просто отлично… кроме одной мелочи – при изменении размеров окна элементы управления на форме сильно мерцают. Да, вроде бы мелочь. Да, многие коммерческие приложения тоже мерцают… даже ОЧЕНЬ многие.
Читать дальше