Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Win+X handling is hacky #3

Closed
valinet opened this issue Aug 13, 2021 · 0 comments
Closed

Win+X handling is hacky #3

valinet opened this issue Aug 13, 2021 · 0 comments
Labels
enhancement New feature or request fixed

Comments

@valinet
Copy link
Owner

valinet commented Aug 13, 2021

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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed
Projects
None yet
Development

No branches or pull requests

1 participant