Как определить, когда открывается меню «Пуск» / стартовый экран Windows?

Как настроить обработчик событий или обратный вызов для открытия меню «Пуск» Windows (или начального экрана Windows 8)?

Или, по крайней мере, как проверить, открыто ли в данный момент меню «Пуск»?

Я предпочитаю решение этой проблемы в C #, но решение в C ++ также высоко ценится.

2

Решение

Очевидно, что функция обратного вызова / события видимости стартового экрана не работает для настольного приложения (см.#ifкод ниже), но простой опрос работает хорошо.

#include <algorithm>        // std::swap
#include <functional>       // std::function
#include <iostream>
#include <stdlib.h>         // EXIT_FAILURE, EXIT_SUCCESS
#include <stdexcept>        // std::runtime_error, std::exception
#include <system_error>     // std::system_error
#include <string>           // std::string
using namespace std;

#include <conio.h>          // _kbhit

#undef UNICODE
#define UNICODE
#include <windows.h>
#include <shobjidl.h>       // IAppVisibilityEvents

auto fail( string const& message, int code = 0 )
-> bool
{ throw system_error( code, system_category(), message ); }

class On_block_exit
{
private:
function<void()>    f_;
public:
~On_block_exit() { f_(); }
On_block_exit( function<void()> f ): f_( f ) {}
};

enum Success { success };

auto operator>>( HRESULT const hr, Success const )
-> bool
{ ::SetLastError( hr );  return SUCCEEDED( hr ); }

template< class Interface >
class Com_ptr
{
private:
Interface*  p_;
public:
Interface* pointer() const { return p_; }
Interface* operator->() const { return p_; }

void** as_out_arg()
{
*this = Com_ptr();
return reinterpret_cast<void**>( &p_ );
}

friend
void swap( Com_ptr& a, Com_ptr& b ) throw()
{ swap( a.p_, b.p_ ); }

void operator=( Com_ptr rhs ) { swap( *this, rhs ); }

~Com_ptr() { if( p_ ) { p_->Release(); } }

Com_ptr( Interface* const p = nullptr ): p_( p ) {}

Com_ptr( Com_ptr const& other )
: p_( other.p_ )
{ if( p_ ) { p_->AddRef(); } }
};

auto is_startscreen_shown( Com_ptr<IAppVisibility> p_app_visibility )
-> bool
{
BOOL    result;
p_app_visibility->IsLauncherVisible( &result )
>> success
|| fail( "IAppVisibility::IsLauncherVisible", ::GetLastError() );
return !!result;
}

template< class Base >
struct With_dummy_iunknown_
: Base
{
ULONG __stdcall AddRef() override { return 0; }

ULONG __stdcall Release() override { return 0; }

HRESULT __stdcall QueryInterface( REFIID riid, void **ppvObject ) override
{
if( riid == IID_IUnknown )
{
*ppvObject = this;
return S_OK;
}
return E_NOINTERFACE;
}
};

void cpp_main()
{
::CoInitialize( nullptr )
>> success
|| fail( "CoInitialize", ::GetLastError() );

Com_ptr<IAppVisibility> p_app_visibility;

::CoCreateInstance(
CLSID_AppVisibility, nullptr, CLSCTX_ALL, IID_IAppVisibility, p_app_visibility.as_out_arg()
) >> success
|| fail( "CoCreateInstance CLSID_AppVisibility IID_IAppVisibility", ::GetLastError() );

cout << "Press the 'Any' key to quit." << endl;
bool was_shown = false; bool first_iteration = true; int n = 0;
for( ;; )
{
if( _kbhit() ) { break; }

bool const is_shown = is_startscreen_shown( p_app_visibility );
if( first_iteration || is_shown != was_shown )
{
cout << n << ": ";
if( is_shown )
{
cout << "Currently showing the start screen" << endl;
}
else
{
cout << "Currently showing normal desktop or app." << endl;
}
++n;
}
first_iteration = false;
was_shown = is_shown;
Sleep( 50 );
}

#if 0
struct Events: IAppVisibilityEvents
{
HRESULT __stdcall AppVisibilityOnMonitorChanged(
HMONITOR                monitor_handle,
MONITOR_APP_VISIBILITY  previous_mode,
MONITOR_APP_VISIBILITY  current_mode
) override
{ return S_OK; }

HRESULT __stdcall LauncherVisibilityChange(
BOOL is_now_visible
) override
{
cout
<< (!!is_now_visible? "Showing the start screen" : "Hiding start screen, showing desktop/app")
<< endl;
return S_OK;
}
};

With_dummy_iunknown_<Events> events;
DWORD cookie = 1;
p_app_visibility->Advise( &events, &cookie )
>> success
|| fail( "IAppVisibility::Advise", ::GetLastError() );
On_block_exit unadvise( [=](){ p_app_visibility->Unadvise( cookie ); } );

::MessageBox( 0, L"Press OK to quit.", L"Watching...", MB_SETFOREGROUND );
#endif
}

auto main()
-> int
{
try
{
cpp_main();
return EXIT_SUCCESS;
}
catch( system_error const& x )
{
cerr << "!" << x.what() << " (code " << x.code().value() << ")" << endl;
}
catch( exception const& x )
{
cerr << "!" << x.what() << endl;
}
return EXIT_FAILURE;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]