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; }
HRESULT SwitchVirtualDesktop(IVirtualDesktopManagerInternal *pDesktopManager, bool reverse) { IVirtualDesktop *pCurrentDesktop = nullptr; HRESULT hr = pDesktopManager->GetCurrentDesktop(&pCurrentDesktop); if (SUCCEEDED(hr)) { IVirtualDesktop *pNextDesktop = nullptr; AdjacentDesktop direction = reverse ? AdjacentDesktop::LeftDirection : AdjacentDesktop::RightDirection; hr = pDesktopManager->GetAdjacentDesktop(pCurrentDesktop, direction, &pNextDesktop); if (FAILED(hr)) { IObjectArray *pObjectArray = nullptr; hr = pDesktopManager->GetDesktops(&pObjectArray); if (SUCCEEDED(hr)) { int nextIndex = 0; if (reverse) { UINT count; hr = pObjectArray->GetCount(&count); if (SUCCEEDED(hr)) nextIndex = count - 1; } hr = pObjectArray->GetAt(nextIndex, __uuidof(IVirtualDesktop), (void**)&pNextDesktop); pObjectArray->Release(); } } if (SUCCEEDED(hr)) { hr = pDesktopManager->SwitchDesktop(pNextDesktop); pNextDesktop->Release(); } pCurrentDesktop->Release(); } return hr; }
void HandleSysCommand(WPARAM wParam, HWND hwnd) { if (wParam == MOVETOMENU_NEW) { // abort command, too many commands in a short period of time if (nLastCommand > GetTickCount64()) { return; } 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)) { return; } GUID id; hr = pNewDesktop->GetID(&id); if (SUCCEEDED(hr)) { HWND focusHwnd = NULL; if (!bSwitchDesktopAfterMove) { focusHwnd = hwnd; do { focusHwnd = GetNextWindow(focusHwnd, GW_HWNDNEXT); } while (focusHwnd && EnumWindowsProc(focusHwnd, NULL)); } Log("pDesktopManager->MoveWindowToDesktop(%X, %X)", hwnd, id); hr = pDesktopManager->MoveWindowToDesktop(hwnd, id); if (SUCCEEDED(hr)) { if (bSwitchDesktopAfterMove) { pDesktopManagerInternal->SwitchDesktop(pNewDesktop); } else if (focusHwnd) { SetForegroundWindow(focusHwnd); } } else { Log("Error %d on moving %X to %X", hr, hwnd, id); } } pNewDesktop->Release(); nLastCommand = GetTickCount64() + COMMAND_TIMEOUT; } else if (wParam >= MOVETOMENU_START && wParam <= MOVETOMENU_LAST) { // abort command, too many commands in a short period of time if (nLastCommand > GetTickCount64()) { return; } Log("Getting RootWindow of %X", hwnd); HWND rootHwnd = GetAncestor(hwnd, GA_ROOTOWNER); if (rootHwnd != NULL) { 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; } IVirtualDesktop *pDesktop = nullptr; if (SUCCEEDED(pObjectArray->GetAt((UINT)wParam - MOVETOMENU_START, __uuidof(IVirtualDesktop), (void**)&pDesktop))) { GUID id; hr = pDesktop->GetID(&id); if (SUCCEEDED(hr)) { HWND focusHwnd = NULL; if (!bSwitchDesktopAfterMove) { focusHwnd = hwnd; do { focusHwnd = GetNextWindow(focusHwnd, GW_HWNDNEXT); } while (focusHwnd && EnumWindowsProc(focusHwnd, NULL)); } Log("pDesktopManager->MoveWindowToDesktop(%X, %X)", hwnd, id); hr = pDesktopManager->MoveWindowToDesktop(hwnd, id); if (SUCCEEDED(hr)) { // If there are no windows delete the desktop if (bDeleteEmptyDesktops) { IVirtualDesktop *pCurrentDesktop = nullptr; hr = pDesktopManagerInternal->GetCurrentDesktop(&pCurrentDesktop); if (SUCCEEDED(hr)) { if (pCurrentDesktop != pDesktop) { if (EnumWindows((WNDENUMPROC)EnumWindowsProc, NULL) != FALSE) { Log("Removing Desktop"); pDesktopManagerInternal->RemoveDesktop(pCurrentDesktop, pDesktop); } } pCurrentDesktop->Release(); } } if (bSwitchDesktopAfterMove) { pDesktopManagerInternal->SwitchDesktop(pDesktop); } else if (focusHwnd != NULL) { SetForegroundWindow(focusHwnd); } } else { Log("Error %X on moving %X to %X", hr, hwnd, id); } } pDesktop->Release(); } pObjectArray->Release(); nLastCommand = GetTickCount64() + COMMAND_TIMEOUT; } 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 if (bCreateNewDesktopOnMove) { Log("Create new desktop"); HandleSysCommand(MOVETOMENU_NEW, hwnd); } } }
VOID AddMenu(HWND hwnd, HMENU menu) { if (bAddedMenu == true) return; HMENU systemMenu; if ((systemMenu = GetSystemMenu(hwnd, FALSE)) == NULL) { return; } if (menu != INVALID_HANDLE_VALUE && menu != systemMenu) { return; } bAddedMenu = true; if (!InitCom()) { return; } 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; } MENUITEMINFO MoveToItem = { 0 }; MoveToItem.cbSize = sizeof(MoveToItem); MoveToItem.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | MIIM_STRING; Log("Add MoveToMenu"); MoveToItem.wID = MOVETOMENU_ID; MoveToItem.dwTypeData = TEXT("Move &To"); MoveToItem.hSubMenu = CreateMenu(); InsertMenuItem(systemMenu, SC_CLOSE, FALSE, &MoveToItem); for (UINT i = 0; i < count && i < MAXDESKTOPS; ++i) { IVirtualDesktop *pDesktop = nullptr; if (FAILED(pObjectArray->GetAt(i, __uuidof(IVirtualDesktop), (void**)&pDesktop))) continue; char desktopName[64] = { 0 }; sprintf_s(desktopName, sizeof(desktopName), "Desktop &%d", i + 1); MENUITEMINFO item = { 0 }; item.cbSize = sizeof(item); item.fMask = MIIM_CHECKMARKS | MIIM_STATE | MIIM_ID | MIIM_STRING; item.fState = (pDesktop == pCurrentDesktop) ? MFS_CHECKED : MFS_UNCHECKED; item.wID = MOVETOMENU_START + i; item.dwTypeData = desktopName; InsertMenuItem(MoveToItem.hSubMenu, -1, FALSE, &item); pDesktop->Release(); } // Create 'New Desktop' Item { MENUITEMINFO item = { 0 }; item.cbSize = sizeof(item); item.fMask = MIIM_ID | MIIM_STRING; item.fState = MFS_UNCHECKED; item.wID = MOVETOMENU_NEW; item.dwTypeData = TEXT("&New Desktop"); InsertMenuItem(MoveToItem.hSubMenu, -1, FALSE, &item); } pObjectArray->Release(); if (pCurrentDesktop != nullptr) { pCurrentDesktop->Release(); } }
void wxTaskBarJumpListImpl::LoadKnownCategory(const wxString& title) { IApplicationDocumentLists *docList = 0; HRESULT hr = CoCreateInstance ( wxCLSID_ApplicationDocumentLists, NULL, CLSCTX_INPROC_SERVER, wxIID_IApplicationDocumentLists, reinterpret_cast<void **>(&docList) ); if ( FAILED(hr) ) { wxLogApiError("CoCreateInstance(wxCLSID_ApplicationDocumentLists)", hr); return; } if ( !m_appID.empty() ) docList->SetAppID(m_appID.wc_str()); IObjectArray *array = NULL; wxASSERT_MSG( title == "Recent" || title == "Frequent", "Invalid title." ); hr = docList->GetList ( title == "Recent" ? ADLT_RECENT : ADLT_FREQUENT, 0, wxIID_IObjectArray, reinterpret_cast<void **>(&array) ); if ( FAILED(hr) ) { wxLogApiError("IApplicationDocumentLists::GetList", hr); return; } UINT count = 0; array->GetCount(&count); for (UINT i = 0; i < count; ++i) { IUnknown *collectionItem = NULL; hr = array->GetAt(i, wxIID_IUnknown, reinterpret_cast<void **>(&collectionItem)); if ( FAILED(hr) ) { wxLogApiError("IObjectArray::GetAt", hr); continue; } IShellLink *shellLink = NULL; IShellItem *shellItem = NULL; wxTaskBarJumpListItem* item = NULL; if ( SUCCEEDED(collectionItem->QueryInterface( wxIID_IShellLink, reinterpret_cast<void**>(&shellLink))) ) { item = GetItemFromIShellLink(shellLink); shellLink->Release(); } else if ( SUCCEEDED(collectionItem->QueryInterface( wxIID_IShellItem, reinterpret_cast<void**>(&shellItem))) ) { item = GetItemFromIShellItem(shellItem); shellItem->Release(); } else { wxLogError("Can not query interfaces: IShellLink or IShellItem."); } if ( item ) { if ( title == wxT("Frequent") ) m_frequent->Append(item); else m_recent->Append(item); } collectionItem->Release(); } array->Release(); docList->Release(); }
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)) { return; } GUID id; hr = pNewDesktop->GetID(&id); if (SUCCEEDED(hr)) { 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) { Log("Getting RootWindow of %X", hwnd); HWND rootHwnd = GetAncestor(hwnd, GA_ROOTOWNER); if (rootHwnd != NULL) { 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; } IVirtualDesktop *pDesktop = nullptr; if (SUCCEEDED(pObjectArray->GetAt((UINT)wParam - MOVETOMENU_START, __uuidof(IVirtualDesktop), (void**)&pDesktop))) { GUID id; hr = pDesktop->GetID(&id); if (SUCCEEDED(hr)) { 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); } } }