28.06.08
Как сделать чтоб WPF Popup был не поверх всех окон (или Win32 API живет до сих пор)
Уже несколько раз подряд за последние дни упираюсь в “пределы” WPF. Причём задачи были отнюдь не экзотические.
Класс Popup генерирует окно, которое располагается поверх всех окон в системе. Если вы хотите изменить это вам поможет только Win32 API:
[DllImport(“user32″, EntryPoint = “SetWindowPos”)]
private static extern int SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int cx, int cy, UInt32 wFlags);
const UInt32 SWP_NOSIZE = 0×0001;
const UInt32 SWP_NOMOVE = 0×0002;
const UInt32 SWP_NOACTIVATE = 0×0010;
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
static readonly IntPtr HWND_TOP = new IntPtr(0);
public static void Popup_SetZOrderTop(Popup pop)
{
IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(pop.Child)).Handle;
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}
С помощью этой функции также можно регулировать какое из окон находиться наверху в данный момент.
Получение текущих координат мыши в WPF возможно только с указанием контрола, относительно которого вам нужны эти координаты. А что делать если этот самый контрол нужно двигать?
public struct POINT
{
public int x;
public int y;
};
[DllImport(“user32.dll”)]
static extern bool GetCursorPos(out POINT point);
Еще пара полезных функций (поиск окна и получение его положения):
[DllImport(“user32.dll”, SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport(“user32.dll”)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
};
А как же правило “если уперся во что-то, то дверь в другом месте”? В смысле зачем использовать Popup если требуется менять его z-order? С мышью и двиганьем окошка - вообще не понял в чём суть проблемы.
Это хорошее правило, но попапы на что-то другое менять не хотелось.
С мышью и двиганьем окна проблема в том что попап - это не стандартное окно и ему mousedrag (или как там событие называется, не помню точно) не прописать вроде как.
Вот тут про курсор хорошо написано, можно и без WIN API:
http://www.codegod.de/webappcodegod/render-3ds-3d-models-with-wpf-and-xaml-AID433.aspx
А насчет приоретету по изображению - действительно схалтурили. Нужно сделть счетчик, где цифры бегают, как у одометра у машины или у старого электросчетчика, плюс под ним рисунок динамически меняется. И не знаю даже что предпринять.