I want to create Windows 10 desktop widget. I created C# WinForms project, and using WinAPI I track switching between windows, and when desktop is shown, I show my form. Is there an easier way to do this? I think, I can show my form under all other windows, but i don't know, how to do it. Full code of my existing form:
public partial class Form1 : Form
{
WINEVENTPROC foregroundChanged => new WINEVENTPROC(ForegroundChanged);
public Form1()
{
InitializeComponent();
SafeHandle foregroundHook = PInvoke.SetWinEventHook(
PInvoke.EVENT_OBJECT_FOCUS,
PInvoke.EVENT_OBJECT_FOCUS,
null,
foregroundChanged,
0,
0,
PInvoke.WINEVENT_OUTOFCONTEXT | PInvoke.WINEVENT_SKIPOWNPROCESS);
foreach (var scrn in Screen.AllScreens)
{
if (scrn.Bounds.Contains(this.Location))
{
this.Location = new Point(scrn.Bounds.Right - this.Width, scrn.Bounds.Top);
return;
}
}
}
unsafe struct PathBuffer
{
public fixed char Buffer[(int)PInvoke.MAX_PATH];
}
private unsafe uint GetProcessPidByHWND(HWND hWND)
{
uint dwProcessId = 0;
PInvoke.GetWindowThreadProcessId(hWND, &dwProcessId);
return dwProcessId;
}
private unsafe string GetProcessPathByHWND(HWND hWND)
{
uint pid = GetProcessPidByHWND(hWND);
SafeFileHandle process = PInvoke.OpenProcess_SafeHandle(
Windows.Win32.System.Threading.PROCESS_ACCESS_RIGHTS.PROCESS_VM_READ
| Windows.Win32.System.Threading.PROCESS_ACCESS_RIGHTS.PROCESS_QUERY_INFORMATION,
false,
pid);
PathBuffer pathBuffer = new PathBuffer();
PWSTR pathPWSTR = new PWSTR(pathBuffer.Buffer);
PInvoke.GetModuleFileNameEx(process, null, pathPWSTR, PInvoke.MAX_PATH);
return pathPWSTR.ToString();
}
private unsafe void ForegroundChanged(
HWINEVENTHOOK hWinEventHook,
uint eventType,
HWND hwnd,
int idObject,
int idChild,
uint dwEventThread,
uint dwmsEventTime)
{
uint desktopPid = GetProcessPidByHWND(PInvoke.GetShellWindow());
uint currPid = GetProcessPidByHWND(PInvoke.GetForegroundWindow());
if (desktopPid == currPid)
{
Show();
}
else
{
Hide();
}
}
}