diff --git a/.gitignore b/.gitignore
index 064db0e..aba634f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,10 @@
Release/
Debug/
x64/
+Utils/*.obj
+Utils/*.exe
*.opensdf
*.sdf
*.suo
-*.dll
\ No newline at end of file
+*.dll
+*.aps
\ No newline at end of file
diff --git a/Hook/Hook.vcxproj b/Hook/Hook.vcxproj
index b32a68d..74c357e 100644
--- a/Hook/Hook.vcxproj
+++ b/Hook/Hook.vcxproj
@@ -169,6 +169,9 @@
+
+
+
diff --git a/Hook/Hook.vcxproj.filters b/Hook/Hook.vcxproj.filters
index c6375b3..de85191 100644
--- a/Hook/Hook.vcxproj.filters
+++ b/Hook/Hook.vcxproj.filters
@@ -25,4 +25,9 @@
+
+
+ Header Files
+
+
\ No newline at end of file
diff --git a/Hook/VirtualDesktops.h b/Hook/VirtualDesktops.h
index 66c83bf..e830012 100644
--- a/Hook/VirtualDesktops.h
+++ b/Hook/VirtualDesktops.h
@@ -1,7 +1,7 @@
/**
* MoveToDesktop
*
-* Copyright (C) 2015 by Tobias Salzmann
+* Copyright (C) 2015-2016 by Tobias Salzmann
*
* 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
diff --git a/Hook/dll.cpp b/Hook/dll.cpp
deleted file mode 100644
index 17b74cc..0000000
--- a/Hook/dll.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
-* MoveToDesktop
-*
-* Copyright (C) 2015 by Tobias Salzmann
-*
-* 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, see .
-*/
-
-
-#include
-#include "hook.h"
-
-
-
diff --git a/Hook/hook.cpp b/Hook/hook.cpp
index 907ea4c..6e20dcf 100644
--- a/Hook/hook.cpp
+++ b/Hook/hook.cpp
@@ -1,7 +1,7 @@
/**
* MoveToDesktop
*
-* Copyright (C) 2015 by Tobias Salzmann
+* Copyright (C) 2015-2016 by Tobias Salzmann
* Copyright (C) 2008-2011 by Manuel Meitinger
*
* This program is free software: you can redistribute it and/or modify
@@ -22,48 +22,9 @@
#include
#include
-
+#include
#include "VirtualDesktops.h"
-
-#ifdef _DEBUG
-#define LOGFILE "%temp%\\MoveToDesktop.log"
-void Log(char *message)
-{
- FILE *file;
-
- TCHAR logFile[MAX_PATH] = {0};
- ExpandEnvironmentStrings(LOGFILE, logFile, _countof(logFile));
- file = fopen(logFile, "a");
-
- if (file == NULL) {
- return;
- }
- else
- {
- char exepath[MAX_PATH];
- char msg[1024] = "";
- GetModuleFileName(0, exepath, MAX_PATH);
- sprintf(msg, "%s: %s\n", exepath, message);
- fputs(msg, file);
- fclose(file);
- }
-
- if (file)
- fclose(file);
-}
-#else
-#define Log
-#endif
-
-
-
-#define MAXDESKTOPS 255
-#define MOVETOMENU_ID (0xDE100)
-#define MOVETOMENU_NEW (MOVETOMENU_ID + 1)
-#define MOVETOMENU_START (MOVETOMENU_NEW + 1)
-#define MOVETOMENU_LAST (MOVETOMENU_START + MAXDESKTOPS)
-
-
+#include "hook.h"
IServiceProvider* pServiceProvider = nullptr;
IVirtualDesktopManager *pDesktopManager = nullptr;
@@ -79,21 +40,37 @@ enum EComStatus
int ComStatus = COMSTATUS_UNINITIALIZED;
bool bAddedMenu = false;
+bool bReadIni = false;
+bool bSwitchDesktopAfterMove = false;
+
+#define INIFILE "%APPDATA%\\MoveToDesktop.ini"
BOOL InitCom()
{
+ Log("Initalizing Com");
if (ComStatus == COMSTATUS_INITIALIZED)
+ {
+ Log("> Allready Initialized!");
return true;
+ }
else if (ComStatus == COMSTATUS_ERROR)
+ {
+ Log("> Allready tried to initialize but it failed.");
return false;
+ }
ComStatus = COMSTATUS_ERROR;
- ::CoInitialize(NULL);
-
- HRESULT hr = ::CoCreateInstance(CLSID_ImmersiveShell, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IServiceProvider), (PVOID*)&pServiceProvider);
+ HRESULT hr = ::CoInitialize(NULL);
+ if (FAILED(hr))
+ {
+ Log("> CoInitialize failed: %X", hr);
+ return FALSE;
+ }
+ hr = ::CoCreateInstance(CLSID_ImmersiveShell, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IServiceProvider), (PVOID*)&pServiceProvider);
if (FAILED(hr))
{
+ Log("> CoCreateInstance failed: %X", hr);
return FALSE;
}
@@ -102,7 +79,7 @@ BOOL InitCom()
hr = pServiceProvider->QueryService(__uuidof(IVirtualDesktopManager), &pDesktopManager);
if (FAILED(hr))
{
-
+ Log("> QueryService(DesktopManager) failed");
pServiceProvider->Release();
pServiceProvider = nullptr;
return FALSE;
@@ -113,7 +90,7 @@ BOOL InitCom()
hr = pServiceProvider->QueryService(CLSID_VirtualDesktopAPI_Unknown, &pDesktopManagerInternal);
if (FAILED(hr))
{
-
+ Log("> QueryService(DesktopManagerInternal) failed");
pDesktopManager->Release();
pDesktopManager = nullptr;
pServiceProvider->Release();
@@ -121,7 +98,6 @@ BOOL InitCom()
return FALSE;
}
-
ComStatus = COMSTATUS_INITIALIZED;
return TRUE;
}
@@ -137,6 +113,17 @@ VOID FreeCom()
}
}
+VOID ReadIni()
+{
+ if (bReadIni == true)
+ return;
+ bReadIni = true;
+ Log("Reading Ini");
+ TCHAR iniFile[MAX_PATH] = { 0 };
+ ExpandEnvironmentStrings(INIFILE, iniFile, _countof(iniFile));
+ bSwitchDesktopAfterMove = (GetPrivateProfileInt("MoveToDesktop", "SwitchDesktopAfterMove", 0, iniFile) != 0);
+ Log("Ini: SwitchDesktopAfterMove = %d", (bSwitchDesktopAfterMove ? 1 : 0));
+}
INT GetIndexOfItem(HMENU menu, UINT id)
{
@@ -151,8 +138,7 @@ INT GetIndexOfItem(HMENU menu, UINT id)
return -1;
}
-
-void AddMenu(HWND hwnd, HMENU menu)
+VOID AddMenu(HWND hwnd, HMENU menu)
{
if (bAddedMenu == true)
return;
@@ -207,7 +193,7 @@ void AddMenu(HWND hwnd, HMENU menu)
MoveToItem.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | MIIM_STRING;
Log("Add MoveToMenu");
MoveToItem.wID = MOVETOMENU_ID;
- MoveToItem.dwTypeData = TEXT("Move To");
+ MoveToItem.dwTypeData = TEXT("Move &To");
MoveToItem.hSubMenu = CreateMenu();
InsertMenuItem(systemMenu, SC_CLOSE, FALSE, &MoveToItem);
@@ -221,7 +207,7 @@ void AddMenu(HWND hwnd, HMENU menu)
char desktopName[64] = { 0 };
- sprintf_s(desktopName, sizeof(desktopName), "Desktop %d", i + 1);
+ sprintf_s(desktopName, sizeof(desktopName), "Desktop &%d", i + 1);
MENUITEMINFO item = { 0 };
item.cbSize = sizeof(item);
@@ -240,7 +226,7 @@ void AddMenu(HWND hwnd, HMENU menu)
item.fMask = MIIM_ID | MIIM_STRING;
item.fState = MFS_UNCHECKED;
item.wID = MOVETOMENU_NEW;
- item.dwTypeData = TEXT("New Desktop");
+ item.dwTypeData = TEXT("&New Desktop");
InsertMenuItem(MoveToItem.hSubMenu, -1, FALSE, &item);
}
@@ -253,7 +239,7 @@ void AddMenu(HWND hwnd, HMENU menu)
}
}
-void RemoveMenu(HWND hwnd, HMENU menu)
+VOID RemoveMenu(HWND hwnd, HMENU menu)
{
if (bAddedMenu == false)
return;
@@ -279,16 +265,80 @@ void RemoveMenu(HWND hwnd, HMENU menu)
}
Log("Remove MoveToMenu");
DestroyMenu(MoveToItem.hSubMenu);
- DeleteMenu(systemMenu, MoveToItem.wID, MF_BYCOMMAND);
-
-
-
+ DeleteMenu(systemMenu, MoveToItem.wID, MF_BYCOMMAND);
+}
+
+INT GetCurrentDesktopIndex(UINT *count)
+{
+ *count = 0;
+ IObjectArray *pObjectArray = nullptr;
+ IVirtualDesktop *pCurrentDesktop = nullptr;
+
+ if (!InitCom())
+ {
+ Log("InitCom failed");
+ return -1;
+ }
+
+ HRESULT hr = pDesktopManagerInternal->GetDesktops(&pObjectArray);
+ if (FAILED(hr))
+ {
+ Log("pDesktopManagerInternal->GetDesktops failed %x", hr);
+ return -1;
+ }
+
+ hr = pObjectArray->GetCount(count);
+ if (FAILED(hr))
+ {
+ Log("pObjectArray->GetCount failed %x", hr);
+ pObjectArray->Release();
+ return -1;
+ }
+
+
+ hr = pDesktopManagerInternal->GetCurrentDesktop(&pCurrentDesktop);
+ if (FAILED(hr))
+ {
+ Log("pDesktopManagerInternal->GetCurrentDesktop failed %x", hr);
+ pObjectArray->Release();
+ return -1;
+ }
+
+ int index = -1;
+ for (UINT i = 0; i < *count && i < MAXDESKTOPS && index == -1; ++i)
+ {
+ IVirtualDesktop *pDesktop = nullptr;
+
+ if (FAILED(pObjectArray->GetAt(i, __uuidof(IVirtualDesktop), (void**)&pDesktop)))
+ continue;
+ if (pDesktop == pCurrentDesktop)
+ {
+ index = MOVETOMENU_START + i;
+ }
+ pDesktop->Release();
+ }
+
+ pObjectArray->Release();
+
+ if (pCurrentDesktop != nullptr)
+ {
+ pCurrentDesktop->Release();
+ }
+ return index;
}
void HandleSysCommand(WPARAM wParam, HWND hwnd)
{
if (wParam == MOVETOMENU_NEW)
{
+ Log("Getting RootWindow of %X", hwnd);
+ HWND rootHwnd = GetAncestor(hwnd, GA_ROOTOWNER);
+ if (rootHwnd != NULL)
+ {
+ hwnd = rootHwnd;
+ }
+
+ Log("Moving %X to new", hwnd);
IVirtualDesktop *pNewDesktop = nullptr;
HRESULT hr = pDesktopManagerInternal->CreateDesktopW(&pNewDesktop);
if (FAILED(hr))
@@ -299,23 +349,37 @@ void HandleSysCommand(WPARAM wParam, HWND hwnd)
hr = pNewDesktop->GetID(&id);
if (SUCCEEDED(hr))
{
- pDesktopManager->MoveWindowToDesktop(hwnd, id);
+ Log("pDesktopManager->MoveWindowToDesktop(%X, %X)", hwnd, id);
+ hr = pDesktopManager->MoveWindowToDesktop(hwnd, id);
+ if (SUCCEEDED(hr))
+ {
+ if (bSwitchDesktopAfterMove)
+ {
+ pDesktopManagerInternal->SwitchDesktop(pNewDesktop);
+ }
+ }
+ else
+ {
+ Log("Error %d on moving %X to %X", hr, hwnd, id);
+ }
}
pNewDesktop->Release();
}
else if (wParam >= MOVETOMENU_START && wParam <= MOVETOMENU_LAST)
{
- HMENU systemMenu;
- if ((systemMenu = GetSystemMenu(hwnd, FALSE)) == NULL)
+ Log("Getting RootWindow of %X", hwnd);
+ HWND rootHwnd = GetAncestor(hwnd, GA_ROOTOWNER);
+ if (rootHwnd != NULL)
{
- return;
+ hwnd = rootHwnd;
}
-
+ Log("Moving %X to %X", hwnd, wParam);
IObjectArray *pObjectArray = nullptr;
HRESULT hr = pDesktopManagerInternal->GetDesktops(&pObjectArray);
if (FAILED(hr))
{
+ Log("Failed to get desktops for %X", hwnd);
return;
}
@@ -327,12 +391,59 @@ void HandleSysCommand(WPARAM wParam, HWND hwnd)
if (SUCCEEDED(hr))
{
- pDesktopManager->MoveWindowToDesktop(hwnd, id);
+ Log("pDesktopManager->MoveWindowToDesktop(%X, %X)", hwnd, id);
+ hr = pDesktopManager->MoveWindowToDesktop(hwnd, id);
+ if (SUCCEEDED(hr))
+ {
+ if (bSwitchDesktopAfterMove)
+ {
+ pDesktopManagerInternal->SwitchDesktop(pDesktop);
+ }
+ }
+ else
+ {
+ Log("Error %X on moving %X to %X", hr, hwnd, id);
+ }
}
pDesktop->Release();
}
pObjectArray->Release();
}
+ else if (wParam == MOVETOMENU_LEFT)
+ {
+ UINT count;
+ int index = GetCurrentDesktopIndex(&count);
+ Log("Current Index is %d", index);
+ Log("Current Count is %d", count);
+ if (index == -1)
+ return;
+ if (index == MOVETOMENU_START)
+ return;
+ Log("Switch to %d", index - 1);
+ HandleSysCommand(--index, hwnd);
+ }
+ else if (wParam == MOVETOMENU_RIGHT)
+ {
+ UINT count;
+ int index = GetCurrentDesktopIndex(&count);
+ Log("Current Index is %d", index);
+ Log("Current Count is %d", count);
+ if (index == -1)
+ return;
+ if (index == MOVETOMENU_LAST)
+ return;
+ if ((++index) <= (int)(count + MOVETOMENU_NEW))
+ {
+ Log("Switch to %d", index);
+ HandleSysCommand(index, hwnd);
+
+ }
+ else
+ {
+ Log("Create new desktop");
+ HandleSysCommand(MOVETOMENU_NEW, hwnd);
+ }
+ }
}
LRESULT CALLBACK CallWndProc(INT code, WPARAM wParam, LPARAM lParam)
@@ -392,7 +503,7 @@ LRESULT CALLBACK CallWndProc(INT code, WPARAM wParam, LPARAM lParam)
// Do the command
case WM_SYSCOMMAND:
{
- Log("WM_SYSCOMMAND");
+ Log("WM_SYSCOMMAND %X %X", msg->wParam, msg->hwnd);
HandleSysCommand(msg->wParam, msg->hwnd);
break;
}
@@ -405,21 +516,27 @@ LRESULT CALLBACK CallWndProc(INT code, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK GetMsgProc(INT code, WPARAM wParam, LPARAM lParam)
{
#define msg ((PMSG)lParam)
-
- if (code == HC_ACTION && msg->message == WM_SYSCOMMAND)
+ if (code == HC_ACTION)
{
- Log("WM_SYSCOMMAND");
- HandleSysCommand(msg->wParam, msg->hwnd);
+ switch (msg->message)
+ {
+ case WM_SYSCOMMAND:
+ {
+ Log("WM_SYSCOMMAND");
+ HandleSysCommand(msg->wParam, msg->hwnd);
+ break;
+ }
+ }
}
- return CallNextHookEx(NULL, code, wParam, lParam);
+ return CallNextHookEx(NULL, code, wParam, lParam);
#undef msg
}
-
BOOL WINAPI DllMain(HINSTANCE handle, DWORD dwReason, LPVOID reserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
+ ReadIni();
}
else if (dwReason == DLL_PROCESS_DETACH)
{
diff --git a/Hook/hook.h b/Hook/hook.h
new file mode 100644
index 0000000..dbbdb85
--- /dev/null
+++ b/Hook/hook.h
@@ -0,0 +1,64 @@
+/**
+* MoveToDesktop
+*
+* Copyright (C) 2015-2016 by Tobias Salzmann
+*
+* 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, see .
+*/
+
+#define MAXDESKTOPS 255
+#define MOVETOMENU_ID (0xDE100)
+#define MOVETOMENU_NEW (MOVETOMENU_ID + 1)
+#define MOVETOMENU_START (MOVETOMENU_NEW + 1)
+#define MOVETOMENU_LAST (MOVETOMENU_START + MAXDESKTOPS)
+#define MOVETOMENU_LEFT (MOVETOMENU_LAST + 1)
+#define MOVETOMENU_RIGHT (MOVETOMENU_LEFT + 1)
+
+
+#ifdef _DEBUG
+#define LOGFILE "%temp%\\MoveToDesktop.log"
+#include
+inline void Log(char *message, ...)
+{
+ FILE *file;
+
+ TCHAR logFile[MAX_PATH] = { 0 };
+ ExpandEnvironmentStrings(LOGFILE, logFile, _countof(logFile));
+ fopen_s(&file, logFile, "a");
+
+ if (file == NULL) {
+ return;
+ }
+ else
+ {
+ char exepath[MAX_PATH];
+ char inpmsg[1024] = "";
+ char finalmsg[1024 + MAX_PATH] = "";
+ va_list ptr;
+ va_start(ptr, message);
+ vsprintf_s(inpmsg, sizeof(inpmsg), message, ptr);
+ va_end(ptr);
+ GetModuleFileName(0, exepath, MAX_PATH);
+
+ sprintf_s(finalmsg, sizeof(finalmsg), "%s: %s\n", exepath, inpmsg);
+ fputs(finalmsg, file);
+ fclose(file);
+ }
+
+ if (file)
+ fclose(file);
+}
+#else
+#define Log
+#endif
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 8cb79ca..b136b75 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
/**
* MoveToDesktop
*
-* Copyright (C) 2015 by Tobias Salzmann
+* Copyright (C) 2015-2016 by Tobias Salzmann
*
* 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
diff --git a/MoveToDesktop.ini b/MoveToDesktop.ini
new file mode 100644
index 0000000..c18e41a
--- /dev/null
+++ b/MoveToDesktop.ini
@@ -0,0 +1,6 @@
+;
+; Place this file in %AppData%
+;
+[MoveToDesktop]
+; Switch Desktop after window was moved
+SwitchDesktopAfterMove=1
\ No newline at end of file
diff --git a/MoveToDesktop.sln b/MoveToDesktop.sln
index 64fa05f..50a3157 100644
--- a/MoveToDesktop.sln
+++ b/MoveToDesktop.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MoveToDesktop", "MoveToDesktop\MoveToDesktop.vcxproj", "{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}"
ProjectSection(ProjectDependencies) = postProject
@@ -12,30 +12,24 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hook", "Hook\Hook.vcxproj",
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
- Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Debug|Any CPU.ActiveCfg = Debug|Win32
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Debug|x64.ActiveCfg = Debug|x64
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Debug|x64.Build.0 = Debug|x64
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Debug|x86.ActiveCfg = Debug|Win32
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Debug|x86.Build.0 = Debug|Win32
- {47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Release|Any CPU.ActiveCfg = Release|Win32
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Release|x64.ActiveCfg = Release|x64
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Release|x64.Build.0 = Release|x64
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Release|x86.ActiveCfg = Release|Win32
{47BF4015-D8CF-4B07-B657-7E7ABDB72FDC}.Release|x86.Build.0 = Release|Win32
- {88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Debug|Any CPU.ActiveCfg = Debug|Win32
{88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Debug|x64.ActiveCfg = Debug|x64
{88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Debug|x64.Build.0 = Debug|x64
{88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Debug|x86.ActiveCfg = Debug|Win32
{88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Debug|x86.Build.0 = Debug|Win32
- {88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Release|Any CPU.ActiveCfg = Release|Win32
{88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Release|x64.ActiveCfg = Release|x64
{88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Release|x64.Build.0 = Release|x64
{88D0BB04-305D-47DC-B4BD-9D3398FAFFE6}.Release|x86.ActiveCfg = Release|Win32
diff --git a/MoveToDesktop/MoveToDesktop.vcxproj b/MoveToDesktop/MoveToDesktop.vcxproj
index 985c3f9..0013945 100644
--- a/MoveToDesktop/MoveToDesktop.vcxproj
+++ b/MoveToDesktop/MoveToDesktop.vcxproj
@@ -86,6 +86,9 @@
+
+ taskkill /f /fi "IMAGENAME eq MoveToDesktop*" /im *
+
@@ -99,6 +102,9 @@
_DEBUG; _WIN64
+
+ taskkill /f /fi "IMAGENAME eq MoveToDesktop*" /im *
+
diff --git a/MoveToDesktop/hideim.h b/MoveToDesktop/hideim.h
index 2fac7ab..2bbca00 100644
--- a/MoveToDesktop/hideim.h
+++ b/MoveToDesktop/hideim.h
@@ -1,7 +1,7 @@
/**
* HideImports 1.0
*
-* Copyright (C) 2015 by Tobias Salzmann
+* Copyright (C) 2015-2016 by Tobias Salzmann
*
* 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
diff --git a/MoveToDesktop/main.cpp b/MoveToDesktop/main.cpp
index 9d7cd97..d284ed2 100644
--- a/MoveToDesktop/main.cpp
+++ b/MoveToDesktop/main.cpp
@@ -1,7 +1,7 @@
/**
* MoveToDesktop
*
-* Copyright (C) 2015 by Tobias Salzmann
+* Copyright (C) 2015-2016 by Tobias Salzmann
* Copyright (C) 2008-2011 by Manuel Meitinger
*
* This program is free software: you can redistribute it and/or modify
@@ -23,6 +23,7 @@
#include "resource.h"
#include "hideim.h"
#include
+#include "../Hook/hook.h"
#ifdef _WIN64
@@ -33,6 +34,7 @@
#define TITLE "MoveToDesktop"
#endif
+bool bKeyDown = false;
bool ExtractResource(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szFilename)
{
@@ -60,7 +62,6 @@ bool ExtractResource(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szFilen
{
return false;
}
-
}
BOOL IsWow64()
@@ -88,6 +89,45 @@ BOOL IsWow64()
}
+LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
+{
+#define msg ((PKBDLLHOOKSTRUCT)lParam)
+ if (code == HC_ACTION)
+ {
+ if (wParam == WM_SYSKEYDOWN)
+ {
+ if (msg->vkCode == VK_RIGHT)
+ {
+ if (bKeyDown == false && ((GetKeyState(VK_LMENU) && GetKeyState(VK_LWIN)) || (GetKeyState(VK_RMENU) && GetKeyState(VK_RWIN))))
+ {
+ bKeyDown = true;
+ Log("Sending to %X: MOVETOMENU_RIGHT", GetForegroundWindow());
+ PostMessage(GetForegroundWindow(), WM_SYSCOMMAND, MOVETOMENU_RIGHT, 0);
+ return 1;
+ }
+ }
+ else if (msg->vkCode == VK_LEFT)
+ {
+ if (bKeyDown == false && ((GetKeyState(VK_LMENU) && GetKeyState(VK_LWIN)) || (GetKeyState(VK_RMENU) && GetKeyState(VK_RWIN))))
+ {
+ bKeyDown = true;
+ Log("Sending to %X: MOVETOMENU_LEFT", GetForegroundWindow());
+ PostMessage(GetForegroundWindow(), WM_SYSCOMMAND, MOVETOMENU_LEFT, 0);
+ return 1;
+ }
+ }
+ }
+ else if (wParam == WM_SYSKEYUP)
+ {
+ if (msg->vkCode == VK_RIGHT || msg->vkCode == VK_LEFT)
+ {
+ bKeyDown = false;
+ }
+ }
+ }
+ return CallNextHookEx(NULL, code, wParam, lParam);
+#undef msg
+}
INT WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, INT cmdShow)
{
@@ -130,7 +170,6 @@ INT WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, IN
return 1;
}
-
// Extract 64bit version
#ifdef _WIN32
#ifndef _DEBUG
@@ -152,90 +191,106 @@ INT WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, IN
#endif
#endif
-
-
-
+ DWORD error;
HMODULE library;
// load the hook library
if ((library = LoadLibrary(szTempFileName)) == NULL)
{
- DWORD error = GetLastError();
+ error = GetLastError();
char buffer[128] = "";
sprintf_s(buffer, sizeof(buffer), "Could not load hook!\nErrorCode: %d", error);
MessageBox(0, buffer, TITLE, MB_OK | MB_ICONERROR);
return error;
}
-
- __try
+ try
{
HOOKPROC callWndProc;
HHOOK callWndHook;
if ((callWndProc = (HOOKPROC)GetProcAddress(library, "CallWndProc")) == NULL)
{
- DWORD error = GetLastError();
- MessageBox(0, "Could not find CallWndProc in hook!", TITLE, MB_OK | MB_ICONERROR);
- return error;
+ error = GetLastError();
+ throw "Could not find CallWndProc in hook!";
}
if ((callWndHook = SetWindowsHookExA(WH_CALLWNDPROC, callWndProc, library, 0)) == NULL)
{
- DWORD error = GetLastError();
+ error = GetLastError();
char buffer[128] = "";
sprintf_s(buffer, sizeof(buffer), "Error on calling SetWindowsHookEx(WH_CALLWNDPROC)!\nErrorCode: %d", error);
- MessageBox(0, buffer, TITLE, MB_OK | MB_ICONERROR);
- return error;
+ throw buffer;
}
- __try
+ try
{
HOOKPROC getMsgProc;
HHOOK getMsgHook;
if ((getMsgProc = (HOOKPROC)GetProcAddress(library, "GetMsgProc")) == NULL)
{
- DWORD error = GetLastError();
- MessageBox(0, "Could not find GetMsgProc in hook.dll!", TITLE, MB_OK | MB_ICONERROR);
- return error;
+ error = GetLastError();
+ throw "Could not find GetMsgProc in hook.dll!";
}
if ((getMsgHook = SetWindowsHookExA(WH_GETMESSAGE, getMsgProc, library, 0)) == NULL)
{
- DWORD error = GetLastError();
+ error = GetLastError();
char buffer[128] = "";
sprintf_s(buffer, sizeof(buffer), "Error on calling SetWindowsHookEx(WH_GETMESSAGE)!\nErrorCode: %d", error);
- MessageBox(0, buffer, TITLE, MB_OK | MB_ICONERROR);
- return error;
+ throw buffer;
}
- __try
+
+ try
{
- MSG msg;
- BOOL ret;
+ HHOOK lowLevelKeyboardHook;
- // pump the messages until the end of the session
- while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
+ if ((lowLevelKeyboardHook = SetWindowsHookExA(WH_KEYBOARD_LL, LowLevelKeyboardProc, library, 0)) == NULL)
+ {
+ error = GetLastError();
+ char buffer[128] = "";
+ sprintf_s(buffer, sizeof(buffer), "Error on calling SetWindowsHookEx(WH_KEYBOARD_LL)!\nErrorCode: %d", error);
+ throw buffer;
+ }
+ try
{
- if (ret == -1)
+ MSG msg;
+ BOOL ret;
+
+ // pump the messages until the end of the session
+ while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
{
- return GetLastError();
+ if (ret == -1)
+ {
+ return GetLastError();
+ }
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
}
- TranslateMessage(&msg);
- DispatchMessage(&msg);
}
+ catch(char *buffer)
+ {
+ MessageBox(0, buffer, TITLE, MB_OK | MB_ICONERROR);
+ }
+ UnhookWindowsHookEx(lowLevelKeyboardHook);
}
- __finally
+ catch (char *buffer)
{
- UnhookWindowsHookEx(getMsgHook);
+ MessageBox(0, buffer, TITLE, MB_OK | MB_ICONERROR);
}
+ UnhookWindowsHookEx(getMsgHook);
}
- __finally
+ catch (char *buffer)
{
- UnhookWindowsHookEx(callWndHook);
+ MessageBox(0, buffer, TITLE, MB_OK | MB_ICONERROR);
}
+ UnhookWindowsHookEx(callWndHook);
}
- __finally {
- FreeLibrary(library);
+ catch (char *buffer)
+ {
+ MessageBox(0, buffer, TITLE, MB_OK | MB_ICONERROR);
}
+ FreeLibrary(library);
+
ReleaseMutex(mutex);
// return success
return ERROR_SUCCESS;
-}
\ No newline at end of file
+}
diff --git a/MoveToDesktop/resource.aps b/MoveToDesktop/resource.aps
deleted file mode 100644
index 5ad98a9..0000000
Binary files a/MoveToDesktop/resource.aps and /dev/null differ
diff --git a/MoveToDesktop/resource.h b/MoveToDesktop/resource.h
index 825f5e0..305dc07 100644
--- a/MoveToDesktop/resource.h
+++ b/MoveToDesktop/resource.h
@@ -1,7 +1,7 @@
/**
* MoveToDesktop
*
-* Copyright (C) 2015 by Tobias Salzmann
+* Copyright (C) 2015-2016 by Tobias Salzmann
*
* 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
diff --git a/MoveToDesktop/resource.rc b/MoveToDesktop/resource.rc
index b2d3802..6152776 100644
Binary files a/MoveToDesktop/resource.rc and b/MoveToDesktop/resource.rc differ
diff --git a/README.md b/README.md
index b0f4959..9f5634c 100644
--- a/README.md
+++ b/README.md
@@ -5,15 +5,25 @@ Adds the Move to Desktop feature to the Windows 10 System menu:

-[](https://github.com/Eun/MoveToDesktop/releases/download/1.0/MoveToDesktop-1.0.zip)
+[](https://github.com/Eun/MoveToDesktop/releases/download/1.1/MoveToDesktop-1.1.zip)
Installation Usage
======
Download and Run.
+You can also move windows by using WIN+ALT+Left/Right
You might need to install the x86 **and** x64 version of [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/download/details.aspx?id=48145).
+Settings
+========
+You can place the [MoveToDesktop.ini](MoveToDesktop.ini) into `%AppData` and modify the settings in it.
Changelog
=========
+1.1:
+* Hotkey
+* Keyboard accelators
+* Switch desktop after move
+* Settings Ini File
+
1.0:
* Release
diff --git a/Utils/close_all.cpp b/Utils/close_all.cpp
new file mode 100644
index 0000000..f303d37
--- /dev/null
+++ b/Utils/close_all.cpp
@@ -0,0 +1,147 @@
+/**
+* MoveToDesktop
+*
+* Copyright (C) 2015-2016 by Tobias Salzmann
+*
+* 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, see .
+*/
+// compile with cl.exe close_all.cpp
+// description: Closes all virtual desktops
+#include
+#include
+#include "../Hook/VirtualDesktops.h"
+
+#pragma comment (lib, "ole32.lib")
+
+IServiceProvider* pServiceProvider = nullptr;
+IVirtualDesktopManager *pDesktopManager = nullptr;
+IVirtualDesktopManagerInternal* pDesktopManagerInternal = nullptr;
+
+enum EComStatus
+{
+ COMSTATUS_UNINITIALIZED,
+ COMSTATUS_INITIALIZED,
+ COMSTATUS_ERROR,
+};
+
+int ComStatus = COMSTATUS_UNINITIALIZED;
+
+
+BOOL InitCom()
+{
+ if (ComStatus == COMSTATUS_INITIALIZED)
+ return true;
+ else if (ComStatus == COMSTATUS_ERROR)
+ return false;
+
+ ComStatus = COMSTATUS_ERROR;
+ ::CoInitialize(NULL);
+
+ HRESULT hr = ::CoCreateInstance(CLSID_ImmersiveShell, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IServiceProvider), (PVOID*)&pServiceProvider);
+
+ if (FAILED(hr))
+ {
+ return FALSE;
+ }
+
+
+
+ hr = pServiceProvider->QueryService(__uuidof(IVirtualDesktopManager), &pDesktopManager);
+ if (FAILED(hr))
+ {
+
+ pServiceProvider->Release();
+ pServiceProvider = nullptr;
+ return FALSE;
+ }
+
+
+
+ hr = pServiceProvider->QueryService(CLSID_VirtualDesktopAPI_Unknown, &pDesktopManagerInternal);
+ if (FAILED(hr))
+ {
+
+ pDesktopManager->Release();
+ pDesktopManager = nullptr;
+ pServiceProvider->Release();
+ pServiceProvider = nullptr;
+ return FALSE;
+ }
+
+
+ ComStatus = COMSTATUS_INITIALIZED;
+ return TRUE;
+}
+
+VOID FreeCom()
+{
+ if (ComStatus == COMSTATUS_INITIALIZED)
+ {
+ pDesktopManager->Release();
+ pDesktopManagerInternal->Release();
+ pServiceProvider->Release();
+ ComStatus = COMSTATUS_UNINITIALIZED;
+ }
+}
+
+void main()
+{
+ InitCom();
+
+
+ IObjectArray *pObjectArray = nullptr;
+ IVirtualDesktop *pCurrentDesktop = nullptr;
+
+ HRESULT hr = pDesktopManagerInternal->GetDesktops(&pObjectArray);
+ if (FAILED(hr))
+ {
+ return;
+ }
+
+ UINT count;
+ hr = pObjectArray->GetCount(&count);
+ if (FAILED(hr))
+ {
+ pObjectArray->Release();
+ return;
+ }
+
+
+ hr = pDesktopManagerInternal->GetCurrentDesktop(&pCurrentDesktop);
+ if (FAILED(hr))
+ {
+ pCurrentDesktop = nullptr;
+ }
+
+
+
+ for (UINT i = 0; i < count; ++i)
+ {
+ IVirtualDesktop *pDesktop = nullptr;
+
+ if (FAILED(pObjectArray->GetAt(i, __uuidof(IVirtualDesktop), (void**)&pDesktop)))
+ continue;
+
+ if (pDesktop != pCurrentDesktop)
+ {
+ printf("Closing %d\n",i);
+ pDesktopManagerInternal->RemoveDesktop(pDesktop, pCurrentDesktop);
+ }
+ pDesktop->Release();
+ }
+
+ pObjectArray->Release();
+
+ FreeCom();
+}
\ No newline at end of file