mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-29 12:45:28 -05:00
Compare commits
11 Commits
file-diff
...
virtual-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d381b9ba1 | ||
|
|
d66a2dc408 | ||
|
|
2ac1a226e2 | ||
|
|
f56b0b56a7 | ||
|
|
6c1eb3ffab | ||
|
|
e9d6067db2 | ||
|
|
d691492a31 | ||
|
|
950dfe8688 | ||
|
|
fb38f60609 | ||
|
|
3c283a0818 | ||
|
|
271bbcbe95 |
@@ -108,6 +108,7 @@ set(advanced-scene-switcher_HEADERS
|
|||||||
src/headers/macro-condition-source.hpp
|
src/headers/macro-condition-source.hpp
|
||||||
src/headers/macro-condition-streaming.hpp
|
src/headers/macro-condition-streaming.hpp
|
||||||
src/headers/macro-condition-video.hpp
|
src/headers/macro-condition-video.hpp
|
||||||
|
src/headers/macro-condition-virt-desktop.hpp
|
||||||
src/headers/macro-condition-window.hpp
|
src/headers/macro-condition-window.hpp
|
||||||
src/headers/macro.hpp
|
src/headers/macro.hpp
|
||||||
src/headers/macro-selection.hpp
|
src/headers/macro-selection.hpp
|
||||||
@@ -176,6 +177,7 @@ set(advanced-scene-switcher_SOURCES
|
|||||||
src/macro-condition-source.cpp
|
src/macro-condition-source.cpp
|
||||||
src/macro-condition-streaming.cpp
|
src/macro-condition-streaming.cpp
|
||||||
src/macro-condition-video.cpp
|
src/macro-condition-video.cpp
|
||||||
|
src/macro-condition-virt-desktop.cpp
|
||||||
src/macro-condition-window.cpp
|
src/macro-condition-window.cpp
|
||||||
src/macro.cpp
|
src/macro.cpp
|
||||||
src/macro-selection.cpp
|
src/macro-selection.cpp
|
||||||
|
|||||||
@@ -124,6 +124,10 @@ AdvSceneSwitcher.condition.idle.entry="No keyboard or mouse inputs for {{duratio
|
|||||||
AdvSceneSwitcher.condition.pluginState="Plugin state"
|
AdvSceneSwitcher.condition.pluginState="Plugin state"
|
||||||
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Automated scene change was triggered in this interval"
|
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Automated scene change was triggered in this interval"
|
||||||
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
||||||
|
AdvSceneSwitcher.condition.virtDesktop="Virtual desktop"
|
||||||
|
AdvSceneSwitcher.condition.virtDesktop.notAvailable="Not availbale"
|
||||||
|
AdvSceneSwitcher.condition.virtDesktop.entry.line1="Active virtual desktop is {{virtDesktops}}"
|
||||||
|
AdvSceneSwitcher.condition.virtDesktop.entry.line2="Current: {{currentDesktop}}"
|
||||||
AdvSceneSwitcher.condition.interval="Interval"
|
AdvSceneSwitcher.condition.interval="Interval"
|
||||||
AdvSceneSwitcher.condition.interval.entry="{{duration}} have passed"
|
AdvSceneSwitcher.condition.interval.entry="{{duration}} have passed"
|
||||||
AdvSceneSwitcher.condition.counter="Count"
|
AdvSceneSwitcher.condition.counter="Count"
|
||||||
|
|||||||
51
src/headers/macro-condition-virt-desktop.hpp
Normal file
51
src/headers/macro-condition-virt-desktop.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
class MacroConditionVirtDesktop : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionVirtDesktop>();
|
||||||
|
}
|
||||||
|
long _desktop = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionVirtDesktopEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionVirtDesktopEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionVirtDesktop> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionVirtDesktopEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionVirtDesktop>(
|
||||||
|
cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void DesktopChanged(int value);
|
||||||
|
void UpdateCurrentDesktop();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_virtDesktops;
|
||||||
|
QLabel *_currentDesktop;
|
||||||
|
std::shared_ptr<MacroConditionVirtDesktop> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -9,3 +9,5 @@ std::pair<int, int> getCursorPos();
|
|||||||
int secondsSinceLastInput();
|
int secondsSinceLastInput();
|
||||||
void GetProcessList(QStringList &processes);
|
void GetProcessList(QStringList &processes);
|
||||||
bool isInFocus(const QString &executable);
|
bool isInFocus(const QString &executable);
|
||||||
|
bool GetCurrentVirtualDesktop(long &desktop);
|
||||||
|
bool GetVirtualDesktopCount(long &ndesktops);
|
||||||
|
|||||||
@@ -393,3 +393,67 @@ int secondsSinceLastInput()
|
|||||||
|
|
||||||
return idle_time;
|
return idle_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetCurrentVirtualDesktop(long &desktop)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
long unsigned nitems;
|
||||||
|
long unsigned int bytes = 0;
|
||||||
|
int format = 0;
|
||||||
|
unsigned char *data;
|
||||||
|
Window root;
|
||||||
|
Atom request;
|
||||||
|
Display *display = disp();
|
||||||
|
|
||||||
|
//TODO check for _NET_CURRENT_DESKTOP
|
||||||
|
if (!ewmhIsSupported()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = XInternAtom(display, "_NET_CURRENT_DESKTOP", False);
|
||||||
|
root = XDefaultRootWindow(display);
|
||||||
|
|
||||||
|
int status = XGetWindowProperty(display, root, request, 0L, 1L, false,
|
||||||
|
XA_CARDINAL, &type, &format, &nitems,
|
||||||
|
&bytes, &data);
|
||||||
|
|
||||||
|
if (status == Success && nitems > 0) {
|
||||||
|
desktop = *((long *)data);
|
||||||
|
} else {
|
||||||
|
desktop = -1;
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
return desktop != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetVirtualDesktopCount(long &ndesktops)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
long unsigned nitems;
|
||||||
|
long unsigned int bytes = 0;
|
||||||
|
int format = 0;
|
||||||
|
unsigned char *data;
|
||||||
|
Window root;
|
||||||
|
Atom request;
|
||||||
|
Display *display = disp();
|
||||||
|
|
||||||
|
//TODO check for _NET_NUMBER_OF_DESKTOPS
|
||||||
|
if (!ewmhIsSupported()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = XInternAtom(display, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||||
|
root = XDefaultRootWindow(display);
|
||||||
|
|
||||||
|
int status = XGetWindowProperty(display, root, request, 0L, 1L, false,
|
||||||
|
XA_CARDINAL, &type, &format, &nitems,
|
||||||
|
&bytes, &data);
|
||||||
|
|
||||||
|
if (status == Success && nitems > 0) {
|
||||||
|
ndesktops = *((long *)data);
|
||||||
|
} else {
|
||||||
|
ndesktops = 0;
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
return ndesktops != 0;
|
||||||
|
}
|
||||||
|
|||||||
113
src/macro-condition-virt-desktop.cpp
Normal file
113
src/macro-condition-virt-desktop.cpp
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
#include "headers/macro-condition-edit.hpp"
|
||||||
|
#include "headers/macro-condition-virt-desktop.hpp"
|
||||||
|
#include "headers/utility.hpp"
|
||||||
|
#include "headers/advanced-scene-switcher.hpp"
|
||||||
|
|
||||||
|
const std::string MacroConditionVirtDesktop::id = "virtual_desktop";
|
||||||
|
|
||||||
|
bool MacroConditionVirtDesktop::_registered = MacroConditionFactory::Register(
|
||||||
|
MacroConditionVirtDesktop::id,
|
||||||
|
{MacroConditionVirtDesktop::Create,
|
||||||
|
MacroConditionVirtDesktopEdit::Create,
|
||||||
|
"AdvSceneSwitcher.condition.virtDesktop"});
|
||||||
|
|
||||||
|
bool MacroConditionVirtDesktop::CheckCondition()
|
||||||
|
{
|
||||||
|
long curDesktop;
|
||||||
|
GetCurrentVirtualDesktop(curDesktop);
|
||||||
|
return _desktop == curDesktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionVirtDesktop::Save(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
MacroCondition::Save(obj);
|
||||||
|
obs_data_set_int(obj, "desktop", static_cast<int>(_desktop));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionVirtDesktop::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
MacroCondition::Load(obj);
|
||||||
|
_desktop = obs_data_get_int(obj, "desktop");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void populateVirtualDesktopSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
long count;
|
||||||
|
GetVirtualDesktopCount(count);
|
||||||
|
|
||||||
|
for (long i = 0; i < count; i++) {
|
||||||
|
list->addItem(std::to_string(i).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroConditionVirtDesktopEdit::MacroConditionVirtDesktopEdit(
|
||||||
|
QWidget *parent, std::shared_ptr<MacroConditionVirtDesktop> entryData)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
_currentDesktop = new QLabel();
|
||||||
|
_currentDesktop->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
|
_virtDesktops = new QComboBox();
|
||||||
|
QWidget::connect(_virtDesktops, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(DesktopChanged(int)));
|
||||||
|
populateVirtualDesktopSelection(_virtDesktops);
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
|
QHBoxLayout *line1Layout = new QHBoxLayout;
|
||||||
|
QHBoxLayout *line2Layout = new QHBoxLayout;
|
||||||
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
|
{"{{virtDesktops}}", _virtDesktops},
|
||||||
|
{"{{currentDesktop}}", _currentDesktop},
|
||||||
|
};
|
||||||
|
placeWidgets(
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.virtDesktop.entry.line1"),
|
||||||
|
line1Layout, widgetPlaceholders);
|
||||||
|
placeWidgets(
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.virtDesktop.entry.line2"),
|
||||||
|
line2Layout, widgetPlaceholders);
|
||||||
|
mainLayout->addLayout(line1Layout);
|
||||||
|
mainLayout->addLayout(line2Layout);
|
||||||
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
// Current virtual desktop position
|
||||||
|
QTimer *timer = new QTimer(this);
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(UpdateCurrentDesktop()));
|
||||||
|
timer->start(1000);
|
||||||
|
|
||||||
|
_entryData = entryData;
|
||||||
|
UpdateEntryData();
|
||||||
|
_loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionVirtDesktopEdit::DesktopChanged(int value)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
|
_entryData->_desktop = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionVirtDesktopEdit::UpdateEntryData()
|
||||||
|
{
|
||||||
|
if (!_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_virtDesktops->setCurrentIndex(_entryData->_desktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionVirtDesktopEdit::UpdateCurrentDesktop()
|
||||||
|
{
|
||||||
|
long curDesktop;
|
||||||
|
if (GetCurrentVirtualDesktop(curDesktop)) {
|
||||||
|
_currentDesktop->setText(QString::number(curDesktop));
|
||||||
|
} else {
|
||||||
|
_currentDesktop->setText(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.virtDesktop.notAvailable"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -281,3 +281,13 @@ bool isInFocus(const QString &executable)
|
|||||||
|
|
||||||
return (equals || matches);
|
return (equals || matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetCurrentVirtualDesktop(long &desktop)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetVirtualDesktopCount(long &ndesktops)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <objectarray.h>
|
||||||
|
#include <shobjidl_core.h>
|
||||||
#include <util/platform.h>
|
#include <util/platform.h>
|
||||||
#include <TlHelp32.h>
|
#include <TlHelp32.h>
|
||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
@@ -11,6 +13,7 @@
|
|||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
#define MAX_SEARCH 1000
|
#define MAX_SEARCH 1000
|
||||||
|
#define MAXDESKTOPS 255
|
||||||
|
|
||||||
static bool GetWindowTitle(HWND window, std::string &title)
|
static bool GetWindowTitle(HWND window, std::string &title)
|
||||||
{
|
{
|
||||||
@@ -285,3 +288,265 @@ int secondsSinceLastInput()
|
|||||||
{
|
{
|
||||||
return (getTime() - getLastInputTime()) / 1000;
|
return (getTime() - getLastInputTime()) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Virtual Desktop code
|
||||||
|
// based on https://github.com/Eun/MoveToDesktop/
|
||||||
|
//
|
||||||
|
// TODO:
|
||||||
|
// - clean up
|
||||||
|
// - call FreeCom() on exit
|
||||||
|
|
||||||
|
struct IApplicationView : public IUnknown {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
MIDL_INTERFACE("FF72FFDD-BE7E-43FC-9C03-AD81681E88E4")
|
||||||
|
IVirtualDesktop : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE IsViewVisible(
|
||||||
|
IApplicationView * pView, int *pfVisible) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetID(GUID * pGuid) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IVirtualDesktopManagerInternal : public IUnknown {
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetCount(UINT *pCount) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE MoveViewToDesktop(
|
||||||
|
IApplicationView *pView, IVirtualDesktop *pDesktop) = 0;
|
||||||
|
|
||||||
|
// 10240
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE CanViewMoveDesktops(
|
||||||
|
IApplicationView *pView, int *pfCanViewMoveDesktops) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE
|
||||||
|
GetCurrentDesktop(IVirtualDesktop **desktop) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE
|
||||||
|
GetDesktops(IObjectArray **ppDesktops) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE
|
||||||
|
SwitchDesktop(IVirtualDesktop *pDesktop) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE
|
||||||
|
CreateDesktopW(IVirtualDesktop **ppNewDesktop) = 0;
|
||||||
|
|
||||||
|
// pFallbackDesktop - ??????? ???? ?? ??????? ????? ???????? ??????? ????? ???????? ??????????
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE
|
||||||
|
RemoveDesktop(IVirtualDesktop *pRemove,
|
||||||
|
IVirtualDesktop *pFallbackDesktop) = 0;
|
||||||
|
|
||||||
|
// 10240
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE
|
||||||
|
FindDesktop(GUID *desktopId, IVirtualDesktop **ppDesktop) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
IServiceProvider *pServiceProvider = nullptr;
|
||||||
|
IVirtualDesktopManager *pDesktopManager = nullptr;
|
||||||
|
IVirtualDesktopManagerInternal *pDesktopManagerInternal = nullptr;
|
||||||
|
|
||||||
|
const CLSID CLSID_ImmersiveShell = {0xC2F03A33, 0x21F5, 0x47FA, 0xB4,
|
||||||
|
0xBB, 0x15, 0x63, 0x62,
|
||||||
|
0xA2, 0xF2, 0x39};
|
||||||
|
|
||||||
|
const CLSID CLSID_VirtualDesktopAPI_Unknown = {0xC5E0CDCA, 0x7B6E, 0x41B2, 0x9F,
|
||||||
|
0xC4, 0xD9, 0x39, 0x75,
|
||||||
|
0xCC, 0x46, 0x7B};
|
||||||
|
|
||||||
|
const IID IID_IVirtualDesktopManagerInternal = {0xEF9F1A6C, 0xD3CC, 0x4358,
|
||||||
|
0xB7, 0x12, 0xF8,
|
||||||
|
0x4B, 0x63, 0x5B,
|
||||||
|
0xEB, 0xE7};
|
||||||
|
|
||||||
|
const IID UUID_IVirtualDesktopManagerInternal_10130{0xEF9F1A6C, 0xD3CC, 0x4358,
|
||||||
|
0xB7, 0x12, 0xF8,
|
||||||
|
0x4B, 0x63, 0x5B,
|
||||||
|
0xEB, 0xE7};
|
||||||
|
const IID UUID_IVirtualDesktopManagerInternal_10240{0xAF8DA486, 0x95BB, 0x4460,
|
||||||
|
0xB3, 0xB7, 0x6E,
|
||||||
|
0x7A, 0x6B, 0x29,
|
||||||
|
0x62, 0xB5};
|
||||||
|
const IID UUID_IVirtualDesktopManagerInternal_14393{0xf31574d6, 0xb682, 0x4cdc,
|
||||||
|
0xbd, 0x56, 0x18,
|
||||||
|
0x27, 0x86, 0x0a,
|
||||||
|
0xbe, 0xc6};
|
||||||
|
|
||||||
|
enum EComStatus {
|
||||||
|
COMSTATUS_UNINITIALIZED,
|
||||||
|
COMSTATUS_INITIALIZED,
|
||||||
|
COMSTATUS_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
int ComStatus = COMSTATUS_UNINITIALIZED;
|
||||||
|
#define COMMAND_TIMEOUT 500 // Blocks Command below this timeout
|
||||||
|
bool bAddedMenu = false;
|
||||||
|
bool bReadIni = false;
|
||||||
|
bool bSwitchDesktopAfterMove = false;
|
||||||
|
bool bCreateNewDesktopOnMove = false;
|
||||||
|
bool bDeleteEmptyDesktops = true;
|
||||||
|
ULONGLONG nLastCommand = 0;
|
||||||
|
|
||||||
|
UINT16 GetWinBuildNumber()
|
||||||
|
{
|
||||||
|
UINT16 buildNumbers[] = {10130, 10240, 14393};
|
||||||
|
OSVERSIONINFOEXW osvi = {sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0};
|
||||||
|
ULONGLONG mask = ::VerSetConditionMask(0, VER_BUILDNUMBER, VER_EQUAL);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(buildNumbers) / sizeof(buildNumbers[0]);
|
||||||
|
i++) {
|
||||||
|
osvi.dwBuildNumber = buildNumbers[i];
|
||||||
|
if (VerifyVersionInfoW(&osvi, VER_BUILDNUMBER, mask) != FALSE) {
|
||||||
|
return buildNumbers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL InitCom()
|
||||||
|
{
|
||||||
|
if (ComStatus == COMSTATUS_INITIALIZED) {
|
||||||
|
return true;
|
||||||
|
} else if (ComStatus == COMSTATUS_ERROR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComStatus = COMSTATUS_ERROR;
|
||||||
|
HRESULT hr = ::CoInitialize(NULL);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT16 buildNumber = GetWinBuildNumber();
|
||||||
|
|
||||||
|
switch (buildNumber) {
|
||||||
|
case 10130:
|
||||||
|
hr = pServiceProvider->QueryService(
|
||||||
|
CLSID_VirtualDesktopAPI_Unknown,
|
||||||
|
UUID_IVirtualDesktopManagerInternal_10130,
|
||||||
|
(void **)&pDesktopManagerInternal);
|
||||||
|
break;
|
||||||
|
case 10240:
|
||||||
|
hr = pServiceProvider->QueryService(
|
||||||
|
CLSID_VirtualDesktopAPI_Unknown,
|
||||||
|
UUID_IVirtualDesktopManagerInternal_10240,
|
||||||
|
(void **)&pDesktopManagerInternal);
|
||||||
|
break;
|
||||||
|
case 14393:
|
||||||
|
default:
|
||||||
|
hr = pServiceProvider->QueryService(
|
||||||
|
CLSID_VirtualDesktopAPI_Unknown,
|
||||||
|
UUID_IVirtualDesktopManagerInternal_14393,
|
||||||
|
(void **)&pDesktopManagerInternal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetCurrentVirtualDesktop(long &desktop)
|
||||||
|
{
|
||||||
|
UINT count = 0;
|
||||||
|
IObjectArray *pObjectArray = nullptr;
|
||||||
|
IVirtualDesktop *pCurrentDesktop = nullptr;
|
||||||
|
|
||||||
|
if (!InitCom()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr = pDesktopManagerInternal->GetDesktops(&pObjectArray);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pObjectArray->GetCount(&count);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
pObjectArray->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pDesktopManagerInternal->GetCurrentDesktop(&pCurrentDesktop);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
pObjectArray->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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 = i;
|
||||||
|
}
|
||||||
|
pDesktop->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
pObjectArray->Release();
|
||||||
|
|
||||||
|
if (pCurrentDesktop != nullptr) {
|
||||||
|
pCurrentDesktop->Release();
|
||||||
|
}
|
||||||
|
desktop = index;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetVirtualDesktopCount(long &ndesktops)
|
||||||
|
{
|
||||||
|
if (!InitCom()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
IObjectArray *pObjectArray = nullptr;
|
||||||
|
HRESULT hr = pDesktopManagerInternal->GetDesktops(&pObjectArray);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT count;
|
||||||
|
hr = pObjectArray->GetCount(&count);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
pObjectArray->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pObjectArray->Release();
|
||||||
|
ndesktops = count;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user