WPF - убрать значок системного меню из модального окна, но не из главного окна приложения - PullRequest
3 голосов
/ 22 июня 2010

Я пытаюсь сделать (в WPF):

  1. Иметь файл .exe, который отображает значок системного меню (значок в левом верхнем углу окна) как обычно
  2. Этот значок не отображается в модальных окнах, вызываемых этим приложением

Я попробовал решение здесь: Удаление значка из окна WPF

Иэто сработало.Загружаемый образец того же самого по адресу: http://blogs.msdn.com/b/wpfsdk/archive/2007/08/02/a-wpf-window-without-an-window-icon-the-thing-you-click-to-get-the-system-menu.aspx

Однако он перестает работать, если я добавляю файл .ico в свойства проекта .exe (Свойства -> Приложение -> Значок и манифест).Вы можете попробовать это с загружаемым примером.

Кажется, что значок из .exe используется и в модальных окнах (которые мы имеем в .dll-файлах), даже если свойства этого .dll говорят "значок по умолчанию ".Он должен передаваться из .exe.Итак, есть ли способ показать значок в главном окне, но не в дочернем окне?

Возможно, более простой способ задать вопрос: возможно ли удалить значок, даже если он есть.Файл ico указывает в свойствах проекта?

Единственное, что я нашел для работы, - это установить WindowStye модального окна на «ToolWindow».Это дает мне почти то, что я хочу: нет значка, и кнопка «Закрыть» («х» в правом верхнем углу) все еще там.Тем не менее, х супер маленький.Это лучшее, что есть?

Спасибо за любую помощь.

1 Ответ

6 голосов
/ 29 июля 2010

У меня была такая же проблема.Похоже, что WS_EX_DLGMODALFRAME удаляет значок только тогда, когда собственное окно Win32 окна WPF не имеет значка, связанного с ним.WPF (удобно) использует значок приложения в качестве значка по умолчанию для всех окон без явно установленного значка.Обычно это не вызывает никаких проблем и избавляет нас от необходимости вручную устанавливать значок приложения в каждом окне;однако это вызывает у нас проблему, когда мы пытаемся удалить значок.

Поскольку проблема заключается в том, что WPF автоматически устанавливает для нас значок окна, мы можем отправить WM_SETICON в окно Win32.сбросить его значок, когда мы применяем WS_EX_DLGMODALFRAME.

const int WM_SETICON = 0x0080;
const int ICON_SMALL = 0;
const int ICON_BIG = 1;

[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SendMessage(
    IntPtr hWnd, 
    int msg,
    IntPtr wParam, 
    IntPtr lParam);

Код для удаления значка:

IntPtr hWnd = new WindowInteropHelper(window).Handle;
int currentStyle = NativeMethods.GetWindowLongPtr(hWnd, GWL_EXSTYLE);

SetWindowLongPtr(
    hWnd,
    GWL_EXSTYLE,
    currentStyle | WS_EX_DLGMODALFRAME);

// reset the icon, both calls important
SendMessage(hWnd, WM_SETICON, (IntPtr)ICON_SMALL, IntPtr.Zero);
SendMessage(hWnd, WM_SETICON, (IntPtr)ICON_BIG, IntPtr.Zero);

SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, 
    SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

Редактировать: О, и это выглядит такэто работает, только когда приложение запускается вне Visual Studio.

...