Entwickler-Ecke
WinForms - JavaScript drucken unterbinden bzw ohne Dialog drucken
Leon669 - Mo 08.08.16 08:58
Titel: JavaScript drucken unterbinden bzw ohne Dialog drucken
Ich nochmal und es geht wieder um denn Visual Webbrowser...
Ich habe folgendes Problem.
Auf einer Website ist ein Drucken Button nun öffnet sich daraufhin der Windows Drucken Dialog. Meine Frage ist es möglich dies zu unterbinden und mit der webbrowser.print() Variante die entsprechende Seite zu Drucken oder die Seite ohne denn Drucken Dialog zu drucken?
LG
Delete - Di 09.08.16 00:45
- Nachträglich durch die Entwickler-Ecke gelöscht -
Leon669 - Di 09.08.16 08:55
Beides Funktioniert nicht
Nummer eins gar nicht bei der zweiten Variante kann ich es nicht zu 100% sagen, da sich das Drucken Dialog Fenster erst nach wenigen sekunden öffnet und ich nun nicht weiss ob der befehl überhaupt ausgeführt werden kann.
ich habe es so aufgerufen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45:
| namespace Webbrowser { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.StartPosition = FormStartPosition.Manual; this.Location = new Point(-5, 0); SHDocVw.WebBrowser_V1 axBrowser = (SHDocVw.WebBrowser_V1)webBrowser1.ActiveXInstance; axBrowser.NewWindow += axBrowser_NewWindow; } void axBrowser_NewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed) { Processed = true; webBrowser1.Navigate(URL); ClosePrintDlg(); }
[System.Runtime.InteropServices.DllImport("User32.dll")] static extern int FindWindow(string lpClassName, string lpWindowName);
[System.Runtime.InteropServices.DllImport("User32.dll")] static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
const int WM_SYSCOMMAND = 0x0112; const int SC_CLOSE = 0xF060;
private void CloseWindow(string className, string windowName) { int windowHandle = FindWindow(className, windowName); if (windowHandle != 0) SendMessage(windowHandle, WM_SYSCOMMAND, SC_CLOSE, 0); }
const string PRINTDLG_CLASS = "#32770"; const string PRINTDLG_WINDOW = "Drucken";
private void ClosePrintDlg() { CloseWindow(PRINTDLG_CLASS, PRINTDLG_WINDOW); } } } |
Moderiert von
Th69: Full-Quote entfernt.
Moderiert von
Th69: Code- durch C#-Tags ersetzt
Palladin007 - Di 09.08.16 09:22
Kannst Du mir ein kleines Test-Projekt hoch laden?
Hab vorhin versucht, den Drucken-Dialog im WinForms WebBrowser durch einen Button-Click auf zu kriegen, aber scheinbar klappt das, wie ich es kenne, im IE nicht :/ Asche auf mein Haupt :D
Ich hab erst heute Abend wieder Zeit, aber mal schauen, ob ich dann was in der tiefen WinApi-Trickkiste finde
Wäre ja gelacht, wenn man das nicht auch irgendwie umgehen kann ^^
Zum Standart-WebBrowser in WinForms selber kann ich leider nichts sagen, hab nur einmal vor Ewigkeiten was damit gemacht und danach direkt die Chrome-Variante herunter geladen :D
Delete - Di 09.08.16 13:41
- Nachträglich durch die Entwickler-Ecke gelöscht -
Palladin007 - Di 09.08.16 19:59
Ok, ist doch ganz schon verzwickt die Sache
Der WebBrowser hat kein Event, was geworfen wird.
Auch wird keine WindowsMessage gesendet
Es läuft alles rein durch den IE, der im Hintergrund läuft.
Aktuell bin ich soweit, dass ich das COM-Objekt von dem IE-Webbrowser habe und die ComTypeDescription.
Und da hänge ich ...
Ich habe 51 Events, zwei davon heißen:
PRINTTEMPLATEINSTANTIATION
PRINTTEMPLATETEARDOWN
Zu diesen beiden Events bekomme ich dann aber auch nur eine sourceIID (Doppeltes I ist gewollt, das heißt so)
Das COM_Objekt selber wird vom WinForms-WebBrowser mit Hilfe
dieses Interfaces [
http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/UnsafeNativeMethods.cs,5675b8c7e9940807] genutzt.
Allerdings sieht das auch nicht so aus, als bekäme ich da hilfreiche Infos.
Wenn noch jemand eine Idee hat, wie ich irgendwie erfahren kann, ob sich das Ding geöffnet hat oder noch besser: Wie ich das abbrechen kann, ich bin ganz Ohr :D
Damit ich aber nicht ganz mit leeren Händen da stehe, hab ich mal das CloseWindow über die WinApi zum Laufen gebracht.
Das Problem war, dass der PrintDialog asynchron angezeigt wird. Der ist also noch gar nicht da, wenn versucht wird, das Fenster zu schließen.
Also hab ich das ganze in eine asynchrone Methode gelegt, die alle 10 Millisekunden prüft ob das Fenster da ist und es dann auch direkt wieder schließt.
Daraus könnte man dann natürlich auch ein Event machen, damit Du dann z.B. auf eigene Faust drucken kannst.
Dss das Fenster kurz auf flackert kann ich aber nicht verhindern.
Der Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| private async Task ClosePrintDialog() { const string PRINTDLG_CLASS = "#32770"; const string PRINTDLG_WINDOW = "Drucken"; const int WM_SYSCOMMAND = 0x0112; const int SC_CLOSE = 0xF060;
int printDialogWindowHandle;
do { printDialogWindowHandle = FindWindow(PRINTDLG_CLASS, PRINTDLG_WINDOW); await Task.Delay(10); } while (printDialogWindowHandle == 0);
SendMessage(printDialogWindowHandle, WM_SYSCOMMAND, SC_CLOSE, 0); ClosePrintDialogTimer.Stop(); }
[DllImport("User32.dll")] static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")] static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); |
Delete - Di 09.08.16 22:44
- Nachträglich durch die Entwickler-Ecke gelöscht -
Palladin007 - Di 09.08.16 23:00
Mit dem Timer hat es nicht funktioniert, hab aber auch nicht groß weiter geschaut, warum nicht.
Mein Plan war, dass der Timer sich selber deaktiviert, nachdem er das PrintWindow geschlossen hat. Soweit kam es aber nie.
Da ich hier sowieso nicht auf Threadsicherheit achten muss - Windows ist ja threadsicher - habe ich es direkt mit Tasks.
Das macht den Code auch übersichtlicher, wie ich finde, da ich keinen Timer starten und beenden und auch auf kein Tick-Event hören muss.
PS:
Umittelbar vor, während oder nach dem ShowPrintDialog wird kein einziges Event geworfen.
Ich hab mir extra per Reflection alle verfügbaren Events raus suchen und abonieren lassen, damit ich auch keines vergesse.
Die kann man also nicht als Ausgangspunkt nehmen
Delete - Mi 10.08.16 02:44
- Nachträglich durch die Entwickler-Ecke gelöscht -
Palladin007 - Mi 10.08.16 05:59
Kann sein, weiß ich nicht :D
Aber eine Lösung gegen das kurz aufflackern haben wir immer noch nicht :/
Es ist zwar eine funktionierende Lösung, aus Sicht eines Entwicklers, aber für den Benutzer sieht das schon reichtlich komisch aus.
Dann doch lieber einen anderen WebBrowser verwenden, vielleicht haben ja die .NET-Implementierungen der Konkurenz da Möglichkeiten eingebaut.
Der WebBrowser von WinForms basiert sowieso noch auf Version 4 und sollte damit vermieden werden :D Zumindest hab ich das irgendwo in diesem COM-Objekt gelesen
Palladin007 - Mi 10.08.16 20:06
Dann ist wohl das Interface, was der WebBrowser nutzt, das, was noch zu IE4-Zeiten verwendet wurde. Irgendwoher muss das ja kommen :D
Aber hat sonst niemand eine Idee, wie man Events von COM-Objekten abonieren kann?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!