diff --git a/Application/Application.rc b/Application/Application.rc index a6651a7b..0131a5c5 100644 --- a/Application/Application.rc +++ b/Application/Application.rc @@ -28,8 +28,8 @@ LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,0,451 - PRODUCTVERSION 1,3,0,451 + FILEVERSION 1,3,0,454 + PRODUCTVERSION 1,3,0,454 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,12 +45,12 @@ BEGIN BLOCK "040b04b0" BEGIN VALUE "FileDescription", "Rainmeter - A Customizable Resource Meter" - VALUE "FileVersion", "1, 3, 0, 451" + VALUE "FileVersion", "1, 3, 0, 454" VALUE "InternalName", "Rainmeter" VALUE "LegalCopyright", "Copyright (C) 2010 - Rainy" VALUE "OriginalFilename", "Rainmeter.exe" VALUE "ProductName", "Rainmeter" - VALUE "ProductVersion", "1, 3, 0, 451" + VALUE "ProductVersion", "1, 3, 0, 454" END END BLOCK "VarFileInfo" diff --git a/Plugins/PluginVirtualDesktops/DexpotConstants.h b/Plugins/PluginVirtualDesktops/DexpotConstants.h new file mode 100644 index 00000000..eea52ad1 --- /dev/null +++ b/Plugins/PluginVirtualDesktops/DexpotConstants.h @@ -0,0 +1,117 @@ +#ifndef _DEXPOT_CONSTANTS_H_ +#define _DEXPOT_CONSTANTS_H_ + +#define DEXPOTTITLE _T("Dexpot - Main Menu") +#define DEXPOTCLASS _T("ThunderRT6FormDC") +#define DEXPOTCLASS2 _T("ThunderFormDC") + +#define WM_HOOXPOTRUFT 1802 + +#define DEX_SWITCHDESKTOP (WM_HOOXPOTRUFT + 1) +#define DEX_DEXPOTCOMMAND (WM_HOOXPOTRUFT + 2) + +#define DEX_MOVEICONS (WM_HOOXPOTRUFT + 13) +#define DEX_COPYICONS (WM_HOOXPOTRUFT + 14) +#define DEX_REMOVEICONS (WM_HOOXPOTRUFT + 15) + +#define DEX_REGISTERPLUGIN (WM_HOOXPOTRUFT + 200) +#define DEX_UNREGISTERPLUGIN (WM_HOOXPOTRUFT + 217) +#define DEX_SETFILEMAP (WM_HOOXPOTRUFT + 218) + +#define DEX_REGISTERHOTKEY (WM_HOOXPOTRUFT + 211) +#define DEX_LOADSETTINGS (WM_HOOXPOTRUFT + 212) +#define DEX_REGISTEROPTION (WM_HOOXPOTRUFT + 213) +#define DEX_SETOPTIONVALUE (WM_HOOXPOTRUFT + 214) +#define DEX_SETHOTKEYVALUE (WM_HOOXPOTRUFT + 215) +#define DEX_SAVESETTINGS (WM_HOOXPOTRUFT + 216) + +#define DEX_GETSCREENSHOT (WM_HOOXPOTRUFT + 201) +#define DEX_GETDESKTOPWIDTH (WM_HOOXPOTRUFT + 202) +#define DEX_GETDESKTOPHEIGHT (WM_HOOXPOTRUFT + 203) +#define DEX_GETCURRENTDESKTOP (WM_HOOXPOTRUFT + 204) +#define DEX_GETDESKTOPCOUNT (WM_HOOXPOTRUFT + 205) +#define DEX_SETSWITCHINGEXCEPTION (WM_HOOXPOTRUFT + 206) +#define DEX_GETSWITCHINGEXCEPTION (WM_HOOXPOTRUFT + 207) +#define DEX_SETMINANIMATION (WM_HOOXPOTRUFT + 208) +#define DEX_DEBUGOUTPUT (WM_HOOXPOTRUFT + 209) +#define DEX_GETDEBUGMODE (WM_HOOXPOTRUFT + 210) +#define DEX_GETLANGUAGEFILE (WM_HOOXPOTRUFT + 219) +#define DEX_INSERTMAINMENUITEM (WM_HOOXPOTRUFT + 220) +#define DEX_GETDESKTOPTITLE (WM_HOOXPOTRUFT + 221) +#define DEX_GETDESKTOPWALLPAPER (WM_HOOXPOTRUFT + 222) +#define DEX_ISPORTABLE (WM_HOOXPOTRUFT + 223) +#define DEX_GETDEXPOTHOME (WM_HOOXPOTRUFT + 224) +#define DEX_GETAPPDATAPATH (WM_HOOXPOTRUFT + 225) +#define DEX_GETTRAYICONMODE (WM_HOOXPOTRUFT + 226) +#define DEX_SETTRAYICONMODE (WM_HOOXPOTRUFT + 227) +#define DEX_GATHERWINDOWS (WM_HOOXPOTRUFT + 228) +#define DEX_MOVEWINDOW (WM_HOOXPOTRUFT + 229) +#define DEX_COPYWINDOW (WM_HOOXPOTRUFT + 230) +#define DEX_SETFOREGROUNDWINDOW (WM_HOOXPOTRUFT + 231) +#define DEX_ASSIGNWINDOW (WM_HOOXPOTRUFT + 232) +#define DEX_SWITCHTOWINDOW (WM_HOOXPOTRUFT + 233) +#define DEX_SHOWWINDOW (WM_HOOXPOTRUFT + 234) +#define DEX_UPDATESCREENSHOT (WM_HOOXPOTRUFT + 235) +#define DEX_REMOVEMAINMENUITEM (WM_HOOXPOTRUFT + 236) +#define DEX_SUBSCRIBEHOOXPOT (WM_HOOXPOTRUFT + 237) +#define DEX_UNSUBSCRIBEHOOXPOT (WM_HOOXPOTRUFT + 238) +#define DEX_GETACTIVEWINDOW (WM_HOOXPOTRUFT + 239) +#define DEX_GETWINDOWSONDESKTOP (WM_HOOXPOTRUFT + 240) +#define DEX_OPENWINDOWMENU (WM_HOOXPOTRUFT + 241) +#define DEX_OPENMAINMENU (WM_HOOXPOTRUFT + 242) + +#define DEX_SWITCHING (WM_HOOXPOTRUFT + 100) +#define DEX_SWITCHED (WM_HOOXPOTRUFT + 101) +#define DEX_SHUTDOWN (WM_HOOXPOTRUFT + 102) +#define DEX_LOAD (WM_HOOXPOTRUFT + 103) +#define DEX_HOTKEY (WM_HOOXPOTRUFT + 104) +#define DEX_SETOPTION (WM_HOOXPOTRUFT + 105) +#define DEX_CONFIGURE (WM_HOOXPOTRUFT + 106) +#define DEX_MENUCOMMAND (WM_HOOXPOTRUFT + 107) +#define DEX_SWITCHREQUEST (WM_HOOXPOTRUFT + 108) +#define DEX_DESKTOPCOUNTCHANGED (WM_HOOXPOTRUFT + 109) +#define DEX_DESKTOPCONTENTCHANGED (WM_HOOXPOTRUFT + 111) +#define DEX_DESKTOPCONFIGURATIONCHANGED (WM_HOOXPOTRUFT + 112) +#define DEX_DEXPOTSETTINGSCHANGED (WM_HOOXPOTRUFT + 113) + +#define DEX_SWITCH_NOSCREENSHOT 0x0001 +#define DEX_SWITCH_DONTSWITCH 0x0002 +#define DEX_SWITCH_NOANIMATION 0x0004 + +#define DEX_OPTION_TYPE_INTEGER 1 +#define DEX_OPTION_TYPE_STRING 2 + +#define DEX_COMMAND_SETTINGS 1 +#define DEX_COMMAND_DESKTOPWINDOWS 2 +#define DEX_COMMAND_MANAGER 3 +#define DEX_COMMAND_CONFIGUREDESKTOPS 4 +#define DEX_COMMAND_PREVIEW 6 +#define DEX_COMMAND_RULES 7 +#define DEX_COMMAND_ABOUT 8 +#define DEX_COMMAND_EXIT 9 +#define DEX_COMMAND_QUICKEXIT 10 +#define DEX_COMMAND_FULLSCREENPREVIEW 11 +#define DEX_COMMAND_WINDOWCATALOG 12 +#define DEX_COMMAND_APPLYRULES 13 + +#define DEX_TRAYICON_NONE 0 +#define DEX_TRAYICON_NORMAL 1 +#define DEX_TRAYICON_CURRENTDESKTOP 2 +#define DEX_TRAYICON_NEXTPREVIOUS 3 +#define DEX_TRAYICON_ONEPERDESKTOP 4 + +#define DEX_EXCEPTION_UNKNOWN 0 +#define DEX_EXCEPTION_NORMAL 1 +#define DEX_EXCEPTION_MOVE 2 +#define DEX_EXCEPTION_STICKY 3 +#define DEX_EXCEPTION_CLOSE 6 +#define DEX_EXCEPTION_IGNORE 4 +#define DEX_EXCEPTION_HIDE 5 +#define DEX_EXCEPTION_DONTMOVE 7 + +#define DEX_DEBUG_LOGFILE 0x0001 +#define DEX_DEBUG_IMAGING 0x0002 +#define DEX_DEBUG_TASKBAR 0x0004 +#define DEX_DEBUG_RECOVERY 0x0008 + +#endif diff --git a/Plugins/PluginVirtualDesktops/DexpotMeasure.cpp b/Plugins/PluginVirtualDesktops/DexpotMeasure.cpp new file mode 100644 index 00000000..d685ca6c --- /dev/null +++ b/Plugins/PluginVirtualDesktops/DexpotMeasure.cpp @@ -0,0 +1,620 @@ +/* + Copyright (C) 2010 Patrick Dubbert + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "DexpotMeasure.h" + +#include +#include + +#include "DexpotConstants.h" +#include "../../Library/Export.h" + +int DexpotMeasure::InstanceCount = 0; +HWND DexpotMeasure::hWndDexpot = NULL; +HWND DexpotMeasure::hWndMessageWindow = NULL; +std::set DexpotMeasure::DexpotMeasures; +TCHAR DexpotMeasure::StringBuffer[STRINGBUFFER_SIZE]; +UINT DexpotMeasure::WM_DEXPOTSTARTED = RegisterWindowMessage(_T("DexpotStarted")); +BOOL DexpotMeasure::PluginRegistered = FALSE; +HWND DexpotMeasure::hWndRainmeterControl = NULL; +int DexpotMeasure::CurrentDesktop = 0; + +std::vector DexpotDesktopNameMeasure::DesktopNames; +std::vector DexpotDesktopWallpaperMeasure::DesktopWallpapers; + +DexpotMeasure::DexpotMeasure(HMODULE instance, UINT _id) : VDMeasure(instance, _id) +{ +} + +DexpotMeasure* DexpotMeasure::CreateMeasure(HMODULE instance, UINT id, LPCTSTR iniFile, LPCTSTR section) +{ + std::wstring TypeString(ReadConfigString(section, _T("VDMeasureType"), _T(""))); + + if(TypeString == _T("VDMActive")) return new DexpotVDMActiveMeasure(instance, id); + else if(TypeString == _T("DesktopCount")) return new DexpotDesktopCountMeasure(instance, id); + else if(TypeString == _T("CurrentDesktop")) return new DexpotCurrentDesktopMeasure(instance, id); + else if(TypeString == _T("SwitchDesktop")) return new DexpotSwitchDesktopMeasure(instance, id); + else if(TypeString == _T("Screenshot")) return new DexpotScreenshotMeasure(instance, id); + else if(TypeString == _T("DesktopName")) return new DexpotDesktopNameMeasure(instance, id); + else if(TypeString == _T("DesktopWallpaper")) return new DexpotDesktopWallpaperMeasure(instance, id); + else if(TypeString == _T("Command")) return new DexpotCommandMeasure(instance, id); + + return NULL; +} + +UINT DexpotMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + if(InstanceCount == 0) + { + hWndRainmeterControl = FindWindow(_T("DummyRainWClass"), _T("Rainmeter control window")); + hWndMessageWindow = CreateMessageWindow(); + } + InstanceCount++; + + if(!PluginRegistered && FindDexpotWindow()) + { + SendNotifyMessage(hWndDexpot, DEX_REGISTERPLUGIN, 0, (LPARAM) hWndMessageWindow); + CurrentDesktop = (int) SendMessage(hWndDexpot, DEX_GETCURRENTDESKTOP, 0, 0); + PluginRegistered = TRUE; + } + + InitializeData(); + DexpotMeasures.insert(this); + + return 0; +} + +void DexpotMeasure::Finalize() +{ + InstanceCount--; + if(InstanceCount == 0) + { + if(PluginRegistered) + { + SendNotifyMessage(hWndDexpot, DEX_UNREGISTERPLUGIN, 0, (LPARAM) hWndMessageWindow); + PluginRegistered = FALSE; + } + DestroyWindow(hWndMessageWindow); + UnregisterClass(_T("DexpotPluginWindowClass"), hInstance); + } + DexpotMeasures.erase(this); +} + +UINT DexpotMeasure::Update() +{ + return 0; +} + +LPCTSTR DexpotMeasure::GetString(UINT flags) +{ + _stprintf_s(StringBuffer, STRINGBUFFER_SIZE, _T("%i"), Update()); + return StringBuffer; +} + +void DexpotMeasure::OnDexpotStarted() +{ + InitializeData(); +} + +BOOL DexpotMeasure::FindDexpotWindow() +{ + if(IsWindow(hWndDexpot)) return TRUE; + hWndDexpot = FindWindow(DEXPOTCLASS, DEXPOTTITLE); + return hWndDexpot != NULL; +} + +HWND DexpotMeasure::CreateMessageWindow() +{ + WNDCLASS wc; + + ZeroMemory(&wc, sizeof(wc)); + wc.hInstance = hInstance; + wc.lpszClassName = _T("DexpotPluginWindowClass"); + wc.lpfnWndProc = WindowProc; + RegisterClass(&wc); + + HWND hWnd = CreateWindowEx(0, _T("DexpotPluginWindowClass"), _T("Dexpot Rainmeter Plugin"), 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL); + SetWindowLong(hWnd, GWL_STYLE, 0); + SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + MoveWindow(hWnd, 0, 0, 0, 0, FALSE); + + return hWnd; +} + +void DexpotMeasure::SendBang(std::wstring &Bang) +{ + COPYDATASTRUCT cds; + + cds.dwData = 1; + cds.cbData = (DWORD) (Bang.length() + 1) * sizeof(wchar_t); + cds.lpData = (PVOID) Bang.c_str(); + + SendMessage(hWndRainmeterControl, WM_COPYDATA, (WPARAM) hWndMessageWindow, (LPARAM) &cds); +} + +LRESULT CALLBACK DexpotMeasure::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case DEX_SWITCHED: + CurrentDesktop = HIWORD(lParam); + for(std::set::iterator i = DexpotMeasures.begin(); i != DexpotMeasures.end(); ++i) + { + (*i)->OnSwitched(LOWORD(lParam), HIWORD(lParam), LOWORD(wParam), HIWORD(wParam)); + } + return 0; + + case DEX_DESKTOPCOUNTCHANGED: + for(std::set::iterator i = DexpotMeasures.begin(); i != DexpotMeasures.end(); ++i) + { + (*i)->OnDesktopCountChanged((int)wParam); + } + return 0; + + case DEX_SHUTDOWN: + PluginRegistered = FALSE; + for(std::set::iterator i = DexpotMeasures.begin(); i != DexpotMeasures.end(); ++i) + { + (*i)->OnShutdown(); + } + return 0; + + case DEX_DESKTOPCONFIGURATIONCHANGED: + for(std::set::iterator i = DexpotMeasures.begin(); i != DexpotMeasures.end(); ++i) + { + (*i)->OnDesktopConfigurationChanged(); + } + return 0; + + case WM_COPYDATA: + if((HWND) wParam == hWndDexpot) + { + COPYDATASTRUCT *cds = (COPYDATASTRUCT*) lParam; + switch(LOWORD(cds->dwData)) + { + case DEX_GETDESKTOPTITLE: + DexpotDesktopNameMeasure::SetDesktopName(HIWORD(cds->dwData), std::wstring((LPTSTR) cds->lpData)); + break; + case DEX_GETDESKTOPWALLPAPER: + DexpotDesktopWallpaperMeasure::SetDesktopWallpaper(HIWORD(cds->dwData), std::wstring((LPTSTR) cds->lpData)); + break; + } + } + return 0; + + default: + if(message == WM_DEXPOTSTARTED) + { + hWndDexpot = (HWND) wParam; + if(!hWndDexpot) FindDexpotWindow(); + if(hWndDexpot) + { + SendMessage(hWndDexpot, DEX_REGISTERPLUGIN, 0, (LPARAM) hWndMessageWindow); + CurrentDesktop = (int) SendMessage(hWndDexpot, DEX_GETCURRENTDESKTOP, 0, 0); + PluginRegistered = TRUE; + } + for(std::set::iterator i = DexpotMeasures.begin(); i != DexpotMeasures.end(); ++i) + { + (*i)->OnDexpotStarted(); + } + return 0; + } + } + + return DefWindowProc(hWnd, message, wParam, lParam); +} + + +/* + * DexpotDesktopCountMeasure + * + */ +DexpotDesktopCountMeasure::DexpotDesktopCountMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {} + +UINT DexpotDesktopCountMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + DesktopCount = 0; + OnChange = ReadConfigString(section, _T("VDOnChange"), _T("")); + + CountType = Total; + LPCTSTR TypeString = ReadConfigString(section, _T("VDDesktopCount"), _T("")); + if(_tcsicmp(TypeString, _T("X")) == 0) CountType = Columns; + else if(_tcsicmp(TypeString, _T("Y")) == 0) CountType = Rows; + + DexpotMeasure::Initialize(iniFile, section); + return 20; +} + +void DexpotDesktopCountMeasure::InitializeData() +{ + if(PluginRegistered) DesktopCount = (int) SendMessage(hWndDexpot, DEX_GETDESKTOPCOUNT, 0, 0); +} + +UINT DexpotDesktopCountMeasure::Update() +{ + if(CountType == Rows) return 1; + else return DesktopCount; +} + +void DexpotDesktopCountMeasure::OnDesktopCountChanged(int NewCount) +{ + DesktopCount = NewCount; + if(OnChange.length()) SendBang(OnChange); +} + + +/* + * DexpotCurrentDesktopMeasure + * + */ +DexpotCurrentDesktopMeasure::DexpotCurrentDesktopMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {} + +UINT DexpotCurrentDesktopMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + OnChange = ReadConfigString(section, _T("VDOnChange"), _T("")); + + DexpotMeasure::Initialize(iniFile, section); + return 0; +} + +UINT DexpotCurrentDesktopMeasure::Update() +{ + return CurrentDesktop; +} + +void DexpotCurrentDesktopMeasure::OnSwitched(int FromDesktop, int ToDesktop, WORD Flags, WORD Trigger) +{ + if(OnChange.length()) SendBang(OnChange); +} + + +/* + * DexpotVDMActiveMeasure + * + */ +DexpotVDMActiveMeasure::DexpotVDMActiveMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {}; + +UINT DexpotVDMActiveMeasure::Update() +{ + return PluginRegistered ? 1 : 0; +} + +UINT DexpotVDMActiveMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + OnActivate = ReadConfigString(section, _T("VDOnActivate"), _T("")); + OnDeactivate = ReadConfigString(section, _T("VDOnDeactivate"), _T("")); + + DexpotMeasure::Initialize(iniFile, section); + return 1; +} + +void DexpotVDMActiveMeasure::OnShutdown() +{ + if(OnDeactivate.length()) SendBang(OnDeactivate); +} + +void DexpotVDMActiveMeasure::OnDexpotStarted() +{ + if(OnActivate.length()) SendBang(OnActivate); +} + + +/* + * DexpotSwitchDesktopMeasure + * + */ +DexpotSwitchDesktopMeasure::DexpotSwitchDesktopMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {} + +void DexpotSwitchDesktopMeasure::ExecuteBang(LPCTSTR args) +{ + if(PluginRegistered) + { + DWORD Desktop; + + if(_tcsicmp(args, _T("next")) == 0) Desktop = MAKELPARAM(0, 1); + else if(_tcsicmp(args, _T("prev")) == 0) Desktop = MAKELPARAM(0, 2); + else if(_tcsicmp(args, _T("back")) == 0) Desktop = MAKELPARAM(0, 3); + else Desktop = _ttoi(args); + + SendNotifyMessage(hWndDexpot, DEX_SWITCHDESKTOP, 0, Desktop); + } +} + + +/* + * DexpotScreenshotMeasure + * + */ +DexpotScreenshotMeasure::DexpotScreenshotMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {} + +UINT DexpotScreenshotMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + OutputFile = ReadConfigString(section, _T("VDOutputFile"), _T("")); + DesktopNumber = _ttoi(ReadConfigString(section, _T("VDDesktop"), _T("0"))); + Width = _ttoi(ReadConfigString(section, _T("VDWidth"), _T("0"))); + Height = _ttoi(ReadConfigString(section, _T("VDHeight"), _T("0"))); + RefreshOnUpdate = _ttoi(ReadConfigString(section, _T("VDRefreshOnUpdate"), _T("0"))); + + DexpotMeasure::Initialize(iniFile, section); + return 0; +} + +UINT DexpotScreenshotMeasure::Update() +{ + if(RefreshOnUpdate && (DesktopNumber == 0 || DesktopNumber == CurrentDesktop)) + { + UpdateScreenshot(); + } + return 0; +} + +LPCTSTR DexpotScreenshotMeasure::GetString(UINT flags) +{ + return OutputFile.c_str(); +} + +void DexpotScreenshotMeasure::InitializeData() +{ + UpdateScreenshot(); +} + +void DexpotScreenshotMeasure::OnSwitched(int FromDesktop, int ToDesktop, WORD Flags, WORD Trigger) +{ + if(DesktopNumber == FromDesktop || DesktopNumber == 0) + { + UpdateScreenshot(); + } +} + +void DexpotScreenshotMeasure::UpdateScreenshot() +{ + int Desktop = DesktopNumber == 0 ? CurrentDesktop : DesktopNumber; + int nBytes = 0; + BYTE *pBytes = NULL; + HANDLE fm; + HANDLE mutex; + + if(!IsWindow(hWndDexpot)) return; + + int DesktopWidth = (int) SendMessage(hWndDexpot, DEX_GETDESKTOPWIDTH, Desktop, 0); + int DesktopHeight = (int) SendMessage(hWndDexpot, DEX_GETDESKTOPHEIGHT, Desktop, 0); + + mutex = OpenMutex(SYNCHRONIZE, FALSE, _T("DexpotScreenshotMutex")); + WaitForSingleObject(mutex, 2000); + fm = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, DesktopWidth * DesktopHeight * 4, L"Local\\DexpotScreenshotFilemap"); + pBytes = (BYTE*) MapViewOfFile(fm, FILE_MAP_ALL_ACCESS, 0, 0, 0); + if(pBytes) nBytes = (int) SendMessage(hWndDexpot, DEX_GETSCREENSHOT, Desktop, 0); + + if(nBytes > 0 && nBytes == DesktopWidth * DesktopHeight * 4) + { + HDC ScreenDC; + HDC MemDC; + HDC MemDC2; + HBITMAP OriginalBitmap; + HBITMAP ScaledBitmap; + HGDIOBJ OldBitmap; + HGDIOBJ OldBitmap2; + BYTE *ScaledBytes; + BITMAPINFO bmi; + BITMAPFILEHEADER bmfh; + int ScaledHeight = Height; + int ScaledWidth = Width; + + if(ScaledHeight == 0) ScaledHeight = (int) ((float) DesktopHeight * (ScaledWidth / (float) DesktopWidth) + .5f); + if(ScaledWidth == 0) ScaledWidth = (int) ((float) DesktopWidth * (ScaledHeight / (float) DesktopHeight) + .5f); + if(ScaledHeight == 0) ScaledHeight = DesktopHeight; + if(ScaledWidth == 0) ScaledWidth = DesktopWidth; + + ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = DesktopWidth; + bmi.bmiHeader.biHeight = DesktopHeight; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = nBytes; + + ScreenDC = GetDC(NULL); + MemDC = CreateCompatibleDC(ScreenDC); + MemDC2 = CreateCompatibleDC(ScreenDC); + OriginalBitmap = CreateCompatibleBitmap(ScreenDC, DesktopWidth, DesktopHeight); + SetDIBits(MemDC2, OriginalBitmap, 0, DesktopHeight, pBytes, &bmi, 0); + OldBitmap2 = SelectObject(MemDC2, (HGDIOBJ) OriginalBitmap); + + nBytes = ScaledWidth * ScaledHeight * 4; + bmi.bmiHeader.biWidth = ScaledWidth; + bmi.bmiHeader.biHeight = ScaledHeight; + bmi.bmiHeader.biSizeImage = nBytes; + + ScaledBitmap = CreateDIBSection(MemDC, &bmi, 0, (void**) &ScaledBytes, NULL, 0); + OldBitmap = SelectObject(MemDC, (HGDIOBJ) ScaledBitmap); + SetStretchBltMode(MemDC, HALFTONE); + StretchBlt(MemDC, 0, 0, ScaledWidth, ScaledHeight, MemDC2, 0, 0, DesktopWidth, DesktopHeight, SRCCOPY); + GdiFlush(); + + ZeroMemory(&bmfh, sizeof(BITMAPFILEHEADER)); + bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + bmfh.bfSize = bmfh.bfOffBits + nBytes; + bmfh.bfType = 0x4d42; + + std::ofstream ofs(OutputFile.c_str(), std::ios_base::binary); + if(ofs) + { + ofs.write((char*) &bmfh, sizeof(BITMAPFILEHEADER)); + ofs.write((char*) &bmi, sizeof(BITMAPINFOHEADER)); + ofs.write((char*) ScaledBytes, nBytes); + ofs.close(); + } + + SelectObject(MemDC, OldBitmap); + SelectObject(MemDC2, OldBitmap2); + DeleteObject(ScaledBitmap); + DeleteObject(OriginalBitmap); + DeleteDC(MemDC); + DeleteDC(MemDC2); + ReleaseDC(NULL, ScreenDC); + } + + UnmapViewOfFile(pBytes); + CloseHandle(fm); + ReleaseMutex(mutex); + CloseHandle(mutex); +} + + +/* + * DexpotDesktopNameMeasure + * + */ +DexpotDesktopNameMeasure::DexpotDesktopNameMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {} + +UINT DexpotDesktopNameMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + DesktopNumber = _ttoi(ReadConfigString(section, _T("VDDesktop"), _T("0"))); + return DexpotMeasure::Initialize(iniFile, section); +} + +LPCTSTR DexpotDesktopNameMeasure::GetString(UINT flags) +{ + UINT Desktop = (DesktopNumber == 0 ? CurrentDesktop : DesktopNumber) - 1; + if(Desktop >= 0 && Desktop < DesktopNames.size()) + { + return DesktopNames[Desktop].c_str(); + } + else + { + StringBuffer[0] = _T('\0'); + return StringBuffer; + } +} + +void DexpotDesktopNameMeasure::InitializeData() +{ + if(PluginRegistered) + { + int DesktopCount = (int) SendMessage(hWndDexpot, DEX_GETDESKTOPCOUNT, 0, 0); + DesktopNames.resize(DesktopCount); + if(DesktopNumber == 0) + { + for(int i = 1; i <= DesktopCount; i++) + { + PostMessage(hWndDexpot, DEX_GETDESKTOPTITLE, i, (LPARAM) hWndMessageWindow); + } + } + else if(DesktopNumber > 0 && DesktopNumber <= DesktopCount) + { + PostMessage(hWndDexpot, DEX_GETDESKTOPTITLE, DesktopNumber, (LPARAM) hWndMessageWindow); + } + } +} + +void DexpotDesktopNameMeasure::OnDesktopConfigurationChanged() +{ + InitializeData(); +} + +void DexpotDesktopNameMeasure::SetDesktopName(UINT Desktop, std::wstring &Name) +{ + if(--Desktop >= DesktopNames.size()) DesktopNames.resize(Desktop + 1); + if(Desktop >= 0) DesktopNames[Desktop] = Name; +} + + +/* + * DexpotDesktopWallpaperMeasure + * + */ +DexpotDesktopWallpaperMeasure::DexpotDesktopWallpaperMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {} + +UINT DexpotDesktopWallpaperMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + DesktopNumber = _ttoi(ReadConfigString(section, _T("VDDesktop"), _T("0"))); + return DexpotMeasure::Initialize(iniFile, section); +} + +LPCTSTR DexpotDesktopWallpaperMeasure::GetString(UINT flags) +{ + if(DesktopNumber == 0) + { + SystemParametersInfo(SPI_GETDESKWALLPAPER, STRINGBUFFER_SIZE, StringBuffer, 0); + return StringBuffer; + } + else if(DesktopNumber > 0 && (UINT) DesktopNumber <= DesktopWallpapers.size()) + { + return DesktopWallpapers[DesktopNumber - 1].c_str(); + } + + StringBuffer[0] = _T('\0'); + return StringBuffer; +} + +void DexpotDesktopWallpaperMeasure::InitializeData() +{ + if(PluginRegistered) + { + int DesktopCount = (int) SendMessage(hWndDexpot, DEX_GETDESKTOPCOUNT, 0, 0); + DesktopWallpapers.resize(DesktopCount); + if(DesktopNumber == 0) + { + for(int i = 1; i <= DesktopCount; i++) + { + PostMessage(hWndDexpot, DEX_GETDESKTOPWALLPAPER, i, (LPARAM) hWndMessageWindow); + } + } + else if(DesktopNumber > 0 && DesktopNumber <= DesktopCount) + { + PostMessage(hWndDexpot, DEX_GETDESKTOPWALLPAPER, DesktopNumber, (LPARAM) hWndMessageWindow); + } + } +} +void DexpotDesktopWallpaperMeasure::OnSwitched(int FromDesktop, int ToDesktop, WORD Flags, WORD Trigger) +{ + PostMessage(hWndDexpot, DEX_GETDESKTOPWALLPAPER, FromDesktop, (LPARAM) hWndMessageWindow); +} + +void DexpotDesktopWallpaperMeasure::OnDesktopConfigurationChanged() +{ + InitializeData(); +} + +void DexpotDesktopWallpaperMeasure::SetDesktopWallpaper(UINT Desktop, std::wstring &Wallpaper) +{ + if(--Desktop >= DesktopWallpapers.size()) DesktopWallpapers.resize(Desktop + 1); + if(Desktop >= 0) DesktopWallpapers[Desktop] = Wallpaper; +} + + +/* + * DexpotCommandMeasure + * + */ +DexpotCommandMeasure::DexpotCommandMeasure(HMODULE instance, UINT id) : DexpotMeasure(instance, id) {} + +void DexpotCommandMeasure::ExecuteBang(LPCTSTR args) +{ + if(PluginRegistered) + { + COPYDATASTRUCT cds; + + cds.dwData = DEX_DEXPOTCOMMAND; + cds.lpData = (PVOID) args; + cds.cbData = (DWORD) (_tcslen(args) + 1) * sizeof(TCHAR); + + SendMessage(hWndDexpot, WM_COPYDATA, (WPARAM) hWndMessageWindow, (LPARAM) &cds); + } +} diff --git a/Plugins/PluginVirtualDesktops/DexpotMeasure.h b/Plugins/PluginVirtualDesktops/DexpotMeasure.h new file mode 100644 index 00000000..129aeabe --- /dev/null +++ b/Plugins/PluginVirtualDesktops/DexpotMeasure.h @@ -0,0 +1,208 @@ +/* + Copyright (C) 2010 Patrick Dubbert + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#pragma once +#include "VDMeasure.h" + +#include +#include +#include +#include +#include + +#define STRINGBUFFER_SIZE MAX_PATH + +class DexpotMeasure : public VDMeasure +{ +public: + DexpotMeasure(HMODULE instance, UINT id); + virtual ~DexpotMeasure(void) {}; + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual void Finalize(); + virtual UINT Update(); + virtual LPCTSTR GetString(UINT flags); + virtual void ExecuteBang(LPCTSTR args) {}; + + static DexpotMeasure* CreateMeasure(HMODULE instance, UINT id, LPCTSTR iniFile, LPCTSTR section); + +protected: + virtual void InitializeData() {}; + virtual void OnSwitched(int FromDesktop, int ToDesktop, WORD Flags, WORD Trigger) {}; + virtual void OnDesktopCountChanged(int) {}; + virtual void OnShutdown() {}; + virtual void OnDexpotStarted(); + virtual void OnDesktopConfigurationChanged() {}; + + static void SendBang(std::wstring&); + + static HWND hWndDexpot; + static HWND hWndMessageWindow; + static TCHAR StringBuffer[STRINGBUFFER_SIZE]; + static BOOL PluginRegistered; + static int CurrentDesktop; + +private: + static BOOL FindDexpotWindow(); + static HWND CreateMessageWindow(); + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + + static int InstanceCount; + static HWND hWndRainmeterControl; + static std::set DexpotMeasures; + static UINT WM_DEXPOTSTARTED; +}; + + +class DexpotDesktopCountMeasure : public DexpotMeasure +{ +public: + DexpotDesktopCountMeasure(HMODULE instance, UINT id); + virtual ~DexpotDesktopCountMeasure(void) {}; + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual UINT Update(); + virtual void InitializeData(); + virtual void OnDesktopCountChanged(int); + +private: + enum DesktopCountType + { + Total, + Columns, + Rows, + }; + + int DesktopCount; + std::wstring OnChange; + DesktopCountType CountType; +}; + + +class DexpotCurrentDesktopMeasure : public DexpotMeasure +{ +public: + DexpotCurrentDesktopMeasure(HMODULE instance, UINT id); + virtual ~DexpotCurrentDesktopMeasure(void) {}; + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual UINT Update(); + virtual void OnSwitched(int, int, WORD, WORD); + +private: + std::wstring OnChange; +}; + + +class DexpotVDMActiveMeasure : public DexpotMeasure +{ +public: + DexpotVDMActiveMeasure(HMODULE instance, UINT id); + virtual ~DexpotVDMActiveMeasure(void) {}; + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual UINT Update(); + virtual void OnShutdown(); + virtual void OnDexpotStarted(); + +private: + std::wstring OnActivate; + std::wstring OnDeactivate; +}; + + +class DexpotSwitchDesktopMeasure : public DexpotMeasure +{ +public: + DexpotSwitchDesktopMeasure(HMODULE instance, UINT id); + virtual ~DexpotSwitchDesktopMeasure(void) {}; + + virtual void ExecuteBang(LPCTSTR args); +}; + + +class DexpotScreenshotMeasure : public DexpotMeasure +{ +public: + DexpotScreenshotMeasure(HMODULE instance, UINT id); + virtual ~DexpotScreenshotMeasure(void) {}; + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual UINT Update(); + virtual LPCTSTR GetString(UINT flags); + virtual void InitializeData(); + virtual void OnSwitched(int, int, WORD, WORD); + +private: + void UpdateScreenshot(); + + std::wstring OutputFile; + int DesktopNumber; + int Width; + int Height; + BOOL RefreshOnUpdate; +}; + + +class DexpotDesktopNameMeasure : public DexpotMeasure +{ +public: + DexpotDesktopNameMeasure(HMODULE instance, UINT id); + virtual ~DexpotDesktopNameMeasure(void) {}; + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual LPCTSTR GetString(UINT flags); + virtual void InitializeData(); + virtual void OnDesktopConfigurationChanged(); + + static void SetDesktopName(UINT Desktop, std::wstring &Name); + +private: + int DesktopNumber; + static std::vector DesktopNames; +}; + + +class DexpotDesktopWallpaperMeasure : public DexpotMeasure +{ +public: + DexpotDesktopWallpaperMeasure(HMODULE instance, UINT id); + virtual ~DexpotDesktopWallpaperMeasure(void) {}; + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual LPCTSTR GetString(UINT flags); + virtual void InitializeData(); + virtual void OnSwitched(int FromDesktop, int ToDesktop, WORD Flags, WORD Trigger); + virtual void OnDesktopConfigurationChanged(); + + static void SetDesktopWallpaper(UINT Desktop, std::wstring &Wallpaper); + +private: + int DesktopNumber; + static std::vector DesktopWallpapers; +}; + + +class DexpotCommandMeasure : public DexpotMeasure +{ +public: + DexpotCommandMeasure(HMODULE instance, UINT id); + virtual ~DexpotCommandMeasure(void) {}; + + virtual void ExecuteBang(LPCTSTR args); +}; diff --git a/Plugins/PluginVirtualDesktops/PluginVirtualDesktops.vcproj b/Plugins/PluginVirtualDesktops/PluginVirtualDesktops.vcproj new file mode 100644 index 00000000..7b3fade2 --- /dev/null +++ b/Plugins/PluginVirtualDesktops/PluginVirtualDesktops.vcproj @@ -0,0 +1,610 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/PluginVirtualDesktops/VDMeasure.h b/Plugins/PluginVirtualDesktops/VDMeasure.h new file mode 100644 index 00000000..195fd8d5 --- /dev/null +++ b/Plugins/PluginVirtualDesktops/VDMeasure.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2010 Patrick Dubbert + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#pragma once + +#include + +class VDMeasure +{ +public: + VDMeasure(HMODULE instance, UINT id) { hInstance = instance; ID = id; }; + virtual ~VDMeasure(void) {}; + +/* + This function is called when the measure is initialized. + The function must return the maximum value that can be measured. + The return value can also be 0, which means that Rainmeter will + track the maximum value automatically. The parameters for this + function are: + + iniFile The name of the ini-file (usually Rainmeter.ini) + section The name of the section in the ini-file for this measure +*/ + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section) = 0; + +/* + If the measure needs to free resources before quitting. + The plugin can export Finalize function, which is called + when Rainmeter quits (or refreshes). +*/ + virtual void Finalize() = 0; + +/* + This function is called when new value should be measured. + The function returns the new value. +*/ + virtual UINT Update() = 0; + +/* + This function is called when the value should be + returned as a string. +*/ + virtual LPCTSTR GetString(UINT flags) = 0; + + virtual void ExecuteBang(LPCTSTR args) = 0; + +protected: + static HMODULE hInstance; + UINT ID; +}; diff --git a/Plugins/PluginVirtualDesktops/VirtuaWinMeasure.cpp b/Plugins/PluginVirtualDesktops/VirtuaWinMeasure.cpp new file mode 100644 index 00000000..fb33e0d7 --- /dev/null +++ b/Plugins/PluginVirtualDesktops/VirtuaWinMeasure.cpp @@ -0,0 +1,148 @@ +/* + Copyright (C) 2010 Patrick Dubbert + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "VirtuaWinMeasure.h" + +#include + +#include "VirtuaWinMessages.h" +#include "../../Library/Export.h" + +HWND VirtuaWinMeasure::vwHandle = NULL; +std::map VirtuaWinMeasure::StringToType; + +VirtuaWinMeasure::VirtuaWinMeasure(HMODULE instance, UINT id) : VDMeasure(instance, id) +{ + if(StringToType.size() == 0) + { + StringToType.insert(std::make_pair(std::wstring(L"VDMActive"), VDMActive)); + StringToType.insert(std::make_pair(std::wstring(L"DesktopCount"), DesktopCountTotal)); + StringToType.insert(std::make_pair(std::wstring(L"CurrentDesktop"), CurrentDesktop)); + StringToType.insert(std::make_pair(std::wstring(L"SwitchDesktop"), SwitchDesktop)); + } +} + +VirtuaWinMeasure::~VirtuaWinMeasure(void) +{ +} + +UINT VirtuaWinMeasure::Initialize(LPCTSTR iniFile, LPCTSTR section) +{ + std::wstring TypeString(ReadConfigString(section, _T("VDMeasureType"), _T(""))); + std::map::iterator i = StringToType.find(TypeString); + if(i != StringToType.end()) + { + Type = i->second; + } + else + { + Type = Unknown; + } + + switch(Type) + { + case VDMActive: + return 1; + + case DesktopCountTotal: + { + LPCTSTR CountType = ReadConfigString(section, _T("VDDesktopCount"), _T("")); + if(_tcsicmp(CountType, _T("X")) == 0) Type = DesktopCountColumns; + else if(_tcsicmp(CountType, _T("Y")) == 0) Type = DesktopCountRows; + if(FindVirtuaWinWindow()) + { + return (UINT) SendMessage(vwHandle, VW_DESKTOP_SIZE, 0, 0); + } + break; + } + } + + return 0; +} + +void VirtuaWinMeasure::Finalize() +{ +} + +UINT VirtuaWinMeasure::Update() +{ + if(!FindVirtuaWinWindow()) + { + return 0; + } + + switch(Type) + { + case VDMActive: + return 1; + + case DesktopCountColumns: + return (UINT) SendMessage(vwHandle, VW_DESKX, 0, 0); + + case DesktopCountRows: + return (UINT) SendMessage(vwHandle, VW_DESKY, 0, 0); + + case DesktopCountTotal: + return (UINT) SendMessage(vwHandle, VW_DESKX, 0, 0) * (UINT) SendMessage(vwHandle, VW_DESKY, 0, 0); + + case CurrentDesktop: + return (UINT) SendMessage(vwHandle, VW_CURDESK, 0, 0); + } + + return 0; +} + +LPCTSTR VirtuaWinMeasure::GetString(UINT flags) +{ + static TCHAR Buffer[MAX_PATH]; + Buffer[0] = _T('\0'); + + switch(Type) + { + case VDMActive: + case DesktopCountColumns: + case DesktopCountRows: + case DesktopCountTotal: + case CurrentDesktop: + swprintf_s(Buffer, MAX_PATH, L"%i", Update()); + break; + } + + return Buffer; +} + +void VirtuaWinMeasure::ExecuteBang(LPCTSTR args) +{ + INT32 Desktop; + + if(!FindVirtuaWinWindow()) return; + + switch(Type) + { + case SwitchDesktop: + Desktop = _wtoi(args); + SendNotifyMessage(vwHandle, VW_CHANGEDESK, Desktop, 0); + } +} + +BOOL VirtuaWinMeasure::FindVirtuaWinWindow() +{ + if(IsWindow(vwHandle)) return TRUE; + vwHandle = FindWindow(_T("VirtuaWinMainClass"), _T("VirtuaWinMainClass")); + return vwHandle != NULL; +} diff --git a/Plugins/PluginVirtualDesktops/VirtuaWinMeasure.h b/Plugins/PluginVirtualDesktops/VirtuaWinMeasure.h new file mode 100644 index 00000000..bd0260c3 --- /dev/null +++ b/Plugins/PluginVirtualDesktops/VirtuaWinMeasure.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2010 Patrick Dubbert + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#pragma once +#include "VDMeasure.h" + +#include +#include +#include + +class VirtuaWinMeasure : + public VDMeasure +{ +public: + VirtuaWinMeasure(HMODULE, UINT id); + virtual ~VirtuaWinMeasure(void); + + virtual UINT Initialize(LPCTSTR iniFile, LPCTSTR section); + virtual void Finalize(); + virtual UINT Update(); + virtual LPCTSTR GetString(UINT flags); + virtual void ExecuteBang(LPCTSTR args); + +private: + enum MeasureType + { + Unknown, + VDMActive, + DesktopCountRows, + DesktopCountColumns, + DesktopCountTotal, + CurrentDesktop, + SwitchDesktop, + }; + + static BOOL FindVirtuaWinWindow(); + + MeasureType Type; + static std::map StringToType; + static HWND vwHandle; + +}; diff --git a/Plugins/PluginVirtualDesktops/VirtuaWinMessages.h b/Plugins/PluginVirtualDesktops/VirtuaWinMessages.h new file mode 100644 index 00000000..af39b9af --- /dev/null +++ b/Plugins/PluginVirtualDesktops/VirtuaWinMessages.h @@ -0,0 +1,172 @@ +#ifndef _MESSAGES_H_ +#define _MESSAGES_H_ +/************************************************************************* + * + * VirtuaWin - Virtual Desktop Manager (virtuawin.sourceforge.net) + * ConfigParameters.h - Dfinition of all module messages + * + * Copyright (c) 1999-2005 Johan Piculell + * Copyright (c) 2006-2010 VirtuaWin (VirtuaWin@home.se) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + ************************************************************************* + * This is a definition of all possible messages to send to VirtuaWin + * and the messages that VirtuaWin uses for module communication + * + * All messages starting with VW_ is for controlling VirtuaWin + * and messages starting with MOD_ is messages sent by VirtuaWin + * + * For example if you want to step one desktop to the left: + * PostMessage(VirtuaWin HWND, VW_CHANGEDESK, VW_STEPLEFT, 0); + * For messages where you expect a return value, use the SendMessage + * function instead, see some win32 documentation for more info. + * + * Note: the message numbers is not all in sequence! + * + *************************************************************************/ + +/* Message, switch to a specified desktop, sent with following wParam or 1..vwDESKTOP_MAX */ +#define VW_CHANGEDESK (WM_USER + 10) +#define VW_STEPPREV (WM_USER + 1) +#define VW_STEPNEXT (WM_USER + 2) +#define VW_STEPLEFT (WM_USER + 11) +#define VW_STEPRIGHT (WM_USER + 12) +#define VW_STEPUP (WM_USER + 13) +#define VW_STEPDOWN (WM_USER + 14) +/* Message, close VirtuaWin */ +#define VW_CLOSE (WM_USER + 15) +/* Message, display setup dialog */ +#define VW_SETUP (WM_USER + 16) +/* Message, remove the systray icon */ +#define VW_DELICON (WM_USER + 17) +/* Message, displays the systray icon */ +#define VW_SHOWICON (WM_USER + 18) +/* Message, bring up the help */ +#define VW_HELP (WM_USER + 19) +/* Message, gather all windows */ +#define VW_GATHER (WM_USER + 20) +/* Message, retuns desktop width */ +#define VW_DESKX (WM_USER + 21) +/* Message, retuns desktop height */ +#define VW_DESKY (WM_USER + 22) +/* Message, request the window list from VirtuaWin - RETIRED. + * This message was too dependent on the Window data structure, creating modules which + * are very version dependent. As to v4.0 support for this message has been removed, + * Module writers are encouraged to use the VW_WINGETINFO message instead see SF bug + * 1915723 for more information */ +#define VW_WINLIST (WM_USER + 23) +/* Message, returns the current desktop number */ +#define VW_CURDESK (WM_USER + 24) +/* Message, assign a window to the specified desktop wParam is the window + * handle (HWND, 0 for foreground window) and lParam is either VW_STEP* (see + * 6 defines above) or the desktop number. If desk is -ve window is assigned + * to desk (-lParam) and VW changes to the desk. Returns 0 if window was not + * found (i.e. not managed by VW), non-zero otherwise */ +#define VW_ASSIGNWIN (WM_USER + 25) +/* Message, set the sticky state of a window. wParam is the window handle + * (HWND, 0 for foreground window) and lParam should be -1 for toggle, 0 for + * unset and 1 for set sticky state. */ +#define VW_SETSTICKY (WM_USER + 26) +/* Message, make a window the foreground, only if visible + wParam is the window handle (HWND) */ +#define VW_FOREGDWIN (WM_USER + 27) +/* Message, return VirtuaWin's installation path. The path will be returned via a WM_COPYDATA + * message, set wParam to the HWND which is to receive the WM_COPYDATA message */ +#define VW_INSTALLPATH (WM_USER + 28) +/* Message, return VirtuaWin's user application data path. The path will be returned via a + * WM_COPYDATA message, set wParam to the HWND which is to receive the WM_COPYDATA message */ +#define VW_USERAPPPATH (WM_USER + 29) +/* Message, access a window, wParam is the window handle (HWND) and lParam is the method: + 0 - Use user's 'On hidden window activation' preference (ignore -> move) + 1 - Move window to this desk + 2 - Show window to this disk + 3 - Change to window's desk + -1 - Use window's 'On hidden window activation' setting (if set to ignore nothing will happen) + Returns 0 if window was not found (i.e. not managed by VW), non-zero otherwise */ +#define VW_ACCESSWIN (WM_USER + 39) +/* Message, return the information VW has on the window given via wParam. 0 is returned if the + * window is not found, otherwise use the 2 macros to extract the window flags (see vwWINFLAGS_* + * defines in Defines.h, the hide method flags are not given) and the windows desk. To check + * if a window is hung do: + * if(((vwGetWindowInfoFlags(ii) & vwWINFLAGS_SHOWN) == 0) ^ ((vwGetWindowInfoFlags(ii) & vwWINFLAGS_SHOW) == 0)) + */ +#define VW_WINGETINFO (WM_USER + 40) +#define vwWindowGetInfoFlags(ii) ((ii) & 0x00ffffff) +#define vwWindowGetInfoDesk(ii) (((ii) >> 24) & 0x00ff) +/* Message, Desk image generation message, the action of the message depends on the + * value of wParam: + * 0 - Returns the current status of image generation + * 1 - Enables image generation, lParam specifies the required image height + * (aspect ratio is maintained). Returns 1 if generation is enabled. + * 2 - Disables image generation. Note: as multiple modules may enable image + * generation an 'enable' counter is kept, each 'enable' message increments + * and each disable decrements this counter. Image generation only stops + * when the counter returns to zero. Returns 1 if counter was decremented, + * 0 if counter is already 0. + * 3 - Updates the current desk's image if image generation is enabled, returns + * 1 if successfully updated, 0 otherwise. + * 4 - Returns the desk image height if enabled, 0 otherwise + * 5 - Returns the desk image width if enabled, 0 otherwise */ +#define VW_DESKIMAGE (WM_USER + 41) +/* Message, set the main VirtuaWin enable/disable state. If wParam is 0 + the current state is not changed, 1 for toggle, 2 for disable + and 3 for enable. Returns the previous state, 1 for enable & 0 for disabled. */ +#define VW_ENABLE_STATE (WM_USER + 42) +/* Message, return the name of the desk specified by the lParam, if lParam is set + * to 0 the current desktop name is returned. The name will be returned via a WM_COPYDATA + * message, set wParam to the HWND which is to receive the WM_COPYDATA message */ +#define VW_DESKNAME (WM_USER + 43) +/* Message, returns the value of vwDESKTOP_SIZE in Defines.h, this can be used to + * quickly obtain the maximum size of any desk based array, i.e. guaranteed to be greater + * than the current desktop. Note the this is not true of (DESKX * DESKY) due to hidden desktops. */ +#define VW_DESKTOP_SIZE (WM_USER + 44) +/* Message, set whether a window is managed by VW. wParam is the window handle + * (HWND, 0 for foreground window) and lParam should be 0 for not managed and 1 for managed. */ +#define VW_WINMANAGE (WM_USER + 45) +/* Message, executes a hotkey command as if the user pressed the hotkey, where wParam is the + * command id (see second column in vwCommands.def), LOWORD(lParam) is the desk (if required) and + * HIWORD(lParam) is the modifier, only bit vwHOTKEY_WIN_MOUSE is used (and only set if really + * needed as the command will fail if there is no window under the mouse). The return is dependent + * on the command being executed. */ +#define VW_HOTKEY (WM_USER + 46) + +/* Message & WM_COPYDATA ID, inserts or removes items from the control menu. */ +#define VW_CMENUITEM (WM_USER + 47) + +/* Message, sent by VirtuaWin after a switch. lParam will contain current desktop number + if wParam isn't one of the following, then wParam will also contain current desktop. + If desktop cycling is enabled, there will be two MOD_CHANGEDESK sent when going + "over the edge". The first one will have a MOD_STEP* parameter, and the second + will have current desktop in both parameters. +*/ +#define MOD_CHANGEDESK (WM_USER + 30) +#define MOD_STEPLEFT (WM_USER + 31) +#define MOD_STEPRIGHT (WM_USER + 32) +#define MOD_STEPUP (WM_USER + 33) +#define MOD_STEPDOWN (WM_USER + 34) + +/* Message, sent just after the module is started. wParam will contain VirtuaWin hWnd */ +#define MOD_INIT (WM_USER + 35) +/* Message, sent when VirtuaWin quits or reloads its modules */ +#define MOD_QUIT (WM_USER + 36) +/* Message, sent by VirtuaWin when setup button is pressed in "module tab", + * wParam set to the HWND of the 'parent' window or 0 */ +#define MOD_SETUP (WM_USER + 37) +/* Message, sent by VirtuaWin when the configuration has been updated */ +#define MOD_CFGCHANGE (WM_USER + 38) + +#endif diff --git a/Plugins/PluginVirtualDesktops/VirtualDesktops.cpp b/Plugins/PluginVirtualDesktops/VirtualDesktops.cpp new file mode 100644 index 00000000..38f182ea --- /dev/null +++ b/Plugins/PluginVirtualDesktops/VirtualDesktops.cpp @@ -0,0 +1,162 @@ +/* + Copyright (C) 2010 Patrick Dubbert + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* + + VirtualDesktops Plugin + ---------------------- + + This plugin aims to give Rainmeter skins access to various virtual desktop + managers through a common interface. The following VDMs are supported: + + * Dexpot + * VirtuaWin + + To add support for another virtual desktop manager, + + 1) implement a new class derived from VDMeasure + 2) include its header file below + 3) add a new case for the "VDManager" config string in the Initialize + funtion below + + Different types of measures are identified using the "VDMeasureType" config + string, i.e. + + [VirtualDesktopsMeasure] + Measure=Plugin + Plugin=VirtualDesktops.dll + VDManager=SomeVDM + VDMeasureType=... + + The following basic measure types have to be implemented: + + * VDMActive: returns 1 when the VDM is running, 0 otherwise + + * DesktopCount: returns the number of virtual desktops available; when + "VDDesktopCount=X" or "VDDesktopCount=Y" is given, returns + the number of columns or rows, respectively, in a grid of + desktops + + * CurrentDesktop: returns the number of the currently active desktop + + * SwitchDesktop: when sent a desktop number as a bang, switches to the + corresponding desktop + + You're welcome to add any other measure types that suit the feature set of + the virtual desktop manager in question. Examples can be found in the + existing implementations. + +*/ + +#include "DexpotMeasure.h" +#include "VirtuaWinMeasure.h" + +#include +#include +#include + +#include "../../Library/Export.h" + +extern "C" +{ + __declspec(dllexport) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); + __declspec(dllexport) void Finalize(HMODULE instance, UINT id); + __declspec(dllexport) UINT Update(UINT id); + __declspec(dllexport) LPCTSTR GetString(UINT id, UINT flags); + __declspec(dllexport) void ExecuteBang(LPCTSTR args, UINT id); + __declspec(dllexport) UINT GetPluginVersion(); + __declspec(dllexport) LPCTSTR GetPluginAuthor(); +} + +std::map Measures; +HMODULE VDMeasure::hInstance; + +UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +{ + VDMeasure *Measure = NULL; + LPCTSTR VDManager = ReadConfigString(section, _T("VDManager"), _T("")); + + if(_tcsicmp(VDManager, _T("Dexpot")) == 0) + { + Measure = DexpotMeasure::CreateMeasure(instance, id, iniFile, section); + } + else if(_tcsicmp(VDManager, _T("VirtuaWin")) == 0) + { + Measure = new VirtuaWinMeasure(instance, id); + } + + if(Measure) + { + Measures.insert(std::make_pair(id, Measure)); + return Measure->Initialize(iniFile, section); + } + + return 0; +} + +UINT Update(UINT id) +{ + std::map::iterator i = Measures.find(id); + if(i != Measures.end()) + { + return i->second->Update(); + } + + return 0; +} + +LPCTSTR GetString(UINT id, UINT flags) +{ + std::map::iterator i = Measures.find(id); + if(i != Measures.end()) + { + return i->second->GetString(flags); + } + + return _T(""); +} + +void ExecuteBang(LPCTSTR args, UINT id) +{ + std::map::iterator i = Measures.find(id); + if(i != Measures.end()) + { + i->second->ExecuteBang(args); + } +} + +void Finalize(HMODULE instance, UINT id) +{ + std::map::iterator i = Measures.find(id); + if(i != Measures.end()) + { + i->second->Finalize(); + delete i->second; + Measures.erase(i); + } +} + +UINT GetPluginVersion() +{ + return 1000; +} + +LPCTSTR GetPluginAuthor() +{ + return _T("Dexpot GbR (info@dexpot.de)"); +} diff --git a/Rainmeter.sln b/Rainmeter.sln index cec7a6b9..32cc4e3d 100644 --- a/Rainmeter.sln +++ b/Rainmeter.sln @@ -92,6 +92,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWin7Audio", "Plugins\ {BE9D2400-7F1C-49D6-8498-5CE495491AD6} = {BE9D2400-7F1C-49D6-8498-5CE495491AD6} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginVirtualDesktops", "Plugins\PluginVirtualDesktops\PluginVirtualDesktops.vcproj", "{4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}" + ProjectSection(ProjectDependencies) = postProject + {BE9D2400-7F1C-49D6-8498-5CE495491AD6} = {BE9D2400-7F1C-49D6-8498-5CE495491AD6} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -296,6 +301,18 @@ Global {6D032D6B-7656-4743-B454-3388E2921EB0}.Release64|Win32.Build.0 = Release64|Win32 {6D032D6B-7656-4743-B454-3388E2921EB0}.Release64|x64.ActiveCfg = Release64|x64 {6D032D6B-7656-4743-B454-3388E2921EB0}.Release64|x64.Build.0 = Release64|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.Build.0 = Debug|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.ActiveCfg = Debug|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.Build.0 = Debug|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.ActiveCfg = Release|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.Build.0 = Release|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.ActiveCfg = Release|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.Build.0 = Release|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release64|Win32.ActiveCfg = Release64|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release64|Win32.Build.0 = Release64|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release64|x64.ActiveCfg = Release64|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release64|x64.Build.0 = Release64|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/revision-number.h b/revision-number.h index e3ce7547..c462a5a6 100644 --- a/revision-number.h +++ b/revision-number.h @@ -1,2 +1,2 @@ #pragma once -const int revision_number = 451; \ No newline at end of file +const int revision_number = 454; \ No newline at end of file