Laden...

Forenbeiträge von PoWl Ingesamt 219 Beiträge

12.10.2009 - 20:04 Uhr

Danke,

ich hab OnStartup überschrieben und somit funktionierts 😃

12.10.2009 - 18:05 Uhr

Hi,

tut mir leid dass dieser Thread einen so unverständlichen Titel hat. Ich habe nach folgendem Schema:

mehrere Programminstanzen verhindern?

.. meine Grund-Klasse von WindowsFormsApplicationBase abgeleitet um eine SingleInstance Anwendung zu realisieren. Bei erneutem Start der Anwendung soll eine Meldung in der bereits laufenden Anwendung aufpoppen und sich die gerade eben neu gestartete sofort wieder beenden. Allerdings funktioniert das nicht so ganz.

Denn in meinem Fall wird im Konstruktor der Klasse Program eine serielle Verbindung aufgebaut. Natürlich funktioniert das nicht, wenn diese in einem anderen mit dem gleichen Port schon aufgebaut wurde, und das gibt dann eine nette Fehlermeldung. Diese Fehlermeldung sollte aber garnicht erst erscheinen, da im OnStartupNextInstance EventHandler ja schon eine Meldung aufpoppt und die nächste Instanz eigentlich automatisch geschlossen werden sollte.

Was kann man da machen? Ich habe schon probiert nach dem Run-Befehl in der Main Methode die serielle Verbindung aufzubauen aber da tut sich natürlich nichts mehr.

lg PoWl

12.10.2009 - 12:01 Uhr

Ah na das ist ja super. Habs auch gleich hinbekommen 😃 Dankeschön!

11.10.2009 - 23:42 Uhr

Klingt interessant mit ILmerge. Leider verstehe ich absolut nicht wie man das Ding bedient.

10.10.2009 - 02:25 Uhr

Das ganze auf zwei Forms aufzuteilen dient mehr Designzwecken. Ich mag für jede Extrafunktion ein kleines schnuckliges Form haben. Noch dazu sind die Forms rahmenlos. Siehe Anhang.

10.10.2009 - 01:25 Uhr

D.h. wenn ich irgendwelche zusätzlichen Funktionalitäten in meine Software einbaue wie z.B. den Wecker kann es durchaus sein, dass ich an dem Teil der nur für die Beleuchtung zuständig ist, auch was werkeln muss. Z.B. einen FadeIn, der eignetlich nur vom wecker benutzt wird und ohne den garnicht benötigt würde.

Ich tu mir da grad immernoch ein wenig schwierig. Ich würde das Wissen darüber, wie geweckt wird, eindeutig dem Wecker-Teil zuordnen. Er regelt zwar die Beleuchtung aber nur er muss wissen, wie. Gäbe es den Wecker nicht, gäbe es auch den FadeIN nicht.

Und was ist, wenn ich es so mache wie anfangs beschrieben, dass ich Form1 nur zur Visualisierung benutze und für die Steuerung der Beleuchtung eine statische Klasse verwende?

10.10.2009 - 00:56 Uhr

Diese Vorgehensweise ist übrigens ziemlich dirty, weil die MouseMoves nicht mehr so funzen, wie jeder das von jedem Control erwartet.
Evtl besser ein eigenes Event implementieren, "MouseDownOutOfCircle" oderso 😉.

Ah, gute Idee, nur.. wie mache ich, dass mein MouseDownOutOfCircle-Event auch gefeuert wird?

Die OnMouseDown überschreiben?

{
base.OnMouseDown(blablabla);

  if(Zeiger ist im nicht Kreis)
  {
    OnMouseDownOutOfCircle(blablabla);
  }
}

Werden die standard-Events vom System gefeuert oder steckt da auch wieder ein stückchen software dahinter?

kann das event dann auch im VS im editor angezeigt werden?

10.10.2009 - 00:49 Uhr

D.h. Form1 muss zwangsläufig wissen, wie man weckt. Und Form2 weiß, dass geweckt werden soll und wann, und wie lange.

Das ist aber trotzdem nicht besonders modular. Ich stell mir den Idealfall so vor, dass ein Teil der Software nur für die Beleuchtung an sich zuständig ist und der andere Teil für den Wecker, und der Wecker sagt dem Beleuchtungsteil, wie es die Lichter hochzufahren hat. Das Beleuchtungsteil sagt ihm noch wann es aufhören muss. Und zwar so,dass möglichst keine Weckerspezifischen Funktonen in Form1 übrig bleiben, wenn ich den Wecker irgendwann aus dem Programm ganz einfach entfernen wollte.

Oder denk ich da zu modular?

10.10.2009 - 00:29 Uhr

Das stünde doch aber wieder im Gegensatz zur Modularität. Die Weckerfunktion soll sich eigentlich nur komplett auf Form2 beschränken, Form1 soll damit nix zu tun haben.

10.10.2009 - 00:22 Uhr

Nein, ErfinderDesRades, das was du beschreibst ist das, was ich gerne erreichen würde. Es ist momentan schon so, dass das Label einen viereckigen Bereich definiert, auf dem kein Event ausgelöst wird, da dieser zum Label und nicht mehr zum Form gehört. Ich hätte aber gerne, dass der Bereich, der im Label außerhalb des Visualisierungsbereichs liegt, zum Form angehört bzw. dass meine Mausevents darauf reagieren.

Ich habe das Label halt als dll vorliegen, natürlich auch als Source, es wär kein Problem es so umzubauen. Wenn ich die Events auch beim Label registriere befindet sich der EventHandler dann aber in der Form-Klasse. Und um eine Kollisionserkennung mit dem Kreis zu machen müsste ich zugang zum Graphics-Objekt haben. Andernfalls könnte ich mein Label auch so umprogrammieren, dass es mir eine Methode bereitstellt, die mir einen einfachen boolschen Wert zurückgibt, der mir sagt, ob sich der Mauszeiger gerade im Visualisierungsbereich befindet oder nicht. Meine eigens erstellte Label-Klasse erbt ja von der richtigen Label-Klasse. Kann ich darin dann nicht auch das MouseDown Event so verändern, dass es nur ausgelöst wird, wenn sich der Mauszeiger nicht im Visualisierungsbereich befindet?

09.10.2009 - 22:33 Uhr

Hi,

ich möchte eine kleine Speiseplan Verwaltung für ein Altenheim Schreiben und brauche dafür auch einige Druck-Funktionen. Da ich nicht gern alles selbst zeichne um es dann rauszudrucken und eine Template-Funktion, die die Verwalterin auch selbst ganz einfach nutzen kann, äußerst nützlich wäre, dachte ich daran, ein paar vorgefertigte Word-Tabellen wie z.B. die Tabelle für den Speiseplan oder die Tabelle mit der Liste, wer welches Essen bekommt, einfach als .doc Datei zu speichern, in die entsprechenden Stellen bestimmte Platzhalter einzubauen wie z.B. <Menü-A_Montag> und diese dann per C# füllen zu lassen.

Eine bestimmte Tabelle müsste sogar komplett dynamisch erzeugt werden, da dort die Anzahl der Zeilen von der aktuellen Bewohnerzahl abhängt.

Wie gehe ich an die Sache ran?

lg PoWl

09.10.2009 - 20:44 Uhr

Das Problem ist, dass ich aus dem Steuerelement eine eigene dll gemacht habe und somit gar kein Zugriff auf das Graphics-Objekt habe um das vom Event-Handler aus zu prüfen.

Außer, ich würde das Graphics-Objekt öffentlich zugänglich machen.

09.10.2009 - 19:43 Uhr

Hi, zu meinem Programm: Ich habe am PC ein kleines Hardware-Interface um zwei Lampen zu steuern. Dazu eine Software über RS-232 mit dem Hardware-Interface kommuniziert.

Beim Start der Software wird Form1 geöffnet, aber erstmal nicht angezeigt. Über Form1 wird auch ein notifyIcon erzeugt. Form1 enthält zwei Trackbars, mit welchen die Lichtintensität gesteuert werden kann. Dann gibt es noch ein Form2, das wird aus Form1 heraus instanziiert und bleibt ebenfalls erstmal im Hintergrund bis es aus dem Contextmenü von notifyIcon1 heraus sichtbar gemacht wird. Dieses Form2 soll einen Zusatz darstellen, nämlich einen Lichtwecker. Darin kann man den Wecker einschalten und eine Uhrzeit einstellen, zu der das Licht langsam eingefadet werden soll. In Form2 befindet sich demnach auch ein Timer um die Uhrzeit bei aktiviertem Wecker abzufragen und ein weiterer Timer, der beim Weckvorgang eingeschaltet wird und jede Sekunde einmal das Licht ein stückchen heller schaltet. Und genau das ist das Problem.

Der Timer muss für die Erhellung des Lichts sorgen in dem der die Trackbar bei jedem Tick um 1 nach oben schiebt. Wenn das nicht mehr möglich ist, muss die Trackbar den Wecker darüber in Kenntnis setzen, dass das Licht nun vollständig an ist, woraufhin sich der Timer abschaltet. Ebenso soll dieser FadeIn durch ein manuelles Bedienen der Trackbar abgebrochen werden, wodurch wieder der Timer aus Form2 in kenntnis gesetzt werden muss, was ja aber kein Problem ist, da Form1 ja Form2 sehr wohl kennen darf und die entsprechende Funktion um den Weckvorgang abzubrechen ganz einfach aufrufen darf.

Aber irgendwie passt mir der ganze Umstand mit den Events überhaupt nicht. Auf der einen Seite stellt Form1 eine Methode bereit um die Erhöhung des Trackbar.Value zu kapseln, welche von einem Event in Form2 abonniert wird, das manuell jede Sekunde im Timer-Tick ausgelöst wird. Andererseits löst dann Form1 wieder direkt in Form2 eine Methode aus, welche den Vorgang abbrechen kann. Da verschwimmt die ganze Hierarchie irgendwie. Form1 und Form2 sind eigentlich eher gleichwertig, sollten sich untereinander kennen und gegenseitig auf sich zugreifen können.

Wie sollte ich das besser machen? Mein erster Gedanke ist:

  • Das notifyIcon als Haupelement des Programms ansehen und dieses als static definiert aus der main-Methode heraus starten, ebenso die SerialPort Verbindung.
  • Form1 und Form2 aus Main heraus instanziieren.
  • Form1 und Form2 direkt? oder über Events? mit der Verbindung kommunizieren lassen.

Form1 dient dann nur noch als Visualizer, allerdings muss es irgendwie auch ne Möglichkeit geben, dass es in Form2 den Weckvorgang unterbricht sobald man die Trackbar von Hand bedient.

Oder soll eine extra Klasse für die Kommunikation mit dem Hardware-Interface geschaffen werden? Da kann ja die Program-Klasse in der auch die Main liegt.

Irgendwie noch alles nicht so ausgereift.
Wenn ichs Quick&Dirty programmieren wollte würd ich einfach nun Form2 mit Form1 kommunizieren lassen, aber ich möchts als Übung ansehen und daher so richtig wie nur möglich machen.

Danke fürs Durchlesen und für alle Antworten!
lg PoWl

08.10.2009 - 14:34 Uhr

Es wird natürlich als Fake eingestuft, da es ja auch vom Label und nicht vom Form ausgelöst wird. Fakt ist, es ist ein MouseLeave. Wie soll ich jedoch nun richtig prüfen ob die Maus das Form denn tatsächlich verlassen hat? Zum Zeitpunkt wenn das Event ausgelöst wird befindet sie sich ja noch im Form. Erst dann springt sie heraus, wodurch aber kein weiteres Event mehr ausgelöst wird. Ich könnts mal mit einem MouseLeave-Event im Label probieren.

//Edit: OK, wenn ich allen MouseLeave Events noch den Eventhandler des Form1 zuteile kriege ich auf jeden Fall als letztes ein "echtes MouseLeave" wenn der Mauszeiger auch nur irgendwie herausgekommen ist.

Es gibt doch sicher eine Möglichkeit sich ein Array mit den Referenzen auf die Steuerelementen, die ein Form besitzt ausgeben zu lassen. Damit könnte ich bei allen automatisch den Eventhandler setzen.

08.10.2009 - 13:42 Uhr

Naja die Fake-Erkennung verhindert ja nur, dass ein MouseEnter bzw. MouseLeave Event eine bestimmte Aktion ausführt obwohl der Mauszeiger sich nicht aus dem Fenster heraus sondern nur auf ein darinliegendes Steuerelement bewegt hat in dem es die Mauskoordinaten prüft. Das funktioniert schon und ist ganz simpel. Ich habe mir die Koordinaten schon ausgeben lassen und angeguckt, da stimmt soweit alles.

Wenn ich mit dem Mauszeiger wie beschrieben aus dem Fenster heraus schnell über das Label in der linken oberen Ecke drüberziehe. Kriege ich teilweise nur ein "Fake MousLeave". Und zwar dann wenn der Mauszeiger gerade das Label berührt. Fake MouseEnter und echter MouseLeave bleiben dann leider aus. Wenn beim Verlassen des Fensters dann aber nicht nochmal ein Event ausgelöst wird kann ich dann auch keine Aktion mehr ausführen. D.h. ich müsste wohl einen Timer oder sowas bei jedem ausgelösten Event starten, der mir dann nochmal separat prüft, ob sich der Mauszeiger inzwischen außerhalb des Fenster befindet und dieses somit verlassen hat. Richtig?

lg PoWl

07.10.2009 - 23:14 Uhr

Hi,

ich habe ein Steuerelement von Label abgeleitet um darin erstens einen Text anzeigen und noch einen runden, dicken Kreis drum herumzeichnen zu können. Der Kreis ist per MouseClick anklickbar und hat eine bestimmte Funktion.

Das ganze befindet sich in einem Form ohne Rahmen, d.h. man kann dieses Form nur über den Bildschirm bewegen indem man dort auf eine beliebige Stelle klickt und es mit geeigneten Eventhandlern für die Ergeignisse MouseDown, MouseMove und MouseUp wie gewohnt herumzieht. Das funktioniert allerdings nicht wenn ich mich mit dem Mauszeiger in dem rechteckigen Bereich des Label-Steuerelements aber nicht innerhalb des gezeichneten Kreises befinde. Und genau hier soll es trotzdem funktionieren. Leider kann man keine Transparente als Hintergrundfarbe des Steuerelements auswählen.

Gibts da eine andere Lösung?

07.10.2009 - 18:27 Uhr
    private void Form1_MouseLeave(object sender, EventArgs e)
    {
      if (!RectangleToScreen(ClientRectangle).Contains(MousePosition))
      {
        mouseout = true;
        Console.WriteLine("Echter MouseLeave!");
      }
      else
      {
        Console.WriteLine("Fake MouseLeave!");
      }
    }

Ich habe das nun mal so gemacht , allerdings ergibt sich dadurch auch ein Problem wenn ich mit der Maus schnell über das Fenster, insbesondere über ein Label, das dem Fensterrand sehr nahe liegt, drüberziehe. Da würden mehrere Events kurz hintereinander ausgelöst werden, aber teilweise werden sie auch einfach verschluckt. Das hat zur Folge, dass die Maus das Anwendungsfenster verlassen kann ohne ein MouseLeave-Event auszulösen.

Wenn ich vom Fensterinneren in Richtung Fensterrand übers Label fahre gibt es zuerst, wenn der Mauszeiger den Bereich des Labels betritt, ein MouseLeave-Event, das wird anhand der Maus-Koordinaten als falsch erkannt. Danach, beim verlassen des Label-Bereichs und somit wiederbetreten des Form-Bereichs ein MouseEnter-Event, das ebenfalls als Falsch erkannt wird (da zuvor kein echtes mouseleave stattfand und ich dies in einer boolschen variable speichere). Nun erreiche ich den Fensterrand und es wird ein echtes MouseLeave Event gefeuert und auch als solches erkannt. Die Fenstertransparenz wird dann auf 0.5 gesetzt zur Veranschaulichung.

Wenn ich den Mauszeiger allerdings sehr schnell über den Bildschirm bewege werden einige Events einfach übersprungen. U.A. das MouseLeave beim erreichen des Rands. Das Fenster kriegt somit garnicht mit, dass ich seinen Bereich verlassen hab. Was tu ich dagegen am geschicktesten? Einen Timer damit beschäftigen, ständig zu checken ob sich die Maus noch im Bereich des Fensters befindet und ob das Fenster grade im Vordergrund ist?

07.10.2009 - 18:16 Uhr

Hast recht, danke, jetzt gehts 😃

07.10.2009 - 17:36 Uhr

Wenn ich nun auch mal meinen Senf dazugeben darf. Für alle die es kurz und knackig haben wollen erstellen ein neues WindowsForms Projekt, fügen bei den Verweisen "Microsoft.VisualBasic" hinzu, öffnen die Program.cs und schreiben dort folgendes rein:

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;


namespace OnyOne
{
  class Program : WindowsFormsApplicationBase
  {
    public Program()
    {
      this.IsSingleInstance = true;
      this.EnableVisualStyles = true;
    }

    protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
    {
      base.OnStartupNextInstance(eventArgs);
      MessageBox.Show("Diese Anwendung lässt sich nur einmal starten!","Fehler!");
      eventArgs.BringToForeground = true;
    }

    [STAThread]
    static void Main(string[] args)
    {
      Program MyApp = new Program();
      MyApp.ApplicationContext.MainForm = new Form1();
      MyApp.Run(args);
    }
  }
}

Natürlich noch den Namespace anpassen. Getestet unter WinXP 😃

07.10.2009 - 17:23 Uhr

Hi,

beim Start öffnet mein Programm hier eine Serielle Verbindung, jedoch kann da schonmal was schief laufen wie z.B. dass der COM-Port aus irgendwelchen unerfindlichen Gründen schon geöffnet wurde. In diesem Fall soll die Anwendung gleich wieder beendet werden, was ich im Catch-Block mit Application.Exit() erreichen möchte. Jedoch geschieht das einfach nicht. 🤔


    public Form1()
    {
      InitializeComponent();

      try
      {
        serialPort1.Open();
      }
      catch (UnauthorizedAccessException)
      {
        MessageBox.Show("Der Serielle Anschluss COM2 ist bereits geöffnet!", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        Application.Exit();
      }
    }

Hat jemand eine Idee warum?
lg PoWl

07.10.2009 - 13:51 Uhr

Ich würde das ganze gerne in GDI+ realisieren, damit ich was schönes dabei lernen kann. WPF wäre auch eine Möglichkeit aber ich interessiere mich nun eben für die Mathematischen Grundlagen dafür 😃

Im Tutorial von Floste habe ich nun leider nicht allzuviel verstanden. Bzw. ist mir noch völlig unklar was diese Matrix genau darstellen soll (einen einzelnen Punkt im Koordinatensystem? Ein Vertex?) Mit Matritzen kenne ich mich ehrlich gesagt auch nicht aus. Das einzige wo ich bisher eine Matrix verwendet habe, ist beim Lösen linearer Gleichungssysteme im Mathe-Abi.

06.10.2009 - 23:55 Uhr

Hi,

ich würde mir gerne ein Programm schreiben um Vektoren, Geraden und Ebenen in einem einfachen 3-Dimensionalen Koordinatensystem anzeigen zu lassen. Allerdings soll das ganze perspektivisch in 3D gezeichnet werden, sich drehen neigen lassen und es soll gezoomt werden können.

Später, wenn ich das soweit geschafft habe, sollen die Ebenen nur über einen bestimmten Bereich gezeichnet werden und zusätzlich noch halbtransparent sein. Natürlich muss man dann auch noch berechnen was alles hinter der Ebenen liegt. Noch später sollen einzelne Objekte wie eine Gerade, Ebene, Punkt durch Anklicken selektierbar sein so dass man verschiedene Informationen anzeigen kann oder irgendwelche Operationen damit ausführen kann.

Kennt jemand eine Seite, wo die mathematischen Grundlagen dazu erklärt werden? Am besten anschaulich.

Ach ja, ich möchte nicht WPF oder irgendwelche fertigen Engines verwenden. Das ganze soll auch nur ganz ganz einfach werden um dabei ein paar Grundlagen zu erlernen.

lg PoWl

06.10.2009 - 16:33 Uhr

Ich weiß, ich wollte deine Aussage ja auch nur eben nochmal bestätigen. Ich warte auf weitere Antworten und Vorschläge 😉

06.10.2009 - 16:22 Uhr

Wenn der Bus entsprechend gestaltet ist kann das Hauptprogramm neue Teilnehmer am Bus erkennen. Ebenso Teilnehmer, die sich nicht mehr am Bus befinden. Dann hätte man zumindest kenntnis darüber, welche Teilnehmer grade da sind.

In der Tat fällt Option 1) eigentlich aus.

06.10.2009 - 15:34 Uhr

Hi,

ich sags vorab, ich bin noch nicht so fit in C# und das wird sich auch erst im Laufe der nächsten Monate ändern. Trotzdem denke ich jetzt schon über die Machbarkeit eines Projekts nach:

Zur Automatisierung verschiedener Dinge möchte ich ein Bus-System an meinem PC betreiben. Hierfür soll es ein Programm auf dem PC geben, von diesem aus verschiedene Busteilnehmer steuerbar sind. Natürlich sind das ganz unterschiedliche Teilnehmer, von denen nicht jeder ständig manuell gesteuert werden muss, aber jeder von ihnen benötigt quasi seine eigene kleine Software. Da ich jedoch beabsichtige das Projekt öffentlich zugänglich zu machen damit es auch andere Leute nutzen können, möchte ich mir intensivere Gedanken zur Software machen.

Um nun mit verschiedenen Busteilnehmern zu kommunizieren muss eine solche Steueranwendung mit einem Hardwareinterface z.B. per RS-232 kommunizieren. Da ich einen COM-Port allerdings sinnvollerweise zur Kommunikation nur einmal öffnen kann bietet es sich an nur einem einzigen Programm die Kommunikation vom PC zum Bus zu überlassen.

Abhängig davon, welche Teilnehmer gerade am Bus online sind, sind natürlich auch unterschiedliche Steuerinterfaces in der Software nötig.

Ich habe nun mehrere Möglichkeiten zur Umsetzung, wobei die Hauptsoftware zur Kommunikation mit dem Bus-Interface ständig als eigenständiges Programm läuft.

  1. Die Hauptsoftware enthält von vornherein stämtliche Steuerinterfaces für verschiedenste Bus-Teilnehmer, die man, abhängig davon ob ein entsprechender Teilnehmer am Bus online ist einfach in einem separaten Fenster öffnen kann um dort die Einstellungen für den Teilnehmer vorzunehmen. Leider keine gute Lösung, da man nur durch Neukompilierung neue Steuerinterfaces hinzufügen kann und ggf. die Software mit Steuerinterfaces belastet ist, die nie gebraucht werden. Fremde Entwickler haben kaum die Möglichkeit eigens programmierte Steuerinterfaces weiterzugeben.

  2. Die Steuerinterfaces werden als eigenständige Programme kompiliert und der einfachen Erreichbarkeit halber in das Verzeichnis des Hauptprogramms kopiert. Die Kommunikation mit dem Hauptprogramm erfolgt im Hintergrund. Eine schon bessere Lösung, da die Weitergabe von Programmen relativ einfach erfolgt und fremde Entwickler mit einem Grundgerüst an Sourcecode relativ einfach eigene Steuerinterfaces programmieren können, ohne sich mit dem Sourcecode des Hauptprogramms auseinandersetzen zu müssen. Dafür erscheint mir jedoch die Kommunikation mit dem Hauptprogramm schwierig realisierbar, bzw. umständlich, richtig?

  3. Die Steuerinterfaces werden als Plugins zum Hauptprogramm hinzugefügt, wenn möglich sogar zur Laufzeit. Leider habe ich nicht die geringste Ahnung wie sowas in Interaktion mit dem Hauptprogramm möglich ist, vor allem nicht, wie man sowas programmiert. Das Steuerinterface müsste dabei auf die Kommunikationsresourcen des Hauptprogramms zugreifen und den gesamten Inhalt des Fensters des Steuerinterfaces enthalten, wobei dessen Fenstertitel z.B. wiederum vom Hauptprogramm bestimmt wird. Kann man sowas als .dll verpacken? Ist dabei nicht der gesamte Sourcecode des Hauptprogramms notwendig damit VS weiß, welche Variablen verfügbar sind und auf welche es dann zugreifen kann?

lg Paul H.

06.10.2009 - 14:57 Uhr

Hab meinen Post inzwischen wieder editiert 😉

Danke für deinen Code. Allerdings ist das ganze nun scheinbar noch ein wenig anfälliger für schnelle Mausbewegungen geworden.

06.10.2009 - 14:21 Uhr

Das führt leider zu einem Problem:

    private void Form1_MouseLeave(object sender, EventArgs e)
    {
      int x = this.PointToClient(Control.MousePosition).X;
      int y = this.PointToClient(Control.MousePosition).Y;


      Console.WriteLine("MouseLeave! X: "+x+", Y: "+y+";     Width: "+Width+", Height: "+Height);
    }

Width und Height sind jedoch immer 6px größer als die Mauskoordinaten beim Verlassen des Fensters.. Ich denke da wird einfach der Fensterrand mit einbezogen. Soll ich da einfach immer 6 subtrahieren oder gibts noch eine eigenschaft, die die breite und höhe des arbeitsbereichs, auf den das event reagiert, bereitstellt?

06.10.2009 - 13:58 Uhr

@JAck30lena.. ja, einleuchtend.. danke 😉

@herbivore, ja das deactivate-ereignis suche ich.

noch was: wie kann ich am besten erkennen ob der Mauszeiger den Bereich des Fensters verlassen hat? Das Mouseleave Event feuert auch wenn ich mich mit der Maus über einem Steuerelement befinde. Im Event-Handler zusätzlich Checken ob sich die Maus-Koordinaten im Fenster befinden?

05.10.2009 - 22:32 Uhr

Uh, danke für den Tipp aber das funktioniert irgendwie überhaupt nicht.

Beim Start der Anwendung lasse ich das Fenster minimiert starten. D.h. es ist noch garnicht sichtbar. Erst bei Doppelklick auf das Trayicon wird es per

    private void notifyIcon1_DoubleClick(object sender, EventArgs e)
    {
      WindowState = FormWindowState.Normal;
      SetForegroundWindow(Handle);
    }

in den Vordergrund geholt.
Dann wird das LostFocus Event 36 mal gefeuert, zumindest musste ich eben 36 mal meine Test-Messagebox wegklicken...

Nunja, dann kann man das Fenster ganz normal benutzen, wenn es dann allerdings wirklich den Focus verliert wird das event nicht gefeuert.

//Edit: Wenn ich im Eventhandler nur per Console eine Meldung ausgeb geschieht das irgendwie nur einmal?! Aber gleich beim erscheinen des Fensters und danach nicht mehr.

lg PoWl

05.10.2009 - 21:59 Uhr

Hi,

gibt es ein Event, das ausgelöst wird, wenn das Fenster den Focus verliert? Ich möchte dadurch nämlich erreichen, dass das Fenster dann automatisch in den Hintergrund verschwindet, da es sich nur um ein kleines Traybartool handelt.

lg PoWl

05.10.2009 - 21:29 Uhr

Hi,

ich habe eine kleine rahmenlose Fensteranwendung. Im Designer habe ich zu Form1 ein NotifyIcon hinzugefügt, welches auch korrekt in der Traybar angezeigt wird. Im MouseClick Eventhandler, der sich in der Form1-Klasse befindet, möchte ich nun das Form1 in den Vordergrund bringen wenn es hinter irgendwelchen Programmfenstern verschwunden ist.

Folgende Funktionen zeigen da leider keine Wirkung:
this.BringToFront();
this.Show();
this.Focus();

Da ich das Problem mittlerweile in den Griff gekriegt habe hier nochmal die Lösung für alle Suchenden:


using System.Runtime.InteropServices;

....

  public partial class Form1 : Form
  {
    [DllImport("user32.dll")]
    public extern static int SetForegroundWindow(IntPtr HWnd);

    private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
    {
      SetForegroundWindow(this.Handle);
    }

Das funktioniert nun 😃

10.09.2009 - 01:21 Uhr

Hi, ich bin grad nach längerer Pause wieder in die C# Programmierung eingestiegen, hab mir dafür auch gleich mal n gescheites buch gekauft (Visual C# 2008 von galileo.. mag lieber n schönes buch als das openbook und ich find wer so n tolles buch rausbringt sollte unterstützt werden)

also ich würde das dann halt so machen dass ich einfach ein wave-file mit den takt-ticks im loop laufen lasse, das sollte ja möglich sein... weitere wave-sounds werden dann per line-in aufgenommen und ebenfalls im loop abgespielt. dann laufen eben mehrere loops nebenher und fangen alle gleichzeitig an.

das müsste doch gehen oder?

03.03.2009 - 07:32 Uhr

Hi,

da ich auf aufwändige grafische Oberflächen mit viel Spielerei stehe möchte ich mich demnächst mit WPF beschäftigen. Ich frage mich nun allerdings welches Buch ich hierfür kaufen soll.

Es gibt das vom Galileo Verlag:
http://www.galileocomputing.de/katalog/buecher/titel/gp/titelID-1615

Und dann stach mir noch dieses ins Auge, das vom gleichen Verlag wie mein C# Kochbuch kommt:
http://www.amazon.de/Windows-Presentation-Foundation-NET-Benutzerschnittstellen/dp/3446410414

Die sehen beide recht ordentlich aus. Ich weiß nur leider nicht welches der beiden ich nehmen soll oder ob ein völlig anderes sogar noch besser ist.

Kann da jemand etwas zu sagen?

lg PoWl

02.03.2009 - 00:56 Uhr

OK, die zwei Punkte sind durchaus berechtigt. (Treffen aber in meinem Fall nicht zu)

war das mit dem Events eigentlich so gemeint, dass Form2 Form1 etwas mitteilt, indem es die daten über die EventArgs an Form2 übergibt oder indem es Form1 durch auslösen des Events dazu bewegt, sich die Daten von Form1 abzuholen?

Mit ersterer Methode wäre es völlig Form1 überlassen, wie es mit den Daten umgeht, ganz recht. Allerdings muss dann Form2 natürlich auch wissen, welche Daten es an Form1 senden muss. Insofern kann es verschiedene Daten in Form1 auch direkt oder höchstens über Properties manipulieren. Wenn man das Form wiederverwertet oder austauscht muss das so oder so passen.

Ich finde beides bringt nur vorteile, wenn man so modular und variabel bleiben möchte, dass man eines der beiden forms jederzeit austauschen könnte, was ich niemals vor habe 😉

02.03.2009 - 00:47 Uhr

Hm ja, danke. Also helfen tut mir das schon, so könnte ich das zumindest machen. Die Änderung der Werte in Form2 soll in Form1 sofort übernommen werden. Insofern könnte ich das mit einem Event machen, das bei einer Änderung ausgelöst wird und dann alle Werte updated (nicht nur, diejenigen, die sich tatsächlich geändert haben).

Bisher konnte mich jedoch noch keiner davon abbringen, das als vollkommen sinnlos zu erachten. Begründung: Siehe letzter Absatz des letzten Postings 😉

Sobald es um das Thema geht heißt es generell immer nur "die SOLLEN unabhängig sein". Ich frag mich jedes mal "Warum!?" aber eine plausible Antwort darauf wird nie geliefert. Dieser Fakt wird einfach vorausgesetzt.

Das soll natürlich nicht heißen, dass sich in anderen Anwendungsfällen, wo die beiden Forms wirklich unterschiedliche Aufgaben haben, nicht die genannten Methoden sinnvoller sind. Aber bei mir, wo das Form2 nur eine erweiterung, eine "Fernbedienung" zu Form1 ist?

Nunja, ich werde es wohl entgegen aller Kritiken dabei belassen, dass ich versuche, auf Form1 von Form2 aus direkt zuzugreifen, das ist hier in meinen Augen einfach das einzig Sinnvolle. Eine Fernbedienung schickt dem Fernseher ja auch direkt ihre Signale.

lg PoWl

02.03.2009 - 00:09 Uhr

OK, was mache ich, wenn ich ein extra-Form habe in dem man immens viele Einstellungen tätigen kann? Soll ich dann für jeden Pups, den ich dort verändere, ein eigenes Event definieren, welches einen Eventhandler im Hauptform aufruft? Das bläht den Code ja auf wie sonstwas und macht alles äußerst unübersichtlich.

Außerdem, was macht es für einen Unterschied, ob Form2 nun einen Eventhandler im Hauptform aufruft oder gewisse Variablen direkt ändert.

Der Sinn erschließt sich mir noch nicht so ganz 😉 Aber danke für die Bemühungen!

Bisher erzählt jeder, die Forms sollen unabhängig voneinander sein. Warum? In meinem Fall liegt es in ihrer Natur nicht voneinander unabhängig zu sein. Form2 ist ganz klar von Form1 abhängig, es ist diesem untergeordnet. Ohne Form1 darf es kein Form2 geben. Form2 bietet nur bei bedarf ein paar Steuerelemente um verschiedene Variablen in Form1 zu manipulieren, das ist der einzige Zweck von Form2. Man könnte die Steuerelemente in Form2 ebensogut in Form1 platzieren, aber das sieht halt meiner Meinung nach nicht so schön aus. Form1 soll schön aussehen, Form2 soll die Funktionalität bieten. Im Grunde genommen soll dich das alles wie ein großes Form verhalten.

lg PoWl

01.03.2009 - 23:12 Uhr

Danke,

mal jemand, der meine Sprache spricht. Dann werd ich es mal über events versuchen.

01.03.2009 - 22:49 Uhr

Ok, ich frage nun mal ganz penetrant:

Warum so umständlich?

Ich hab mich nun schon durchs Forum gelesen bzw. ein bisschen alles überflogen. Es gibt ja hunderte Lösungsansätze. Aber es kann doch nicht angehen, dass meine beiden Forms nicht einfach miteinander kommunizieren dürfen. Überall heißt es nur "das ist nicht gut" oder "das macht man nicht". Sowas erzählt man kleinen Kindern, die die Gründe, warum man etwas nicht macht, noch nicht verstehen, aber nicht mir.

Also, was spricht konkret dagegen?

Mein Form2 ist ja quasi nur ein kleines Options-fenster in dem ich verschiedene Einstellungen tätige, die Form1 betreffen, und folglich natürlich auch an Form1 übergeben werden sollen. Da ich in Form1 die beiden Timer drin habe, die die Wecker-funktionalität übernehmen. Das kann ich wohl auch nicht in eine dritte, unabhängige, Formfreie Klasse auslagern da die Timer ja direkt an Forms gekoppelt sind, oder? Und das mit zeitverzögerten Threads zu machen hat mir herbivore nun auch nicht empfehlen können, ich selbst halte das auch für unsinnig wenn es mit den Timern aus Form1 so unkompliziert geht.

Ich habe in Form2 Form1 sogar als Owner definiert, d.h. die beiden Forms treten nur im Doppelpack auf. Was spricht also dagegen aus Form2 heraus direkt Variablen und Objekte in Form1 zu modifizieren und die neuen Werte direkt an Form1 zu übergeben. Ohne Umwege wie Events oder sonstwas.

Das wäre doch äußerst praktisch. Auch wenn das in anderen Anwendungsfällen vielleicht nicht so sinnvoll erscheinen mag wo es eher Sinn macht, die Funktionalität von der GUI mehr zu trennen. Wo dann verschiedene Forms mit einem gemeinsamen funktionellen Hauptblock kommunizieren. Aber hier, wo mein Form1 der funktionelle Hauptblock ist, der neben GUI eben die ganze Funktionalität des Programms bietet und Form2 nur eine visuelle Erweiterung von Form1 ist - ich hätte die Steuerelemente von Form2 ebensogut direkt in Form1 reinmachen können aber das wollte ich eben aus optischen Gründen nicht - macht es doch sinn, dass Form2 direkt mit Form1 kommuniziert, wie als wären die Forms quasi garnicht getrennt.

Ich möchte hier keine etablierten Programmiertechniken in Frage stellen aber ich sehe speziell in meinem Fall die direkte Kommunikation von Form2 mit Form1 eben als am allersinnvollsten an.

lg PoWl

01.03.2009 - 13:22 Uhr

Ich habe mal die Instanz der Klasse Form2 in WeckerForm umbenannt, bringt mir aber auch nix.

Wenn ich (Owner as Form1). Weckzeit verändern möchte erhalte ich Fehler 1 Der Zugriff auf "Backpanelswitcher.Form1.Weckzeit" ist aufgrund der Sicherheitsebene nicht möglich. C:\Dokumente und Einstellungen\Administrator\Eigene Dateien\Visual Studio 2008\Projects\Backpanelswitcher2\Backpanelswitcher2\Form2.cs 28 24 Backpanelswitcher2

ist das unsafe? Die Schreibweise kenn ich garnicht. Wenn es funktioniert sobald ich unsicheren code zulasse ok, aber wie macht man das normalerweise? Scheint ja nicht sonderlich elegant zu sein. Ich bräuchte sowas wie "Parent", "Opener", oder eine Referenz zum Hauptfenster-Objekt. Soll ich beim Erstellen des WeckerForm-Objekts im Form1-Konstruktor einfach eine Referenz auf das Hauptfenster-Objekt mittels WeckerForm.Hauptfenster = this; , nachdem ich in der Form2-Klasse eine Variable "Hauptfenster" mit dem Typ Form angelegt habe, übergeben?

@herbivore: danke, ich schaus mir mal an.
Also es ist so, dass das Wecker-gedöns von Timern in Form1 erledigt wird und ich darin deshalb auch die Variablen ändern muss. Oder soll ich das ganze lieber mit Threads erledigen?

Ich muss zugeben, meine Programm.cs ist ziemlich leer. Alles spielt sich in der Form1.cs ab.

01.03.2009 - 12:45 Uhr

[EDIT=herbivore]Abgeteilt von Zweites Form beliebig oft öffnen und schließen, ohne es dabei zu zerstören[EDIT]

Ok 😃

noch gleich ne frage:

Die Klasse meines Hauptfensters heißt Form1. Die Klasse meines kleinen Dialogfensters heißt Form2 und das davon erzeugte Objekt steckt auch in der gleichnamigen Variable Form2. Vielleicht nicht sonderlich geschickt aber bisher hats nicht gestört.

Wie erhalte ich aus der Sicht des Form2-Objekts eine Referenz auf das Form1-Objekt, also das Hauptfenster-Objekt?

Ich möchte in der OnValueChanged-Methode eines Controls von Form2 im Form1-Objekt die Variable Weckzeit ändern.

Im Konstruktor von Form1 erstelle ich ja eine Instanz von Form2:


  public partial class Form1 : Form
  {
    DateTime Weckzeit;
    Form Form2;

    public Form1()
    {
      [...]

      Form2 = new Form2();
      Form2.Owner = this;
    }

Form2.Owner erhält also eine Referenz auf das Form1-Objekt. Wenn ich in der besagten OnValueChanged-Methode mittels this.Owner.Weckzeit versuche, auf die Variable im Form1-Objekt zuzugreifen meckert VS rum.

Fehler 2 "System.Windows.Forms.Form" enthält keine Definition für "Weckzeit", und es konnte keine Erweiterungsmethode "Weckzeit" gefunden werden, die ein erstes Argument vom Typ "System.Windows.Forms.Form" akzeptiert. (Fehlt eine Using-Direktive oder ein Assemblyverweis?) C:\Dokumente und Einstellungen\Administrator\Eigene Dateien\Visual Studio 2008\Projects\Backpanelswitcher2\Backpanelswitcher2\Form2.cs 28 18 Backpanelswitcher2

Wie ist das am besten zu lösen? Gibt es da sowas wie Parent oder so? Steckt eine Referenz auf das Hauptfenster-Objekt in irgendeiner Variablen? Wenn ich versuche Form1.Weckzeit anzusprechen denkt er, ich meine mit Form1 die Klasse, nicht das Hauptfenster-Objekt.

lg PoWl

01.03.2009 - 12:10 Uhr

Bingo.

Hab jetzt das onclosing überschrieben und darin e.Cancle = true gesetzt und Form2.Hide() ausgeführt.

Form2.Owner hab ich im Konstruktor von Form1 auf "this" gesetzt.

Klappt nun alles so wie ich das wollte, danke! 😃

wieso ist e.Cancle eigentlich ein Property und keine Methode? "Abbrechen" ist doch etwas, das ich tue, das ich ausführe. Ich hätte daraus eine Methode gemacht. Ist natürlich im Endeffekt egal, fühlt sich nur komisch an beim Programmieren.

lg PoWl

01.03.2009 - 11:44 Uhr

Hi, danke, aber ich habe mich nun soweit entschieden, dass die Form2-Instanz immer erhalten bleiben soll. Das ist in meinem Fall einfacher und sinnvoller, zumindest erscheint es mir so, da ich dann die Controls nicht immer neu mit ihren Werten befüllen muss.

Jetzt muss ich nur das Disposing verhindern, wie mach ich das?

Ach ja: Das Form2 ist ein kleines Dialogfenster das nicht in der Taskleiste angezeigt wird. Allerdings kann es so auch mal passieren, dass das Fenster zwar geöffnet aber nirgendwo sichtbar ist. Kann man irgendwie das Form2 automatisch mit in den Vordergrund holen sobald Form1 in der Taskbar anklickt und dieses somit in den Vordergrund kommt?

Einfach, dass Form2 mit Form1 immer im Doppelpack erscheint, auch, dass es verschwindet, wenn Form1 minimiert wird.

lg PoWl

01.03.2009 - 10:46 Uhr

Hi,

ich habe eine WinForms Anwendung wobei Form1 das Standardforumlar ist. Darin gibt es eine PictureBox, ein kleines Wecker-Icon. Wenn man darauf klickt soll sich ein zweites Form öffnen indem man diverse Einstellungen tätigen kann.

Ich habe also in VS ein neues Form "Form2" hinzugefügt und es nach meinen Vorstellungen designed. In der Form1-Klasse erstelle ich zunächst mal eine Instanz davon:

    Form Form2 = new Form2();

und im Picturebox Click-Event öffne ich es dann und bringe es n den Vordergrund, falls es schon offen ist.

    private void pictureBox1_Click(object sender, EventArgs e)
    {
      Form2.Show();
      Form2.BringToFront();
    }

Das Problem ist nun, wenn ich das Form2 schließe, wird gleich das ganze Form2-Objekt vernichtet. Allerdings möchte ich das Form2-Fenster beliebig oft wieder öffnen können. Es soll sich also nur schließen, nicht gleich komplett disposen.

Wie erledige ich das am geschicktesten? In jedem Click-Event eine neue Instanz des Form2 erstellen oder verhindern, dass es komplett disposed wird? Letzteres wäre mir ehrlich gesagt lieber, die Einstellungen die man dort tätigt sollen möglichst erhalten bleiben.

lg PoWl

28.02.2009 - 11:10 Uhr

Hi,

wundersamerweise hat alles was ich sagen möchte in den Thread-Titel gepasst. Es geht darum, dass wenn ich mir kleine Tools schreibe, ich gelegentlich verhindern möchte, dass diese mehrfach geöffnet werden können. Stattdessen soll das bereits laufende Programm benachrichtigt und in den Vordergrund geholt werden, meinetwegen sich ein bisschen schütteln oder so^^.

Hat da jemand Infos zu?
Ich meine hier irgendwo mal einen Thread gelesen zu haben der ein Fenster dann benachrichtigt, nur stand nicht dabei wie man die Nachrichten empfängt.

Wie holt man ein Fenster von sich aus in den Vordergrund?

lg PoWl

23.02.2009 - 09:58 Uhr

OK, überredet 😉

Noch ein paar Fragen:
Wie kann ich dem Steuerelement ein OnValueChanged-Event hinzufügen?
//Edit: Gelöst.

Wie könnte ich außerdem noch Auswahlfelder in den Designer einfügen mit dem ich z.B. die Farbe auswählen kann?
// Edit: hat sich erledigt, im 🛈 stehts

Wie kann ich ein vorhandenes Rectangle am besten um 1 Pixel nach rechts und nach unten verschieben und um 2px in beide Richtungen kleiner machen?
// Edit: hat sich erledigt, darf aber trotzdem beantwortet werden

Noch offen:

Wie könnte ich erreichen, dass das das Steuerelement immer genauso Breit, wie auch hoch gemacht werden kann?

Was hat das [DefaultValue:(xxx)] für einen Effekt? Ob ich das drin stehen hab oder nicht ändert nichts an allem. Im Designer erscheinen auch nur die Anfangswerte, mit denen ich die Variablen initialisiere.

Ich habe das Steuerelement nun als .dll vorliegen und jedes mal wenn ich es in einem Programm verwende wird diese .dll im Release-Verzeichnis dazukopiert. Kann ich das ganze auch komplett in einer .exe verpacken oder muss ich den Steuerelement-Code irgendwie in mein aktuelles Projekt mit aufnehmen oder gar dafür umschreiben?

lg PoWl

22.02.2009 - 22:17 Uhr

Ah, na das funktioniert ja prima, danke! Ich werde auf dieser Basis mal weitermachen 😃

Ja klar, eine exe kann viel böses, es ging mir eher um herbivores Beschreibung, dass man ja nicht unbedingt was böses vom User erwarten müsse sondern einfach nur eine Fehlfunktion des Programms. Und da fragte ich nun was an einem Control so fehlfunktionieren könnte, dass es in der Lage ist, dem System ernsthafte Schäden zuzufügen.

22.02.2009 - 20:31 Uhr

@herbi, daran habe ich nicht gedacht, bin natürlich auch keinem böse der vorsichtig ist! Ich kanns ja nachvollziehen, wie ich schon sagte, trotzdem ist es traurig und nervig das kann man nicht ganz leugnen 😉. Kann denn so ein einfaches control tatsächlich Schaden anrichten?

@ ErfinderDesRades, danke für deine Arbeit! Ich habe gerade versucht das zu verwertern aber ich weiß nicht wie. Alle Tuorials im Internet gehen von Visual Studio aus, ich hab allerdings nur die Express-Version. Und da kann man, wenn man ein neues Projekt erstellt kein Steuerelement als Vorlage nehmen. Ich hab versucht ein leeres Projekt zu erstellen, dann ein Benutzersteuerelement hinzuzufügen und als Sourcecode deinen Code verwendet. Allerdings weiß ich nicht wie ich dann weitermachen soll, wie daraus dann am Ende tatsächlich ein Steuerlement wird.

Sagtmal, liegen Steuerelemente normalerweise dann nicht als .dll vor?

lg PoWl

22.02.2009 - 14:59 Uhr

Klar kennt ihr mich nicht, aber habt ihr schon Leute getroffen die so krank sind erstmal so einen Thread ans laufen zu kriegen um dann ne exe zu posten, nur um damit fremde Systeme zu zerstöreren oder generell anderen zu schaden? Passiert das so oft? Das kommt mir grad so vor wie als dürfte ich morgens beim Bäcker keine Brötchen mehr holen weil sie vergiftet sein könnten.

22.02.2009 - 14:23 Uhr

Grr, ich kanns ja nachvollziehen aber es ist einfach nur traurig und nervig, dass man in nem Programmiererforum gleich als potenzieller böser Cracker hingestellt wird, der eine konkrete Problemstellung im Forum + eine .exe-Datei postet, einzig und allein um anderen damit Schaden zuzufügen indem die .exe dann sein System vernichtet.

Im Anhang nochmal das ganze VS Projekt ohne irgendwelche Exen.
Diejenigen die es interessiert, dürfen es gerne runterladen, kompilieren, und sich anschauen. Die anderen dürfen es gerne einfach ignorieren.

lg PoWl

22.02.2009 - 13:42 Uhr

Also die HScrollBar gehört nicht dazu, sry falls das verwirrt hat. Genau, es geht darum eine Grad-Zahl (0-360°) zu visualisieren. Danke für die Hilfe bisher, ich werde das nachher einfach mal probieren und mich dann zurückmelden wenn ich nicht weiterkomme.

Im Anhang mal das Programm damit ihr euch das vorstellen könnt. die Trackbar kann man natürlich mit der Maus auch anfassen. Die Trackbar ist noch nicht mit der HScrollBar verbunden, jedoch die HScrollBar mit der Trackbar 😉