WPF - remove the system menu icon from the modal window, but not in the main application window

I am trying to do (in WPF):

  • Have a .exe file that displays the system menu icon (the icon in the upper left corner of the window), as usual.
  • Do not show this icon in modal windows called by this application

I tried the solution here: Removing the icon from the WPF window

And it worked. There's a downloadable sample of the same: 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

However, it stops working if I add the .ico file to the properties of the .exe project (Properties → Application → Icon and manifest). You can try this with a downloadable sample.

It seems that the icon from .exe is also used in modal windows (which we have in DLL files), even if the properties of this .dll say "default icon". It must be transferred from .exe. So, is there a way to show the icon in the main window, but not in the child window?

Perhaps an easier way to ask the question is: is it possible to delete the icon, even if the .ico file is specified in the project properties?

The only thing I found to work was to set the WindowStye of the modal window to "ToolWindow". This gives me almost what I want: the icon and the Close button ("x" in the upper right corner). However, x is super small. Is this the best there is?

Thanks for any help.

+3
source share
1 answer

I had the same problem. It seems that WS_EX_DLGMODALFRAME only deletes the icon when there is no icon associated with it in the Win32 window of the Win32 window. WPF (conveniently) uses the application icon as the default icon for all windows without an explicitly set icon. Usually this does not cause any problems and eliminates the need to manually install the application icon in each window; however, this creates a problem for us when we try to remove the icon.

Since the problem is that WPF automatically sets the window icon for us, we can send WM_SETICON to the Win32 window before resetting its icon when we use 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); 

Code to remove the icon:

 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); 

Edit: Oh, and it looks like this only works when the application starts outside of Visual Studio.

+6
source

All Articles