Laden...
B
Borg myCSharp.de - Member
Berlin, Germany Dabei seit 23.08.2006 1.529 Beiträge
Benutzerbeschreibung

Forenbeiträge von Borg Ingesamt 1.529 Beiträge

29.01.2007 - 00:07 Uhr

Kann man die Schrift in der RTB glätten lassen?

ClearType ist eine Windows-Einstellung (Systemsteuerung\System\Erweitert\Systemleistung\Einstellungen\Visuelle Effekte\Kanten der Bildschirm...), die man meines Wissens nicht für einzelne Controls an- und ausschalten kann.

29.01.2007 - 00:02 Uhr

Rein aus Performance-Gesichtspunkten heraus bestehen keine Probleme, da die blockierende Operation halt wartet, wenn keine Daten vorhanden sind, und ansonsten liest, bis er auf ein Zeilenende trifft.

28.01.2007 - 23:50 Uhr

Vielleicht liegt es daran, dass deine Variable genauso heißt, wie die Spalte der Tabelle?

27.01.2007 - 17:33 Uhr

Für eine XML-Datei gibt es nur sehr wenige Regeln. Für dich ist aber wichtig, dass man jedes beliebige Tag in jeder Kombination mit anderen Tags und mit Attributen benutzen kann.
Ein Schema bringt jetzt aber Ordnung in das Chaos, in dem es erlaubte Tags, deren Stellung zu einander, Attribute und ähnliches definiert.
Erst durch die Prüfung kann man damit feststellen, ob eine gültige XML-Datei auch die benötigten Strukturen aufweist.
So stellt XHTML beispielsweise gültiges XML dar. Allerdings wird eine XHTML-Datei wohl kaum als sinnvolle Konfigurationsdatei für dein Programm dienen können, da sie eben nicht die von dir gestellten Anforderungen an die Struktur erfüllt.

27.01.2007 - 17:28 Uhr

Du kannst doch bestimmt alternative Installationsquellen einstellen...

27.01.2007 - 17:26 Uhr

Du musst dein Control in die GroupBox packen..

EDIT: Bzw., malst du direkt auf die Form? Die ist nämlich unabänderbar permanent im Hintergrund (logischerweise).

27.01.2007 - 16:19 Uhr

<asp:label>...</asp:label>
</asp:button>...</>

Ist das normal das manche Controls einen langen Abschlusstag haben
und manche einfach nur </> ?

Das ist weder normal, noch XML.
Es ist einfach ein Fehler.
Das erklärt aber, warum du Darstellungsprobleme hast...

27.01.2007 - 14:52 Uhr

Ich möchte auch nicht so schnell aufgeben. Also startet ich einen neuen Erklärungsversuch.
Eine reine Klassenhierarchie funktioniert sehr gut, solange sich die Klassen wunderbar eindeutig per ist ein bzw. ist kein unterscheiden lassen. Gerade für Mischformen würde man sich dann aber entscheiden müssen, da eine Klasse nun mal nur eine Elternklasse haben kann. Daher führt man Interfaces ein. Diese bieten dann keine Unterscheidung hinsichtlich ist ein und ist kein sondern hinsichtlich kann etwas und kann etwas nicht.

Als Beispiel bleiben wir mal bei den Fahrzeugen.
Deine Klassenhierarchie willst du zuerst nach Fortbewegungsart aufbauen.
Dann erhältst du ungefähr so etwas:


Fahrzeug
    |---- Wasserfahrzeug
    |               |------- MitSchraube
    |               |                  |---------- UBoot
    |               |                  |---------- Tanker
    |               |                  |---------- Fähre
    |               |                  |---------- Eisbrecher
    |               |------- MitSegel
    |                                  |---------- Schoner
    |                                  |---------- Jolle
    |---- Landfahrzeug
    |               |------- MitMotor
    |                                  |---------- PKW
    |                                  |---------- LKW
    |---- Luftfahrzeug
                    |------- MitTragflächen
                                       |---------- Propeller
                                       |                    |----- TurboProp
                                       |---------- Jet
                                       |---------- Rotor

Jetzt stellst du aber fest, dass du in deinem Programm ebenfalls eine Unterteilung nach Funktion benötigst. Dies würde ein derartiges Klassendiagramm ergeben:


Fahrzeug
    |---- Transport
    |               |------- Fracht
    |               |                  |---------- Tanker
    |               |                  |---------- Schoner
    |               |                  |---------- Jolle
    |               |                  |---------- LKW
    |               |------- Personen
    |                                  |---------- Fähre
    |                                  |---------- PKW
    |---- Forschung
    |               |------- UBoot
    |---- Unterstützung
                    |------- Eisbrecher

Wie du siehst, sind beides (hier nicht vollständig) eine Sortierung anhand eines bestimmten Kriteriums. Damit stellen beide Hierarchien nur eine unterschiedliche Sichtweise auf die realen Objekte dar. Damit sind beide richtig.
Das Problem ist nun zu entscheiden, welchen dieser Hierarchien man für sein Programm nutzt. Oftmals benötigt man verschiedene Kriterien, an denen man Objekte unterscheiden kann.
Und da kommen Interfaces ins Spiel. Diese stellen, wie oben bereits kurz angedeutet, vereinfacht eine Funktionsbeschreibung zur Verfügung. Ein Klasse hat entweder diese Funktion oder eben nicht. Wenn ich jetzt also das Interface ITransport definieren würde, dann würden alle Transporter im zweiten Diagramm dieses Interface implementieren (und damit diese Funktion besitzen), die anderen halt nicht.
Damit kann ich aber eine Hierarchie wie im ersten Diagramm aufbauen, und trotzdem eine Unterteilung nach Funktion haben.
Wenn ich nun die erste Hierarchie implementiere und alle Transporter suche, "frage" ich einfach jedes Objekt, ob es transportieren kann (in C#: if (xxx is ITransport)...).

Ich hoffe, das bewegt dich dazu, den Thread-Titel doch noch zu ändern...

27.01.2007 - 14:10 Uhr

Ich würde das ganze so machen:

public class BinaryTreeDraw : Control
{
   private Tree<GeneticData> TheTree;
   private Pen penEllipse;
   private Pen penLine;
   private Pen penText;
   private StringFormat strFormat;
   private Graphics g;

   internal BinaryTreeDraw(Tree<GeneticData> tree)
   {
      InitializeComponent();
      this.TheTree = tree;
      penEllipse = new Pen(Color.Brown);
      penLine = new Pen(Color.Black);
      penText = new Pen(Color.Black);
      strFormat = new StringFormat();
      strFormat.LineAlignment = StringAlignment.Center;
   }

   protected override void OnPaint( PaintEventArgs e )
   {
      base.OnPaint( e );
      g = e.Graphics;
      RectangleF Root = new RectangleF( this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width, this.ClientRectangle.Height );
      this.DrawTree( this.TheTree, Root );
   }

   private void DrawTree( Tree<GeneticData> what, RectangleF where )
   {
      float HorizontalCenter = where.Left + where.Width / 2;
      g.FillEllipse(penEllipse.Brush, HorizontalCenter - 10, where.Top, 20, 20 );
      g.DrawString(what.NodeData.Name,this.Font,penText.Brush,HorizontalCenter,where.Top+20,strFormat);
      float Xstart = HorizontalCenter;
      float Ystart = where.Top + 20 + this.Font.GetHeight();
      float Yend = Ystart + 20;
      if ( what.LeftTree != null )
      {
         float Xend = where.Left + where.Width / 4;
         g.DrawLine( penLine, Xstart, Ystart, Xend, Yend );
         this.DrawTree(what.LeftTree,new RctangleF(where.Left,Yend,where.Width/2,where.Height-Yend));
      }
      if ( what.RightTree != null )
      {
         float Xend = Xstart + where.Width / 4;
         g.DrawLine( penLine, Xstart, Ystart, Xend, Yend );
         this.DrawTree( what.RightTree, new RctangleF(Xstart,Yend,where.Width/2,where.Height-Yend));
      }
   }
}

Ist natürlich absolut ungetestet, aber sieht ehrlich gesagt deutlich besser aus...

EDIT: Habe das jetzt mal überarbeitet. So leitet es sich jetzt von Control ab und nutzt das ClientRectangle und nicht e.ClipBounds als Zeichenfläche...

27.01.2007 - 13:20 Uhr

Hi Borion,

benutzte doch switch-case. Damit wird erstens dein Quellcode übersichtlicher und zweitens wird nur solange verglichen, bis der richtige String identifiziert wurde.
Siehe auch switch - else if.

26.01.2007 - 23:36 Uhr

BitConverter.GetBytes liefert dir ein Array. Daher kannst du auch dessen Mehtoden benutzen: BitConverter.GetBytes( x ).CopyTo( destination, startindex ).

26.01.2007 - 23:32 Uhr

bool hasInterface = (myObject as IMyInterface) != null;

oder kurz:

bool hasInterface = myObject is IMyInterface;
26.01.2007 - 21:19 Uhr

Wieso jetzt plötzlich Access? Ich dachte, du wolltest den SQL Server nehmen?
Auf jeden Fall wird deine Frage durch eine simple Forensuche garantiert beantwortet.

26.01.2007 - 21:14 Uhr

Ich verstehe es irgendwie immer noch nicht.
Mit einer Datenstruktur wie

public class myLinkedTree
{
   public int a, b, c, d;
   public myLinkedTree SubTree;
   public myLinkedTree NextTree;
   public void myLinkedTree( int _a, int _b, int _c, int _d, myLinkedTree Next, myLinkedTree Sub )
   {
      a = _a; b = _b; c = _c; d = _d;
      NextTree = Next;
      SubTree = Sub;
   }
   public bool IsTrue()
   {
       // a, b, c & d auswerten
   }
   public void Evaluate()
   {
      if (this.IsTrue())
      {
         if (SubTree != null)
            SubTree.Evaluate();
      }
      else
      {
         if (NextTree != null)
            NextTree.Evaluate();
      }
   }
}

hast du das ganze doch abgebildet. Die Logik, um diese Datenstruktur zu füllen und auszuwerten, ist relativ offensichtlich.

Und den Baum kannst du auch einfach durch geschachtelte new erzeugen.

26.01.2007 - 19:32 Uhr

Dein Fehler war übrigens, die Binärdatei(!) zunächst als String einzulesen, was ja in den seltensten Fällen sinnvoll ist.

Der eigentliche Fehler war aber, dass du dann auch noch behauptet hast, dieser "binäre String" wäre ASCII...

EDIT: Ist wirklich kürzer. Ich vergesse diese 2.0er statischen File-Methoden immer...

26.01.2007 - 19:22 Uhr
private static string EncodeFileToBase64( string filename )
{
   using( FileStream myStream = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) )
   {
      byte[] content = new byte[ myStream.Length ];
      myStream.Read( content, 0, myStream.Length );
      myStream.Close();
      return Convert.ToBase64String( content );
   }
}
26.01.2007 - 18:09 Uhr

Das funktioniert so auch nicht. Windows kennt per se nur Shift, Alt und Strg als Umschalttasten. Daher werden nur diese zusätzlich zu einer anderen Taste übermittelt.
Zwei Möglichkeiten, dies zu umgehen:

  1. andere Shortcuts wählen. So halte ich Strg-Shift-C und Strg-Shift-V für viel eingängiger...
  2. Du speicherst in einem extra Array für jede Taste, ob sie gedrückt ist oder nicht. In KeyDown speicherst du gedrückt, in KeyUp halt nicht gedrückt. Die Auswertung dann je nach Wunsch in einer der beiden.
26.01.2007 - 17:34 Uhr

Ich glaube, ein Baum ist deine Datenstruktur (nicht binär).

26.01.2007 - 14:47 Uhr

100KB * 200 sind bei mir bescheidene 20 MB. Das ist wohl eher ein Datenbänkchen...
Mit anderen Worten: auch mit 2000 Bildern brauchst du dir keine Sorgen zu machen. Erst bei deutlich mehr wird es dann überlegenswert, nicht die Bilder selbst, sondern nur Pfade zu den Dateien in der DB zu speichern.

Mit dem SQL Server Express bist du wahrscheinlich gut bedient.

26.01.2007 - 14:35 Uhr

Wenn ich jetzt das Register wieder lese, müsste ja auch eine 8 zurückkommen oder?!? das tut es auf jeden Fall nicht. Es kommt 0x7A zurück.

Nein. Das Control Register ist Write-Only.
Funktioniert es damit nun, oder nicht?

26.01.2007 - 14:27 Uhr

Ich hoffe man versteht mein Kauderwelsch da oben.

Nicht so richtig. Aber das, was ich verstehe, führt mich dazu, deine Frage,

ob man das ganz nicht vieleicht mit Hilfe eines RekursivenBaumes lösen könnte mit ja zu beantworten. Wenn du schon von Dingen wie "Unterarray" redest, schreit das verdächtig nach Baum...

26.01.2007 - 14:20 Uhr

@punkdevil: Was hältst du eigentlich vom Debuggen?

26.01.2007 - 02:03 Uhr

Wäre es nicht logischer, wenn nicht das verschwindene Fenster 2 sondern das offen bleibende Fenster 1 das Fenster 3 öffnet? Vielleicht ist dein Problem damit auch schon gelöst...

26.01.2007 - 01:57 Uhr

Ich bezweifle zwar, dass sich die Registry-Pfade unterscheiden, aber zumindest EvilMM sollte das - in Anbetracht seines hier vorgestellten Projektes USBSync - aufklären können...

26.01.2007 - 01:47 Uhr

Als Empfehlung: der besseren Übersichtlichkeit wegen solltest du den Port hexadezimal schreiben. Dann sparst du dir auch die Umrechung.

Ansonsten vermute ich mal, dass der Port als Eingang konfiguriert ist. Um ihn als Ausgang zu setzen (und das PS-Signal zu aktivieren), musst du im Control Register Bit 5 löschen und Bit 3 setzen (schreibe 0x8 nach Basisadresse + 2). Anschliessend sollte es funktionieren...

26.01.2007 - 01:25 Uhr

Wenn du die Struktur auch speichern willst, musst du rekursiv alle Unterverzeichnisse durchsuchen.
In der rekursiven Funktion legst du zuerst das aktuelle Verzeichnis im ZIP an, dann suchst du alle Dateien in diesem Verzeichnis und fügst diese hinzu. Anschliessend suchst du alle untergeordneten Verzeichnisse und rufst deine Funktion für jedes dieser Verzeichnisse wieder auf.

25.01.2007 - 14:59 Uhr

Na ja, ich hatte meine Jugendjahre, da war Saufen, mit Freunden abhängen und Party machen auf der Tagesordnung.
Aber mittlerweile ist das nicht mehr so wichtig, kommt viel seltener vor. Ich spiele auch, allerdings nicht wirklich regelmäßig. Immer nur dann, wenn ich vor dem Computer sitze und keine Lust habe irgendetwas zu tun, ein/zwei Stündchen zur Ablenkung.

Und vielleicht zweimal im Jahr eine mehrtägige LAN-Party.

25.01.2007 - 13:06 Uhr

Und wenn du oben das e.Graphics.FillRectangle(new SolidBrush(Color.Black), 0, 0, 500, 300); durch e.Graphics.DrawImageUnscaled( myImage, 0, 0 ); ersetzt funktioniert es nicht?

25.01.2007 - 12:41 Uhr

Du musst Form.TransparencyKey noch entsprechend setzen.

25.01.2007 - 12:39 Uhr

Ich verstehe zwar nicht, wo daran das Problem ist, aber schon mal versucht, zuerst das Item zu selektieren, was ganz oben stehen soll (in deinem Beispiel Item3) und dann das eigentliche?

25.01.2007 - 12:31 Uhr

Ich verstehe den Sinn nicht. Wenn man den Hintergrund sehen soll, kann man doch einfach die Farbe der Form als transparent einstellen.
Oder habe ich wirklich nur nicht verstanden, warum du es so kompliziert machen willst?

25.01.2007 - 12:20 Uhr

Zur genaueren Erklärung: Ein binäre Formatierung klingt zwar schrecklich performance-kostend, macht aber nichts anderes, als die Objekte, so wie sie im Speicher liegen zu serialisieren, damit du sie in einen Stream speichern kannst. Und Serialisierung ist, wie FZelle schon sagte, dein Stichwort.

25.01.2007 - 01:13 Uhr

Auch gerade gesehen. Habe den Code korrigiert.

24.01.2007 - 21:56 Uhr

Stimmt, und zwar Environment.TickCount.

Trotzdem verstehe ich den Code nicht.

char[,] Matrix = new char[7,7];
const string buchstaben "abcdefghijklnmopqrstuvwxyzäöüaeirs";
Random ran = new Random();
for (int row = 0; row < Matrix.GetLength( 0 ); row++ )
   for (int col = 0; col < Matrix.GetLength( 1 ); col++ )
      Matrix[ row, col ] = buchstaben[ ran.Next( buchstaben.Length ) ];
24.01.2007 - 21:42 Uhr

Verstehe ich das jetzt richtig? Du hast in zwei Monaten nicht die Lösung gefunden?

24.01.2007 - 21:20 Uhr

Da ist das Problem:

Random RandomClass = new Random();

Du verwendest Random ohne Seed und erhältst damit immer die gleiche Folge von Pseudo-Zufallszahlen.
Daher:

Random RandomClass = new Random( DateTime.Now.GetHashCode() );
24.01.2007 - 21:17 Uhr

lstvReisekosten.Groups.Add( Reisekosten2006 )

24.01.2007 - 20:11 Uhr

Ich will hier noch anmerken, dass nicht die Methoden des Frameworks case-insensitive sind. Diese kapseln nur das zugrunde liegende System.
Auf Windows werden per Default zwar Groß- und Kleinschreibung gespeichert, jedoch bei allen Operation ignoriert (case-persisting, case-insensitive).
Auf Linux (Mono) hingegen beachtet das System die Groß-/Kleinschreibung und damit auch die Methoden des Frameworks.

Dein Fehler liegt eher daran, dass File.Exists für Ordner immer false zurückliefert. Das wird auch so in der Dokumentation beschrieben (soll heißen: Lesen lernen!).
Es ist jetzt nicht schwer zu erraten, was du für Ordner benutzen musst...

24.01.2007 - 19:53 Uhr

Nur interessehalber: was ist das denn für ein Gerät, das eine derart komische (fast schon abartige) Form der Konfiguration benutzt?
Vor allem: kann ich auf die gleiche Art im Betrieb eine neue IP verschicken? Und damit das Gerät quasi nutzlos machen? Was macht da Gerät bei fehlerhaften IP-Adressen?

24.01.2007 - 19:38 Uhr

Hier der Code von System.Windows.Forms.ListViewGroupItemCollection.CheckListViewItem:

private void CheckListViewItem(ListViewItem item)
{
      if ((item.ListView != null) && (item.ListView != this.group.ListView))
      {
            throw new ArgumentException(SR.GetString("OnlyOneControl", new object[] { item.Text }), "item");
      }
}

Der Code verrät uns, dass die Exception geworfen wird, wenn das Item zu einer Gruppe hinzugefügt wird, die nicht zum gleichen ListView wie die Gruppe selbst gehört.
Und das bedeutet, dass deine Gruppe Reisekosten2006 sich nicht in lstvReisekosten.Groups befindet. Daher: Gruppe klonen und auch dort hinzufügen.

24.01.2007 - 13:17 Uhr

Mit Sicherheit nicht, weil ich den Code einfach von IPInterfaceProperties.GatewayAddresses aus der MSDN-Lib kopiert habe...

24.01.2007 - 13:13 Uhr

Du kannst aber zählen. Wenn heute Mittwoch der 24. ist, hatte ich schon am 17., am 10. und am 3. einen Mittwoch. Also ist heute der vierte Mittwoch im Monat.

EDIT:
Kurz gesagt: 24 / 7 = 3,6 > 3 => es gab drei Mittwoche vorher => heute ist der vierte.

24.01.2007 - 13:10 Uhr

Entschuldigung, habe mich auch etwas gehen lassen.

Um wieder zum Thema zurückzukommen: ich vermute, dass diese Funktion primär eingebaut wurde, um die Hardwarehersteller - also die Treiberprogrammierer - zu erschrecken.
Einem Bericht von Microsoft zufolge sind an über 90% aller Abstürze Treiberprobleme schuld. Und jetzt hat Microsoft eine Methode, problematische Treiber zu deaktivieren. natürlich mit dem Hinweis an den Kunden:

"Der Treiber für das Gerät X des Herstellers Y ist dafür bekannt Windows-Abstürze zu verursachen und wurde daher deaktiviert.
Bitte wenden sie sich an den Support von Y, um neue Treiber zu erhalten."

In diesem Sinne betrachtet, führt dies langfristig zu besseren Treibern.

Die Abschaltung einer Version mit ungültigem Lizenzschlüssel ist ja schon mit WGA Notification in Windows XP implementiert.
Nur halte ich dieses Mittel für absolut ineffektiv und daher sinnlos.
Wer sich einen neuen Rechner oder Vista selbst kauft, hat eine gültige Lizenz. Wer eine Kopie einsetzt, wird auch die mit Sicherheit auftauchenden Hacks und Cracks benutzen.
Die Frage bleibt bloß, wieso ich ein Verfahren einsetzen soll, dass nicht wirksam ist, aber die Gefahr der Fehleinschätzung birgt.

24.01.2007 - 12:48 Uhr

Mit Vista fährt Microsoft eine noch nie dagewesene Geld-aus-Kunden-press-Maschinerie auf.
In der aktuellen c't (3/2007, S. 98) befindet sich eine Tabelle mit den Features der verschiedenen Vista-Versionen sowie deren Features und Preisen.
Aus Copyright-Gründen möchte ich diese hier nicht hochladen, ihr könnt sie euch ja bei eurem Zeitschriftenhändler des Vertrauens anschauen (oder die 3,30€ ausgeben).

Gehen wir doch mal die Features für den Geiz-Ist-Geil-Käufer durch:
Dieser bekommt vermutlich Vista Home Basic und gegen Aufpreis Vista Home Premium. Dieses werden sie auch nehmen, denn wer dieser Klientel will auf seinem 4GHz DualCore-Boliden schon auf die neue Oberfläche verzichten.
Dann sitzt er zu Hause, schließt seinen Scanner oder sein Faxmodem an und will scannen oder faxen. Vista bietet natürlich auch die Funktionen an. Der User klickt darauf, aber Überraschung: Windows meldet, dass für diese Funktion Vista Busines oder Ultimate benötigt wird. Aber alles kein Problem, dank Anytime-Upgrade. Einfach auf eine Website gehen, per Kreditkarte bezahlen und es gibt einen neuen Schlüssel. Doch halt, was steht da? Business kann zwar faxen und scannen, aber plötzlich funktioniert der DVD-Player, Movie Maker und das MediaCenter nicht mehr. Muss wohl doch Ultimate sein.
Gut, also doch Ultimate gekauft. Genauer gesagt, den Schlüssel. Denn sämtliche benötigten Daten sind auf der DVD bereits drauf.
Microsoft freut's. Ein Produkt billig (OEM) an Hersteller abgeben, aber derart in den Funktionen beschränken, dass man zwangsläufig upgraden muss. Am einfachsten übers Netz. So geht das ganze Geld auch direkt an Microsoft.
Mal sehen, wann die Autohersteller auf die Idee kommen, Einbauschächte für's Radio, Kindersitzhalterungen und Kofferraum nur gegen Aufpreis nutzbar zu machen.

Und dann wäre da ja noch die rechtliche Grauzone:
Wenn man Vista Home Basic in der Upgrade-Version für 119€ kauft (in der Systembuilder gibt es nur 32 oder 64 Bit), hat man einen Kaufvertrag mit dem Händler abgeschlossen. Was Microsoft in seinen EULAs schreibt, ist daher völlig egal. Daher kann man also rechtlich völlig einwandfrei, gelieferte - jedoch verborgene - Funktionen zum Vorschein bringen und nutzen. Also einfach warten, bis die ersten Anleitungen im Netz erscheinen, wie man, ohne den Schlüssel zu wechseln, die zusätzlichen Features installieren und nutzen kann.
ist legal und provoziert - zumindest bei mir - auch kein schlechtes Gewissen.
Dann noch den Hack drüber, der Microsoft am (theoretischen) Abschalten von Komponenten über's Netz hindert...

Natürlich ist das Einsetzen nicht-lizensierter Software für Entwickler schädigend. Allerdings macht sich Microsoft mit dieser Politik keine Freunde.

Nur den Geiz-ist-geil-Käufer interessiert das alles nicht. Der will den neuen Shooter unbedingt mit dem neuen DirectX mit einer neuen Oberfläche. Dem ist es egal, was Microsoft theoretisch mit dem Rechner machen kann (an dieser Klientel sieht man auch deutlich, wieviele Sachen es gibt, die einem egal sein können).
Dem ist ja eigentlich alles egal. Hauptsache er ist satt und kann über die Politik meckern.
Das ist ja auch erklärte Firmenpolitik: Windows ist die Cash-Cow, die alles andere finanziert.
Und jetzt hat Microsoft für die nächsten fünf bis zehn Jahre eine neue, goldene Cash-Cow am Markt, die die Entwicklung von richtigen Produkten finanziert. Vor allem macht sie es möglich, neue Märkte mit extrem teuren Kampagnen zu überrennen und zu übernehmen.
So funktioniert unser Wirtschaftssystem nun mal...

24.01.2007 - 12:04 Uhr

Selbst wenn du diesen Avatar als unkomrimiertes Bitmap sendest, ist er gerade mal 100x100x4 = 40000Bytes ~ 40KB groß.
Daher könntest du einfach beim Start der Chatsession das Icon mitschicken, merken würden das nur ISDN- und Modem-Nutzer. Und diese sind aufgrund der fehlenden Flatrate eher nicht die häufigen Chatter.

Ich würde es aber trotzdem speichern. Beim Start der Chatsession können die beiden Partner sich ja mitteilen, wann der Avatar das letzte Mal geändert wurde. Dann wissen sie, ob sie es neu austauschen müssen.

24.01.2007 - 11:56 Uhr

In leichter Abwandlung:

char[] theString = sText.ToCharArray();
int numHochkomma = 0;
for ( int i = 0; i < theString.Length; i++ )
{
   if (theString[i] == '\'') // einfaches Hochkomma
   {
      numHochkomma++;
   }
   else if ((theString[i] == '\"') // doppeltes Hochkomma (Anführungszeichen)
              ((numHochkomma % 2) == 1)) // ungerade Zahl von Hochkommas
   {
      theString[i] == '\''; // ersetze durch einfaches Hochkomma
   }
}
string nText = new string( theString );
24.01.2007 - 01:58 Uhr

Wurde doch schon geschrieben.
Du benötigst die Grundklassen Punkt und Vektor.
Anschließend würde ich eine Klasse Punktmenge definieren, von dieser leiten sich 1D, 2D und 3D Klassen ab. Jede dieser Klassen hat jetzt wieder Ableitungen wie Gerade, Linienzug und Bezier-Kurve von 1D, Ebene, Polygon, Kreis und Fraktal von 2D sowie Raum, Kugel und Polyeder von 3D (und eventuell andere). Desweiteren kann ja jede der Klassen ein Interface zum Darstellen implementieren.
Wenn du dann noch verschiedene Klassen implementierst, die Operationen auf diese Objekte (skalieren, drehen, verschieben) oder Operationen mit diesen Objekten (Vereinigung, Schnitt, Differenz) implementieren, hast du schon eine komplette Geometrie-Engine entwickelt.

Du kannst das natürlich auch viel allgemeiner aufziehen, das wird dann aber derartig mathematisch, dass der "spielerische Anschauungs- und Lerneffekt" deutlich zu kurz kommt.
Auch so stellt das nicht wenig Arbeit dar.

24.01.2007 - 01:40 Uhr
public static void DisplayGatewayAddresses()
{
    Console.WriteLine("Gateways");
    NetworkInterface[] adapters  = NetworkInterface.GetAllNetworkInterfaces();
    foreach (NetworkInterface adapter in adapters)
    {
        IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
        GatewayIPAddressInformationCollection addresses = adapterProperties.GatewayAddresses;
        if (addresses.Count >0)
        {
            Console.WriteLine(adapter.Description);
            foreach (GatewayIPAddressInformation address in addresses)
            {
                Console.WriteLine("  Gateway Address ......................... : {0}", 
                    address.Address.ToString());
            }
            Console.WriteLine();
        }
    }
}