2009-02-27 20 views
19

Estoy usando Visual C# 2008 Express. Me gustaría utilizar el mismo ícono para la aplicación (es decir, el ícono que se muestra para el .exe) y para el formulario principal. Desafortunadamente, VC# no parece ser muy inteligente al respecto, e insiste en duplicar los datos del icono.Evitar recursos duplicados de iconos en un proyecto .NET (C#)

No parece haber una manera de seleccionar un ícono "ya incrustado" para usar en el icono de formulario o proyecto (solo seleccionando un archivo), y utilizando el mismo archivo para ambos íconos simplemente incrusta el archivo dos veces como Hasta donde yo puedo ver No es gran cosa (el espacio en el disco duro es barato ahora, ¿no?), Pero me molesta.

¿Alguna idea de cómo evitar esto? ¿Hay alguna forma de cargar programáticamente el icono del ejecutable para usarlo cuando se crea el formulario, por ejemplo? Un par de publicaciones en el foro sobre cosas similares parecen sugerir que los recursos de .NET no usan el viejo sistema de recursos normal de Windows. ¿Hay alguna forma de acceder a los recursos antiguos? ¿O tengo que vincular las funciones de API de Win32 para hacerlo?

+0

¿Por qué no utilizar la herencia? Defina el icono en una clase de formulario personalizada y úselo en todas partes. –

+0

Recuerdo mis tiempos de programación Delphi ... self.Icon = Application.Icon; : P ... demasiado difícil en .NET: D – Learner

+0

posible duplicado de [¿Alguna manera fácil de usar iconos de recursos?] (Http: // stackoverflow.com/questions/5656809/any-easy-way-to-use-icons-from-resources) – KyleMit

Respuesta

6

Sí, es bastante molesto. Pero el problema con la respuesta propuesta de Icon.ExtractAssociatedIcon es que recuperará el icono de 32x32 y luego reducirá a un icono de 16x16 en la ventana de formularios o en la barra de tareas, lo que se verá terrible a menos que el icono de 32x32 esté muy ingeniosamente construido.

La forma en que estoy haciendo es con interoperabilidad (poner la primera línea en su forma constructor):

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

Pero esto no es muy grande, ya sea, ya que hace desea que el icono 32x32 para cosas como la lista de iconos Alt-Tab. Entonces realmente necesita extraer el icono completo, que es un trabajo más grande. Tal vez haya una manera directa de combinar los dos íconos en uno. O puede hacer como este programa codeproject, que extrae el ícono completo en primer lugar con una enorme pila de código.

14

Tienes razón, y es bastante molesto.

Tienes que cargar los íconos tú mismo en lugar de depender del código generado por el diseñador. Guardar el icono como un recurso de proyecto, a continuación, cargar el recurso a la propiedad de la forma Icon en el constructor del formulario:

this.Icon = Properties.Resources.myIconResourceName; 
+0

Eso no lo resuelve: insertar el icono como un recurso del proyecto es lo mismo que configurarlo en el diseñador del formulario: duplica los datos del icono, que es lo que intento evitar. –

+0

Ya debe estar incrustado como un recurso cuando agrega el icono como el icono del proyecto, ¿no? –

+0

No es que pueda ver ... el icono utilizado para el ejecutable parece ser completamente independiente del sistema de recursos .NET. –

10

Usted está buscando Icon.ExtractAssociatedIcon. Llamada pasando tu ejecutable:

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

Por favor explique por qué esto es lento? Si es porque está usando la reflexión, puede resolverse fácilmente utilizando Application.ExecutablePath en lugar de Assembly.GetExecutingAssembly(). Ubicación. –

+0

¡La mejor solución! Que no duplican ícono en los recursos y muestran el ícono de mejor calidad en la barra de tareas. ¡Gracias! – Geograph

1

Tuve un problema similar.

I have and exe icon Quiero reutilizar para subformularios sin aumentar el tamaño del archivo.

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

No sé si esto es útil, pero quiero compartirlo de todos modos.

3

Creo que en muchos casos, incluso un icono duplicado es al final del día más eficiente que tratar de extraerlo del recurso no administrado, considerando que no puede usar Icon.ExtractAssociatedIcon para rutas UNC.

Cuestiones relacionadas