Laden...
P
Pulpapex myCSharp.de - Member
Java-Entwickler Rostock Dabei seit 22.07.2003 939 Beiträge
Benutzerbeschreibung

Forenbeiträge von Pulpapex Ingesamt 939 Beiträge

16.02.2005 - 15:33 Uhr

4) setze a auf 1 und b auf 2
5) a=b; // kann nicht gekapselt werden in c#
6) setze a auf 5 (b bleibt 2)

Die Variable b wird in dem Fall auch 2. Liegt daran, dass a und b nach der Zuweisung die selbe Instanz halten. Allerdings, die Instanz, die vor der Zuweisung in a war, ist immer noch 1. Sollte auch so zu erwarten sein, es sind ja zwei Instanzen.

Worauf du wahrscheinlich hinaus möchtest, sind Referenzen auf Referenzen. Man hat zwei Variablen a und b und wenn man b auf einen neuen Wert ändert, ändert sich auch a. Sowas geht in C# tatsächlich nicht (mangels eines Zeigertyps). Man kann es nur mit zwei Objekten, wo das erste Objekt als Referenz auf das zweite Objekt dient, nachbilden.

Mit Methoden-Parametern ist es dann doch wieder möglich. Übergibt man ein Objekt über einen ref-Parameter und wird der Parameter in der Methode auf eine neue Instanz geändert, ändert sich auch die Variable in der aufrufenden Methode.

public void Caller() {
  object a = "test";
  Callee(ref a);
  // a == "geändert";
}

public void Callee(ref object s) {
  s = "geändert";
}
16.02.2005 - 14:01 Uhr

struct - Vererbung (Ableiten nicht möglich)

Structs sind Wertetypen mit einer festgelegten Anordnung ihrer Datenfeldern, nicht mehr und nicht weniger. Man kann also sagen "Byte X im Struct S gehört zum Struct-Feld F".

Würde man Vererbung unterstützen wollen, müssten noch jede Menge Hilfsinformationen mit im Struct gespeichert werden. Damit würde der Datentyp inkompatiblen z.B. zum C-struct werden.

Man sollte froh sein, dass überhaupt Methoden unterstützt werden. Ist es etwa in C++ so, dass Wertetypen abgeleitet werden können oder wie kommst du sonst auf solche Ideen?

Gruss
Pulpapex

15.02.2005 - 17:48 Uhr

Ich habe eine Idee, weiss nicht wie man das in ASP.NET macht, ist pures Html.

Und zwar kann man im Html-Head ein Meta-Element angeben, das bewirkt, dass die aktuelle Seite angezeigt wird, danach aber sofort zu einer anderen Seite gewechselt wird. Kennt man von "Download beginnt in Kürze"-Seiten.

Auf der ersten Seite ist die Ansicht mit der Baumstruktur ohne Inhalt, nur die Ausschrift "bitte warten ...". Die Seite wechselt automatisch zur zweiten Seite, wo die Baumstruktur geladen ist. Da das Laden länger dauert, bleibt die erste Seite noch solange sichtbar, bis der Vorgang abgeschlossen ist.

Für den Benutzer sieht es so aus als warte die Seite auf den Abschluss des Ladevorganges. Noch eine kleine Ladeanimation und die Illusion ist perfekt.

Der Vorteil hierbei ist, dass keinerlei Scriptcode auf Clientseite erforderlich ist. Der Nachteil ist, dass nicht direkt in der Seite geladen wird.

Das Meta-Element sieht so aus, anzugeben im <head>-Element:

<meta http-equiv="refresh" content="0; URL=relativeUrl" />

Um zu sehen wie das Laden in einer einzelnen Seite funktioniert, einfach mal so eine Seite im Netz suchen, die das macht. Die Funktionsweise müsste aus dem Seiten-Quelltext ersichtlich sein.

Gruss
Pulpapex

15.02.2005 - 15:49 Uhr

DataBinding.Add benötigt 3 Argumente.

Probier mal folgendes:

// _idaendern.Text an this.Wert binden.
_idaendern.DataBindings.Add("Text", this, "Wert");
15.02.2005 - 14:16 Uhr

Du gibst aber schnell auf,
wie geht es denn nicht?

15.02.2005 - 13:53 Uhr
// textBox.Text binden an
// anotherObject.IntProperty.
textBox.DataBindings.Add("Text", anotherObject, "IntProperty");

Änderungen in textBox.Text werden ab sofort nach anotherObject.IntProperty übernommen, wobei Datentypen automatisch konvertiert werden.

Irgendwie war das immer bisschen hakelig. Ich kann das jetzt leider nicht ausprobieren, vielleicht weiss sonst jemand was hierbei noch zu beachten ist.

15.02.2005 - 11:37 Uhr

Wenn textBox.Text an mittels DataBinding an eine int-Eigenschaft gebunden wird, können nur noch Zahlwerte eingegeben werden. Ich glaube sogar der alte Wert wird wieder hergestellt, wenn eine Eingabe unzulässig war, bin mir aber nicht sicher. Kann auch sein, dass nur alles markiert wird und ein Warnsignal ertönt. Irgendwie war das mal so und mal so.

Gruss
Pulpapex

15.02.2005 - 08:57 Uhr

Zum Installieren von .Net-Bibliotheken im GAC gibt es gacutil.exe. Bibliotheken im GAC sind systemweit verfügbar.

Ausführen an der Konsole:

\> gacutil.exe /i <assembly.dll>

MSDN:
Global Assembly Cache Tool (Gacutil.exe)
Working with Assemblies and the Global Assembly Cache

Gruss
Pulpapex

14.02.2005 - 21:12 Uhr

Hi Malcolm,

Zeig mal den Code um die obere Code-Zeile. Man sieht gar nicht wo das aufgerufen wird. Wahrscheinlich in der Main-Methode oder? Und die befindet sich in der Snake-Klasse?

Aus statischen Methoden kann man ohne Instanz nicht auf Instanz-Variablen zugreifen. "this" bezeichnet die aktuelle Instanz, in einer statischen Methode gibt es keine Instanz.

public class Snake : Form {

  public Panel panel1;

  public static void Main() {

    // Geht nicht, da eine Snake-Instanz
    // für den Zugriff auf panel1 benötigt wird.
    panel1 = new Panel();

    // Das funktioniert, Zugriff erfolgt über die Snake-Instanz.
    // (ist aber trotzdem Unsinn.)
    Snake snake = new Snake();
    snake.panel1 = new Panel();
  }
}

Warum muss das Panel im Konstruktor übergeben werden? Normalerweise gehört sowas zum Innenleben einer Klasse und wird nicht nach außen gegeben.

public class Snake : Form {

  private Panel panel1;

  public Snake() {
     this.panel1 = new Panel();
  }

  public static void Main() {

    // Snake erzeugen, panel1 wird im Konstruktor erzeugt.
    Snake snake = new Snake();
  }
}

Gruss
Pulpapex

14.02.2005 - 17:36 Uhr

Ich würde erstmal versuchen die Test-Anwendungen zum Laufen zu bringen, besonders die ohne .Net.

Hast du das gemacht?

* If you still have an issue with GTK, it may help to install the gtk runtimes I
included. Don't forget to add the install path to your PATH directive.

14.02.2005 - 14:46 Uhr

Original von norman_timo
Ja sicherlich habe ich deinen Beitrag gesehen! Aber der Compiler hatte schon gemeckert bei der alleinigen Benutzung des Flags 'Static', er will immer das 'InvokeMember' Flag dabei haben.

Und was passiert, wenn du doch mal beide Flags angibst? Ich bin mir fast sicher, dass das so funktioniert.

14.02.2005 - 13:52 Uhr

Hi TomLeech,

das PropertyGrid erlaubt aufklappbare Baumstrukturen. Man kann eine Liste von Elementen anzeigen lassen, wobei jedes einzelne Element wiederum eine Liste sein kann.

Gruss
Pulpapex

14.02.2005 - 13:12 Uhr

Hi Maddinel,

Mit der WaveOut-Api ist das machbar, da man da mit Sound-Buffers arbeitet, also direkten Zugriff auf die Audiodaten hat. Auf kleine Blöcke der Audiodaten wird eine Fast Fourier Transformation angewendet, Ergebnis sind Amplitudenwerte für die verschiedenen Frequenzbereiche, also die Equalizer-Werte.

Es sind also zwei Teilprobleme. Einmal WaveOut, da müsste was auf CodeProject zu finden sein. Und einmal FFT, da müsstest du Google für bemühen.

Gruss
Pulpapex

14.02.2005 - 12:58 Uhr

Hi norman_timo,
meinen Post oben schon gesehen?

14.02.2005 - 12:12 Uhr

Hast du die beiden Test-Anwendungen ausprobiert? Die erste ist eine C/C++ Anwendung, die Mozilla ohne .Net einbettet. Wenn die schon nicht funktioniert, stimmt generell was nicht. Die zweite Anwendung testet Gecko# aus .Net heraus.

14.02.2005 - 12:01 Uhr

Hi norman_timo,

hast du wirklich in die Msdn-Hilfe geguckt? Eigentlich steht dort alles.
Probier das mal:

int result = (int)type.InvokeMember(
  "MyMethod",
  BindingFlags.InvokeMethod | BindingFlags.Static, 
  null,             // DefaultBinder
  null,             // Keine Instanz
  null);            // Keine Parameter

wahrscheinlich reicht auch BindingFlags.Static alleine, die InvokeMember-Methode impliziert schon, dass etwas aufgerufen werden soll.

Msdn: InvokeMember Method

Gruss
Pulpapex

14.02.2005 - 11:16 Uhr

Das bedeutet, dass es sich bei der Dll um keine .Net Assembly, sondern um eine normale Dll handelt. Die Dll wird nur intern vom Gecko.WebControl verwendet. Sie darf deshalb nicht als Verweis ins Projekt eingebunden werden, der Compiler braucht die Dll nicht und kann sowieso nichts mit ihr anfangen. Sie muss nur an der richtigen Stelle im Dateisystem liegen, so dass das Gecko.WebControl sie finden kann.

Hast du den Mozilla/Firefox installiert? Kann sein, dass noch weitere Dlls benötigt werden. Die eine Dll enthält ja nicht den gesamten Browser. Die restlichen Browser-Bibliotheken müssen also auch auffindbar sein.

Gruss
Pulpapex

14.02.2005 - 09:23 Uhr

Geht nicht anders, du musst das byte-Array mit new instanziieren und das einzelne Byte hineinkopieren (Array ist ein Object, byte ein ValueType). ... wenn so ein Array häufiger benötigt wird, am besten eine Member-Variable dafür in der Klasse vorsehen, das immer wieder verwendet werden kann.

Gruss
Pulpapex

14.02.2005 - 09:17 Uhr

Du kannst die ListViewItem.Tag-Eigenschaft benutzen und dort Strings für deinen Indexer ablegen (der der mit Zahlen und Strings funktioniert). Um jetzt die Details zu einem ListView-Eintrag abzufragen, verwendet man nicht mehr den Index, sondern eben diese Tag-Eigenschaft.

if(this.listView.SelectedItems.Count > 0) {
  ListViewItem item = this.listView.SelectedItems[0];
  string detailsKey = (string)item.Tag;
  object details = this.data[detailsKey];
}

Gruss
Pulpapex

14.02.2005 - 01:15 Uhr

Dein Gtk#-Code scheint C# 2.0 Code zu sein.

Statt

wc.NetStop += MakeShot;

muss man in .Net 1.1 noch

wc.NetStop += new EventHandler(MakeShot);

schreiben.

13.02.2005 - 21:43 Uhr

Nur das IOtSession-Interface ist sichtbar, nicht aber die implementierende Klasse OtSessionClass. Warum soll die Session auf einmal mit new erzeugt werden? Analog zum Code oben müsste es heissen:

IOtSession pSession = pApp.MakeSession("ENES", 5085, "basri", "test");

Das "p"-Präfix für Pointer würde ich in C#-Code aber weglassen.

Gruss
Pulpapex

13.02.2005 - 21:11 Uhr

Das Verhalten lässt sich nicht nachvollziehen, poste mal bisschen mehr Code. Statt Convert.ToString würde ich aber schon mal einen Cast nach string verwenden.

So habe ich es versucht, ... funktioniert:

object text = "aäbc";
MessageBox.Show((string)text);

Mit der ArrayList hat es auch nichts zu tun, habe sie weggelassen.

Gruss
Pulpapex

13.02.2005 - 18:06 Uhr

Ich hab einiges dazu gefunden wie man in .Net einen Screenshot macht.
Googlesuche: .net c# screen capture

Zwei Links:
C# Corner: Screen Capture in C# and GDI+
Developer fusion: Capture a Screen Shot

Die verwendete Technik mit PInvoke funktioniert auch mit dem Gecko-ActiveX-Control, falls du es mit Gecko# nicht hinbekommst.

Um nicht den gesamten Screen zu capturen, übergibt man der GetWindowGC-Methode die Handle-Eigenschaft des Gecko-Controls. Am Ende der Aktion erhält man ein Bitmap-Handle, aus dem in .Net ein Bitmap-Objekt erzeugt wird. Das Bitmap kann dann wie gewohnt skaliert werden.

// Edit: ich weiss nicht ob es möglich ist zu capturen, wenn das Control nicht angezeigt wird. Die Beispiel-Links oben müssen den Web-Browser jedenfalls angezeigt haben. So ist es in deinem Beispiel-Code mit Gtk# und Gecko# auch.

13.02.2005 - 17:07 Uhr

Hi x-sharp,

Hast du es mit dem Gecko-ActiveX-Control nicht hinbekommen? Wenn Gecko# ein Gtk#-Control ist, wird man es nicht als WinForm-Control verwenden können ... denke ich mir so, aber ich hab Gtk# noch nie benutzt.

13.02.2005 - 16:43 Uhr

Klick in der Entwicklungsumgebung mit der Maus mal rechts vor einer Code-Zeile in den grauen Bereich. Es erscheint ein roter Punkt, das ist ein Breakpoint.

Wenn du deine Anwendung jetzt startest, wird sie jedes Mal, wenn die Codezeile ausgeführt wird, unterbrochen und man kann sich den Inhalt von Variablen anschauen. Ausserdem ist im Stacktrace zu sehen welche Methode die aktuelle Methode aufgerufen hat.

Ein Breakpoint in der Data.Werkzeuge-Eigenschaft gesetzt und man sieht, dass die comboBoxAll_TextChanged-Methode auf die Eigenschaft zugreift. Die Methode sieht so aus:

private void comboBoxAll_TextChanged(object sender, EventArgs e) {

            blatt.Werkzeuge[1] = comboBoxW1.Text;
            blatt.Werkzeuge[2] = comboBoxW2.Text;
            blatt.Werkzeuge[3] = comboBoxW3.Text;
            blatt.Werkzeuge[4] = comboBoxW4.Text;
            blatt.Werkzeuge[5] = comboBoxW5.Text;
            blatt.Werkzeuge[6] = comboBoxW6.Text;
            blatt.Werkzeuge[7] = comboBoxW7.Text;
            blatt.Werkzeuge[8] = comboBoxW8.Text;
            blatt.Werkzeuge[9] = comboBoxW9.Text;
            blatt.Werkzeuge[10] = comboBoxW10.Text;
            blatt.Werkzeuge[11] = comboBoxW11.Text;
            blatt.Werkzeuge[12] = comboBoxW12.Text;

            blatt.Material[1] = comboBoxM1.Text;
            blatt.Material[2] = comboBoxM2.Text;
            blatt.Material[3] = comboBoxM3.Text;
            blatt.Material[4] = comboBoxM4.Text;
            blatt.Material[5] = comboBoxM5.Text;
            blatt.Material[6] = comboBoxM6.Text;
            blatt.Material[7] = comboBoxM7.Text;
            blatt.Material[8] = comboBoxM8.Text;
            blatt.Material[9] = comboBoxM9.Text;
            blatt.Material[10] = comboBoxM10.Text;
            blatt.Material[11] = comboBoxM11.Text;
            blatt.Material[12] = comboBoxM12.Text;
}

Die Methode ist der TextChanged-Ereignishandler für alle ComboBoxes. Das Ereignis wird ausgelöst, wenn sich der Text irgendeiner ComboBox ändert. Es werden die Werte der ComboBoxes in die Eigenschaften Werkzeuge und Material übernommen.

Und genau das passiert in deinem oben geposteten Code - der Text in den ComboBoxes wird geändert worauf jedes Mal das TextChanged-Ereignis ausgelöst wird und Werkzeuge und Material aus den ComboBoxes gefüllt werden.

Dass das 0-te Array-Element nicht betroffen ist, liegt daran, dass erst ab Index 1 zugewiesen wird (siehe Code). CopyTo verwendest du wiederum mit Index 0, also da stimmt auch irgendetwas nicht. Besser du gewöhnst dir Index 0 als kleinsten Index an.

Gruss
Pulpapex

13.02.2005 - 12:24 Uhr

Was heisst denn die Arrays werden "gelöscht"? Werden die Arrays selbst null, wird ihre Länge 0, werden die Elemente null oder Leerstring? Dann noch ein paar Fragen: verwendest du DataBinding? Hast du in den Accessoren beider Eigenschaften schon mal Breakpoints gesetzt, um zu sehen, welcher Code sie verwendet?

Ich vermute, der Fehler liegt nicht im geposteten Code-Abschnitt. Vielleicht könntest du aber trotzdem auch die Version des Code-Abschnittes posten, die nicht funktioniert.

Gruss
Pulpapex

12.02.2005 - 03:05 Uhr

allerdings sind einige Routinen nicht ganz schlecht, aber die kann man sich wenn man Bock hat mit google oder so suchen

Oder mit www.koders.com // 177,432,215 lines of code

11.02.2005 - 20:36 Uhr

Ob ein Programm eine Konsole anzeigt oder nicht, kann in den Projekt-Einstellungen geändert werden. Auch eine Fenster-Anwendung kann eine Konsole haben. Musst mal bisschen suchen, die Einstellung müsste bei den Compiler-Optionen sein.

11.02.2005 - 15:18 Uhr

Die GetLastError-Funktion wird schon durch die Marshal-Klasse bereitgestellt.

int lastError = Marshal.GetLastWin32Error();

In der API-Doku steht, dass Marshal.GetLastWin23Error verwenden soll, statt eine eigene DllImport-Methode für die Funktion zu schreiben. Weiter zu beachten ist, dass LastError nur bei Plattform-Aufrufen verfügbar ist, wenn im DllImport-Attribut zu einer Methode SetLastError=true angegeben ist.

[DllImport("user32.dll", SetLastError=true)]
public static extern int MessageBoxA(/*..*/);

MSDN: Marshal.GetLastWin32Error Method

11.02.2005 - 10:25 Uhr

Dieser Tipp aus der Seite ist extrem wichtig:
Put a single catch (Exception ex) per thread

Ist mir schon passiert, dass ich in einer Methode, die ich mit einem asynchronen Delegat aufrufe, keinen solchen try-catch-Block hatte. Ich hab ewig gesucht bis ich den Fehler gefunden hatte. Weil, es gibt keinen Stacktrace, der Thread wird einfach stillschweigend abgebrochen.

11.02.2005 - 09:26 Uhr

Es gibt Module. Wofür sie gebraucht werden, weiss ich allerdings auch nicht. Es ist wohl so, dass mehrere Module zu Assemblies kombiniert werden können. Der C#-Compiler generiert mit der Option /target:module Modul-Dateien. Mit /addmodule können bestehende Module zu einer zu generierenden Assembly hinzugefügt werden.

Ausserhalb einer Assembly machen Module wenig Sinn. Es gibt auch kein Sprachkonstrukt, dass ein Modul in C# abbildet - so wie Namespaces und Klassen, ein Module-Schlüsselwort gibt es nicht. Allerdings kann mittels Reflektion auf Module in einer Assembly zugegriffen werden.

Es gibt wohl nur wenige Einsatzscenarien für so was. Mir fällt auf die Schnelle nicht viel ein. Vielleicht Vorcompilierung, damit grosse Projekte schneller erstellt werden können? Oder Code-Komponenten, die durch Kopieren in mehreren Assemblies wiederverwendet werden sollen?

Gruss
Pulpapex

10.02.2005 - 22:20 Uhr

Die Namensgebung der Methoden ist anfangs verwirrend, wenn man das Visitor-Pattern nicht kennt. Das liegt daran, dass das Pattern es erlaubt, beliebige, neue Operationen auf den Daten-Objekten (Sprite, Label) zu definieren, die wenig bis gar nichts mit einander zu tun haben, für die man aber einheitliche Methodennamen benötigt. Neben der Render-Operation könnte es z.B. eine Operation zum Neuberechnen von Objekt-Positionen nach physikalischen Gesetzen geben oder eine Operation, die Werte für Statistiken sammelt usw.

Wenn es wirklich nur ums Rendern geht, kann die Namensgebung deutlicher gemacht werden, das Prinzip bleibt aber das selbe.

Das ganze mal in Code, zuerst die renderbaren Objekte:

// Interface für renderbare Objekte.
public interface IRenderable {
  void RenderWith(IRenderer r);
}

// Sprite-Klasse, bewegliche Vordergrundobjekte.
public class Sprite : IRenderable {

  // Sprite vom übergebenen Renderer rendern lassen.
  // Welcher Renderer das ist und wo er herkommt,
  // ist uninteressant.
  public void RenderWith(IRenderer r) {

    // Die zugehörige Render-Methode aufrufen.
    // Sich selbst als Parameter übergeben.
    r.RenderSprite(this);
  }
}

// Label-Klasse, Text-Overlays.
public class Label : IRenderable {

  // Label vom übergebenen Renderer rendern lassen.
  public void RenderWith(IRenderer r) {
    r.RenderLabel(this);
  }
}

Renderer: Klassen zum Rendern der Objekte. Es können beliebig viele,
verschiedene Renderer definiert werden. Für jedes renderbare
Objekt muss eine Render-Methode vorgesehen werden.

// Interface für Renderer.
public interface IRenderer {
  void RenderSprite(Sprite s);
  void RenderLabel(Label l);
}

// Eine Renderer-Implementierung für Direct3D.
// Die Klasse definiert Render-Methoden
// für die verschiedenen Objekte. Wo die Objekte
// herkommen ist uninteressant.
public class D3DRenderer : IRenderer {

  // Das Direct3D-Device.
  public Microsoft.DirectX.Direct3D.Device Device {
    // get; set;
  }

  public void RenderSprite(Sprite s) {
    // Hier der Code zum Sprite-Rendern in D3D.
  }

  public void RenderLabel(Label l) {
    // Hier der Code zum Label-Rendern in D3D.
  }
}

RenderWorld: der D3DRenderer auf die renderbaren Objekte angewendet:

// Eine Klasse, die das ganze verwendet.
public class Client {

  private World world;
  private D3DRenderer d3dRenderer = new D3DRenderer();

  // Die Spielwelt
  public World World {
    get { return world; }
    set { world = value; }
  }

  // Der Renderer
  public D3DRenderer D3DRenderer {
    get { return d3dRenderer; }
  }

  // ----------------------------------------
  // Methode zum Rendern der Spielwelt.
  // so wird das Visitor-Pattern angewendet.
  // ----------------------------------------
  public void RenderWorld() {

    D3DRenderer.Device.BeginScene();

    // Nacheinander alle Objekte in der Spielwelt rendern lassen.
    foreach(IRenderable renderObject in World.Parts) {
       renderObject.RenderWith(D3DRenderer);
    }

    D3DRenderer.Device.EndScene();
  }
}

// Spielwelt-Klasse.
public class World {

  private List parts = new ArrayList();

  // Eine Liste mit allen Objekten in der Spielwelt.
  // (mir fällt kein guter Name ein)
  public List Parts {
    get { return parts; }
  }
}

Ich weiss, sieht nach viel Code aus, ist es aber nicht. Das meiste sind die Kommentare. 😉

Gruss
Pulpapex

10.02.2005 - 13:53 Uhr

File.Create gibt schon den geöffneten FileStream zurück. Du versuchst die Datei dann mit new StreamWriter ein zweites Mal zu öffnen.

Versuch es mal so:

Stream stream = File.Create(Application.StartupPath + "\\\\figuren.txt");
StreamWriter writer = new StreamWriter(stream);
// ..
10.02.2005 - 12:43 Uhr

Die Seite erklärt es so:

Zuerst das Control für COM registrieren. Am Dos-Prompt im Verzeichnis der Dll eingeben:

\> regsvr32 mozctlx.dll

Danach kann es in eine IDE integriert werden, Beispiel VB.NET:

Using the control from VB .NET

The Mozilla Browser control should be usable from any automation control container. This includes Visual Basic .NET, so follow these steps to add the control to your VB project:

* Install the control / or compile it and ensure it is registered.  
* In the &quot;View&quot; menu, click &quot;Toolbox&quot;  
* Click the &quot;Components&quot; tab  
* Right-click anywhere in the &quot;Toolbox&quot; and click &quot;Customize Toolbox...&quot;  
* In the &quot;COM Components&quot; tab, check the &quot;MozillaBrowser Class&quot; and click &quot;OK&quot;  
* The Mozilla Browser control should now appear as &quot;Browser&quot; in the &quot;Toolbox&quot; for insertion into any application. (Click and drag onto your form)

In SharpDevelop müsste es ganz ähnlich funktionieren. Irgendwo müsste es ne Option zum Hinzufügen von Steuerelementen zur Designer-Toolbox geben. Dort im Datei-Auswahldialog die Dll des Gecko-Controls auswählen. Das Control müsste dann in der Toolbox auftauchen und sich auf Windows Forms platzieren lassen.

10.02.2005 - 09:06 Uhr

Wenn es noch so einfach ist, reicht IndexOf:

bool isSubstring = "telefonbuch Österreich und Deutschland".IndexOf("buch") >= 0;

Gruss
Pulpapex

09.02.2005 - 22:12 Uhr

Benutzt du einen visuellen Designer? Vielleicht solltest du es da mal ändern. Ausser du bist dir sicher, dein Code wird erst nach dem Designer-Code aufgerufen.

Die Eigenschaft ist jedenfalls die richtige.

09.02.2005 - 21:58 Uhr

Hi Chefkoch,

schau mal hier:
Exposing .NET Framework Components to COM

Gruss
Pulpapex

09.02.2005 - 21:50 Uhr

Hi dragi,

du hast zwar die rand-Variable in der Wuerfel-Klasse auskommentiert, ich vermute aber sie soll noch da sein.

Also, Ziel soll es sein, dass die Wuerfel-Objekte ihr benötigtes Random-Objekt nicht selbst initialisieren, da dann das Problem mit den gleichen Start-Werten auftritt. Die Lösung ist, eine Wuerfel.Rand-Eigenschaft einführen oder das Random-Objekt im Konstruktor zu übergeben.

public class Wuerfel {
 
  private Random rand;

  public Wuerfel() : this(null) {}

  public Wuerfel(Random r) {
    rand = r;
  }

  public Random Rand {
    get { return rand; }
    set { rand = value; }
  }
}

Der Initialisierungscode in MainForm sieht dann so aus:

rand = new Random();
W1 = new Wuerfel(rand);
W2 = new Wuerfel(rand);
W3 = new Wuerfel(rand);
W4 = new Wuerfel(rand);
W5 = new Wuerfel(rand);

Gruss
Pulpapex

09.02.2005 - 21:35 Uhr

Hi n!c3,

dataGrid.RowHeadersVisible = false;
09.02.2005 - 21:18 Uhr

Wie wäre es mit dem Visitor Design Pattern?

Das Pattern ist gut geeignet, um Operationen auf Datenstrukturen zu definieren. Es ist sehr angenehm damit zu programmieren, da man sich keine Gedanken zu machen braucht, welche Methode für eine Operation auf einem Daten-Objekt aufgerufen werden muss - if oder switch-Anweisungen gibt es nicht. Man ruft auf einem Daten-Objekt Accept auf und übergibt die auszuführende Operation (den Visitor) als Parameter.

Ich habe das Visitor Design Pattern für deinen Fall mal als UML-Diagramm gezeichnet (und dabei gleich ein bisschen Visual Paradigm ausprobiert):

Die Accept-Methoden der Daten-Objekte, die wie gesagt die Operationen entgegennehmen, werden folgendermaßen implementiert:

public class Sprite : IModelPart {
  public void Accept(IModelVisitor v) {
    v.VisitSprite(this);
  }
}
public class Obstacle : IModelPart {
  public void Accept(IModelVisitor v) {
    v.VisitObstacle(this);
  }
}
public class Label : IModelPart {
  public void Accept(IModelVisitor v) {
    v.VisitLabel(this);
  }
}

Die Visit-Methoden in den Operationen (den Visitors) bekommen als Parameter das Daten-Objekt, auf dem die Operation angewendet werden soll. In deinem Fall das Sprite oder Label, das gerendert werden soll. Was sonst noch benötigt wird, z.B. ein Direct3D-Device, muss dem konkreten Visitor über Properties mitgeteilt werden.

Ein Client kann das ganze nun verwenden. Im Diagramm ist Beispielcode für eine RenderWorld-Methode angegeben.

Gruss
Pulpapex

09.02.2005 - 18:37 Uhr

Die Fehlermeldung CS2008 bedeutet, dass der Compiler csc ohne die Angabe von Quelldateien aufgerufen wurde. Du hast wahrscheinlich kein Projekt angelegt. Einfach ne cs-Datei in #Develop neu anlegen oder öffnen, reicht nicht.

public static void Main() {}

als Entry-Point anzugeben, ist in Ordnung.

.Net erkennt verschiedene Signaturen der Main-Methode, z.B.:

static void Main();
static int Main();
static int Main(string[] args)

Wichtig ist, dass Main statisch ist.

Gruss
Pulpapex

09.02.2005 - 17:23 Uhr

Habe ich gerade in der c't gelesen, für den Gecko-Renderer (Mozilla/Firefox) gibt es auch ein als Steuerelement einbindbares ActiveX-Control.

www.iol.ie/~locka/mozilla/mozilla.htm

09.02.2005 - 14:56 Uhr

Kurz und knapp - nein.

Mit .Net Bordmitteln geht es nicht, da kann man nur auf Dateiebene lesen und schreiben. Mit Windows-Programmierung könnte es u.U. gehen. Aber selbst da dürfte es sehr schwierig sein, da man am Dateisystem vorbei direkt auf Sektoren zugreifen müsste. Sowas ist Anwendungsprogrammen nicht gestattet, du müsstest wahrscheinlich einen Windows Treiber mit Kernel Mode Rechten schreiben.

Einstieg: How to Write a Windows Driver

Gruss
Pulpapex

09.02.2005 - 09:14 Uhr

Es muss doch auch moeglich sein, eine HTML-Seite (die aber als String vorliegt, nicht als URL) in einem Formular eines Programmes richtig darzustellen, mit mshtml oder axWebBrowser.

Hi TelStaR,

kann es sein, dass du meinen Post oben übersehen hast? Was du fragst ist so ähnlich im Link beschrieben, den ich angegeben habe. In VS kann man das axWebBrowser-Control zur Designer-Toolbox hinzufügen, indem man "Windows Webbrowser" oder "Windows Internet Controls" aus der Liste der verfügbaren COM-Controls hinzufügt. Wenn beides nicht da ist, muss man windows\system32\shdocvw.dll über den Durchsuchen-Button hinzufügen.

Gruss
Pulpapex

08.02.2005 - 18:25 Uhr

Die Seek-Methode ist in der abstrakten Klasse System.IO.Stream definiert. Alle Streams haben diese Methode, nur unterstützt wird sie halt nicht immer, und NetworkStream unterstützt sie nicht. Wie herbivore schon gesagt hat, werfen die Streams ohne Unterstützung NotSupportedExceptions.

08.02.2005 - 18:19 Uhr

Guck mal hier: Prozess/InternetExplorer schliessen

Da habe ich beschrieben wie man den IE im eigenen Fenster anzeigen und steuern kann... In der generierten COM-Interop-Dll ist auch das als Windows-Control einbettbare IE-Control enthalten. Das lässt sich einfach im visuellen Designer auf eine Form ziehen.

An das Control kommt man auch, wenn man in der IDE einen COM-Verweis auf die Dll hinzufügt.

Gruss
Pulpapex

08.02.2005 - 17:59 Uhr

Es gibt die CanSeek-Methode, mit der überprüft werden kann, ob ein Stream-Objekt Unterstützung zum Fortsetzen bietet. NetworkStream unterstützt es auf jeden Fall nicht, aber FileStream.

Wenn man sich das so überlegt, eine FTPStream-Klasse mit CanSeek == true wäre echt nicht schlecht.

Gruss
Pulpapex

04.02.2005 - 13:06 Uhr

Ich vermute es ist so wie du es schreibst:

"[..] dass ich als Culture nur "de" verwende und dass er damit nicht formatieren und parsen kann."

In in der de-Culture ist ',' das Dezimaltrennzeichen. In SQL darf das natürlich nicht verwendet werden, sonst kommt sowas bei raus:

insert into testTable values (1, 'test', 0,50)

... wie gesagt, nur ne Vermutung,

Gruss
Pulpapex

04.02.2005 - 12:51 Uhr

nur, dass ein byteweises Vorgehen hier beschleunigt wird

Das kann man so nicht stehen lassen.

Erstens wird auch in der foreach-Schleife das byte-Array erstmal erstellt, bevor es iteriert wird (es wird nicht "on the fly" aus dem String iteriert oder so). Und zweitens ist eine foreach-Schleife langsamer als eine for-Schleife.

Die for-Schleife kann direkt auf Array-Elemente zugreifen:

byte[] bytes = Encoding.ASCII.GetBytes("test);
for(int i = 0; i < bytes.Length; i++) {
  byte b = bytes[i];
}

Die foreach-Schleife benötigt dazu einen Enumerator (eine foreach-Schleife wird vom Compiler ungefähr so übersetzt):

byte[] bytes = Encoding.ASCII.GetBytes("test");
IEnumerator e = bytes.GetEnumerator();
while(e.MoveNext()) {
  byte b = (byte)e.Current;
}

Man sieht, dass der foreach-Code aufwändiger ist. Natürlich wird noch optimiert, trotzdem ist die for-Schleife schneller (im Moment noch, es daran gearbeitet, dass die foreach-Schleife mit for gleichzieht).

03.02.2005 - 13:26 Uhr

WebClient ist eine Komponente, die Klasse leitet von System.ComponentModel.Component ab. Komponenten haben eine Dispose-Methode zum Freigeben der von ihnen reservierten System-Ressourcen.

Eine andere Komponente ist zum Beispiel System.Drawings.Graphics, die intern einen Windows Graphics Kontext reserviert. Von diesen Kontexten gibt es nicht unbegrenzt viele, deshalb muss ein selbst erzeugtes Graphics-Objekt so schnell wie möglich wieder freigegeben werden.

Die using-Anweisung vereinfacht den hierfür erforderlichen Code. Die Codezeilen:

using(Component c = new ...) {
  // Code
}

müsste man ohne using-Anweisung so schreiben:

Component c = new ...;
try {
  // Code
} finally {
  if(c != null) {
    c.Dispose();
  }
}