Градиентная програчность

Тема в разделе "WASM.WIN32", создана пользователем Loger, 7 ноя 2004.

  1. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    Как сделать круглое окно, которое бы в центре было абсолютно непрозрачным, и абсолютно прозрачным на краях? Т. е. прозрачность должна градиентно увеличиваться от центра к краям. Есть хотя бы идеи, как такое реализовать?
     
  2. jekyll

    jekyll New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2003
    Сообщения:
    92
    Адрес:
    Russia
    на gdi? gdi+?
     
  3. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    На Gdi
     
  4. jekyll

    jekyll New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2003
    Сообщения:
    92
    Адрес:
    Russia
    Алгоритм то вроде прост:

    1. Получаешь битмап, кот. находится за твоим окном.

    2. Считаешь ручками цвет каждого пикселя, пользуясь формулой круга

    3. Делаешь BitBlt
     
  5. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    1. Как получить битмап изображения под моим окном? Ведь окна не отрисовывают ту свою часть, которая спрятана за другими окнами. И как отловить перерисовку нижележащих окон (неужели нужно хукать все окна в системе)?

    2. Можно по-подробнее про формулу круга?
     
  6. jekyll

    jekyll New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2003
    Сообщения:
    92
    Адрес:
    Russia
    1. На счет отрисовки части окон, которые запрятаны, это ты верно подметил. Но ведь под 2000-XP есть layered windows =) И если его сделать полностью прозрачным, то.. я не проверял, но в DC мы должны получить то, что лежит под нашим окном. А дальше дело техники.

    2. =))))))))))))))))))))))))))))))))))))))))))

    (X-X0)*(X-X0) + (Y-Y0)*(Y-Y0) = R*R
     
  7. vinnie_pooh

    vinnie_pooh New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    98




    Я писАл нечто подобное. Начиналось это с GetDC(0), заканчивалось GetDIBits. Код слишком велик, чтобы его тут приводить целиком.
     
  8. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    vinnie_pooh

    Начиналось это с GetDC(0), заканчивалось GetDIBits.

    Imho. Код получения изображения с контекста дисплея не интересен. Интересно как определить момент, что надо осуществить grab'ление.
     
  9. vinnie_pooh

    vinnie_pooh New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    98
    А... Кажется мы возвращаемся к теме топика "Что делает BeginPaint". Если теперь я понял правильно, то тут возникает две проблемы: 1)когда прозрачное окно перетаскивается и 2) когда оно активизируется. Первую вроде бы решает этот код (перед перетаскиванием запоминать содержимое всего экрана, после копировать на окно его часть):
    Код (Text):
    1. case WM_CREATE:
    2.     hDesktopDC = GetDC(0);
    3.     hStoreDC = CreateCompatibleDC(hDesktopDC);
    4.     //тут надо бы определять истинные размеры экрана)
    5.     hStoreBitmap = CreateCompatibleBitmap(hDesktopDC, 1024, 768);
    6.     hOldBitmap = (HBITMAP)SelectObject(hStoreDC, hStoreBitmap);
    7.     BitBlt(hStoreDC, 0, 0, 1024, 768, hDesktopDC, 0, 0, SRCCOPY);
    8.     break;
    9. case WM_MOVE:
    10.     InvalidateRect(hWnd, 0, 1);
    11.     break;
    12. case WM_LBUTTONDOWN:
    13.     ShowWindow(hWnd, SW_HIDE);
    14.     BitBlt(hStoreDC, 0, 0, 1024, 768, hDesktopDC, 0, 0, SRCCOPY);
    15.  
    16.     ShowWindow(hWnd, SW_SHOWNORMAL);
    17.     SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,lParam);
    18.     break;
    19. case WM_DESTROY:
    20.     SelectObject(hStoreDC, hOldBitmap);
    21.     DeleteObject(hStoreBitmap);
    22.     DeleteDC(hStoreDC);
    23.     ReleaseDC(0, hDesktopDC);
    24.     PostQuitMessage(0);
    25.     break;
    26. case WM_PAINT:
    27.     hDC = BeginPaint(hWnd,&ps);
    28.     GetWindowRect(hWnd, &rect);
    29.     BitBlt(hDC, 0, 0, 200, 70, hStoreDC, rect.left, rect.top, SRCCOPY);
    30.     GetClientRect(hWnd,&rect);
    31.     SetBkMode(hDC,TRANSPARENT);
    32.     SetTextColor(hDC,RGB(255,0,0));
    33.     DrawText(hDC,"Test string",-1,&rect,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    34.     EndPaint(hWnd,&ps);
    35.     break;


    Только окно не дожно быть WS_EX_TRANSPARENT, иначе - лажа, а прозрачность уже и так реализована. Если еще добавить обработку WM_ACTIVATE, то, по-моему, все будет как надо.
     
  10. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    vinnie_pooh

    Твой код не учитывает изменений на экране с момента запуска проги. А прога должна правильно отображать прозрачность даже если под её окном находится окно медиплеера (для начала можно не рассматривать варинат с DirectX) с постоянно меняющейся картинкой. Так что нужно найти способ заставить нижележащие окна перерисовать ту часть, которая находится под моим окном, на моём DC. Или хотя бы захватить кусок экрана под тем местом, куда перетаскивается окно, до того, как оно отрисуется
     
  11. vinnie_pooh

    vinnie_pooh New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    98


    Нет, экран копируется перед перетаскиванием, а не перед запуском:
    Код (Text):
    1. case WM_LBUTTONDOWN:
    2.     ShowWindow(hWnd, SW_HIDE);
    3.     BitBlt(hStoreDC, 0, 0, 1024, 768, hDesktopDC, 0, 0, SRCCOPY);
    4.     ShowWindow(hWnd, SW_SHOWNORMAL);






    Это так, но мне кажется, что это нереально, тем более если нужна полупрозрачность.