I just moved my PC to Windows 8 from Windows 7 and while running our WPF application I noticed that our WPF popups and/or tool tips are now in the lower-left by default inst
Ok, for those that do not want this to occur at all in their app (which was our desire), We have created a nice little hack for WPF. This works well for us.
First:
This code will be what runs which fixes the issue:
public static void SetAlignment()
{
var ifLeft = SystemParameters.MenuDropAlignment;
if (ifLeft)
{
// change to false
var t = typeof(SystemParameters);
var field = t.GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
field.SetValue(null, false);
ifLeft = SystemParameters.MenuDropAlignment;
}
}
However, the environment can de-validate microsofts internal cache of these values, so we have to hook into WinProc to get this. I wont post the WinProc code, just the messages that are needed:
These are the Win32 messages that will de-validate the internal cache:
private const int WM_WININICHANGE = 0x001A;
private const int WM_DEVICECHANGE = 0x219;
private const int WM_DISPLAYCHANGE = 0x7E;
private const int WM_THEMECHANGED = 0x031A;
private const int WM_SYSCOLORCHANGE = 0x15;
And the quick snippit that will set your preference back. Because we are hooked into WinProc, you will want to change this value after WinProc is finished with the message on other handlers. We have a delay to re-set the preference value back to what we want.
if (msg == WM_WININICHANGE || msg == WM_DEVICECHANGE || msg == WM_DISPLAYCHANGE || msg == WM_THEMECHANGED || msg == WM_SYSCOLORCHANGE)
{
Timer timer = null;
timer = new Timer((x) =>
{
WpfHelperHacks.SetAlignment();
timer.Dispose();
},null, TimeSpan.FromMilliseconds(2), TimeSpan.FromMilliseconds(-1));
}
And just like that its complete. I hope this helps someone else!