| 2372 | } |
| 2373 | |
| 2374 | HRESULT __stdcall CShellExt::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState) |
| 2375 | { |
| 2376 | CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Shell :: GetState\n"); |
| 2377 | *pCmdState = ECS_ENABLED; |
| 2378 | Microsoft::WRL::ComPtr<IShellItemArray> ownItemArray; |
| 2379 | if (m_site) |
| 2380 | { |
| 2381 | Microsoft::WRL::ComPtr<IOleWindow> oleWindow; |
| 2382 | m_site.As(&oleWindow); |
| 2383 | if (oleWindow) |
| 2384 | { |
| 2385 | // We don't want to show the menu on the classic context menu. |
| 2386 | // The classic menu provides an IOleWindow, but the main context |
| 2387 | // menu in Win11 does not, except on the left tree view. |
| 2388 | // So we check the window class name: if it's "NamespaceTreeControl", |
| 2389 | // then we're dealing with the main context menu of the tree view. |
| 2390 | // If it's not, then we're dealing with the classic context menu |
| 2391 | // and there we hide this menu entry. |
| 2392 | HWND hWnd = nullptr; |
| 2393 | oleWindow->GetWindow(&hWnd); |
| 2394 | wchar_t szWndClassName[MAX_PATH] = { 0 }; |
| 2395 | GetClassName(hWnd, szWndClassName, _countof(szWndClassName)); |
| 2396 | if (wcscmp(szWndClassName, L"NamespaceTreeControl")) |
| 2397 | { |
| 2398 | CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Shell :: GetState - hidden\n"); |
| 2399 | *pCmdState = ECS_HIDDEN; |
| 2400 | return S_OK; |
| 2401 | } |
| 2402 | else |
| 2403 | { |
| 2404 | // tree view |
| 2405 | if (!psiItemArray) |
| 2406 | { |
| 2407 | // the shell disables dpi awareness for extensions, so enable them explicitly |
| 2408 | DPI_AWARENESS_CONTEXT context = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); |
| 2409 | Microsoft::WRL::ComPtr<INameSpaceTreeControl> nameSpaceTreeCtrl; |
| 2410 | oleWindow.As(&nameSpaceTreeCtrl); |
| 2411 | if (nameSpaceTreeCtrl) |
| 2412 | { |
| 2413 | // we do a hit test on the tree view to get the right-clicked item. |
| 2414 | // however this only works if the menu shows up due to a right-click. |
| 2415 | // if the menu is shown because of a key press (right windows key), |
| 2416 | // then this will get the wrong item if the mouse pointer is somewhere |
| 2417 | // over the tree view while the key is clicked! |
| 2418 | // if the mouse pointer is NOT over the tree view when the menu is brought up |
| 2419 | // via keyboard, then this works fine. |
| 2420 | auto msgPos = GetMessagePos(); |
| 2421 | POINT msgPoint{}; |
| 2422 | msgPoint.x = GET_X_LPARAM(msgPos); |
| 2423 | msgPoint.y = GET_Y_LPARAM(msgPos); |
| 2424 | POINT pt = msgPoint; |
| 2425 | ScreenToClient(hWnd, &pt); |
| 2426 | Microsoft::WRL::ComPtr<IShellItem> shellItem; |
| 2427 | |
| 2428 | nameSpaceTreeCtrl->HitTest(&pt, &shellItem); |
| 2429 | if (shellItem) |
| 2430 | SHCreateShellItemArrayFromShellItem(shellItem.Get(), IID_IShellItemArray, &ownItemArray); |
| 2431 | else |
no test coverage detected