Как получить изображение для различных MessageBoxImage(s) или MessageBoxIcon(s)

Как получить System.Drawing.Image для различных System.Windows.MessageBoxImage(ов) и/или System.Windows.Forms.MessageBoxIcon(ов)


person Simon    schedule 21.08.2009    source источник


Ответы (4)


SystemIcons — это то, что я искал:

SystemIcons.Warning.ToBitmap();
person Simon    schedule 21.08.2009

Вы также можете включить SystemIcons в свой XAML следующим образом:

Включите преобразователь (см. код ниже) в качестве ресурса и элемент управления Image в XAML. В этом примере изображения показан значок информации.

     <Window.Resources>
        <Converters:SystemIconConverter x:Key="iconConverter"/>
     </Window.Resources>

     <Image Visibility="Visible"  
            Margin="10,10,0,1"
            Stretch="Uniform"
            MaxHeight="25"
            VerticalAlignment="Top"
            HorizontalAlignment="Left"
            Source="{Binding Converter={StaticResource iconConverter}, ConverterParameter=Information}"/>

Вот реализация конвертера:

using System;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Data;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

namespace Converters
{
   [ValueConversion(typeof(string), typeof(BitmapSource))]
   public class SystemIconConverter : IValueConverter
   {
      public object Convert(object value, Type type, object parameter, CultureInfo culture)
      {
         Icon icon = (Icon)typeof(SystemIcons).GetProperty(parameter.ToString(), BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
         BitmapSource bs = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
         return bs;
      }

      public object ConvertBack(object value, Type type, object parameter, CultureInfo culture)
      {
         throw new NotSupportedException();
      }
   }
}
person Zamboni    schedule 13.03.2010
comment
Спасибо большое! Это отлично работает! Однако я заметил, что StackOverflow работает под лицензией Creative Commons. Таким образом, технически я не могу использовать/адаптировать ваш код в моем коммерческом приложении (которое я не хочу использовать под лицензией Creative Commons) без вашего разрешения. Вы готовы дать мне разрешение? Я все еще могу доверять вашей работе. - person skybluecodeflier; 07.09.2011
comment
@skybluecodeflier, любой код, размещенный в StackOverflow, является творческим достоянием: meta.stackexchange.com/questions/12527/ - person Ed Bayiates; 02.05.2014
comment
@Zamboni Есть ли какая-то особая причина, по которой ваш преобразователь игнорирует value и выполняет преобразование, используя только parameter? Это кажется нетипичным для преобразователей. - person Disillusioned; 17.10.2016

Как заявляли другие, SystemIcons — это класс, который должен содержать эти значки, но в Windows 8.1 (и, возможно, в более ранних версиях) значки, присутствующие в SystemIcons, отличаются от значков, отображаемых в MessageBoxes в случае Asterisk, Информация и Вопрос. Значки в диалоговом окне выглядят намного плоскими. См., например, значок вопроса:

Значок вопроса

Значок в диалоговом окне — это собственный значок диалогового окна, а самый левый значок в форме на заднем плане — это значок, полученный из класса SystemIcons.

Различные методы и сведения о том, как получить значок из MessageBox, см. в этом ответе, но я привожу здесь краткое изложение, просто для полноты:

Вы должны использовать функцию SHGetStockIconInfo:

 SHSTOCKICONINFO sii = new SHSTOCKICONINFO();
 sii.cbSize = (UInt32)Marshal.SizeOf(typeof(SHSTOCKICONINFO));

 Marshal.ThrowExceptionForHR(SHGetStockIconInfo(SHSTOCKICONID.SIID_INFO,
         SHGSI.SHGSI_ICON ,
         ref sii));
 pictureBox1.Image = Icon.FromHandle(sii.hIcon).ToBitmap();

Обратите внимание на :

Если эта функция возвращает дескриптор значка в элементе hIcon структуры SHSTOCKICONINFO, на который указывает psii, вы несете ответственность за освобождение значка с помощью DestroyIcon. когда он вам больше не нужен.

Конечно, чтобы это работало, вам нужно будет определить несколько перечислений и структур:

public enum SHSTOCKICONID : uint
{
    //...
    SIID_INFO = 79,
    //...
}

[Flags]
public enum SHGSI : uint
{
    SHGSI_ICONLOCATION = 0,
    SHGSI_ICON = 0x000000100,
    SHGSI_SYSICONINDEX = 0x000004000,
    SHGSI_LINKOVERLAY = 0x000008000,
    SHGSI_SELECTED = 0x000010000,
    SHGSI_LARGEICON = 0x000000000,
    SHGSI_SMALLICON = 0x000000001,
    SHGSI_SHELLICONSIZE = 0x000000004
}

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHSTOCKICONINFO
{
    public UInt32 cbSize;
    public IntPtr hIcon;
    public Int32 iSysIconIndex;
    public Int32 iIcon;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260/*MAX_PATH*/)]
    public string szPath;
}

[DllImport("Shell32.dll", SetLastError = false)]
public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
person qqbenq    schedule 21.08.2014

MessageBox.Show(
  "Hello, world!",
  "My App",
  MessageBoxButton.OK, MessageBoxImage.Information);

Так просто, как, что.

person Shankar K Arun    schedule 24.07.2019
comment
Спасибо за ответ. но я действительно хочу использовать экземпляр растрового изображения, а не то, как показать окно сообщения. И добро пожаловать в stackoverflow - person Simon; 25.07.2019