Laden...

Forenbeiträge von Andreas.May Ingesamt 915 Beiträge

06.06.2008 - 09:27 Uhr

Hrm, nur damit das ebenso mal gesehen hast:


class A
{
  public A(string s)
  {
  }
}

class AA : A
{
  public AA(string s, int i) : base(s)
  {
  }

  public AA(int i) : this(string.Empty, i)
  {
  }
}


05.06.2008 - 15:43 Uhr

Hrm, wie hast den Listener implementiert bzw. die MEthode dafür. Läuft da evtl. ne While Schleife und ist diese in einen eigenen Thread?

05.06.2008 - 14:33 Uhr

public MainForm(string displayString)
{

// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();

// displayString global übergeben oder sontwas damit anstellen usw..
}

05.06.2008 - 14:20 Uhr

		[STAThread]
		static void Main(string[] args)
		{
			string test = "40";
			test = HexToAsc(test);
		}

		public static string HexToAsc(string str)
		{
			string[] hex = str.Split();
			string result = null;
			for (int i = 0; i < hex.Length; ++i)
			{
				result += (char)Convert.ToUInt16(hex[i], 16);
			}
			return result;
		}

[Edit] Ha, schneller 😜

05.06.2008 - 12:26 Uhr

Hrm, JAck30lena's Vorschlag für einen Service hört sich eigentlich zeimlich gut an zur performance Verbesserung.

Man müsste mal schauen was via WMI Möglich wäre. Beim anlagen, löschen und unbenennen von Ordnern oder Dateien kann man dann die vollständigen Pfade in eine XML Datei schreiben und in verschiedene Attribute unterteilen: Extension (*.dll, *.txt usw.), FileName, Laufwerkbuchstabe usw. Via Regex und XPath Navigation könnte man dann evtl. effektiver nach Dateien und Ordnern suchen, da diese durch die Aufteilung in Attribute indiziert wurden.

Das sollte denke ich um einiges schneller sein als das Suchen über DirectoryInfo. Natürlich braucht man dann noch eine entsprechende GUI Oberfläche die evtl. mit dem Service komuniziert oder ebenso auf die XML Datei zugreift. Ebenso benötigt man noch Zusatzfunktionen wie z.B. "Reorganisieren" das man z.B. als Job Nachts durchlaufen lassen könnte.

05.06.2008 - 11:37 Uhr

...Da ich aber knapp 5 Jahre lang Zusatzmodule für SAP Business One entwickelte...
welche Programmiersprache wird da eigentlich verwendet?

Na ja, es ist kein ABAP wie bei R/3. Man verwendet entweder C# oder was die meisten wohl nehmen ist VB.NET. Ansprechen tut man das ganze über eine DI und / oder UI Schnittstelle. Allerdings sind diese ziemlich mieß, vorallem die UI Schnittstelle bietet releativ wenige Steuerelemente zur verwendung an. Das einbinden von eigenen Steuerelementen wird zwar unterstützt aber nur via ActiveX und Delphi ist naja etwas zu alt. Auch die Art der Datenbindung funktioniert komplett anders als man es im standard von .NET gewöhnt ist, das ganze ist eher ein rumgemurksel, da die Datenbankschicht ein totales Fiasko ist - da wurde viel zu wenig nachgedacht, auch wenn es beim ersten Eindruck sauber vorkommen mag.

Abhilfe bekommt man wenn man .NET Controls via Win API ins SAP Business One (oder auch R/3) einschleust (injection) und eine eigene Pluginbasierte Schnittstelle als Wrapper drum herum schreibt. Das kostet allerdings viel Aufwand und braucht einige Erfahrung mit den ganzen Besonderheiten der UI und DI Schnittstelle. Ansonsten bei "jeder" Connection ohne Plugin oder Modulverfahren würde jedesmal allein ein AddOn / AddIn ca. 70 MB ARbeitsspeicher verschlingen. Man stelle sich vor, 3 AddOns laufen für jedes dieser AddOns benötigt man allein für die Datenbankconnection 70 MB das wären allein schon 210 MB mit dem Hauptprogramm sind es dann ~290 MB ca. Wenn man als .NET Entwickler sich das erste mal mit SAP Business One beschäfftigt muss man schon erstmal "vor schreck" ziemlich schlucken. Was das Programm als solches angeht will ich es nicht bewerten - Es hat alles sein für und wieder.

Der Umstieg vom reinen C# auf die SAP Art, kam mir persöhnlich in etwa so vor wie von PHP nach C++. Aber ich gehöre zu den Menschen die auch für ABAP kein gutes Wort offen haben, denke manch anderer könnte das ganze anders sehen 😉

Und wenn irgendwann mal das Wort RFC hörts... renn so schnell du kannst. Denn ABAP Programmierer sind "selten netten" Menschen wenn da mit C# rumfummeln musst bekommst mit viel "Glück" nen Ausdruck von den Datenbankfeldern vielleicht sogar noch mit Namen von den Feldern die du als object ansprechen darfst. Und mit ganz viel Glück erhällst auch ne Fehlermeldung was für ein Feld evtl. mit dem falschen Datentyp gefüllt hast. Und absolut unverschämtes Glück hat man dann wenn der ABAP Programmierer dann noch so nett ist und dir bei den Ausdruck der Datenbankfelder und Tabellen dir Farblich die "muss Felder" makiert. Aber wer hat schon soviel Glück?

Na ja du merkst, habe für SAP Programmierung nicht viel übrig, aber dafür wird es auch gut bezahlt - zumindest sollte es für die Bezahlung eines Therapeuten oder dem auffenthalt in einer Nervenklinik ausreichen 😉

05.06.2008 - 10:25 Uhr

Hrm, ich war bisher immer in den Bereichen Mathematik und Warenwirtschaft ziemlich stark. Für das Programmieren an für sich war das ganze eher irrelevant. Da ich aber knapp 5 Jahre lang Zusatzmodule für SAP Business One entwickelte, halfen mir diese Fähigkeiten enorm weiter für das Planen und ausführen von Projekten. Oftmals ist es doch so, dass Berater hier und da mal das ein oder andere übersehen und auch glücklich darüber sind wenn ein Programmierer sich auf selben Level mit ihnen unterhallten kann.

Ansonsten, meine schwächen sind Sprachen – bin Legastheniker, lese zwar enorm viel aber was die Rechtschreibung angeht bin ich nen totaler Looser 😉

05.06.2008 - 09:34 Uhr

....die immer von "wirtschaftlich, von A nach B, kein Geld verschwenden" sprechen bzw so argumentieren, Leute mit wenig Geld.....

Würde sagen, bei mir ist es purer Geiz 🙂

05.06.2008 - 09:25 Uhr

Leider verzögert sich das ganze auf unbestimmte Zeit, derzeit ist einfach das Wetter zu gut um den Tag vor dem Rechner zu verbringen 🙂

02.06.2008 - 16:19 Uhr

Hrm, bei mir muss ein Auto nur fahren können und sollte nen Getränkehalter wie eine Klimaanlage besitzen - mehr brauche ich nicht. Fahre einen kleinen Golf, der tut es alle male für mich.

28.05.2008 - 11:32 Uhr

Meiner ist ebenso ein SyncMaster von Samsung, die Dinger sind wirklich sehr schick.

28.05.2008 - 00:54 Uhr

Geh einfach mal ne Runde Mediamarkt spazieren, schau dir einfach mal die Monitore Live an und wenn merkst das 30" doch okay ist und nicht zu teuer kannst dich ja übers Netz über Vor und Nachteile informieren.

Habe selber einen 22" TFT Monitor und bin damit absolut zufrieden, für Spiele wie für's programmieren klasse. Allerdings muss ich auch zugeben das ich nur für's Programmieren lieber 2 Monitore kaufen würde als einen großen.

27.05.2008 - 18:49 Uhr

Mit Hilfe von XOR kannst du die Typen ausgleidern.


        public enum MODKEY : int
        {
            MOD_NONE = 0,
            MOD_ALT = 1,
            MOD_CONTROL = 2,
            MOD_SHIFT = 4,
            MOD_WIN = 8
        }

Ermitteln von HotKey (z.b. A) und Modifier (STR / CTR / ALT ) in vereinfachter schreibweise.



uint nModifier = (uint)Win32.MODKEY.MOD_NONE;

            Keys nKey = hotKey.Key;
            if ((uint)(hotKey.Key & Keys.Alt) == (uint)Keys.Alt)
            {
                // es kann mehr als nur alt gedrückt sein, z.B. ALT + STR + A, daher +=
                nModifier += (int)Win32.MODKEY.MOD_ALT;
                nKey ^= Keys.Alt;
            }

            if ((uint)(hotKey.Key & Keys.Control) == (uint)Keys.Control)
            {
                nModifier += (int)Win32.MODKEY.MOD_CONTROL;
                nKey ^= Keys.Control;
            }

            if ((uint)(hotKey.Key & Keys.Shift) == (uint)Keys.Shift)
            {
                nModifier += (uint)Win32.MODKEY.MOD_SHIFT;
                nKey ^= Keys.Shift;
            }


Das versenden geht dann wie folgt, SHIFT + TAB, schau dir da am besten die Beispiele aus www.pinvoke.net an, denke dann wird es noch klarer. Die MSDN erklärung ist etwas schwerer zu verstehen.



keybd_event( VK_SHIFT, Mapvirtualkey(VK_SHIFT, 0), 0, 0 );
keybd_event( VK_TAB, MapVirtualKey( VK_TAB,0), 0, 0);
keybd_event( VK_TAB, MapVirtualKey( VK_TAB,0), KEYEVENTF_KEYUP, 0);
keybd_event( VK_SHIFT, Mapvirtualkey(VK_SHIFT, 0), KEYEVENTF_KEYUP, 0 );

Anhand des ermittelten Modifier und des Keys die du ja in deiner Anwendungung via XOR Operator rausfilters kannst du dann den VKCode mit dem Modifeir an die Fremdapplication schicken. Zudem kannst du angeben ob die Tasten gerade gedrückt sind oder ob sie gerade losgelassen wurden. Sinvoll ist wie im Beispiel erstmal anzugeben das sie gedrückt wurden und im anschluss das sie wieder losgelassen werden. Das simmuliert eigentlich das typische Benutzerverhallten.

27.05.2008 - 17:01 Uhr

Hrm, bevor sich jemand unnötigerweise die Mühe macht auf englisch zu Antworten 😉

Wenn das UserControl zur Laufzeit veränderbar sein soll, so kann man das über die WndProc via WindowsNachricht WM_NCHITTEST am leichtesten lösen.

Hier ein Link.

27.05.2008 - 00:04 Uhr

Na ja, denke das hat auch viel mit einem falschen Berufsbild zu tun wie auch vielen damit verbundenen Klischees.

Weis ja nicht wie es anderen geht aber die typischen Klischeefragen gerade richtung Äusserlichkeiten, Arbeitsumgebung Keller und das man ja niemals zwischenmenschliche Kontakte hätte, kommt bei mir eigentlich regelmäßig vor. Das einzige was mich ehrlich gesagt an diesen Beruf nur stört ist die übliche Frage:"Du kenntst dich doch mit Computern aus - ich hätte da mal so eine kleine Frage".

Vielleicht sind Frauen einfach auch nur schlauer und wollen sich gerade diesen Leidensweg spaaren 😉

26.05.2008 - 17:02 Uhr

Mehrdimensionale Arrays mit Jagged-Arrays gepaart.
Siehe Link.

Ich würde im ersten Schritt nicht zwingend alles mit Regex abbilden sondern versuchen erstmal Abschnitte nur auszulesen.

<Name> <Id> Neuer Knotenbezeichner
{ Hier beginnt neuer Knoten
} Hier endet Knoten
<Wert1> Wert in Knoten wenn "beginn neuer Knoten vorher == true".
\n\r neue Zeile
<> neue Spalte

Einfach etwas aufdröseln, denke regex kannst dir dann auch spaaren - aber das hängt eher davon ab was dir leichter fällt performance mäßig sollte sich da glaube ich das ganze kaum was schenken. Egal wie werden es schon einige schleifen sein, denke nur an das Thema rekursion.

26.05.2008 - 15:22 Uhr

Schau mal unter WMI "Win32_OperatingSystem".

BuildNumber
BuildType
Debug
OSType
Version

Irgendeins davon wird es sein.

26.05.2008 - 14:30 Uhr

Na ja, die breite des Rahmens vaariiert nicht nur zwischen den Styles der Betriebssysteme sondern vorallem der dafür verwendeten Windows Themes.

Nutze dafür eigentlich das normale Docking und lasse immer etwas abstand zwischen den Rahmen der Windows Form und den Controls. Dafür brauchst ja nur auf die Eigenschaften der Form im Designer gehen und unter Padding den Abstand einstellen - so 6px reichen im normalfall.

Du kannst auch alternativ um sicher zu gehen das deine Forms immer gleich aussehen WindowsThemes für deine Anwendung deaktivieren über die WindowsAPI.


 protected override void OnHandleCreated(EventArgs e)
      {
        SetWindowTheme(m.HWnd, "", "");
        base.OnHandleCreated(e);
      }


Du kannst auch den aktuellen Fensterrahmen abfragen und deine Controls entsprechend anpassen. Siehe dazu diesen Link.

Falls eigene WindowsBorder verwenden möchtest schau dir diesen Artikel an, es gibt zudem unter .NET-Komponenten und C#-Snippets hier im Forum einige Skinning Tools.

[Edit] norman_timo war schneller 😉

26.05.2008 - 12:35 Uhr

Hrm, habe das wie folgt gelöst, bin gerade an etwas ähnlichem dran nur in einem anderen Zusammenhang.


    private string ConvertToBase64(Bitmap bmp)
    {
      byte[] array = null;
      using (MemoryStream stream = new MemoryStream())
      {
        bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
        stream.Position = 0; // rewind
        array = new byte[stream.Length];
        stream.Read(array, 0, (int)stream.Length);
      }
      return Convert.ToBase64String(array);
    }

    private Image ConverToImage(string str)
    {
      Image img = null;
      using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(str)))
      {
        img = Image.FromStream(stream);
      }
      return img;
    }

26.05.2008 - 10:14 Uhr

Hrm, in der Firma in der ich zuvor gearbeitet habe gab es einen relativ hohen Frauenanteil. Von 6 Programmierern waren es einst 3 Frauen. Allerdings waren gut zwei davon Studentinnen und eine Halbtagskraft.

In der neuen Firma ist gerade mal eine Frau unter ca. 9 Programmierern, Studenten mitgerechnet. Allerdings ist jene als Freelancer unterwegs, was ich mal behaupten würde, noch seltener ist als eine Festangestellte Programmiererin.

Warum es so wenige Programmiererinnen gibt weis ich nicht, aber es ist schade. Mit Frauen arbeitet es sich genauso angenehm wie mit männlichen Kollegen. Hatte damals die Ausbildung der Studentinnen wie Studenten übernommen (nein bin nicht Ausbildungsberechtigt) und ohne das auf alle Beziehen zu wollen, es war mit den weiblichen Studentinnen nen kleinen Tick einfacher - die Zuverlässigkeit was Pünktlichkeit und auch die Übernahme von Aufgaben die man eigentlich nicht so gerne übernimmtwie Dokumentationen, wurden in der Regel etwas sorgsamer erfüllt. Was den Code anging, war es bei beiden Geschlechtern absolut gleich. Das einzige was mich immer noch wundert, waren die unterschiedlichen Bezugsgrößen. Männliche Kollegen bekamen in der Regel etwas mehr Gehalt, gerade die Einstiegsgehälter lagen höher als bei den weiblichen Mitarbeiterinnen.

Ansonsten kann ich kaum etwas berichten, die Arbeit wurde von beiden Geschlechtern immer Erfüllt.
Was extreme Belastbarkeit anging konnten auch Frauen mit hallten, hatte zwar nie von jemanden verlangt 36 Stunden durchweg durchzuarbeiten oder eine 70-90 Stundenwoche abzulegen.

Aber aufgrund einer damaligen Krankheit machte ich das ca. 2 Jahre lang. Dabei gab es einmal eine Studentin die ihr Projekt fertigbringen wollte und es ebenso schaffte 36 Stunden am Stück durchzuarbeiten – das hatte mich schon ziemlich beeindruckt. Musste sie dann mehr oder weniger zwangsweise nach Hause schicken, da mir sonst die Gefahr zu groß wurde das sie am Steuer einschläft 🙂
Natürlich ist das ein Unding und wiederholte sich nicht mehr, aber es hatte mich doch ziemlich beeindruckt.

Was Äußerlichkeiten angeht, denke ich kann man hier nicht verallgemeinern, in der Arbeit achte ich nicht darauf - von mir aus können die Leute auch in der Badehose im Sommer bei der Arbeit rumlaufen. Aber ich denke es gibt da keine Klischees, kenne auch nicht einen einzigen kleinen buckligen lichtscheuen Programmierer mit Bierbauch und schiefer Brille - also den Quasimodofaktor wird man wohl anderweitig suchen müssen.

25.05.2008 - 23:40 Uhr

Hrm, ich würde mal darauf tippen das textbox, listbox, combobox und andere controls manchmal aus mehreren Controls zusammengesetzt wurde. Schau mit dem Spy++ mal bei deinen gewünschten Controls nach ob diese aus mehreren bestehen - Wenn ja musst du natürlich an jedes Handle der Controls die WM_PAINT Nachricht schicken.

Ich kenne layerd windows nicht, daher... nur die Frage beantwortet 🙂

25.05.2008 - 23:28 Uhr

Hallo -hades-

Du hast das MSLLHOOKSTRUCT zwar drinnen aber verwendest es nicht 🙂


public delegate int mouseHookProc(int code, int wParam, ref MSLLHOOKSTRUCT lParam);

[DllImport("user32.dll")]
public static extern IntPtr SetWindowsHookEx(int idHook, mouseHookProc callback, IntPtr hInstance, uint threadId);

private int HookProc(int code, int wParam, ref Win32.MSLLHOOKSTRUCT lParam)
        {
            if (code >= 0)
            {
              usw..
            }
            return Win32.CallNextHookEx(this.m_hHook, code, wParam, ref lParam);
        }


Für den globalen Aufruf gibt es nun verschiedene Ansätze, ich verwende diesen hier wenn es global sein soll, wenn dein aufruf nur auf deinen Thread (GUi Thread) oder nur auf einer speziellen form laufen soll, melde dich nochmal.

Hier der globale Mousehook:


  private void InitHook()
        {
            this.HookProcHandler = new Win32.mouseHookProc(this.HookProc);
            this.m_hInstance = Win32.LoadLibrary("User32");
            this.m_hHook = Win32.SetWindowsHookEx(Win32.WH_MOUSE_LL, this.HookProcHandler, this.m_hInstance, 0);
        }

private void UnHook()
        {
            this.HookProcHandler = null;
            Win32.FreeLibrary(this.m_hInstance);
            Win32.UnhookWindowsHookEx(m_hHook);
        }

Natürlich musst den Code bei dir anpassen, wichtig ist hInstance. LoadLibrary, FreeLibrary und UnhookWindowsHookEx findest unter www.pinvoke.net

25.05.2008 - 23:10 Uhr

Na ja die Vorposter haben alle sammt schon recht.

Nur ganz ehrlich, greife manchmal lieber zu nen kleinen Trick als das mich dran mache ganze Programme umzuschreiben die ich zumeist nichtmal selber Programmiert habe und teilweise zwischen C++ und C# kunterbunt hin und herwechseln. Ich denke genau das ist halt auch hier der Punkt.

Denke darum war auch die Frage "eigener GUI" Thread, ich beantworte nur Fragen so gut wie ich kann und wie es die Zeit erlaubt 🙂

25.05.2008 - 22:45 Uhr

Tut mir leid war eine weile nicht mehr im Forum, war einfach zu schönes Grillwetter 🙂

Unter "Flags" findest du die Modifier.

25.05.2008 - 22:34 Uhr

Meine damit das am besten eine neue Klasse erstellst die von System.Windows.Form.NativeWindow ableiten solltest. Über base.Assert kannst du dann die WndProc Nachrichten abfangen 🙂

Theoretisch kannst auch eine Klasse erstellen diese von Form ableiten und dort die WndProc überschreiben, nur via Subclassing könntest du halt eine Komponente schreiben, diese würde es dir erlauben auf jede gewünschte und vorallem bestehende Form deine zusätzliche Buttons einfügen.

21.05.2008 - 21:50 Uhr

Muh, da hast dir was ausgesucht. Normal würde ich dich auf diesen Artikel verweisen: Eigene Window Rahmen zeichnen. Und auf die vielen codeproject Seiten wo die Leute eher naja tricksen mit ner Form ohne Border...

Aber das hier finde ich viel lustiger: Link

Wenn hilfe brauchst geb bescheid, aber im Prinzip einfach etwas kreativ sein:
Machs dir einfach, statt über nen PocHook nutze NativeWindow. Also eine Klasse erstellen diese leitet von NativeWindow ab und bei base.Assert nimmst das handle des übergebenen Fensters, rest ist echt gut lesbar aus dem C++ code.

Und wenn schlau bist, mach ne Komponente draus und nutze dazu den IExtenderProvider. Mit der Komponente kannst dann im designer diese einfach auf ein form ziehen und deine Buttons sind da. Und wenn ganz viel Geduld hast machst die Buttons generisch so das im Designer buttons über die Propertielist hinzufügen kannst.

Achja deine Buttons sind natürlich grafische objecte, innerhalb dieser Klassen machst einfach nen KlickEvent und reagierst beim subbclassing wie auf der seite beschrieben auf die WindowsNachricht WM_LBUTTONUP - nicht das WM_LBUTTONDOWN. Warum merkst wenn mal auf den minimize Button deines Browsers Klickst und dabei die Taste gedrückt hällst. Der Browser minimiert nicht gleich, sondern wartet auf MouseUp wenn der Button noch im Focus ist !

21.05.2008 - 21:29 Uhr

Schau, bei JAck30lena geposteten Links geht es Hauptsächlich darum das du verstehst das statt Stupide nur auf den Button oder MouseDownEvent zu reagieren und mühevoll etwas hinzukritzeln mit Grafischen Objecten arbeitest solltest.

Grafische Objecte sind eine Ansammlungen von Klassen welche Größe und Form einer grafischen Darstellung beinhalten so wie einer Methode zur Übergabe der Zeichenobjects, der Klasse Graphics.

0 Punkt Koordinatensystem wäre im Normalfall sollte das Koordinatensystem nicht gespiegelt sein, wie michlG schon schrieb. PictureBox.Width / 2 = float X und ictureBox.Height / 2 = Y float .

Punkt P erhältst du beim abonnieren des MouseDown Ereignisses vom PictureBox der X und Y Wert von e.Location in Bezug zum 0 Punkt. Sprich, das was michlG schon postete:
0X – e.Location.X = (float) pX und 0Y – e.Location.X = (float) pY.

Das resultierende Ergebnis von Punkt P speicherst dir global in eine Hilfsvariable.
Da ja nur vom 0 Punkt aus ein Rechteck zeichnen möchtest reicht das auch schon, beim klicken auf dem Button erstellst dann ein neues Grafisches Object, also eine new myDrawingKlasse(<Point 0 Punkt>, <Point P>);. Diese speicherst du dann in eine Liste wie z.B. List< myDrawingKlasse>.

Bei der OnPaint Methode die du ebenso vom PictureBox abonnierst gehst du dann deine Liste von myDrawingKlasse durch und ruft myDrawingKlasse.Draw(<Graphics>) auf. In der MyDrawingKlasse in der Methode Draw kümmerst dich um e.Drawrectangle das diese das Rectangle aus den Bezugsgrößen vom Konstruktor übergebene Parameter erhällt, deinen 0 Punkt wie des Punkt P..

Und schon bist fertig, denke hast das schneller geschrieben als die Leute hier gebraucht haben das zu tippen 😉

Später denke ich blickst dann durch wie du ohne vom 0 Punkt auszugehen zeichnen kannst und dann kannst dich auch mal dranmachen dr4g0n76 QuadTree zu integrieren (siehe dazu Link von JAck30lena).

21.05.2008 - 18:24 Uhr

Sieh dir noch im diesne Zusammenhang folgende Dinge an:

System.ComponentModel.IExtenderProvider
System.Drawing.Design.UITypeEditor
System.ComponentModel.ProvideProperty
System.ComponentModel.ISupportInitialize
System.ComponentModel.DesignTimeVisible

21.05.2008 - 17:54 Uhr

Na ja, dann sollte WMI die erste Wahl sein.

Möchtest dennoch zwingend den Weg gehen und ich kann dir wie gesagt nur WMI dann nahe legen kannst mal folgendes versuchen.

Öffne mal den Ole/Com Viewer, den gibts auch bei der neuen WebInstall für Microsoft Windows SDK Server 2008 als Tool beigelegt. Ansonsten irgendwo im VS Installationsverzeichniss sollte der sich glaube ich auch verstecken.

Dort schaust unter den Type Libraries mal nach ob dir irgendwelche Schnittstellen zur verfügung stehen. Über Type.GetTypeFromCLSID(); oder Type.GetTypeFromProgID(); solltest drankommen, manchmal findest auch nen OCX im WindowsVerzeichniss aus dem dann die Schnittstellen importierne kannst via tlb import. Wenn viiiel Glück hast gibt es evtl. ne interop.XXXX.dll die direkt im Projekt unter Referenzen hinzufügen kannst.

Denke bei sowas spezifischen wirst ohne ein wenig Vorschungsarbeit nicht herumkommen, evtl. bietet dir google eine fertige Antwort.

Ansonsten, sorry, habe mit der exe noch nicht herumgespielt 🙂

21.05.2008 - 17:43 Uhr

Hrm, naja du kannst auch Kompositionen erstellen z.B. indem ein DesignPattern verwendest.

Bei einem Hauptformular das Tool's z.B. über Menüpunkte bereitstellt oder irgendwelche "Sonderaktionen" denke ich da meistens an das CommandPattern mit CommandActions.

Das ganze dröselt sich wie folgt auf, statt für jeden Button nun Mühselig einen ClickEvent zu implementieren und in den entsprechenden gebundenen Methoden mühselig eine Aktion auszuprogrammieren die sich evtl. sogar wiederholt oder im schlimmstenfall sogar wieder rückgängig gemacht werden muss (Undo / Redo) kannst du auch folgendes angehen:

Beim deklarieren deiners MenuItems gibst du die zu verwendende Komposition mit.
Das sieht ca wie folgt aus:


public class MenuAction
    {
      public enum Commands
      {
        CMD_NONE = 0,
        CMD_COPY,
        CMD_PRINT,
        CMD_SAVE
      }

      private Commands m_eCommand;

      public MenuAction(Commands _eCommand)
      {
        this.m_eCommand = _eCommand;
      }

      public void Execute(object sender, EventArgs arg)
      {
        switch (this.m_eCommand)
        {
          case Commands.CMD_SAVE:
            {
              using (SaveFileDialog dlg = new SaveFileDialog())
              {
                // usw...
              }

              break;
            }

          case Commands.CMD_PRINT:
            {
              break;
            }
        }
      }
    }


MenuItem mi = new MenuItem("Save", new MenuAction(MenuAction.Commands.CMD_SAVE).Execute);

Natürlich wird das ganze noch etwas besser wenn man diese Actions wie das MenuAction noch etwas mehr ins OOP einbindet. Das sähe wie folgt aus:


    public interface ICommand
    {
      void Execute(object sender, EventArgs arg);
    }

    public abstract class Commands : ICommand
    {
      public abstract void Execute(object sender, EventArgs arg);
    }

Da ich nun alle Commands sei es nun MenuAction, ButtonAction, FormAction usw. auf eine gemeinsamme Basiesklasse gebracht habe und zudem die Schnittstelle ICommand verwende könnte ich nun über eine Liste alle ICommands speichern die ausgelöst wurden, somit kann ich die Aktionen in der Liste auch wieder Rückgängig machen. Ausserdem habe ich viele Aktionen in einzelne Kompositionen ausgelagert. Zudem könnte ich nun das Observer Model einbinden z.B. für Fehlerbehandlungen oder sogar für's mitloggen aller Aktionen. Theoretisch kannst auch unendlich viele Aktionen erstellen.

Das sähe ca so aus:


    public abstract class Commands : ICommand
    {
      // hier kann ich meine Events binden
      public virtual void Execute(object sender, EventArgs arg)
      {
        this.Execute();
      }

      // hier kann ich manuell aufrufen oder z.B. Threads binden
      public abstract void Execute();

    }

Im Prinzip wenn ein DesignPAttern verwendest reduziert sich der Code pro Klasse und wird zumeist übersichtlicher. Du kannst auch andere Patterns Verwenden 🙂

21.05.2008 - 16:09 Uhr

Hallo Ayke,

du kannst das ganze beim LowLevel hook über die KBDLLHOOKSTRUCT abfragen, so weden dir schon über die Struktur alle relevanten Informationen gegeben wie Tastenkombinationen und was bei Fremdsprachen passiert.

Kannst dir auch mal die UtilitiesLib ansehen, habe dort eine Komponente geschrieben für Keyboard Hook's allerdings hatte ich da die Modifier vergessen, die kannst ja dann rauslesen istja nicht mehr viel Aufwand. Ansonsten im Forum gibt es viele Hook Beispiele von rein C# bis hin zu C++.

21.05.2008 - 16:02 Uhr

Hrm, das kommt nun ganz darauf an was mit dem Icon vorhast, willst es anklicken können und soll dann ein Event geschmissen werden ? Oder soll nur nen Bild dargestellt werden?

Den je nachdem fällt die Antwort bzw. vorallem der Aufwand aus.

21.05.2008 - 15:57 Uhr

Hallo soucy,

Um die Systeminformationen auszulesen solltest eher die .Net eigenen Hausmittel verwenden.

**
System.Windows.Forms.SystemInformation
System.Environment
WMI**

Wenn einfach nur faul bist dann kannst auch den MSInfo32.exe starten entweder über System.Diagnostics.Process oder über die Registry Software\Microsoft\Shared Tools\MSInfo und via Windows API SetParent in dein Form (Fenster) miteinbinden.

21.05.2008 - 14:16 Uhr

Hrm, WM_PAINT Nachrichten können auch explizit aufgerufen werden durch WIN API Befehle wie z.B. UpdateWindow oder RedrawWindow.

RedrawWindow(hWnd, ref rec, IntPtr.Zero, (uint)RDW_VALIDATE | RDW_UPDATENOW);

Aber das ganze wirkt auch nur bedingt, wenn andere Aufrufe von GetMessage und / oder PeekMessage erzeugt werden, wie z.B. beim Resize oder Verschieben kommt es trotzdem zu Fehlern. Da die Fenstergröße bei WM_NCCALCSIZE z.B. dann falsch berechnet wird und somit der zu zeichnende Bereich, dem wie zuvor entspricht, statt einem neuen. Es können auch noch nen paar mehr Nachrichten damit im Zusammenhang auftauchen, müsste man dann nachschauen.

21.05.2008 - 12:11 Uhr

args[0]="C\hallot.txt"

args[0]=@"C:\hallot.txt";

[Edit]
Hätte mal besser alles lesen sollen 😦

Also bei mir kommt ebenso erfolgreich -1

21.05.2008 - 10:59 Uhr

System.IO.Path.GetExtension

21.05.2008 - 10:37 Uhr

Hrm, habe mir den Code mal angesehen und leide rbist immer noch auf dem selben GUI Thread, darum konntest auch kein Application.Run() verwenden. Und deshalb brichst dir auch einen ab bei der gesammten Kommunikation.

Hier mal nen Copy&Paste Beispiel.
Mach dafür einfach mal nen neues Projekt als Windows Forms Application - standardmäßig wird Form1 erstellt und die Klasse Programm, in der Klasse Programm wird in Main via Application.Run(new Form1()); aufgerufen.

Erstell nun einfach eine zusätzliche Form2 und kopiere den Code mal rein.


	public partial class Form2 : Form
	{
		private static Form2 m_frm2 = null;

		private static void Init()
		{
			if (m_frm2 == null)
			{
				Application.Run(new Form2());
			}
		}
		/// <summary>
		///
		/// </summary>
		public static void ShowAsGUIThread()
		{
			new Thread(new ThreadStart(Init)).Start();
		}

		private Form2()
		{
			InitializeComponent();
		}

	}

Geh dann in Form1 und kopiere diesen Code mal rein:


		public Form1()
		{
			InitializeComponent();
			Form2.ShowAsGUIThread();
		}

Und wenn nun das ganze mal debbugst und mit Spy++ ansiehst wirst sehen beide haben andere Threads gehören aber zum selben Prozess.

Wie gesagt der Trick um nun mit Form2 zu Komunizieren besteht darin Form2.Instance ein Statisches Propertie aufzurufen das statt Form2 zurückzugeben, nur ein Interface zurückgibt mit begrenzten Methoden und Properties. Wie die Properties bzw. Methoden dann angesprochen werdne müssen sieht über den Link von herbivore.

Einen eigenen GUI Thread zu erzeugen ist somit ganz einfach, es kommt immer nur darauf an ob dieser einen Sinn hat oder nicht.

20.05.2008 - 17:27 Uhr

Na ja, du hast ja die Möglichkeit mit Multithreads zu arbeiten.

Du erstellst eine Klasse bei der im Konstruktor als übergabe den Process mitgibst, im konstruktor instanzierst du das Process.Exist Event.

Jedesmal wnen dein WMI Event anspringt machst folgendes:


new System.Threading.Thread(new System.Threading.ThreadStart(new Klasse(process).Run)).Start();

Über Waithandels könntest sogar die einzelnen Threads in einem ThreadPool überwachen.

20.05.2008 - 15:53 Uhr

Hallo DrStupid 😉 (netter Nick)

Auf Codeproject findet man reichlich davon diesen hier z.B: Link.

20.05.2008 - 15:47 Uhr

Hrm, dr4g0n76 hatte sich mal damit befasst, allerdings weis ich nicht ob die in mycsarp veröffentlichte Version das gesuchte kann oder ob er noch zum runterladen bereit steht.
Siehe hierzu diesen Link.

Ansonsten hilft vielleicht eine freundliche PN an dr4g0n76 wobei ich nicht weis ob er derzeit reinschaut - hat viel zu tun 🙂

20.05.2008 - 15:42 Uhr

Hrm, würde dir raten weiterhin Application.UseWaitCursor zu arbeiten und stattdessen die Operationen in Threads auszulagen und via Multithreading (also WaitHandles) zu arbeiten. Und schlussendlich wenn alle WaitHandels abgearbeitet sind setzt den Cursor wieder zurück.

20.05.2008 - 14:28 Uhr

Hrm, mich wundert's wirklich das die Event's nicht ankommen.

du kannst auf das MouseMove der kleineren 9 Panels mal versuchen zu reagieren und schauen ob die Nachrichten ankommen. Wenn ja nimmst ne boolische Variable die auf true oder false gestellt wird wenn MouseMove für Panel1 z.B. schon ausgeführt wurde, quasi das selbe wie oben gepostet nur das alle MouseMoves der jeweiligen Panels auf die Methode gebunden werden.

Ansonsten, schau mal im Forum nach global Mouse Hook's und schau das der MouseHookProc auf das Handle deines großen Panels zeigt. So das der 0 Punkt beim großen Panel liegt und nicht auf der Form, dann kannst da auf Mousemove reagierne und das ganze wie oben gepostet angehen.

Aber vielleicht weis ja jemand woran es liegt und warum die Event's nicht ankommen oder hat eine leichtere Lösung parat.

20.05.2008 - 14:16 Uhr

Ich hab mir Khalid's Vorschlag nochmal durch dne Kopf gehen lassen und eigentlich sollte das auch gehen. Zwar wäre das dann ein klassischer Trojaner bei dem Die Virenscanner zwar drauf anspringen sollten aber gehen würde es.

Man müsste das nur in Verbindung mit CreateRemoteThread angehen, wenn man davon ausgeht das ein zeiger nur eine variable ist so könnte man den assembler code überlisten. Indem man mit WriteProcessMemory eine struktur mit eben den aufrufen deiner Methoden via DLLImport in deinen Prozess reinschreibt.

Denke das geht sicherlich auch, bin mir nur nicht sicher ob das in C# wirklich abbildbar ist.

20.05.2008 - 13:43 Uhr

Hrm, mich wundert es zwar das kein MouseEnter ausgelöst wird aber versuch folgendes, schau erstmal nach der DragAndDrop Eigenschaft das die = false ist auf den Panels.

Sollte es dennoch nicht gehen oder du brauchst die DropAndDrag = true Eigenschaft dann kannst du folgendes angehen:

Da deine Panels nebeneinander liegen, nimm ein großes Panel auf dem deine 9 Panels eingebunden nebeneinander liegen. Regiere nun bei dem großen panel auf MouseMove und wenn GetChildAtPoint(e.Location) is Panel1 usw ist dann kannst du da ja reagieren.

Ca. wie folgt:


    Panel PanelGroß = new Panel();
    Panel panelChild1 = new Panel();
    Panel panelChild2 = new Panel();
    private bool ChangedPanel = false;
    void PanelGroß_MouseMove(object sender, MouseEventArgs e)
    {

     Panel child = PanelGroß.GetChildAtPoint(e.Location) as Panel;

     if (child == panelChild1 && !ChangedPanel)
     {
       // mouse enter panel...
       ChangedPanel = true;
     }
     else if (child == panelChild2 && !ChangedPanel)
     {
       // mouse enter panel...
       ChangedPanel = true;
     }
     // usw..
     else
     {
       ChangedPanel = false;
     }
    }

/Edit:
norman_timo war schneller 😉

20.05.2008 - 13:20 Uhr

Und hier der für unmanaged, wenn auch etwas komplexer:


		[DllImport("kernel32.dll")]
		static extern IntPtr LoadLibrary(string csFileName);

		[DllImport("kernel32.dll")]
		static extern IntPtr GetProcAddress(IntPtr IntPtr_Module, string csProcName);

		[DllImport("kernel32.dll")]
		static extern bool FreeLibrary(IntPtr IntPtr_Module);

		private delegate int myFunctionDelegate();
		private myFunctionDelegate Invoke = MyFunction();

		public void bla()
		{
			// hier kannst dir ja noch was besseres einfallen lassen
			using (MemoryStream ms = new MemoryStream(Properties.Resources.MyLib))
			{
				using (FileStream fs = File.Create(@"C:\MyLib.dll"))
				{
					fs.Write(ms.ToArray(), 0, (int)ms.Length);
					fs.Flush();
				}
			}

			int test = Invoke();
		}

		private static myFunctionDelegate MyFunction()
		{
		
			IntPtr hMod = LoadLibrary(@"C:\MyLib.dll");
			IntPtr hFunction = GetProcAddress(hMod, "MyFunction");
			///FreeLibrary(hMod); // kann sein dass das erst nach dem return passieren sollte
			return Marshal.GetDelegateForFunctionPointer(hFunction, typeof(myFunctionDelegate)) as myFunctionDelegate;
		}

Musst halt etwas dran rumpfeilen, konnte es nicht testen.

20.05.2008 - 12:51 Uhr

Hrm, es gibt wieder viele Wege das zu lösen 🙂
Hier der einfachste für .NET.


// myInjection.dll
//namespace myInjection
//{
//  public static class MyTest
//  {
//    public static int Test()
//    {
//      return 1;
//    }
//  }
//}

		public void bla()
		{
			Assembly assembly = Assembly.Load(Properties.Resources.myInjection);

			MethodInfo method = assembly.GetTypes()[0].GetMethod("Test"); // die methode

			int ret = (int)method.Invoke(null, null);

		}

20.05.2008 - 10:51 Uhr

Hrm, kann dir nur nahe legen mal die neue Windows SDK for Windows Server 2008 and .NET Framework 3.5 herunterzuladen. In den Dokus für Win 32 findest eigentlich immer eine sehr exakte Beschreibung der jeweiligen Windows API Funktionen 🙂

Dauert nur nen weilchen mit dem ziehen sind 1,3 GB mit allen drum und dran, die Windows SDK Doku sollte etwas kleiner sein, falls nur diese möchtest - kannst das über den Webinstaller vorher dann auswählen.

20.05.2008 - 10:46 Uhr

Hrm, was für ein Betriebssystem benutzt du den? Muss zugeben habe das bisher nur auf Vista und Xp mal benutzt und von herbivore weis man nun, das es auch unter Windows 2000 geht.

Vielleicht hast ja Vista oder Xp Home und es könnte damit im Zusammenhang zu Problemen kommen?

20.05.2008 - 09:58 Uhr

Hallo HeikoRq,

wie folgt könntest du das Problem versuchen zu lösen.

PID Problem:
Hier kannst du anhand von WMI nach Win32_Process über Name schauen wann "Mozilla Firefox" gestartet wird, über einen Scope lässt du dir ein Event schmeissen über den du dann die ProcessId bekommst. Siehe hierzu einfach im Forum nach, gibt etliche Beispiele dafür 🙂

Über Process bekommst ja das MainWindow Handle. Ich habe mal über dne Spy++ nachgesehen was eine Flashapplication in Mozilla ausmacht und anscheinend kannst du tazächlich über die Win32 API FindWindowEx nach Fenstern suchen vom Klassentyp MozillaWindowClass und somit das Handle ausfindig machen. Wenn du mehrere Flashplayer Animationen auf der Seite hast kannst du anhand von Win32 API EnumWindows über die ProzessId von Mozilla alle Flashplayer Fenster über FindWindowEx ausfindig machen.

Nachdem du nun das Handle oder die Handles von den Flashplayerfilmen ausfindig gemacht hast, kannst du via Win32 API PostMessage Nachrichten wie Tastenkombinationen oder Mausbewegungen seinden. Du kannst anstatt PostMessage auch bei Tastaturkombinationen wie ALT+F1 oder Mauskombinationen wie, bewege Maus zu koordinate X,Y und drücke Linke Maustaste - via win32 API Funktionen keybd_event und mouse_event senden, somit kannst auch PostMessage weglassen.

Die Win API Befehle findest unter www.pinvoke.net. Ein Tipp zur Realisierung, da über WMI nach den Prozessstart von Mozilla Firefox suchst, muss deine Anwendung ja dauerhaft darauf warten bis das Event anspringt. Für ein solches Überwachungsprogramm empfiehlt es sich meistens eine NotifyIcon (Systray) Anwendung zu schreiben - wie man diese realisiert findet man ebenso hier im Forum.

19.05.2008 - 13:49 Uhr

Grml, okay den habe ich bisher nicht entdeckt. Aber der ist nicht Bunt! 🙂

@ Macximilian
Jup genau das meinte ich - nur eben mit einen Assistenten. Also eine Form das auf nen Panel z.B. UserControls reinladet mit Step by Step Anweisungen. UserControls daher da je nach WMI Abfrage das ein oder andere Assistentverhallten sich stark verändert oder gänzlich unterscheidet.

Noch eine Idee wäre über Aspektorientiertes Programmieren einen Logger zu schreiben. Sowas wie log4Net nur das man z.B. über Methoden ein Attribut mitgibt wie z.B.


    [MyErrorProvider(), Fehlerstufe(4)]
    private object test = "bla";
    public int Count
    {
      get 
      {
        return (int)test;
      }
    }

Wenn nun ein Fehler eintritt wird dieser automatisch je nach Loglevel z.B. nach aussen gegeben oder in einen Try Catch abgefangen und der Standardtypenwert zurückgegeben wie hier z.B. eine 0, oder der Fehler wird in die Ereignisanzeige zurückgeschrieben usw.