Программы ассистенты

Тема в разделе "MS Visual C++", создана пользователем Guest, 8 авг 2003.

Статус темы:
Закрыта.
  1. Guest

    Guest Гость

    Все знают десктопные программы-ассистенты (screenmates/deskmates, MS Agent). Весь вопрос, что качественных, без артифактов, достаточно мало. Для реализации экранного помошника есть 2 различных подхода (если знаете еще, подскажите): - рисовать поверх десктопа, запоминать-востанавливать фон и т.д. Здесь сложно уследить за случаями, когда другие окна перекрывают место, где выводится текущий кадр персонажа, если на десктопе идет своя жизнь (меняются-появляются иконки, молчу про Drag'n'Drop) - использовать регионы, примеры есть на codeguru, но это достаточно трудоемкая штука - идея проста: создать полностью прозрачное окно и рисовать в нем просто текущий кадр с действием персонажа, не заботясь о том, на каком фоне его рисуешь, ведь окно прозрачное! Т.е. программа может просто рисовать постоянно меняющиеся картинки в таком прозрачном окне и это создаст эффект анимации персонажа, главное тут, чтобы любые изменения фона не влияли, т.е. просто добавление атрибута WS_EX_TRANSPARENT - это не то что нужно
    Так вот, внимание, вопрос!
    Знает ли кто, как можно создать такое полностью прозрачное-невидимое окно, которое при перемещении по экрану не тащит за собой кусок фона с предыдущего местоположения?
    Кстати, на кодегуру прямого примера нет точно, а то что есть о том как рисовать прозрачные штучки -не то.
     
  2. Guest

    Guest Гость

    Нужно для каждой картинки, входящей в анимацию, делать для окна специальный регион, который включал бы в себя точки, принадлежащие изображению и не включал все остальные. Это можно сделать так (source ниже) : Создать пустой регион, выбрать картинку (bitmap), выбрать прозрачный цвет, проитись по bitmap и для каждого непрозрачного участка в каждой строке bitmap создать регион высотой 1 пиксел и прикомбинировать его к исходному региону. В конце операции установить получившийся регион окну.

    void MakeBitmapRegion (HWND hwnd, 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
     
  3. Guest

    Guest Гость

    Как сделать полностью прозрачное окно, которое не тащит за собою кусок
    фона - понятно. Нужно просто перехватить сообщение WM_WINDOWPOSCHANGING и
    сказать системе, чтобы она не копировала содержимое окна. Для этого в
    структуре WINDOWPOS, указатель на которую передаётся в функцию окна,
    предусмотрен флаг SWP_NOCOPYBITS. В MFC обработчик может выглядеть примерно
    так:


    void CMyWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
    {
    lpwndpos->flags |= SWP_NOCOPYBITS;
    CWnd::OnWindowPosChanging(lpwndpos);
    }


    Другой вопрос, что этого явно не достаточно для реализации прозрачного окна.
    Ведь полностью пустое окно мало кого заинтересует, а если нарисовать в нём
    что-то, а затем сдвинуть окно, за ним потянется шлейф с нарисованным
    изображением.

    Если прозрачные области в окне статические, то есть
    способ лучше - воспользоваться SetWindowRgn. Об этой функции писалось в 7-м
    выпуске рассылки. Но если требуется организовать анимацию на фоне рабочего
    стола, то, вероятно, не обойтись без сохранения фона с его последующим
    восстановлением. Дело в том, что многие программы очень медленно
    перерисовывают свои окна, и поручать им обновление фона под нашим окном не
    представляется возможным.
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей