Как избежать дублирования ресурсов значков в проекте .NET (C #) - PullRequest
20 голосов
/ 28 февраля 2009

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

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

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

Ответы [ 5 ]

14 голосов
/ 28 февраля 2009

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

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

this.Icon = Properties.Resources.myIconResourceName;
11 голосов
/ 28 февраля 2009

Вы ищете Icon.ExtractAssociatedIcon. Позвоните, передав свой исполняемый файл:

var icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
6 голосов
/ 11 марта 2009

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

Я делаю это с помощью взаимодействия (поместите первую строку в конструкторе формы):

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. Таким образом, вам действительно нужно извлечь значок whole , что является более сложной задачей. Может быть, есть простой способ объединить две иконки в одну. Или вы можете сделать так: codeproject программа, которая сначала извлекает весь значок с огромной кучей кода.

3 голосов
/ 15 февраля 2012

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

1 голос
/ 30 июля 2010

У меня была похожая проблема.

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

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

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

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