Как сделать чтоб 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 = 0x0001;

const UInt32 SWP_NOMOVE = 0x0002;

const UInt32 SWP_NOACTIVATE = 0x0010;

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;

};

  • Yuri Zholobov

    А как же правило “если уперся во что-то, то дверь в другом месте”? В смысле зачем использовать Popup если требуется менять его z-order? С мышью и двиганьем окошка – вообще не понял в чём суть проблемы.

  • Это хорошее правило, но попапы на что-то другое менять не хотелось.
    С мышью и двиганьем окна проблема в том что попап – это не стандартное окно и ему mousedrag (или как там событие называется, не помню точно) не прописать вроде как.

  • Sergey Naumov

    Вот тут про курсор хорошо написано, можно и без WIN API:
    http://www.codegod.de/webappcodegod/render-3ds-3d-models-with-wpf-and-xaml-AID433.aspx

    А насчет приоретету по изображению – действительно схалтурили. Нужно сделть счетчик, где цифры бегают, как у одометра у машины или у старого электросчетчика, плюс под ним рисунок динамически меняется. И не знаю даже что предпринять.