123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- #include "main.h"
- #include "config.h"
- #include "wintheme.h"
- #include <shobjidl.h>
- #include <tataki/canvas/bltcanvas.h>
- #include <tataki/bitmap/bitmap.h>
- #include "../Agave/Language/api_language.h"
- typedef HRESULT(WINAPI *DWMREGISTERTHUMBNAIL)(HWND hwndDestination, HWND hwndSource, void **phThumbnailId);
- typedef HRESULT(WINAPI *DWMUPATETHUMBNAILPROPERTIES)(void* hThumbnailId, void* ptnProperties);
- typedef HRESULT(WINAPI *DWMUNREGISTERTHUMBNAIL)(void *hThumbnailId);
- typedef HRESULT(WINAPI *DWMSETWINDOWATTRIBUTE)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
- typedef HRESULT (WINAPI *DWMENABLEMMCSS)(BOOL fEnableMMCSS);
- typedef HRESULT (WINAPI *DWMSETICONICTHUMBNAIL)(HWND hwnd, HBITMAP hbmp, DWORD dwSITFlags);
- typedef HRESULT (WINAPI *DWMINVALIDATEICONICBITMAPS)( HWND hwnd);
- typedef HRESULT (WINAPI *DWMSETICONICLIVEPREVIEWBITMAP )(HWND hwnd, HBITMAP hbmp, POINT *pptClient, DWORD dwSITFlags);
- static HMODULE dwmapi;
- static void *thumbnail;
- static DWMREGISTERTHUMBNAIL regThumbnail;
- static DWMUPATETHUMBNAILPROPERTIES updateProp;
- static DWMUNREGISTERTHUMBNAIL unregThumbnail;
- static DWMSETWINDOWATTRIBUTE setWindowAttribute;
- static DWMENABLEMMCSS dwmEnableMMCSS;
- static DWMSETICONICTHUMBNAIL dwmSetIconicThumbnail;
- static DWMINVALIDATEICONICBITMAPS dwmInvalidateIconicBitmaps;
- static DWMSETICONICLIVEPREVIEWBITMAP dwmSetIconicLivePreviewBitmap;
- HIMAGELIST toolbarIcons = NULL;
- BOOL atti_present=false;
- static bool triedLoad=false;
- static bool LoadDWMApi()
- {
- if (!triedLoad)
- {
- wchar_t gen_win7shell_path[MAX_PATH] = {0};
- PathCombineW(gen_win7shell_path, PLUGINDIR, L"gen_win7shell.dll");
- HMODULE gen_win7shell = LoadLibraryW(gen_win7shell_path);
- if (gen_win7shell)
- {
- atti_present=true;
- FreeLibrary(gen_win7shell);
- }
- dwmapi = LoadLibraryA("dwmapi.dll");
- regThumbnail = (DWMREGISTERTHUMBNAIL)GetProcAddress(dwmapi, "DwmRegisterThumbnail");
- updateProp = (DWMUPATETHUMBNAILPROPERTIES)GetProcAddress(dwmapi, "DwmUpdateThumbnailProperties");
- unregThumbnail = (DWMUNREGISTERTHUMBNAIL)GetProcAddress(dwmapi, "DwmUnregisterThumbnail");
- setWindowAttribute = (DWMSETWINDOWATTRIBUTE)GetProcAddress(dwmapi, "DwmSetWindowAttribute");
- dwmEnableMMCSS = (DWMENABLEMMCSS)GetProcAddress(dwmapi, "DwmEnableMMCSS");
- dwmSetIconicThumbnail = (DWMSETICONICTHUMBNAIL)GetProcAddress(dwmapi, "DwmSetIconicThumbnail");
- dwmInvalidateIconicBitmaps = (DWMINVALIDATEICONICBITMAPS)GetProcAddress(dwmapi, "DwmInvalidateIconicBitmaps");
- dwmSetIconicLivePreviewBitmap = (DWMSETICONICLIVEPREVIEWBITMAP)GetProcAddress(dwmapi, "DwmSetIconicLivePreviewBitmap");
- triedLoad = true;
- }
- return dwmapi && regThumbnail && updateProp && unregThumbnail && setWindowAttribute && dwmEnableMMCSS;
- }
- bool LoadToolbarIcons()
- {
- //toolbarIcons already loaded
- if (toolbarIcons != NULL)
- {
- return true;
- }
-
- //load toolbarIcons
- toolbarIcons = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32, 5, 0);
- if (toolbarIcons == NULL)
- return false;
- for (int i = 0; i < 5; i++)
- {
- HICON hIcon = LoadIconW(hMainInstance, MAKEINTRESOURCE(IDI_TBICON1+i));
- if (hIcon != NULL)
- ImageList_AddIcon(toolbarIcons, hIcon);
- // no need to call DestroyIcon(..) if using LoadIcon(..)
- // as the OS will free things anyway - might be cause of
- // the random button disappearing issue...?
- //DestroyIcon(hIcon);
- }
- return true;
- }
- static BOOL taskbar_inited = FALSE;
- void OnTaskbarButtonCreated(BOOL force)
- {
- if (pTaskbar3 || (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,
- IID_PPV_ARGS(&pTaskbar3))) && pTaskbar3))
- {
- if (force)
- {
- taskbar_inited = TRUE;
- pTaskbar3->HrInit();
- }
- if (taskbar_inited)
- {
- RegisterThumbnailTab(IsWindow(g_dialog_box_parent) ? g_dialog_box_parent : hMainWindow);
- }
- }
- }
- void UnregisterThumbnailTab(HWND hWnd)
- {
- if (LoadDWMApi() && !atti_present)
- {
- if (!IsVistaOrLower() && IsWindow(hWnd) && pTaskbar3 != NULL)
- {
- if (taskbar_inited)
- pTaskbar3->UnregisterTab(hWnd);
- }
- }
- }
- static void addToolbarButtons(HWND hWnd, BOOL update)
- {
- THUMBBUTTON thbButtons[5];
- DWORD dwMask = THB_BITMAP | THB_TOOLTIP;
- thbButtons[0].dwMask = (THUMBBUTTONMASK)dwMask;
- thbButtons[0].iId = 0;
- thbButtons[0].iBitmap = 0;
- StringCbCopyW(thbButtons[0].szTip, sizeof(thbButtons[0].szTip), getStringW(IDS_WIN7TOOLBAR_TOOLTIP_PREVIOUS, NULL, 0));
- thbButtons[1].dwMask = (THUMBBUTTONMASK)dwMask;
- thbButtons[1].iId = 1;
- thbButtons[1].iBitmap = 1;
- StringCbCopyW(thbButtons[1].szTip, sizeof(thbButtons[1].szTip), getStringW(IDS_WIN7TOOLBAR_TOOLTIP_PLAY, NULL, 0));
- thbButtons[2].dwMask = (THUMBBUTTONMASK)dwMask;
- thbButtons[2].iId = 2;
- thbButtons[2].iBitmap = 2;
- StringCbCopyW(thbButtons[2].szTip, sizeof(thbButtons[2].szTip), getStringW(IDS_WIN7TOOLBAR_TOOLTIP_PAUSE, NULL, 0));
- thbButtons[3].dwMask = (THUMBBUTTONMASK)dwMask;
- thbButtons[3].iId = 3;
- thbButtons[3].iBitmap = 3;
- StringCbCopyW(thbButtons[3].szTip, sizeof(thbButtons[3].szTip), getStringW(IDS_WIN7TOOLBAR_TOOLTIP_STOP, NULL, 0));
- thbButtons[4].dwMask = (THUMBBUTTONMASK)dwMask;
- thbButtons[4].iId = 4;
- thbButtons[4].iBitmap = 4;
- StringCbCopyW(thbButtons[4].szTip, sizeof(thbButtons[4].szTip), getStringW(IDS_WIN7TOOLBAR_TOOLTIP_NEXT, NULL, 0));
- if (update)
- pTaskbar3->ThumbBarUpdateButtons(hWnd, ARRAYSIZE(thbButtons), thbButtons);
- else
- pTaskbar3->ThumbBarAddButtons(hWnd, ARRAYSIZE(thbButtons), thbButtons);
- }
- void RegisterThumbnailTab(HWND hWnd)
- {
- if (LoadDWMApi() && !atti_present)
- {
- if (dwmInvalidateIconicBitmaps) // even if DWM is loaded, this only exists on win7 (NT6.1)
- dwmInvalidateIconicBitmaps(hMainWindow);
- if (!IsWindow(hWnd))
- {
- hWnd = hMainWindow;
- }
- if (hWnd != hMainWindow)
- {
- wchar_t title[512] = {0};
- GetWindowTextW(hMainWindow, title, sizeof(title));
- SetWindowTextW(hWnd, title);
- #ifdef WIN64
- HICON hIcon = (HICON)GetClassLongPtr(hMainWindow, GCLP_HICONSM);
- #else
- HICON hIcon = (HICON)GetClassLong(hMainWindow, GCL_HICONSM);
- #endif
- SendMessageW(hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon);
- }
- if (IsWindow(hWnd) && IsWindow(hMainWindow))
- {
- BOOL dwm_setting = FALSE;
- setWindowAttribute(hWnd, DWMWA_FORCE_ICONIC_REPRESENTATION, &dwm_setting, sizeof(dwm_setting));
- setWindowAttribute(hWnd, DWMWA_HAS_ICONIC_BITMAP, &dwm_setting, sizeof(dwm_setting));
- if (!IsVistaOrLower() && pTaskbar3 != NULL)
- {
- // shouldn't fail, but there's a case on loading where it can due to timing quirks
- // so for that we then allow the regsistation to still happen (hence the dup code)
- HRESULT hr = pTaskbar3->RegisterTab(hWnd, hMainWindow);
- if (SUCCEEDED(hr))
- {
- if (SUCCEEDED(pTaskbar3->SetTabOrder(hWnd, NULL)))
- {
- pTaskbar3->SetTabActive(hWnd, hMainWindow, 0);
-
- if (LoadToolbarIcons())
- {
- HRESULT hr = pTaskbar3->ThumbBarSetImageList(hWnd, toolbarIcons);
- if (SUCCEEDED(hr))
- {
- addToolbarButtons(hWnd, false);
- }
- }
- }
- }
- else
- {
- if (SUCCEEDED(pTaskbar3->SetTabOrder(hWnd, NULL)))
- {
- pTaskbar3->SetTabActive(hWnd, hMainWindow, 0);
-
- if (LoadToolbarIcons())
- {
- HRESULT hr = pTaskbar3->ThumbBarSetImageList(hWnd, toolbarIcons);
- if (SUCCEEDED(hr))
- {
- addToolbarButtons(hWnd, false);
- }
- }
- }
- }
- }
- if (hWnd != hMainWindow)
- {
- dwm_setting = TRUE;
- setWindowAttribute(hMainWindow, DWMWA_FORCE_ICONIC_REPRESENTATION, &dwm_setting, sizeof(dwm_setting));
- setWindowAttribute(hMainWindow, DWMWA_HAS_ICONIC_BITMAP, &dwm_setting, sizeof(dwm_setting));
- }
- }
- }
- }
- void DisableVistaPreview()
- {
- if (LoadDWMApi())
- {
- BOOL blah=TRUE;
- setWindowAttribute(hMainWindow, DWMWA_FORCE_ICONIC_REPRESENTATION, &blah, sizeof(blah));
- setWindowAttribute(hMainWindow, DWMWA_HAS_ICONIC_BITMAP, &blah, sizeof(blah));
- }
- }
- static bool done_the_dance=false;
- void DoTheVistaVideoDance()
- {
- if (!done_the_dance && LoadDWMApi())
- {
- dwmEnableMMCSS(TRUE); // the magic "make my program not suck" function
- /* TODO:
- DWM_PRESENT_PARAMETERS dpp;
- memset(&dpp, 0, sizeof(dpp));
- dpp.cbSize = sizeof(dpp);
- dpp.fQueue = true;
- dpp.cBuffer = 8;
- dpp.fUseSourceRate = false;
- dpp.cRefreshesPerFrame = 1;
- dpp.eSampling = DWM_SOURCE_FRAME_SAMPLING_POINT;
- HRESULT hr = DwmSetPresentParameters(hWnd, &dpp);
- */
- // TODO also, unrelated, but check out AvSetMmThreadCharacteristics sometime.
- }
- done_the_dance = true;
- }
- static void Adjust(int bmpw, int bmph, RECT &r)
- {
- // maintain 'square' stretching
- int w = r.right - r.left;
- int h = r.bottom - r.top;
- double aspX = (double)(w)/(double)bmpw;
- double aspY = (double)(h)/(double)bmph;
- double asp = min(aspX, aspY);
- int newW = (int)(bmpw*asp);
- int newH = (int)(bmph*asp);
- r.left = (w - newW)/2;
- r.top = (h - newH)/2;
- r.right = r.left + newW;
- r.bottom = r.top + newH;
- }
- void RefreshIconicThumbnail()
- {
- if (LoadDWMApi() && !atti_present)
- {
- if (dwmInvalidateIconicBitmaps) // even if DWM is loaded, this only exists on win7 (NT6.1)
- dwmInvalidateIconicBitmaps(hMainWindow);
- }
- }
- void OnIconicThumbnail(int width, int height)
- {
- static BltCanvas *iconic_thumbnail_bitmap=0;
- HWND hWnd = g_dialog_box_parent?g_dialog_box_parent:hMainWindow;
- RECT client_size;
- GetClientRect(hWnd, &client_size);
- if (!iconic_thumbnail_bitmap)
- {
- iconic_thumbnail_bitmap = new BltCanvas(client_size.right, client_size.bottom, hMainWindow);
- }
- else
- {
- iconic_thumbnail_bitmap->DestructiveResize(client_size.right, client_size.bottom);
- }
- SendMessageW(hWnd, WM_PRINTCLIENT, (WPARAM) iconic_thumbnail_bitmap->getHDC(), PRF_CHILDREN | PRF_CLIENT | /*PRF_ERASEBKGND |*/ PRF_NONCLIENT /*| PRF_OWNED*/);
- void *bits=0;
- BITMAPINFO bmi = {0};
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = width;
- bmi.bmiHeader.biHeight = -height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- HBITMAP hbmp = CreateDIBSection(iconic_thumbnail_bitmap->getHDC(), &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
- if (hbmp)
- {
- BltCanvas resizedBitmap(hbmp);
- int x=0, y=0;
- RECT dest;
- dest.left = x;
- dest.top = y;
- dest.right = width;
- dest.bottom = height;
- resizedBitmap.drawRect(&dest, 1, 0);
- Adjust(client_size.right, client_size.bottom, dest);
- iconic_thumbnail_bitmap->stretchToRectAlpha(&resizedBitmap, &client_size, &dest);
- dwmSetIconicThumbnail(hMainWindow, hbmp, 0);
- }
- }
- void OnThumbnailPreview()
- {
- static BltCanvas *thumbnail_preview_bitmap=0;
- HWND hWnd = g_dialog_box_parent?g_dialog_box_parent:hMainWindow;
- RECT client_size;
- GetClientRect(hWnd, &client_size);
- if (!thumbnail_preview_bitmap)
- {
- thumbnail_preview_bitmap = new BltCanvas(client_size.right, client_size.bottom, hWnd);
- }
- else
- {
- thumbnail_preview_bitmap->DestructiveResize(client_size.right, client_size.bottom);
- }
- SendMessageW(hWnd, WM_PRINT, (WPARAM) thumbnail_preview_bitmap->getHDC(), PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT /*| PRF_OWNED*/);
- void *bits=0;
- BITMAPINFO bmi = {0};
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = client_size.right - client_size.left;
- bmi.bmiHeader.biHeight = client_size.top - client_size.bottom;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- HBITMAP hbmp = CreateDIBSection(thumbnail_preview_bitmap->getHDC(), &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
- if (hbmp)
- {
- POINT offset;
- offset.x = client_size.left;
- offset.y = client_size.top;
- if (dwmSetIconicLivePreviewBitmap(hWnd, hbmp, &offset, 1) == S_OK)
- {
- MessageBoxA(NULL, "winamp/live", "winamp/live", MB_OK);
- }
- else
- {
- MessageBoxA(NULL, "winamp/no live", "winamp/no live", MB_OK);
- }
- }
- }
|