Главная » Статьи » Мои статьи |
В данной статье будет рассмотрен вопрос создания эффекта "прозрачного" интерфейса программы. Такое можно наблюдать в известном проигрывателе от 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 - а это влечет за собой изменение прозрачности в исходное положение. | |
Просмотров: 1530 | Комментарии: 1 | Рейтинг: 1.0/1 |
Всего комментариев: 0 | |
Меню сайта |
Категории раздела | |
|
Наш опрос |
Статистика |
Онлайн всего: 1 Гостей: 1 Пользователей: 0 |
Жизнь сайта |
Добавь! |
Поиск |
Друзья и рейтинги |