Подтвердить что ты не робот

Предотвращение дублирования ресурсов значков в проекте .NET(С#)

Я использую Visual С# 2008 Express. Я хотел бы использовать тот же значок для приложения (т.е. Значок, показанный для .exe), и для основной формы. К сожалению, VС#, похоже, не очень сообразителен и настаивает на дублировании данных значков.

Кажется, что нет способа выбрать "уже встроенный" значок для использования в значке формы или проекта (только для выбора файла), а использование одного и того же файла для обоих значков просто вставляет файл в два раза больше как я вижу. Это не грандиозное решение (на данный момент место на жестком диске дешево, правда?), Но это меня задевает.

Любая идея, как этого избежать? Есть ли способ программно загрузить исполняемый значок для использования при создании формы, скажем? Несколько сообщений на форуме о подобных вещах, похоже, предполагают, что ресурсы .NET не используют обычную старую систему ресурсов Windows - есть ли способ в рамках получения ресурсов старого стиля? Или мне нужно связать функции API Win32, чтобы сделать это?

4b9b3361

Ответ 1

Да, это довольно раздражает. Но проблема с предлагаемым ответом Icon.ExtractAssociatedIcon заключается в том, что он будет извлекать значок 32x32, а затем уменьшать до 16x16-значка в окне форм или на панели задач, что будет выглядеть ужасно, если ваш значок 32x32 очень умный.

Как я делаю это с interop (помещаем первую строчку в конструктор формы):

this.Icon = ExtractSmallIconFromLibrary(Application.ExecutablePath);
...

public static Icon ExtractSmallIconFromLibrary(string file) {
    IntPtr[] reficon = new IntPtr[1];
    int nextracted = ExtractIconEx(file, 0, null, reficon, 1);
    if (nextracted < 1)
        return null;
    Icon unmanaged_icon = Icon.FromHandle(reficon[0]);
    Icon icon = (Icon)unmanaged_icon.Clone();
    DestroyIcon(unmanaged_icon.Handle);
    return icon;
}

[DllImport("Shell32", CharSet = CharSet.Auto)]
extern static int ExtractIconEx(
    [MarshalAs(UnmanagedType.LPTStr)] 
    string lpszFile,
    int nIconIndex,
    IntPtr[] phIconLarge,
    IntPtr[] phIconSmall,
    int nIcons
    );

[DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

Но это тоже не здорово, так как вам нужен значок 32x32 для таких вещей, как список значков Alt-Tab. Таким образом, вам действительно нужно извлечь весь значок, что является большой работой. Может быть, есть простой способ объединить два значка в один. Или вы можете сделать это как codeproject, которая извлекает весь значок в первую очередь с огромной кучей кода.

Ответ 2

Вы правы, и это довольно раздражает.

Вы должны сами загружать значки, вместо того чтобы полагаться на созданный конструктором код. Сохраните значок в качестве ресурса проекта, а затем загрузите ресурс в свойство формы Icon в конструкторе формы:

this.Icon = Properties.Resources.myIconResourceName;

Ответ 3

Вы ищете Icon.ExtractAssociatedIcon. Вызов вашего исполняемого файла:

var icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);

Ответ 4

Я думаю, что во многих случаях, включая дубликат, значок в конце дня более эффективен, чем попытка извлечь его из неуправляемого ресурса - учитывая, что вы не можете использовать путь Icon.ExtractAssociatedIcon для UNC.

Ответ 5

У меня была аналогичная проблема.

У меня есть и значок exe. Я хочу повторно использовать для подформ без увеличения размера файла.

//From MyApp
MySubForm msf = new MySubForm();
msf.Icon = this.Icon;
msf.Show();

Я не знаю, полезно ли это, но я хочу поделиться им в любом случае.