From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/Plugins/General/gen_tray/TRAYCTL.C | 1526 ++++++++++++++++++++++++++++++++ 1 file changed, 1526 insertions(+) create mode 100644 Src/Plugins/General/gen_tray/TRAYCTL.C (limited to 'Src/Plugins/General/gen_tray/TRAYCTL.C') diff --git a/Src/Plugins/General/gen_tray/TRAYCTL.C b/Src/Plugins/General/gen_tray/TRAYCTL.C new file mode 100644 index 00000000..43725e62 --- /dev/null +++ b/Src/Plugins/General/gen_tray/TRAYCTL.C @@ -0,0 +1,1526 @@ +#define PLUGIN_NAME L"Nullsoft Tray Control" +#define PLUGIN_VERSION L"2.49" + +// Winamp general purpose plug-in mini-SDK +// Copyright (C) 1997, Justin Frankel/Nullsoft +// Modifications and useability enhancements by DrO aka Darren Owen 2006-2014 +#include +#include +#include +#include "../winamp/gen.h" +#include "../winamp/wa_ipc.h" +#include "../winamp/ipc_pe.h" +#include "resource.h" +#include "winampcmd.h" +#include "api__gen_tray.h" +#include + + +#ifndef _DEBUG +BOOL WINAPI _DllMainCRTStartup(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) +{ + DisableThreadLibraryCalls(hInst); + return TRUE; +} +#endif + + +#define NUM_ICONS 8 +#define FOURWAY_NUM 7 +#define SYSTRAY_ICON_BASE 1024 + +// used for Win7+ usage inorder to get the direct location of the icon instead of the prior hacks (thanks MS!) +typedef HRESULT (WINAPI *SHELL_NOTIFYICONGETRECT)(const NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation); +SHELL_NOTIFYICONGETRECT g_Shell_NotifyIconGetRect = 0; + +// Use a guid to uniquely identify our icon +class __declspec(uuid("B4E5FE9B-6A22-450e-9565-941EF50CFEEB")) CompactIcon; + + +// wasabi based services for localisation support +api_service *WASABI_API_SVC = 0; +api_language *WASABI_API_LNG = 0; +HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0; + +int config_enabled = 0, + xporhigher = 0, + custom_enabled = 0, + winver = 0, + flip = 0, + on = 1, + update_file = 0, + isX64 = 0, + no_uninstall = 1, + dlg_init = 0; + +UINT s_uTaskbarRestart=0; +HWND configwnd = 0; +WNDPROC lpWndProcOld = 0; +HICON Icons[NUM_ICONS] = {0}, dummyIcon = 0; +HBITMAP compact = 0; +fileinfo2W file = {0}; + +wchar_t ico_pack[MAX_PATH] = {0}, + ico_pack_base[MAX_PATH] = {0}, + ico_pack_safe[MAX_PATH] = {0}, + wa_path[MAX_PATH] = {0}, + *ini_file = 0, + szDescription[256] = {0}; + +int tips[NUM_ICONS] = { + IDS_PREVIOUS_TRACK, + IDS_PLAY_PAUSE, + IDS_STOP, + IDS_NEXT_TRACK, + IDS_OPEN_FILE, + IDS_COMPACT_MODE, + IDS_DECREASE_VOLUME, + IDS_INCREASE_VOLUME, +}; + +int tips_ex[NUM_ICONS] = { + IDS_HOLD_CTRL, + IDS_HOLD_CTRL, + IDS_HOLD_SHIFT, + -1, + -1, +// IDS_WIN2K_PLUS, + -1, + IDS_CTRL_TO_DECREASE, + IDS_CTRL_TO_INCREASE, +}; + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK ConfigProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam); +HICON CreateInternalIcon(void); +int FileExists(char* filename); +void config(void); +void quit(void); +int init(void); +void config_write(); +void config_read(); + +extern "C" winampGeneralPurposePlugin plugin = +{ + GPPHDR_VER_U, + "nullsoft(gen_tray.dll)", + init, + config, + quit, +}; + +extern "C" __declspec(dllexport) winampGeneralPurposePlugin * winampGetGeneralPurposePlugin() { return &plugin; } + + +HWND GetPlaylistWnd(HWND winamp){ +HWND pl_wnd = 0; + + // get the playlist editor window (either v2.9x method or the older + // for compatibility incase < 2.9x are used + if(SendMessage(winamp,WM_WA_IPC,0,IPC_GETVERSION) >= 0x2900) + { + pl_wnd = (HWND)SendMessage(winamp,WM_WA_IPC,IPC_GETWND_PE,IPC_GETWND); + } + if(!pl_wnd) + { + pl_wnd = FindWindow(L"Winamp PE",0); + } + return pl_wnd; +} + +void FormCompactText(wchar_t* szTip, int szTipLength){ +int got = 0; + + // only update if we really have to (to better mimick Winamp's title behaviour, etc) + // otherwise we query in all cases which can often reflect what appears to be the wrong information since + // the current playlist entry is altered, etc on playlist modification hence an incorrect observation + if(!update_file){ + update_file = 1; + file.fileindex = (int)SendMessage(GetPlaylistWnd(plugin.hwndParent),WM_WA_IPC,IPC_PE_GETCURINDEX,0); + got = (int)SendMessage(GetPlaylistWnd(plugin.hwndParent),WM_WA_IPC,IPC_PE_GETINDEXTITLEW,(LPARAM)&file); + } + + // if it returns 0 then track information was received + if(!got && file.filetitle[0]){ + int time = (int)SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GETOUTPUTTIME); + wchar_t buf[MAX_PATH*2] = {0}, temp[1024] = {0}, *t = temp, *p = 0; + int over = 0, state = 0, blah = 0; + wchar_t stateStr[32] = {0}; + + switch(SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_ISPLAYING)){ + case 0: + WASABI_API_LNGSTRINGW_BUF(IDS_STOPPED_STR,stateStr,32); + state = lstrlen(stateStr); + break; + case 3: + WASABI_API_LNGSTRINGW_BUF(IDS_PAUSED_STR,stateStr,32); + state = lstrlen(stateStr); + break; + } + + p = file.filetitle; + while(p && *p){ + *t++ = *p++; + if(*(p-1) == '&'){ + *t++ = '&'; + *t++ = '&'; + } + } + *t = 0; + + StringCchPrintf(buf,MAX_PATH*2,L"%d. %s",(file.fileindex)+1,file.filetitle); + over = lstrlen(buf); + if(over > szTipLength - 1){over = szTipLength - 1;} + lstrcpyn(szTip,buf,szTipLength); + + if(time != -1){ + time = time/1000; + + if(file.filelength[0]){ + StringCchPrintf(buf,MAX_PATH*2,L" [%02d:%02d/%s]",(time/60),time%60,file.filelength); + blah = lstrlen(buf); + } + else{ + StringCchPrintf(buf,MAX_PATH*2,L" [%02d:%02d]",(time/60),time%60); + blah = lstrlen(buf); + } + } + + if((over + blah + state) > szTipLength){ + int adj = szTipLength-blah-state-1; + szTip[adj] = 0; + szTip[adj-1] = L'.'; + szTip[adj-2] = L'.'; + szTip[adj-3] = L'.'; + } + + if(time != -1){ + StringCchCat(szTip,szTipLength,buf); + } + + if(state){ + StringCchCat(szTip,szTipLength,stateStr); + } + } + + // fall back to the Winamp version just incase + else{ + wchar_t temp[16] = {0}; + StringCchPrintf(temp,16,L"%X",SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GETVERSION)); + StringCchPrintf(szTip,szTipLength,L"Winamp %c.%s",temp[0],&temp[2]); + } +} + +void free_icons(void){ +int i = 0; + for (i = 0; i < NUM_ICONS; i++) + { + if( Icons[i] ) { + DestroyIcon(Icons[i]); + Icons[i] = 0; + } + } + + if(dummyIcon) { + DestroyIcon(dummyIcon); + dummyIcon = 0; + } + + if(compact) { + DeleteObject(compact); + } +} + +void do_icons(int force) +{ + static int l=0; + int i=NUM_ICONS; + + if (l == config_enabled && !force) return; + + if( force ) free_icons(); + + while (i--) + { + if (l & (1<-1:i < NUM_ICONS); (xporhigher?i --:i ++)) + { + if (config_enabled & (1<