Compare commits

...

9 commits

Author SHA1 Message Date
SeraphimaZ 7711a336db removed code for debugging 2021-11-17 12:51:38 +03:00
SeraphimaZ 81018fc84b spell check 2021-11-17 12:04:28 +03:00
SeraphimaZ 7704f153f4 order windows 2021-11-17 11:46:23 +03:00
SeraphimaZ 0c60d64b09 game mode check 2021-11-17 11:24:33 +03:00
SeraphimaZ 4d888627e8 start tracking already topmost on start 2021-11-16 23:27:40 +03:00
SeraphimaZ 82cba89f7d play sound 2021-11-16 22:55:37 +03:00
SeraphimaZ 2695fefaee ctrl + T 2021-11-12 21:20:40 +03:00
SeraphimaZ 0dd4540405 several topmost windows 2021-11-12 21:20:30 +03:00
SeraphimaZ 74614c476c proof of concept 2021-11-10 00:17:44 +03:00
10 changed files with 622 additions and 0 deletions

View file

@ -1309,6 +1309,7 @@ mlcfg
mmdeviceapi
mmi
mmsys
mmsystem
mockapi
MODECHANGE
moderncop
@ -1472,6 +1473,7 @@ NOTIFYICONDATAW
NOTIMPL
notmatch
Noto
NOTOPMOST
NOTRACK
NOUPDATE
NOZORDER
@ -2078,6 +2080,7 @@ svgpreviewhandler
SWC
SWFO
Switchbetweenvirtualdesktops
SWITCHEND
SWP
swprintf
SWRESTORE
@ -2098,6 +2101,7 @@ SYSKEYUP
syslog
SYSMENU
systemd
SYSTEMASTERISK
SYSTEMTIME
systray
Tadele
@ -2402,6 +2406,7 @@ Winhook
winkey
WINL
winmd
winmm
winnt
winres
winrt

View file

@ -0,0 +1,245 @@
#include "pch.h"
#include "AlwaysOnTop.h"
#include <mmsystem.h> // sound
#include <shellapi.h> // game mode
const static wchar_t* HOTKEY_WINDOW_CLASS_NAME = L"HotkeyHandleWindowClass";
// common
extern "C" IMAGE_DOS_HEADER __ImageBase;
// common
inline bool detect_game_mode()
{
QUERY_USER_NOTIFICATION_STATE notification_state;
if (SHQueryUserNotificationState(&notification_state) != S_OK)
{
return false;
}
return (notification_state == QUNS_RUNNING_D3D_FULL_SCREEN);
}
AlwaysOnTop::AlwaysOnTop()
{
s_instance = this;
Init();
StartTrackingTopmostWindows();
}
AlwaysOnTop::~AlwaysOnTop()
{
CleanUp();
}
void AlwaysOnTop::Init()
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
WNDCLASSEXW wcex{};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = WndProc_Helper;
wcex.hInstance = hinstance;
wcex.lpszClassName = HOTKEY_WINDOW_CLASS_NAME;
RegisterClassExW(&wcex);
m_hotKeyHandleWindow = CreateWindowExW(WS_EX_TOOLWINDOW, HOTKEY_WINDOW_CLASS_NAME, L"", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, hinstance, this);
if (!m_hotKeyHandleWindow) {
return;
}
RegisterHotKey(m_hotKeyHandleWindow, 1, MOD_CONTROL | MOD_NOREPEAT, 0x54 /* T */);
// subscribe to windows events
std::array<DWORD, 3> events_to_subscribe = {
EVENT_SYSTEM_MOVESIZEEND,
EVENT_SYSTEM_SWITCHEND,
EVENT_OBJECT_FOCUS
};
for (const auto event : events_to_subscribe)
{
auto hook = SetWinEventHook(event, event, nullptr, WinHookProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
if (hook)
{
m_staticWinEventHooks.emplace_back(hook);
}
else
{
MessageBoxW(NULL, L"Failed to set win event hook", L"AlwaysOnTop error", MB_OK | MB_ICONERROR);
}
}
}
LRESULT AlwaysOnTop::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept
{
if (message == WM_HOTKEY)
{
if (HWND fw{ GetForegroundWindow() })
{
ProcessCommand(fw);
}
}
return 0;
}
void AlwaysOnTop::ProcessCommand(HWND window)
{
bool gameMode = detect_game_mode();
if (!m_activateInGameMode && gameMode)
{
return;
}
bool topmost = IsTopmost(window);
if (topmost)
{
if (ResetTopmostWindow(window))
{
auto iter = std::find(m_topmostWindows.begin(), m_topmostWindows.end(), window);
if (iter != m_topmostWindows.end())
{
m_topmostWindows.erase(iter);
}
}
}
else
{
if (SetTopmostWindow(window))
{
m_topmostWindows.insert(m_topmostWindows.begin(), window);
OrderWindows();
}
}
auto soundPlayed = PlaySound((LPCTSTR)SND_ALIAS_SYSTEMASTERISK, NULL, SND_ALIAS_ID);
if (!soundPlayed)
{
MessageBoxW(NULL, L"Sound playing error", L"AlwaysOnTop error", MB_OK | MB_ICONERROR);
}
}
void AlwaysOnTop::StartTrackingTopmostWindows()
{
using result_t = std::vector<HWND>;
result_t result;
auto enumWindows = [](HWND hwnd, LPARAM param) -> BOOL {
if (!IsWindowVisible(hwnd))
{
return TRUE;
}
auto windowName = GetWindowTextLength(hwnd);
if (windowName > 0)
{
result_t& result = *reinterpret_cast<result_t*>(param);
result.push_back(hwnd);
}
return TRUE;
};
EnumWindows(enumWindows, reinterpret_cast<LPARAM>(&result));
for (HWND window : result)
{
if (IsTopmost(window))
{
m_topmostWindows.push_back(window);
}
}
OrderWindows();
}
void AlwaysOnTop::ResetAll()
{
for (HWND topWindow : m_topmostWindows)
{
if (!ResetTopmostWindow(topWindow))
{
//TODO: log error
}
}
m_topmostWindows.clear();
}
void AlwaysOnTop::CleanUp()
{
ResetAll();
if (m_hotKeyHandleWindow)
{
DestroyWindow(m_hotKeyHandleWindow);
m_hotKeyHandleWindow = nullptr;
}
UnregisterClass(HOTKEY_WINDOW_CLASS_NAME, reinterpret_cast<HINSTANCE>(&__ImageBase));
}
bool AlwaysOnTop::OrderWindows() const noexcept
{
if (m_topmostWindows.empty())
{
return true;
}
BOOL res = true;
for (int i = static_cast<int>(m_topmostWindows.size()) - 1; i >= 0; i--)
{
res &= SetWindowPos(m_topmostWindows[i], nullptr, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
if (!res)
{
MessageBoxW(NULL, L"Failed to order windows", L"AlwaysOnTop error", MB_OK | MB_ICONERROR);
}
}
return res;
}
bool AlwaysOnTop::IsTopmost(HWND window) const noexcept
{
int exStyle = GetWindowLong(window, GWL_EXSTYLE);
return (exStyle & WS_EX_TOPMOST) == WS_EX_TOPMOST;
}
bool AlwaysOnTop::SetTopmostWindow(HWND window) const noexcept
{
return SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
bool AlwaysOnTop::ResetTopmostWindow(HWND window) const noexcept
{
return SetWindowPos(window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
bool AlwaysOnTop::IsTracked(HWND window) const noexcept
{
for (HWND topmostWindow : m_topmostWindows)
{
if (window == topmostWindow)
{
return true;
}
}
return false;
}
void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
{
switch (data->event)
{
case EVENT_SYSTEM_MOVESIZEEND: // moved or resized
case EVENT_SYSTEM_SWITCHEND: // alt-tab
case EVENT_OBJECT_FOCUS: // focused
{
if (IsTracked(data->hwnd))
{
OrderWindows();
}
}
break;
default:
break;
}
}

View file

@ -0,0 +1,78 @@
#pragma once
// common
struct WinHookEvent
{
DWORD event;
HWND hwnd;
LONG idObject;
LONG idChild;
DWORD idEventThread;
DWORD dwmsEventTime;
};
class AlwaysOnTop
{
public:
AlwaysOnTop();
~AlwaysOnTop();
void Init();
protected:
static LRESULT CALLBACK WndProc_Helper(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept
{
auto thisRef = reinterpret_cast<AlwaysOnTop*>(GetWindowLongPtr(window, GWLP_USERDATA));
if (!thisRef && (message == WM_CREATE))
{
const auto createStruct = reinterpret_cast<LPCREATESTRUCT>(lparam);
thisRef = reinterpret_cast<AlwaysOnTop*>(createStruct->lpCreateParams);
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(thisRef));
}
return thisRef ? thisRef->WndProc(window, message, wparam, lparam) :
DefWindowProc(window, message, wparam, lparam);
}
private:
static inline AlwaysOnTop* s_instance = nullptr;
std::vector<HWINEVENTHOOK> m_staticWinEventHooks;
HWND m_hotKeyHandleWindow{ nullptr };
std::vector<HWND> m_topmostWindows;
bool m_activateInGameMode = false;
LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
void ProcessCommand(HWND window);
void StartTrackingTopmostWindows();
void ResetAll();
void CleanUp();
bool OrderWindows() const noexcept;
bool IsTopmost(HWND window) const noexcept;
bool SetTopmostWindow(HWND window) const noexcept;
bool ResetTopmostWindow(HWND window) const noexcept;
bool IsTracked(HWND window) const noexcept;
void HandleWinHookEvent(WinHookEvent* data) noexcept;
static void CALLBACK WinHookProc(HWINEVENTHOOK winEventHook,
DWORD event,
HWND window,
LONG object,
LONG child,
DWORD eventThread,
DWORD eventTime)
{
WinHookEvent data{ event, window, object, child, eventThread, eventTime };
if (s_instance)
{
s_instance->HandleWinHookEvent(&data);
}
}
};

View file

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31424.327
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlwaysOnTop", "AlwaysOnTop.vcxproj", "{24992310-6878-43B7-A01B-B8504A119B77}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{24992310-6878-43B7-A01B-B8504A119B77}.Debug|x64.ActiveCfg = Debug|x64
{24992310-6878-43B7-A01B-B8504A119B77}.Debug|x64.Build.0 = Debug|x64
{24992310-6878-43B7-A01B-B8504A119B77}.Debug|x86.ActiveCfg = Debug|Win32
{24992310-6878-43B7-A01B-B8504A119B77}.Debug|x86.Build.0 = Debug|Win32
{24992310-6878-43B7-A01B-B8504A119B77}.Release|x64.ActiveCfg = Release|x64
{24992310-6878-43B7-A01B-B8504A119B77}.Release|x64.Build.0 = Release|x64
{24992310-6878-43B7-A01B-B8504A119B77}.Release|x86.ActiveCfg = Release|Win32
{24992310-6878-43B7-A01B-B8504A119B77}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5941BFF2-F97E-4BA8-A663-F5861673B0A4}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{24992310-6878-43b7-a01b-b8504a119b77}</ProjectGuid>
<RootNamespace>AlwaysOnTop</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="AlwaysOnTop.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlwaysOnTop.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Windows.CppWinRT.2.0.211028.7\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AlwaysOnTop.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="AlwaysOnTop.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,38 @@
#include "pch.h"
#include "AlwaysOnTop.h"
inline int run_message_loop(const bool until_idle = false, const std::optional<uint32_t> timeout_seconds = {})
{
MSG msg{};
bool stop = false;
UINT_PTR timerId = 0;
if (timeout_seconds.has_value())
{
timerId = SetTimer(nullptr, 0, *timeout_seconds * 1000, nullptr);
}
while (!stop && GetMessageW(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
stop = until_idle && !PeekMessageW(&msg, nullptr, 0, 0, PM_NOREMOVE);
stop = stop || (msg.message == WM_TIMER && msg.wParam == timerId);
}
if (timeout_seconds.has_value())
{
KillTimer(nullptr, timerId);
}
return static_cast<int>(msg.wParam);
}
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ int nCmdShow)
{
winrt::init_apartment();
AlwaysOnTop app;
run_message_loop();
return 0;
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.211028.7" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.211019.2" targetFramework="native" />
</packages>

View file

@ -0,0 +1 @@
#include "pch.h"

4
tools/AlwaysOnTop/pch.h Normal file
View file

@ -0,0 +1,4 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winrt/base.h>