diff --git a/README.markdown b/README.markdown index c01427a..b77d599 100644 --- a/README.markdown +++ b/README.markdown @@ -8,8 +8,12 @@ You probably first need the [VS 2017 runtimes vc_redist.x64.exe and/or vc_redist ## Change log +* 16.05.2021: + + Expose `CreateVirtualDesktop` and `RemoveVirtualDesktop` functions. + * 02.06.2019: - + Exported the Alt+Tab functions prefixed with `View`, this should allow user of the DLL to create native feeling ALT+Tab switcher, since these functions uses the same `IApplicationView` functions as real Alt+Tab switcher itself. The function to get Alt+Tab windows is basically `ViewGetByLastActivationOrder`. @@ -22,7 +26,7 @@ DetectHiddenWindows, On hwnd:=WinExist("ahk_pid " . DllCall("GetCurrentProcessId","Uint")) hwnd+=0x1000<<32 -hVirtualDesktopAccessor := DllCall("LoadLibrary", Str, "C:\Source\CandCPP\VirtualDesktopAccessor\x64\Release\VirtualDesktopAccessor.dll", "Ptr") +hVirtualDesktopAccessor := DllCall("LoadLibrary", Str, "C:\Source\CandCPP\VirtualDesktopAccessor\x64\Release\VirtualDesktopAccessor.dll", "Ptr") GoToDesktopNumberProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "GoToDesktopNumber", "Ptr") GetCurrentDesktopNumberProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "GetCurrentDesktopNumber", "Ptr") IsWindowOnCurrentVirtualDesktopProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "IsWindowOnCurrentVirtualDesktop", "Ptr") @@ -56,7 +60,7 @@ GoToPrevDesktop() { if (current = 0) { GoToDesktopNumber(7) } else { - GoToDesktopNumber(current - 1) + GoToDesktopNumber(current - 1) } return } @@ -67,7 +71,7 @@ GoToNextDesktop() { if (current = 7) { GoToDesktopNumber(0) } else { - GoToDesktopNumber(current + 1) + GoToDesktopNumber(current + 1) } return } @@ -77,7 +81,7 @@ GoToDesktopNumber(num) { ; Store the active window of old desktop, if it is not pinned WinGet, activeHwnd, ID, A - current := DllCall(GetCurrentDesktopNumberProc, UInt) + current := DllCall(GetCurrentDesktopNumberProc, UInt) isPinned := DllCall(IsPinnedWindowProc, UInt, activeHwnd) if (isPinned == 0) { activeWindowByDesktop[current] := activeHwnd @@ -100,9 +104,9 @@ VWMess(wParam, lParam, msg, hwnd) { global IsWindowOnCurrentVirtualDesktopProc, IsPinnedWindowProc, activeWindowByDesktop desktopNumber := lParam + 1 - + ; Try to restore active window from memory (if it's still on the desktop and is not pinned) - WinGet, activeHwnd, ID, A + WinGet, activeHwnd, ID, A isPinned := DllCall(IsPinnedWindowProc, UInt, activeHwnd) oldHwnd := activeWindowByDesktop[lParam] isOnDesktop := DllCall(IsWindowOnCurrentVirtualDesktopProc, UInt, oldHwnd, Int) @@ -111,7 +115,7 @@ VWMess(wParam, lParam, msg, hwnd) { } ; Menu, Tray, Icon, Icons/icon%desktopNumber%.ico - + ; When switching to desktop 1, set background pluto.jpg ; if (lParam == 0) { ; DllCall("SystemParametersInfo", UInt, 0x14, UInt, 0, Str, "C:\Users\Jarppa\Pictures\Backgrounds\saturn.jpg", UInt, 1) @@ -144,12 +148,12 @@ VWMess(wParam, lParam, msg, hwnd) { * int GetCurrentDesktopNumber() * int GetDesktopCount() * GUID GetDesktopIdByNumber(int number) // Returns zeroed GUID with invalid number found - * int GetDesktopNumber(IVirtualDesktop *pDesktop) + * int GetDesktopNumber(IVirtualDesktop *pDesktop) * int GetDesktopNumberById(GUID desktopId) * GUID GetWindowDesktopId(HWND window) * int GetWindowDesktopNumber(HWND window) * int IsWindowOnCurrentVirtualDesktop(HWND window) - * BOOL MoveWindowToDesktopNumber(HWND window, int number) + * BOOL MoveWindowToDesktopNumber(HWND window, int number) * void GoToDesktopNumber(int number) * void RegisterPostMessageHook(HWND listener, int messageOffset) * void UnregisterPostMessageHook(HWND hwnd) @@ -159,7 +163,7 @@ VWMess(wParam, lParam, msg, hwnd) { * int IsPinnedApp(HWND hwnd) // Returns 1 if pinned, 0 if not pinned, -1 if not valid * void PinApp(HWND hwnd) * void UnPinApp(HWND hwnd) - * int IsWindowOnDesktopNumber(HWND window, int number) / + * int IsWindowOnDesktopNumber(HWND window, int number) / * void RestartVirtualDesktopAccessor() // Call this during taskbar created message * int ViewIsShownInSwitchers(HWND hwnd) // Is the window shown in Alt+Tab list? @@ -174,3 +178,6 @@ VWMess(wParam, lParam, msg, hwnd) { * void EnableKeepMinimized() // Deprecated, does nothing * void RestoreMinimized() // Deprecated, does nothing + + * int CreateVirtualDesktop() // Returns new desktop number, -1 if it fails + * bool RemoveVirtualDesktop(int number, int fallbackDesktop) // returns true if success, otherwise false \ No newline at end of file diff --git a/TestVirtualDesktopAccessorWin32/TestVirtualDesktopAccessorWin32.cpp b/TestVirtualDesktopAccessorWin32/TestVirtualDesktopAccessorWin32.cpp index a5fb4f3..69f8783 100644 --- a/TestVirtualDesktopAccessorWin32/TestVirtualDesktopAccessorWin32.cpp +++ b/TestVirtualDesktopAccessorWin32/TestVirtualDesktopAccessorWin32.cpp @@ -84,6 +84,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, RegisterPostMessageHook(hwnd, MESSAGE_OFFSET); std::wcout << "Desktops: " << GetDesktopCount() << "\r\n"; + int newDesktop = CreateVirtualDesktop(); + std::wcout << "New desktop: " << newDesktop << std::endl; + std::wcout << "Removing new desktop: " << RemoveVirtualDesktop(newDesktop, newDesktop - 1) << std::endl; std::wcout << "Console Window's Desktop Number: " << GetWindowDesktopNumber(GetConsoleWindow()) << std::endl; std::wcout << "Current Desktop Number: " << GetCurrentDesktopNumber() << "\r\n"; diff --git a/VirtualDesktopAccessor/dllmain.def b/VirtualDesktopAccessor/dllmain.def index 0c4de2a..b012970 100644 --- a/VirtualDesktopAccessor/dllmain.def +++ b/VirtualDesktopAccessor/dllmain.def @@ -32,4 +32,7 @@ EXPORTS ViewGetByZOrder @28 ViewGetFocused @29 ViewGetLastActivationTimestamp @30 - ViewGetByLastActivationOrder @31 \ No newline at end of file + ViewGetByLastActivationOrder @31 + + CreateVirtualDesktop @32 + RemoveVirtualDesktop @33 diff --git a/VirtualDesktopAccessor/dllmain.h b/VirtualDesktopAccessor/dllmain.h index 8bf4593..4c5c343 100644 --- a/VirtualDesktopAccessor/dllmain.h +++ b/VirtualDesktopAccessor/dllmain.h @@ -243,7 +243,6 @@ int DllExport IsWindowOnDesktopNumber(HWND window, int number) { else { return 0; } - return -1; } @@ -607,7 +606,6 @@ UINT DllExport ViewGetByZOrder(HWND *windows, UINT count, BOOL onlySwitcherWindo for (UINT i = 0; i < count; i++) { HRESULT getAtResult = arr->GetAt(i - 1, IID_IApplicationView, (void**)&view); - if (view != nullptr && getAtResult == S_OK) { HWND wnd = 0; BOOL showInSwitchers = false; @@ -698,7 +696,6 @@ UINT DllExport ViewGetByLastActivationOrder(HWND *windows, UINT count, BOOL only windows[i] = entry.hwnd; i++; } - return i; } @@ -844,4 +841,33 @@ void DllExport UnregisterPostMessageHook(HWND hwnd) { } VOID _OpenDllWindow(HINSTANCE injModule) { -} \ No newline at end of file +} + +DllExport int CreateVirtualDesktop() +{ + _RegisterService(); + + IVirtualDesktop *pDesktop = nullptr; + HRESULT hr = pDesktopManagerInternal->CreateDesktopW(&pDesktop); + + if (SUCCEEDED(hr)) + { + return GetDesktopNumber(pDesktop); + } + + return -1; +} + +DllExport bool RemoveVirtualDesktop(int number, int fallbackDesktop) +{ + _RegisterService(); + + IVirtualDesktop *pDesktop = _GetDesktopByNumber(number); + IVirtualDesktop *pDesktopFallback = _GetDesktopByNumber(fallbackDesktop); + if (pDesktop != nullptr && pDesktopFallback != nullptr) + { + HRESULT hr = pDesktopManagerInternal->RemoveDesktop(pDesktop, pDesktopFallback); + return SUCCEEDED(hr); + } + return false; +} diff --git a/x64/Release/VirtualDesktopAccessor.dll b/x64/Release/VirtualDesktopAccessor.dll index d6af0ad..259dfc9 100644 Binary files a/x64/Release/VirtualDesktopAccessor.dll and b/x64/Release/VirtualDesktopAccessor.dll differ