Skip to content

Win+X handling is hacky #3

Description

@valinet

Current implementation for handling the Win+X combination works fine but it is hacky. There exists a proper implementation but, unfortunately, it does not work, because the returned pMenu pointer differs on each call and is never what it should be. I don't understand why it happens. Open Shell seems to be able to get the pointer just fine running hooked in Explorer as well.

#include <initguid.h>
#include <Windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

DEFINE_GUID(CLSID_ImmersiveShell,
    0xc2f03a33,
    0x21f5, 0x47fa, 0xb4, 0xbb,
    0x15, 0x63, 0x62, 0xa2, 0xf2, 0x39
);

DEFINE_GUID(SID_IImmersiveMonitorService,
    0x47094e3a,
    0x0cf2, 0x430f, 0x80, 0x6f,
    0xcf, 0x9e, 0x4f, 0x0f, 0x12, 0xdd
);

DEFINE_GUID(IID_IImmersiveMonitorService,
    0x4d4c1e64,
    0xe410, 0x4faa, 0xba, 0xfa,
    0x59, 0xca, 0x06, 0x9b, 0xfe, 0xc2
);

DEFINE_GUID(SID_ImmersiveLauncher,
    0x6f86e01c,
    0xc649, 0x4d61, 0xbe, 0x23,
    0xf1, 0x32, 0x2d, 0xde, 0xca, 0x9d
);

DEFINE_GUID(IID_IImmersiveLauncher10RS,
    0xd8d60399,
    0xa0f1, 0xf987, 0x55, 0x51,
    0x32, 0x1f, 0xd1, 0xb4, 0x98, 0x64
);

typedef interface IImmersiveMonitorService IImmersiveMonitorService;

typedef struct IImmersiveMonitorServiceVtbl
{
    BEGIN_INTERFACE

        HRESULT(STDMETHODCALLTYPE* QueryInterface)(
            IImmersiveMonitorService* This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            _COM_Outptr_  void** ppvObject);

    ULONG(STDMETHODCALLTYPE* AddRef)(
        IImmersiveMonitorService* This);

    ULONG(STDMETHODCALLTYPE* Release)(
        IImmersiveMonitorService* This);

    HRESULT(STDMETHODCALLTYPE* method3)(
        IImmersiveMonitorService* This);

    HRESULT(STDMETHODCALLTYPE* method4)(
        IImmersiveMonitorService* This);

    HRESULT(STDMETHODCALLTYPE* method5)(
        IImmersiveMonitorService* This);

    HRESULT(STDMETHODCALLTYPE* GetFromHandle)(
        IImmersiveMonitorService* This,
        /* [in] */ HMONITOR hMonitor,
        _COM_Outptr_  IUnknown** ppvObject);

    END_INTERFACE
} IImmersiveMonitorServiceVtbl;

interface IImmersiveMonitorService
{
    CONST_VTBL struct IImmersiveMonitorServiceVtbl* lpVtbl;
};

DEFINE_GUID(IID_ILauncherTipContextMenu,
    0xb8c1db5f,
    0xcbb3, 0x48bc, 0xaf, 0xd9,
    0xce, 0x6b, 0x88, 0x0c, 0x79, 0xed
);

typedef interface ILauncherTipContextMenu ILauncherTipContextMenu;

typedef struct ILauncherTipContextMenuVtbl
{
    BEGIN_INTERFACE

        HRESULT(STDMETHODCALLTYPE* QueryInterface)(
            ILauncherTipContextMenu* This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            _COM_Outptr_  void** ppvObject);

    ULONG(STDMETHODCALLTYPE* AddRef)(
        ILauncherTipContextMenu* This);

    ULONG(STDMETHODCALLTYPE* Release)(
        ILauncherTipContextMenu* This);

    HRESULT(STDMETHODCALLTYPE* ShowLauncherTipContextMenu)(
        ILauncherTipContextMenu* This,
        /* [in] */ POINT* pt);

    END_INTERFACE
} ILauncherTipContextMenuVtbl;

interface ILauncherTipContextMenu
{
    CONST_VTBL struct ILauncherTipContextMenuVtbl* lpVtbl;
};

int some_method()
{
    HRESULT hr = S_OK;
    hr = CoInitialize(NULL);
    IUnknown* pImmersiveShell = NULL;
    hr = CoCreateInstance(
        &CLSID_ImmersiveShell,
        NULL,
        CLSCTX_INPROC_SERVER,
        &IID_IServiceProvider,
        &pImmersiveShell
    );
    if (SUCCEEDED(hr))
    {
        printf("b\n");
        IImmersiveMonitorService* pMonitorService = NULL;
        IUnknown_QueryService(
            pImmersiveShell,
            &SID_IImmersiveMonitorService,
            &IID_IImmersiveMonitorService,
            &pMonitorService
        );
        if (pMonitorService)
        {
            printf("c\n");
            DWORD pts = GetMessagePos();
            POINT pt;
            pt.x = GET_X_LPARAM(pts);
            pt.y = GET_Y_LPARAM(pts);
            HMONITOR monitor = MonitorFromPoint(
                pt,
                MONITOR_DEFAULTTONULL
            );
            if (monitor)
            {
                printf("d\n");
                IUnknown* pMonitor = NULL;
                pMonitorService->lpVtbl->GetFromHandle(
                    pMonitorService,
                    monitor,
                    &pMonitor
                );
                if (pMonitor)
                {
                    printf("e\n");
                    ILauncherTipContextMenu* pMenu = NULL;
                    IUnknown_QueryService(
                        pMonitor,
                        &IID_ILauncherTipContextMenu,
                        &IID_ILauncherTipContextMenu,
                        &pMenu
                    );
                    if (pMenu)
                    {
                        printf("f %p\n", pMenu);
                        pMenu->lpVtbl->ShowLauncherTipContextMenu(
                            pMenu,
                            0
                        );
                        pMenu->lpVtbl->Release(pMenu);
                    }
                    pMonitor->lpVtbl->Release(pMonitor);
                }
            }
            pMonitorService->lpVtbl->Release(pMonitorService);
        }
        pImmersiveShell->lpVtbl->Release(pImmersiveShell);
    }
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions