Hallo @All,
Ich möchte alle Form-Objekte in meiner Anwendung mit einem neuen Icon versehen.
Das ganze klappt auch schon mit dem nachfolgenden Code, nur bin ich mir nicht sicher ob es da nicht noch bessere Wege gibt.
Ziele:
Danke erst mal für's Lesen.
Gruß
Juy Juka
Der Code:
public void Ausfuehren(string parameter)
{
Application.AddMessageFilter(this);
}
public static System.Windows.Forms.Form GetForm(System.IntPtr handle)
{
return handle == System.IntPtr.Zero ? null : System.Windows.Forms.Control.FromHandle(handle) as System.Windows.Forms.Form;
}
private static System.EventHandler shown;
bool IMessageFilter.PreFilterMessage(ref Message m)
{
System.Windows.Forms.Form f;
if (m != null)
{
if((f = GetForm(m.HWnd)) != null)
{
f.Shown += shown ?? (shown = new System.EventHandler(f_Shown));
}
}
return false;
}
private static System.Drawing.Icon icon;
private void f_Shown(object sender, System.EventArgs e)
{
Form f = sender as Form;
if (f != null)
{
f.Icon = icon ?? (icon = System.Drawing.Icon.FromHandle(Properties.Resources.NeuesIcon.GetHicon()));
}
}
Also ich habe bei mir alle Forms in der Anwendung von einer eigenen abstrakten Klasse Baseform abgeleitet, die wieder von form erbt.
Damit bin ich bis jetzt gut gefahren (mit Standardfunktionen wie drucken, (de)serialisieren etc. in der Baseform, die dann überladen werden können) .
solche Änderungen wie das Icon lassen sich damit dann auch recht einfach ändern, da sie nur in der baseform erfolgen müssten.
Du musst dann natülich einmal heftigst refactoren um das umzusetzen, dafür hast Dus in zukunft aber einfacher...
- Allgemein Bessere Performance (Da der MessageFilter unglaublich oft ausgeführt wird, ist hier jede Optimierung natürlich Goldwert).
Du wertest die Message gar nicht aus. Ich täte denken, in der API ist ein Wert für Form_Shown (oder vergleichbares) hinterlegt, auf den man lauschen könnte.
Edit: guck: int WM_SHOWWINDOW = 24
, guckma, ob das kommt.
Der frühe Apfel fängt den Wurm.
Vielleicht hilf folgende Eigenschaft der Application-Klasse
public static FormCollection OpenForms
{
[UIPermission(SecurityAction.Demand, Window=UIPermissionWindow.AllWindows)]
get
{
return OpenFormsInternal;
}
}
Hallo @All,
@rasepretrep: Basis-Form vor allem abstrakt geht mal garnicht, dieses Desaster hatten wir in der letzten Version der Software. Ein Framework für die Forms (wie du es vorschlägst) ist aber schon ein angestrebtes Ziel, jedoch im nachhinein ist das aus Zeitlichen gründen nicht drin (alls ich die Form's das letzte mal gezählt habe waren es weit über 200 und das ist auch schon wieder 4 Jahre her).
@ErfinderDesRades: Vielen Danke. Wenn man normalerweise nicht so weit in die Windows-Api-Welt eintaucht (ich finde IMessageFilter ist mit dem Kopf vorran drin), sucht man sich nach solchen Konstanten dumm und dämlich.
@Floste: Wenn es jetzt noch ein Ereigniss gibt, das ausgelöst wird, wenn eine neue Form erzeugt wird, muss ich mal zum Augenarzt. 😃 😃
Danke an alle die gepostet haben und danke für eure Zeit und Hilfe.
Gruß
Juy Juka
@Floste: Wenn es jetzt noch ein Ereigniss gibt, das ausgelöst wird, wenn eine neue Form erzeugt wird, muss ich mal zum Augenarzt. 😃 😃
Gibts nicht, lässt sich aber basteln, mit etwas reflection:
Gehen tut das ganz einfach:
class MyArrayList:ArrayList
{
public MyArrayList(ICollection values):base(values)
{
}
public override int Add(object obj)
{
EventFeuern((Form)obj);
return base.Add(obj);
}
}
void EventRegistrieren()
{
MyArrayList newList=new MyArrayList(Application.OpenForms);
typeof(FormCollection).InvokeMember("list", NonPublic|Instance|SetField, null, Application.OpenForms, new object[1]{newList});
}
Jetzt fehlt nurnoch EventFeuern zu implementieren! Ist nicht getestet, sollte aber klappen!
genial! 👍
Das einzige, was nicht funzt ist die Typ-Angabe, da muß ReadonlyCollectionBase angegeben werden, die BasisBasisKlasse von FormCollection.
Der frühe Apfel fängt den Wurm.
Komisch, ich bin mir 110% sicher, dass man mit dieser funktion auch auf geerbte Felder zugreifen kann! (zumindest in manchen situationen)
[EDIT] Woran ich gedacht habe waren keine wirklich privaten felder
Hallo @All,
Danke für eure Zeit und mühe.
Besonderen Dank an Floste, da ich mich für seiner/ihrer Methode entschidene habe und es sauber und flüssig funktioniert.
Gruß
Juy Juka