#include "glass.h" #include "handles.h" static int count; static QColor color; static Handles *handles; Glass::Glass() { if(::count == 0) { handles = new Handles; handles->hDWMDLL = LoadLibraryA("dwmapi.dll"); handles->hTHEMEDLL = LoadLibraryA("uxtheme.dll"); HINSTANCE user32 = GetModuleHandleA("user32.dll"); handles->fSetLayeredWindowAttributes = NULL; if(user32) { handles->fSetLayeredWindowAttributes = (SET_LAYERED_WINDOW_ATTRIBUTES)GetProcAddress(user32, "SetLayeredWindowAttributes"); } if(handles->hDWMDLL) { handles->fDwmEnableComposition = (DWM_ENABLE_COMPOSITION)GetProcAddress(handles->hDWMDLL, "DwmEnableComposition"); handles->fDwmIsCompositionEnabled = (DWM_IS_COMPOSITION_ENABLED)GetProcAddress(handles->hDWMDLL, "DwmIsCompositionEnabled"); handles->fDwmExtendFrameIntoClientArea = (DWM_EXTEND_FRAME_INTO_CLIENT_AREA)GetProcAddress(handles->hDWMDLL, "DwmExtendFrameIntoClientArea"); handles->fDwmEnableBlurBehindWindow = (DWM_ENABLED_BLUR_BEHIND_WINDOW)GetProcAddress(handles->hDWMDLL, "DwmEnableBlurBehindWindow"); } if(handles->hTHEMEDLL) { handles->fOpenThemeData = (OPEN_THEME_DATA)GetProcAddress(handles->hTHEMEDLL, "OpenThemeData"); handles->fCloseThemeData = (CLOSE_THEME_DATA)GetProcAddress(handles->hTHEMEDLL, "CloseThemeData"); handles->fDrawThemeTextEx = (DRAW_THEME_TEXT_EX)GetProcAddress(handles->hTHEMEDLL, "DrawThemeTextEx"); } if(handles->fOpenThemeData && handles->fCloseThemeData) { handles->hTheme = handles->fOpenThemeData(NULL, L"ControlPanelStyle"); } } ::count++; } Glass::~Glass() { ::count--; if(::count == 0) { if(handles->hTheme) { handles->fCloseThemeData(handles->hTheme); } if(handles->hTHEMEDLL) { FreeLibrary(handles->hTHEMEDLL); } if(handles->hDWMDLL) { FreeLibrary(handles->hDWMDLL); } delete handles; } } bool Glass::IsCompositionEnabled() { if(handles->hDWMDLL != NULL) { BOOL bEnabled = FALSE; HRESULT hRes = handles->fDwmIsCompositionEnabled(&bEnabled); return (SUCCEEDED(hRes) && bEnabled); } return false; } void Glass::SetGlass(WId handle, bool isGlass) { if(handles->hDWMDLL) { BOOL bEnabled = FALSE; HRESULT hRes = handles->fDwmIsCompositionEnabled(&bEnabled); if(SUCCEEDED(hRes) && bEnabled) { DWM_BLURBEHIND blurHehind = { 0 }; if(isGlass) { blurHehind.dwFlags = DWM_BB_ENABLE | DWM_BB_TRANSITIONONMAXIMIZED; blurHehind.fEnable = TRUE; blurHehind.fTransitionOnMaximized = FALSE; } else { blurHehind.fEnable = FALSE; blurHehind.fTransitionOnMaximized = FALSE; } handles->fDwmEnableBlurBehindWindow(handle, &blurHehind); } } } void Glass::SetTopmost(WId handle, bool isTopmost) { if(isTopmost) { SetWindowPos((HWND)handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } else { SetWindowPos((HWND)handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } } void Glass::SetTransparent(WId handle, bool isTopmost, bool isTransparent) { DWORD style = GetWindowLong(handle, GWL_EXSTYLE); if(isTransparent) { style = (style | WS_EX_TRANSPARENT); SetTopmost(handle, true); } else { style = (style & ~WS_EX_TRANSPARENT); SetTopmost(handle, isTopmost); } SetWindowLong(handle, GWL_EXSTYLE, style); } void Glass::DrawString(QLabel *label, QPaintEvent *event) { DrawString(label, label->text(), event); } void Glass::DrawString(QCheckBox *checkbox, QPaintEvent *event) { DrawString(checkbox, checkbox->text(), event); } void Glass::DrawString(QWidget *widget, QString &text, QPaintEvent *) { QRect qrect = widget->rect(); QPoint qpoint = widget->pos(); QPainter painter(widget); qpoint.setX(qpoint.x() - 5); qpoint.setY(qpoint.y() - 5); qrect.setWidth(qrect.width() + 10); qrect.setHeight(qrect.height() + 10); HDC hdc; HDC mdc; HBITMAP bmp; BITMAPINFO dib = {0}; hdc = painter.paintEngine()->getDC(); mdc = CreateCompatibleDC(hdc); dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); dib.bmiHeader.biWidth = qrect.width(); dib.bmiHeader.biHeight = -qrect.height(); dib.bmiHeader.biPlanes = 1; dib.bmiHeader.biBitCount = 32; dib.bmiHeader.biCompression = BI_RGB; QPixmap pixmap(qrect.width(), qrect.height()); pixmap.fill(::color); bmp = pixmap.toWinHBITMAP(QPixmap::PremultipliedAlpha); HFONT font = widget->font().handle(); HBITMAP oldBmp = (HBITMAP)SelectObject(mdc, (HGDIOBJ)bmp); HFONT oldFont = (HFONT)SelectObject(mdc, (HGDIOBJ)font); DTTOPTS dto = { sizeof(DTTOPTS) }; const UINT uFormat = DT_LEFT | DT_TOP | DT_NOPREFIX | DT_WORDBREAK; RECT rect = { 5, 5, qrect.width(), qrect.height() }; dto.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE | DTT_SHADOWTYPE; dto.iGlowSize = 5; dto.iTextShadowType = 2; handles->fDrawThemeTextEx(handles->hTheme, mdc, 0, 0, (LPCWSTR)text.utf16(), -1, uFormat, &rect, &dto); BitBlt(hdc, qpoint.x(), qpoint.y(), qrect.width(), qrect.height(), mdc, 0, 0, SRCCOPY); SelectObject(mdc, (HGDIOBJ)oldBmp); SelectObject(mdc, (HGDIOBJ)oldFont); DeleteObject(bmp); DeleteObject(mdc); painter.paintEngine()->releaseDC(hdc); } QPixmap Glass::GetAppIconPixmap(WId handle) { return GetIconPixmap(handle, 0x102); } QPixmap Glass::GetTrayIconPixmap(WId handle) { return GetIconPixmap(handle, 0x102); } QPixmap Glass::GetIconPixmap(WId handle, int idx) { HICON hIcon = LoadIcon((HINSTANCE)GetWindowLong(handle, GWL_HINSTANCE), MAKEINTRESOURCE(idx)); ICONINFO info; GetIconInfo(hIcon, &info); QPixmap pixmap = QPixmap::fromWinHBITMAP(info.hbmColor, QPixmap::Alpha); DeleteObject(info.hbmColor); DeleteObject(info.hbmMask); //DestroyIcon(hIcon); return pixmap; } void Glass::SetBkColor(QColor color) { ::color = color; }