So, I have an application. I want it to always sit exactly one z-level above a target application. It is just going to display a status message in the title bar, it's ugly but it's the requirement I have to meet.
Like this:
I looked into WM_NCPAINT
and it's not really a feasible solution at this stage of the project (prototyping/proposals).
I've discovered the SetWindowPos()
function within user32.dll
:
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, Swp uFlags);
And hook all z-level related events (of all applications) with:
SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_FOCUS, IntPtr.Zero, ZOrderChanged, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS | WINEVENT_SKIPOWNTHREAD);
And this seems to work to some extent. However, as I can only set to be directly behind the target app, I have to call SetWindowPos()
twice, to achieve this, once to aquire the z-level of the target and once to swap the two around:
private void ZOrderChanged(IntPtr hWinEventHook, uint eventType, IntPtr lParam, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
SetWindowPos(Handle, _foxViewHWnd, 0, 0, 0, 0, Swp.Noactivate | Swp.Nomove | Swp.Nosize);
SetWindowPos(_foxViewHWnd, Handle, 0, 0, 0, 0, Swp.Noactivate | Swp.Nomove | Swp.Nosize);
}
This is inefficient, flickers and reeks of code-smell, would anyone know how to avoid this?