Laden...

Forenbeiträge von tikra Ingesamt 185 Beiträge

12.02.2008 - 11:18 Uhr
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("Wollen Sie die Anwendung wirklich beenden?", "Titel", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.No)
                e.Cancel = true;
        }

Die Anwendung schliesst sich einfach, was mache ich falsch?

23.01.2008 - 17:12 Uhr

Okay, DocumentCompleted hat mir das erste Problem gelöst.

Nun bleibt da noch das zweite: Ich drucke das Dokument in einen Postscript-Drucker, sprich in eine Datei und wandle diese nachher in einen .pdf-File um.

Nach dem Aufrufen der Funktion (die das Ereignis zum drucken anstößt und die Postscript-Datei erstellt!) aus dem Programmablauf heraus wird weiter Code abgearbeitet und ein Umwandeln des (noch nicht gedruckten/erstellten) Postscript-Files schlägt fehl.

Funktioniert das irgendwie eleganter:

                            while (!File.Exists("C:\\test.ps"))
                            {
                                Wait(500);
                            }
23.01.2008 - 15:39 Uhr

Ah, wunderbar, Dankeschön.

Zu diesem Event habe ich einen schönen Artikel mit einem Codebeispiel gefunden:

private void PrintHelpPage()
{
    // Create a WebBrowser instance. 
    WebBrowser webBrowserForPrinting = new WebBrowser();

    // Add an event handler that prints the document after it loads.
    webBrowserForPrinting.DocumentCompleted +=
        new WebBrowserDocumentCompletedEventHandler(PrintDocument);

    // Set the Url property to load the document.
    webBrowserForPrinting.Url = new Uri(@"\\myshare\help.html");
}

private void PrintDocument(object sender,
    WebBrowserDocumentCompletedEventArgs e)
{
    // Print the document now that it is fully loaded.
    ((WebBrowser)sender).Print();

    // Dispose the WebBrowser now that the task is complete. 
    ((WebBrowser)sender).Dispose();
}

(http://msdn2.microsoft.com/de-de/library/system.windows.forms.webbrowser.documentcompleted(VS.80).aspx)

23.01.2008 - 14:12 Uhr

Ja es ist ein String und ich denke, das ich den Zugriff dadurch synchronisiere, das ich eben diese while-Warteschleife da eingebaut habe, wenn ich jetzt richtig verstanden habe, was du mit synchronisieren meinst.

Ereignisse bringen mich deswegen nicht weiter, weil auch wenn ich das Aufrufen der Funktion in den Ablauf hineinkopiere, die Abarbeitung der Befehle "zu schnell" erfolgt, sprich auch wenn ich am Ende von myThread ein Ereignis feuere, welches dann den webBrowser initialisiert, den String zuweist und dann druckt, auch dann wird im Prinzip das Ereignis zu früh gefeuert und somit zu früh auf den String zugegriffen.

23.01.2008 - 13:30 Uhr

Ich bin zu dem Entschluss gekommen, das auch Events mich zu 99% nicht weiterbringen bei meiner Problematik.

Ich möchte mein Problem mal ein wenig konkretisieren, um es besser verständlich zu machen:


                            Thread myThread = new Thread(new ThreadStart(myFunction));
                            myThread.Start();
                            
                            while (htmlCode == "")
                            {
                                Wait(1);
                            }

                            InitializeWebBrowser();
                            webBrowser.DocumentText = htmlCode;
                            Wait(2);
                            webBrowser.Print();
                            htmlCode = "";

myFunction liefert im Endeffekt einen String mit html-Code, ausgelesen aus einer Website.

Die Warteschleife und die Wait-Funktion gefallen mir nicht, sind aber irgendwie in dieser form nötig. Ohne die while-Schleife wird direkt das WebBrowser-Element initialisiert und mit "htmlCode" gefüllt, der aber noch nicht zur Verfügung steht.
(Auch wenn ich die Ausführung der Funktion in den Ablauf direkt hineinkopiere und nicht über einen Thread starte, passiert dasselbe. Ich bin mir dessen bewusst, dass der Code nach einem ThreadStart direkt weiter ausgeführt wird und nicht auf eine Beendigung des Threads "gewartet" wird.)

Genauso ärgerlich ist die Wait-Funktion vor dem Drucken, wenn ich diese rausnehme, dann wird eine leere Seite gedruckt, als bräuchte die Zuweisung oder Abarbeitung der Anweisung eine Weile...

16.01.2008 - 19:47 Uhr

Hallo timmi,

Bezogen auf mein Beispiel würde ich also irgendwas vom Benutzer als Start-Signal kriegen ...
ja, z.B. ein Button.Click

... und dann irgendwelche Threads starten und wenn diese abgearbeitet sind werden Ereignisse getriggert ...
genau

welche neue Threads starten, so ungefähr?
Ich hätte jetzt eher ein mit einem "welche die Ergebnisse anzeigen" gerechnet.

herbivore

Aber was, wenn ich zu diesem Zeitpunkt noch keine Anzeigbaren Ergebnisse habe?
Es geht mir ja um die Problematik, dass ich auf etwas "warten" muss um "weitermachen" zu können um keine Asynchronität im Verlauf zu kriegen.

Wenn also der Thread abgearbeitet ist wird ein Ereignis getriggert und dieses ruft einen weiteren Thread auf, der den restlichen Code abarbeitet und DIESER stellt dann die Ergebnisse dar.

Was sagst du zu der Lösung?


Kannst du mir zeigen wie man ein (eigenes) Ereignis definiert und wie ich es aus einem Thread heraus "feuere"?


Vielen Dank schon einmal soweit für die tolle Hilfe...

14.01.2008 - 17:22 Uhr

Kannst du mir evtl. sagen wie ich das hier vereinfachen kann?

g_LogText = globale Variable


        private void WriteLog(string LogText)
        {
            
            if (RichTextBoxLog.InvokeRequired)
            { // Wenn Invoke nötig ist, ...
                // dann Mehode selbst per Invoke aufrufen
                g_LogText = LogText;
                RichTextBoxLog.Invoke(new MethodInvoker(WriteLogInvoke));
                return;
            }
            else
                RichTextBoxLog.Text += LogText + "\r\n";
        }

        private void WriteLogInvoke()
        {
            RichTextBoxLog.Text += g_LogText + "\r\n";
        }

Gibt es wie bei ParametrizedThreadStart auch so eine Möglichkeit der Funktion Parameter zu übergeben die der MethodInvoker aufruft?

14.01.2008 - 16:32 Uhr

Kann es sein, das ich mit diesem Verfahren überdurchschnittlich viele globale Variablen brauche, da ich einem Thread ja keine Parameter übergeben kann?

09.01.2008 - 16:16 Uhr

Bezogen auf mein Beispiel würde ich also irgendwas vom Benutzer als Start-Signal kriegen und dann irgendwelche Threads starten und wenn diese abgearbeitet sind werden Ereignisse getriggert welche neue Threads starten, so ungefähr?

09.01.2008 - 15:09 Uhr

Ich denke aber doch, der Thread holt Daten aus einer Datenbank.
Im GUI-Thread möchte ich jetzt gerne warten bis diese Daten zur Verfügung stehen, da ich sie in einem Webbrowser-Element darstellen möchte.

Die einzige Möglichkeit die ich noch sehe ist, die Geschichte mit dem Webbrowser-Element ebenfalls auf den Thread auszulagern, dann könnte ich aber gleich komplett ALLES auf den Thread auslagern und dann muss ich für jede Kleinigkeit die mit Form-Elementen zu tun hat Invoken, würdest du es so machen? Oder was ist der klassische Weg für sowas?

Bitte schreib doch nicht nur das ich es falsch mache etc., sondern auch vielleicht ein paar Wegweisungen, wie es richtig gemacht wird.

09.01.2008 - 14:07 Uhr

Label.text = var1 + ":\\t\\t" + var2

09.01.2008 - 13:42 Uhr

Hallo ihr,

aus meinem GUI-Thread heraus möchte ich gerne einen Druckauftrag via Acrobat Reader starten, dies habe ich zuerst mit einem neuen Prozess versucht und dann mit

System.Diagnostics.Process.Start(myProcess).WaitForExit()

auf Beendigung des Prozesses gewartet, dies kann ich aber aus dem GUI-Thread heraus nicht tun, da es sich wie erwartet aufhängt, bis eben der Prozess geschlossen wird.

Nun wollte ich das gerne mit einem Thread realisieren, der beim Start eine Funktion aufruft, welche wiederum diesen Prozess startet.

Wie kriege ich das jetzt stylistisch ORDENTLICH hin, das - solange der Thread läuft - im GUI-Thread nicht weiter Code abgearbeitet wird, es soll ja alles zeitlich dort weiterhin übereinstimmen.


Ich hatte schon einmal so ein ähnliches Problem in dem selben Projekt, das habe ich wie folgt gelöst:


                        Thread myThread = new Thread(new ThreadStart(myFunction));
                        myThread.Start();

                        while (ExitFlag == true)
                        {
                            Wait(1);
                        }

ExitFlag wird dann eben in myFunction am Ende der Funktion auf true gesetzt, damit die "Main-Funktion" (GUI-Thread) weiß, der Thread ist mit der Abarbeitung fertig und jetzt kann der GUI-Thread selbst mit der Abarbeitung fortfahren...

Diese Lösung finde ich aber nicht wirklich elegant muss ich sagen.

  1. stören mich diese Sleep-Befehle irgendwie (Wait())
    und
  2. kann es doch nicht sein, das ich nach jedem Thread den ich starte so eine while-Schleife einbauen muss, oder?
29.08.2007 - 09:39 Uhr

Für all' diejenigen, die es interessiert oder einmal ein ähnliches Problem haben, hier die "Lösung" des Problems:

  1. Standarddrucker ändern
  2. webBrowser-Element erzeugen (dynamisch)
  3. webBrowser.Print();

Nicht das Programm zieht sich den Standarddrucker zum Startzeitpunkt des Programms, sondern das webBrowser-Element nutzt denjenigen Standarddrucker zum Zeitpunkt seiner Erzeugung.

Vielen Dank und einen schönen Tag noch! 😉

24.08.2007 - 10:04 Uhr

Original von timmi
So bekommt man den Standarddrucker geändert, jetzt bleibt nur noch das Problem, dass das Programm beim Drucken denjenigen Standarddrucker nimmt, der zum Zeitpunkt des Programmstarts eingestellt ist, d.h. ich brauche eine Methode, die das Form irgendwie komplett neu lädt, hat jemand da einen Ansatz?

//using System.Windows.Forms;  
using System.Runtime.InteropServices;  
  
public class SetDefPrinter {  
    [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]  
    public static extern bool SetDefaultPrinter(string prname);  
  
    public void DefaultPrinter(string prname)  
    {  
        string PrinterName = prname; // Druckernamen zuweisen.  
        SetDefaultPrinter(PrinterName);  
        //if (SetDefaultPrinter(Druckername))  
        //    MessageBox.Show("Erfolgreich!");  
        //else  
        //    MessageBox.Show("Nicht erfolgreich!");  
    }  
}  

Guten Morgen! 🙂

Möchte das Thema noch einmal aufgreifen, wisst ihr eine Lösung zu diesem Problem?

Es gibt nur 2 Lösungen:

  1. webBrowser.Print() irgendwie klar machen, auf einem anderen Drucker zu drucken

oder

  1. einen neuen Standarddrucker einstellen und stumpf webBrowser.Print() aufrufen, dafür ist es allerdings erforderlich, dass das Programm sich irgendwie den neuen Standarddrucker abruft... (was in der herkömmlichen Form nur beim ProgrammSTART passiert, leider!)
20.08.2007 - 11:49 Uhr

Bei Programmende alle Threads schliesen

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Environment.Exit(0);
        }

Läuft.

20.08.2007 - 11:30 Uhr
                    System.Threading.Thread WaitThread = new System.Threading.Thread(new System.Threading.ThreadStart(myMethod));
                    WaitThread.Start();

Ich kann auch in der Methode myMethod nicht WaitThread.Abort() aufrufen.

20.08.2007 - 11:11 Uhr

Der Name "WaitThread" ist im aktuellen Kontext nicht vorhanden.

In dem Thread läuft eine while-Schleife welche MessageBox'es erzeugt.
Ich muss den Thread beenden, wenn das Programm geschlossen wird.

20.08.2007 - 09:11 Uhr

Werde mir Control.Invoke jetzt einmal zu gemühte führen.
Vielen, vielen Dank! 🙂

Edit:

In deinem Codebeispiel, wie schreibe ich es um, dass die Methode einen Parameter entgegen nimmt?
Ich will ja nicht x Methoden für andere Texte haben, wenn ich der Methode aber einen String übergebe, dann knallt es bei

      ctrl.Invoke (new MethodInvoker (MyAccessToControls));

Weil egal wie ich es abändere er da nur den reinen Methodennamen ohne einen Parameter oder runde Klammern haben will.

void MyAccessToControls ()
{
   if (ctrl.InvokeRequired) { // Wenn Invoke nötig ist, ...
      // dann rufen wie die Mehode selbst per Invoke auf
      ctrl.Invoke (new MethodInvoker (MyAccessToControls));
      return;
   }
   // eigentlicher Zugriff; läuft jetzt auf jeden Fall im GUI-Thread
   ctrl.Text = "Hello World!";
}

Habe es mit einer globalen Variablen gelöst, zwar nicht so schön, aber verrichtet seinen Dienst...

17.08.2007 - 14:30 Uhr

Habe jetzt einen Timer mit Event am laufen, aber geht das nicht einfacher?


namespace Update
{
    public partial class Form1 : Form
    {
        static System.Windows.Forms.Timer waitTimer = new System.Windows.Forms.Timer();
        static bool exitFlag = false;

        private static void TimerEvent(Object myObject, EventArgs myEventArgs) {
           waitTimer.Stop();
           exitFlag = true;
        }

        private void UpdateButton_Click_1(object sender, EventArgs e) {
...
                        waitTimer.Tick += new EventHandler(TimerEvent);

                        // Setzt die Wartezeit auf 5 Sekunden
                        waitTimer.Interval = 3000;

                        // Startet den Timer und triggert das Event.
                        waitTimer.Start();
                        
                        while(exitFlag == false) {
                          Application.DoEvents();
                        }
...
}

Noch eine kleine Frage zwischendurch: Ist es nicht möglich aus einem anderen Thread, welcher eine Methode aufruft, auf meine Form-Elemente zuzugreifen?

Möchte in meinem Thread meine RhichTextBox editieren können! 🙁

17.08.2007 - 12:58 Uhr

Ja... so etwas wie einen Timer suchte ich ja, bin halt auf diese Variante mit Sleeps gestoßen, wie funktioniert denn das mit einem Timer? Codetechnisch... finde kein Beispiel dazu.

17.08.2007 - 12:50 Uhr

Sorry, habe es umformuliert... trifft dein Lösungsweg immer noch zu?

17.08.2007 - 12:43 Uhr

Hallo Jungs,

wie erstelle ich einen Thread, der eine Methode aufruft, welche Sleeps beinhaltet und wie sage ich meinem GUI, dass es warten soll, bis die Sleeps durchgelaufen sind, bzw. der Thread abgearbeitet wurde?

Vielen Dank schon einmal...

09.08.2007 - 09:29 Uhr

Gibt es eine Möglichkeit das Form so neu zu initialisieren / neu zu laden, dass es einem Programmneustart ähnelt?

Application.Restart() wäre eine Variante, allerdings geht dabei der ganze Content verloren, andere Ideen?

Gruß

08.08.2007 - 16:27 Uhr

Ich bin mir nicht ganz sicher, ob ich den richtigen Code entdeckt habe... und wenn ja, dann funktioniert er auch noch nicht einwandfrei:

        private void druckenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PrintDocument printDoc = new PrintDocument();
            printDoc.PrinterSettings.PrinterName = comboBox1.Text;
            
            //webBrowser1.ShowPrintDialog();
            //webBrowser1.Print();

            IHTMLDocument2 doc = (IHTMLDocument2)webBrowser1.Document;
            doc.execCommand("Print", true, 0);
        }

Fehler 1 Eine Konvertierung vom Typ "System.Windows.Forms.HtmlDocument" in "mshtml.IHTMLDocument2" ist nicht möglich. C:\Dokumente und Einstellungen\X\Desktop\Y\Z\Form1.cs 62 34 Z

Folgende Verweise/dll's habe ich eingebunden:
Microsoft.mshtml.dll
MsHtmHstInterop.dll

Woher kommt eigentlich die MsHtmHstInterop.dll? Habe die nur in deinem Ordner gefunden, ist also nichts offizielles.

08.08.2007 - 11:12 Uhr

So bekommt man den Standarddrucker geändert, jetzt bleibt nur noch das Problem, dass das Programm beim Drucken denjenigen Standarddrucker nimmt, der zum Zeitpunkt des Programmstarts eingestellt ist, d.h. ich brauche eine Methode, die das Form irgendwie komplett neu lädt, hat jemand da einen Ansatz?

//using System.Windows.Forms;
using System.Runtime.InteropServices;

public class SetDefPrinter {
    [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool SetDefaultPrinter(string prname);

    public void DefaultPrinter(string prname)
    {
        string PrinterName = prname; // Druckernamen zuweisen.
        SetDefaultPrinter(PrinterName);
        //if (SetDefaultPrinter(Druckername))
        //    MessageBox.Show("Erfolgreich!");
        //else
        //    MessageBox.Show("Nicht erfolgreich!");
    }
}
07.08.2007 - 14:12 Uhr

Wie hole ich mir die Eigenschaften des Default Printers? Und wie setze ich die Eigenschaften "um"?

Woher weiss ich, wie ich die Eigenschaften des anderen Druckers den ich ansprechen möchte einstellen muss?

Danke soweit...

PS: Die Seite hilft mir nicht weiter, dort wird nirgendwo ein Drucker geändert bzw. ausgewählt. Es werden lediglich die Methoden page setup/print preview/print setup behandelt, welche mir bei meinem Problem nicht helfen, da sie einen Dialog erfordern.

07.08.2007 - 12:35 Uhr

Wirklich niemand eine Idee? Traurig... X(

Kann ich das Projekt wohl kippen, ohne dat jeht et nich! :\

06.08.2007 - 16:01 Uhr

Ja, da war ich auch schon... hilft mir aber auch nicht weiter, die einzige Möglichkeit ist über den Dialog zu gehen, ich möchte aber gerne eine Druckerliste innerhalb meines Programms haben um gewisse Dinge zu automatisieren.

06.08.2007 - 15:25 Uhr

Warum ist denn das eigentlich so kompliziert?!

Microsoft baut eine neue Struktur wie den Webbrowser ein, lässt dafür die Print()-Methode zu aber vergisst die Möglichkeit andere Drucker auswählen zu können?! 🙁

Ich bin verzweifelt, finde auch keine Alternativen im Netz...

Es gäbe etwas mit WMI win32_printer Klasse, womit man den Standarddrucker verändern könnte (glaube ich), allerdings registriert das Programm dies nicht direkt, es müsste erst neugestartet werden, also auch mehr als suboptimal...

06.08.2007 - 13:43 Uhr

Ist es möglich die Kopf- und Fußzeile beim drucken einer Internetseite auszublenden?

Beim Internet Explorer geht es in den Einstellungen übers GUI und selbst dort ist es sehr versteckt.

Gibt es eine Möglichkeit diese Option über C# zu beeinflussen?

Vielen Dank im vorraus.

06.08.2007 - 12:44 Uhr

Hat es nicht, deswegen Frage ich ja, nur WIE gehe ich es dann anders an?

Oder kann ich vielleicht doch das PrintDocument-Objekt nutzen und als zu druckendes Objekt das Webbrowser-Element angeben?

Bin für jede Hilfe dankbar! :\

06.08.2007 - 11:08 Uhr

Oh ja, in der Tat übersehen.
Tut mir leid, trotzdem vielen Dank für deine Nachsicht! 🙂

06.08.2007 - 10:45 Uhr

In einer String Variable habe ich html-Code gespeichert, ist es möglich diesen direkt im Webbrowser-Element anzeigen zu lassen?

Oder muss ich einen Umweg gehen und den String in eine Textdatei/.html-Datei schreiben und diese dann über eine "lokale URL" im Webbrowser öffnen?

06.08.2007 - 10:31 Uhr

Für einen Test hat er den richtigen Drucker ausgewählt, auf dem ich vorgegeben habe zu drucken (leere Seite, zu Testzwecken):

private void druckenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PrintDocument printDoc = new PrintDocument();
            printDoc.PrinterSettings.PrinterName = comboBox1.Text;
            printDoc.Print();
        }

Nun möchte ich aber ein Webbrowser-Element drucken, dieses wird allerdings nur auf dem Standarddrucker gedruckt, wie komme ich an die PrinterSettings eines Objektes, welches nicht vom Typ PrintDocument ist?

private void druckenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PrintDocument printDoc = new PrintDocument();
            printDoc.PrinterSettings.PrinterName = comboBox1.Text;
            webBrowser1.Print();
        }