«прикрепить к рабочему столу» в Win 7, совместим с XP - PullRequest
4 голосов
/ 28 июля 2010

Как можно добиться эффекта «прикрепить к рабочему столу» (т.е. противостоять команде «Показать рабочий стол») в Win 7, используя подход FindWindow + SetParent или любой другой подход, который также будет работать в XP? Я знаю, что мог бы создать гаджет, но я хотел бы иметь обратную совместимость с XP, где у меня есть этот код, делающий это нормально:

IntPtr hWnd = FindWindow(null, "Untitled - Notepad");
IntPtr hDesktop = FindWindow("ProgMan", "Program Manager");
SetParent(hWnd, hDesktop);

Ответы [ 3 ]

2 голосов
/ 12 августа 2010

в моем приложении WPF я смог решить его с помощью таймера, он работает как в XP, так и в Win 7.

public MainWindow()
{
    InitializeComponent();

    // have some timer to fire in every 1 second
    DispatcherTimer detectShowDesktopTimer = new DispatcherTimer();
    detectShowDesktopTimer.Tick += new EventHandler(detectShowDesktopTimer_Tick);
    detectShowDesktopTimer.Interval = new TimeSpan(0, 0, 1);
    detectShowDesktopTimer.Start();
}

#region support immunizing against "Show Desktop"
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

private string GetWindowText(IntPtr handle)
{
    int chars = 256;
    StringBuilder buff = new StringBuilder(chars);
    if (GetWindowText(handle, buff, chars) > 0)
        return buff.ToString();
    else
        return string.Empty;
}
#endregion

private void detectShowDesktopTimer_Tick(object sender, EventArgs e)
{
    IntPtr fore = GetForegroundWindow();
    if (string.IsNullOrWhiteSpace(GetWindowText(fore)))
        ShowDesktopDetected();
}

private void ShowDesktopDetected()
{
    WindowInteropHelper wndHelper = new WindowInteropHelper(this);
    SetForegroundWindow(wndHelper.Handle);
}
2 голосов
/ 03 ноября 2011

Работая над календарем «приклеенный к рабочему столу», я столкнулся с той же проблемой. Вот мое решение:

/************ win32 interop stuff ****************/


[DllImport( "user32.dll", SetLastError = true )]
static extern int SetWindowLong( IntPtr hWnd, int nIndex, IntPtr dwNewLong );

[DllImport( "user32.dll", SetLastError = true )]
static extern IntPtr FindWindow( string lpWindowClass, string lpWindowName );

[DllImport( "user32.dll", SetLastError = true )]
static extern IntPtr FindWindowEx( IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle );


const int GWL_HWNDPARENT = -8;


/************* in Form_Load or equivalent ***************/


IntPtr hprog = FindWindowEx(
    FindWindowEx(
        FindWindow( "Progman", "Program Manager" ),
        IntPtr.Zero, "SHELLDLL_DefView", ""
    ),
    IntPtr.Zero, "SysListView32", "FolderView"
);

SetWindowLong( this.Handle, GWL_HWNDPARENT, hprog );

Сложнее было установить владельца формы (SetWindowLong + GWL_HWNDPARENT) вместо родителя формы (SetParent). Исправлена ​​ошибка, из-за которой форма не отображалась на рабочем столе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...