setDefaultPrinter propagieren

Fragen rund um diverse Windows-Versionen, ihr Verhalten unter Xbase++ und den Umgang mit der API

Moderator: Moderatoren

Antworten
Ulrich
Rookie
Rookie
Beiträge: 16
Registriert: Do, 28. Jun 2012 9:12

setDefaultPrinter propagieren

Beitrag von Ulrich »

Hallo Allerseits,

wenn ich mit

Code: Alles auswählen

		dllCall( ;
			"winspool.drv", ;
			32, ;
			"SetDefaultPrinterA", ;
			@_defprt ;
		)
einen neuen Defaultprinter setze, und danach den Acrobat Reader drucken lasse, so nimmt der noch den vorherigen Defaultprinter.

Ich versuche mit der Funktion

Code: Alles auswählen

		dllCall( ;
			"user32.dll", ;
			32, ;
			"SendMessageTimeoutA", ;
			0xffff, ;
			0x001a, ;
			0x0000, ;
			0x0000, ;
			0x0000, ;
			1000, ;
			nil ;
		)
Windows eine Sekunde Zeit zu geben, damit alle Prozesse den Wechsel mitbekommen. Leider habe ich einen Fehler in diesem Funktionsaufruf, denn er sollte ja eine Sekunde stehen bleiben - er kommt aber sofort zurück.

SendMessageTimeoutA http://msdn.microsoft.com/en-us/library ... 85%29.aspx
SetDefaultPrinter mit Hinweis auf SendMessageTimeout http://www.pinvoke.net/default.aspx/win ... inter.html

Ich freue mich auf eure Ideen und Hinweise.

Schöne Grüße
Ulrich
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: setDefaultPrinter propagieren

Beitrag von AUGE_OHR »

gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: setDefaultPrinter propagieren

Beitrag von brandelh »

Hi,

oder über die Befehlszeile den Drucker vorgeben, in diesem Thread wurde sowas behandelt, weiter unten auch der Link zu dem Dokument das die AcrobatReader Parameter erklärt.

http://www.xbaseforum.de/viewtopic.php? ... r*+drucken
Gruß
Hubert
Ulrich
Rookie
Rookie
Beiträge: 16
Registriert: Do, 28. Jun 2012 9:12

Re: setDefaultPrinter propagieren

Beitrag von Ulrich »

Danke Jimmy, den Thread habe ich gelesen. SetDefaultPrinter funktioniert, das ist nicht das Thema.

Danke auch Hubert, ich drucke als ActiveX und es gibt leider keine Möglichkeit den Drucker zu setzen. (Oder doch?)

Also nochmal zurück zu meiner Eingangsfrage: Wo habe ich in meinem zweiten Funktionsaufruf einen Fehler? Liegt es daran, dass die Variablen nicht richtig sind? Wie erstelle ich eine Long Variable? 0x0000 ist vermutlich nicht richtig?
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: setDefaultPrinter propagieren

Beitrag von brandelh »

Alle Integerwerte von Xbase++ sind intern LONG Variablen, also:

nLong := 1
nLong := int( 1.2 )
nLong := 0x16 // Hexzahl => 16

Das Ändern des Standarddruckers wird häufig nur nach einem Programmstart erkannt.
Gruß
Hubert
Ulrich
Rookie
Rookie
Beiträge: 16
Registriert: Do, 28. Jun 2012 9:12

Re: setDefaultPrinter propagieren

Beitrag von Ulrich »

Da ich den AcrobatReader immer als Objekt anspreche, sollte es doch einem Programmstart gleichkommen.

Nochmals zurück zur Eingangsfrage: Fällt euch was zur SendMessageTimeout auf?
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: setDefaultPrinter propagieren

Beitrag von georg »

Hallo, Ulrich -


was gibt Dir der Aufruf von SendMessageTimeoutA denn als Ergebnis zurück?

0 würde auf einen Fehler hinweisen, ansonsten sollte der Aufruf erfolgreich gewesen sein.

Wenn der Rückgabewert 0 ist, liefert GetLastError die Ursache (laut MSDN).

Ich habe Deinen o.a. Beispiel-Code um eine Rückgabe erweitert und ein kleines Testprogramm geschrieben, und das wartet bei mir brav 1 Sekunde und gibt 1 als Rückgabewert aus. Demnach scheint das in Ordnung zu sein.

Gegenfrage: was hast Du gegen Sleep()? Sollte die gleiche Aufgabe mit Bordmitteln erfüllen.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Ulrich
Rookie
Rookie
Beiträge: 16
Registriert: Do, 28. Jun 2012 9:12

Re: setDefaultPrinter propagieren

Beitrag von Ulrich »

Habe ich SendMessageTimeOut falsch verstanden? Ich dachte die Funktion propagiert die Änderung an andere laufende Prozesse. ... oder wartet die nur? Dann ist natürlich sleep() einfacher.

Das muss ich noch mal nachlesen. Danke Dir.

Vielleicht liegt es daran, dass ich keinen Rückgabemöglichkeit biete. Das Probiere ich aus.
Ulrich
Rookie
Rookie
Beiträge: 16
Registriert: Do, 28. Jun 2012 9:12

Re: setDefaultPrinter propagieren

Beitrag von Ulrich »

Wenn man per SetDefaultlPrinter den Windows Printer wechselt, muss man die Funktion SendMessageTimeout aufrufen.

Die Funktion SendMessageTimeout hat nichts mit sleep() zu tun, sondern sendet ein Nachricht an alle Windows Fenster (Prozesse), und teilt mit, dass sich die Systemkonfigurtion geändert hat. Somit bekommen alle Windows Fenster (Prozesse) mit, dass sich er Defaultdrucker geändert hat.

Die Wartezeit in SendMessageTimeout gibt nur an, dass die Funktion längstens x Millisekunden wartet, bis sie die Kontrolle zurückgibt. Wenn die Prozesse schnell genug reagieren, kommt die Funktion auch schneller zurück.

Hier mein Code mit Default Printer setzen. Der Code sieht vielleicht etwas ungewohnt aus, das liegt am Präprozessor.

Code: Alles auswählen

function _dms_wDefPrt
	// Default Printer lesen oder setzen

	parameter _defprt

	if empty( _defprt )
		// Lokale Variablen
		private _defprt		:= space( 0x200 )
		private _defprtlen	:= len( _defprt )

		// Default Printer ermitteln
		dllCall( ;
			"winspool.drv", ;
			32, ;
			"GetDefaultPrinterA", ;
			@_defprt, ;
			@_defprtlen ;
		)
		_defprt		:= left( _defprt, at( chr( 0 ), _defprt ) -1 )

	else

		// Default Printer setzen
		dllCall( ;
			"winspool.drv", ;
			32, ;
			"SetDefaultPrinterA", ;
			@_defprt ;
		)

		// Windows den Wechsel mitteilen
			dllCall( ;
			"user32.dll", ;
			32, ;
			"SendMessageTimeoutA", ;	// Sends the specified message to one or more windows.
			0xffff, ;					// HWND_BROADCAST ((HWND)0xffff), the message is sent to all top-level windows in the system.
			0x001a, ;					// UINT		The message to be sent. Applications should send WM_SETTINGCHANGE to all top-level windows when they make changes to system parameters.
			0x0000, ;					// WPARAM	Any additional message-specific information.
			0x0000, ;					// LPARAM	Any additional message-specific information.
			0x0000, ;					// UINT		The behavior of this function.  SMTO_NORMAL The calling thread is not prevented from processing other requests while waiting for the function to return.
			2000, ;						// UINT		The duration of the time-out period, in milliseconds.
			nil ;						// PDWORD	The result of the message processing.
		)

	endif

return _defprt
Grüße
Ulrich
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: setDefaultPrinter propagieren

Beitrag von AUGE_OHR »

Ulrich hat geschrieben:Da ich den AcrobatReader immer als Objekt anspreche, sollte es doch einem Programmstart gleichkommen.
das "terminieren" einer activeX "Verbindung", welches als Thread lauft, könnte eine Weile dauern und bis es dann "wirkt" ...
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

Note This is a blocking or synchronous function and might not return immediately. How quickly this function returns depends on run-time factors such as network status, print server configuration, and printer driver implementation—factors that are difficult to predict when writing an application. Calling this function from a thread that manages interaction with the user interface could make the application appear to be unresponsive.
Ulrich hat geschrieben:...Somit bekommen alle Windows Fenster (Prozesse) mit, dass sich er Defaultdrucker geändert hat.
SendMessageTimeoutA sorgt IMHO, ähnlich wie Sleep(), in erster Line für "Zeit".
auch hast du Recht das die Function "auch schneller zurück" kommt ... aber erst wenn der Notify Event in der Queue ist !

"früher" ( OS() < 5.x ) musste man per

Code: Alles auswählen

SendNotifyMessage(HWND_BROADCAST,WM_WININICHANGE,0,(LPARAM)szWindows);
noch "manuell" den Notify Event senden ... und er funktioniert immer noch ... ;)
gruss by OHR
Jimmy
Ulrich
Rookie
Rookie
Beiträge: 16
Registriert: Do, 28. Jun 2012 9:12

Re: setDefaultPrinter propagieren

Beitrag von Ulrich »

Ich habe die Links vergessen. Bitte um entschuldigung.

Erklärung zu SendMessageTimeout:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

SendMessageTimeout wird in meinem Beispiel genutzt, um den Prozessen mitzuteilen, dass eine Systemändernug stattgefunden hat.
Diese Funktion hat rein garnichts mit sleep() zu tun. Siehe auch mein vorheriger Post.

SendNotifyWindows:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

Diese Funktion ähnelt sehr SendMessageTimeout. Durch Angabe von HWND_BRODCAST (0xffff) wird die Nachricht an alle Prozesse gesendet.

Ein Hinweis zu einem früheren Zeitpunkt hätte mir geholfen, doch leider habe ich nicht klar zu Ausdruck gebracht, wie meine eigentliche Frage lautet. Sorry.
Antworten