Пятница, 22.11.2024, 18:46 | Приветствую Вас Гость

C/С++ Программирование на языке высокого уровня

Главная » Статьи » Мои статьи

Создание прозрачного интерфейса программ в Windows 2000-XP

В данной статье будет рассмотрен вопрос создания эффекта "прозрачного" интерфейса программы. Такое можно наблюдать в известном проигрывателе от Nullsoft'a Winamp.

В этой программе эффект достигается выбором опции меню "Window Settings" > "Opacity" > ...

Вот это работает лишь в операционных системах, которые основаны на NT - сама NT, 2000 и XP (на Vista еще не проверял, хотя должно тоже работать).

В данной статье будет рассмотрен вопрос создания эффекта "прозрачного" интерфейса программы. Такое можно наблюдать в известном проигрывателе от Nullsoft'a Winamp.

В этой программе эффект достигается выбором опции меню "Window Settings" > "Opacity" > ...

Вот это работает лишь в операционных системах, которые основаны на NT - сама NT, 2000 и XP (на Vista еще не проверял, хотя должно тоже работать).

 

Мы же напишем небольшую программку, с помощью которой можно будет делать вот такие вещи:

 

Так с помощью "волшебной палочки" можно сделать "прозрачным" известный блокнот.

Для программирования данной утилиты нам понадобится: VC6 SP4, Win 2000/Win XP

Предисловие

На данную тему уже написано достаточное количество статей, есть и исходные коды. Недостаток лишь в том, что все это на английском языке (лично я на русском ничего подобного не нашел). Попробую восполнить данный пробел и рассказать о "секретах" создания прозрачных интерфейсов.

Наша утилита будет называться "WinTrans", с ее помощью можно сделать прозрачным любое запущенное приложение путем простого наведения специальной палочки (иконка в левом верхнем углу) на заголовок программы. Также можно задавать уровень прозрачности просто передвигая ползунок.

Начинаем кодинг

Почему эта функция работает только в Windows 2000 и Windows XP? Да потому, что в библиотеку User32.dll была добавлена новая функция SetLayeredWindowAttributes.

Для того, чтобы ее можно было использовать, нужно сначала задать параметр WS_EX_LAYERED (0x00080000) или же вызвать функцию SetWindowLong.

Функция SetLayeredWindowAttributes получает следующие аргументы:

 

·     HWND hWnd: дескриптор окна (window)

·     COLORREF col: цвет "прозрачности"

·     BYTE bAlpha: если установлено значение в 0, то окно будет полностью прозрачным, если же 255 - то непрозрачным (т.е. исходного цвета)

·     DWORD dwFlags: если флаг равен 1, то прозрачность будет относиться только к цвету col, если 2 - то прозрачным будет все окно, исходя из значений параметра bAlpha

В недрах кода...

В заголовочном файле WinTransDlg.h необходимо объявить следующие переменные:

 

bool m_bTracking;  //  Принимает значение true или false, в зависимости от того, было ли движение курсора

HWND m_hCurrWnd;   //  Дескриптор окна, над которым последний раз остановился курсор

HCURSOR m_hCursor; //  Сам курсор в виде "волшебной палочки"

Также необходимо объявить функцию, которая будет указывать на SetLayeredWindowAttributes функцию. Последняя функция объявлена в библиотеке User32.dll

 

typedef BOOL (WINAPI *lpfn) (HWND hWnd, COLORREF cr,

              BYTE bAlpha, DWORD dwFlags);

lpfn g_pSetLayeredWindowAttributes;

Через событие OnInitDialog мы получаем адрес функции SetLayeredWindowAttributes и сохраняем его в g_pSetLayeredWindowAttributes. Также производится загрузка курсора и сохранение его в дескрипторе m_hCursor.

 

BOOL CWinTransDlg::OnInitDialog()

{

    ....

    //  указатель на функцию SetLayeredWindowAttributes

    //  в библиотеке User32.dll

    HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL"));

    g_pSetLayeredWindowAttributes = (lpfn)GetProcAddress(hUser32,

                 "SetLayeredWindowAttributes");

    if (g_pSetLayeredWindowAttributes == NULL)

        AfxMessageBox (

            "Layering is not supported in this version of Windows",

             MB_ICONEXCLAMATION);

 

    //  Загрузка курсора

    HINSTANCE hInstResource = AfxFindResourceHandle(

         MAKEINTRESOURCE(IDC_WAND), RT_GROUP_CURSOR);

    m_hCursor = ::LoadCursor( hInstResource,

                              MAKEINTRESOURCE(IDC_WAND) );

    ...

}

Далее идет объявление дескрипторов для событий WM_LBUTTONDOWN, WM_LBUTTONUP и WM_MOUSEMOVE. Дескриптор для WM_LBUTTONDOWN выглядит так:

 

void CWinTransDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

    ...

    SetCapture();             

                               

    m_hCurrWnd = NULL;        

                              

    m_bTracking = true;       

    ::SetCursor(m_hCursor);                                  

    ...

}

Дескриптор для движения курсора:

 

void CWinTransDlg::OnMouseMove(UINT nFlags, CPoint point)

{

    ...

    if (m_bTracking)

    {

        ...

        //  преобразование координат курсора

        ClientToScreen(&point);

        ...

        m_hCurrWnd = ::WindowFromPoint(point);

        ...

        // Детали окна - класс, заголовок и т.д.

        ...

    }

    ...

}

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

 

void CWinTransDlg::OnLButtonUp(UINT nFlags, CPoint point)

{

    ...

    //  остановка движения курсора

    ReleaseCapture();

    m_bTracking = false;

 

    //  Если окно, на которое наведен курсор, не является окном приложения WinTrans,

    //  производится установка степени прозрачности этого окна, в соответствии со значением,

    //  которое задается ползунком.

    if (g_pSetLayeredWindowAttributes && m_hCurrWnd != m_hWnd)

    {

        ::SetWindowLong(m_hCurrWnd, GWL_EXSTYLE,

                        GetWindowLong(m_hCurrWnd,

                        GWL_EXSTYLE) ^ WS_EX_LAYERED);

        g_pSetLayeredWindowAttributes(m_hCurrWnd, 0,

                        (BYTE)m_slider.GetPos(), LWA_ALPHA);

 

        ::RedrawWindow(m_hCurrWnd, NULL, NULL,

                       RDW_ERASE | RDW_INVALIDATE |

                       RDW_FRAME | RDW_ALLCHILDREN);

    }

    ...

}

Послекодие :)

Наша программка WinTrans работает корректно только когда курсор "волшебной палочки" наводится на заголовок (обычно это полоска темно-синего цвета вверху программы) того приложения, у которого мы желаем изменить степень прозрачности. Не верите - попробуйте на практике.

А для того, чтобы снова вернуть изображению исходный вид, нужно просто еще раз навести курсор на его заголовок. Это возможно по той причине, что в функции OnLButtonUp изменяется параметр WS_EX_LAYERED - а это влечет за собой изменение прозрачности в исходное положение.

Категория: Мои статьи | Добавил: PvP (09.05.2010)
Просмотров: 1530 | Комментарии: 1 | Рейтинг: 1.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Меню сайта
Категории раздела
Мои статьи [10]
Наш опрос
Оцените мой сайт
Всего ответов: 11
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Жизнь сайта
Добавь!
Поиск
Друзья и рейтинги
Топ100- Программирование