AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Änderungen an Druckeren erkennen (neu, gelöscht)
Thema durchsuchen
Ansicht
Themen-Optionen

Änderungen an Druckeren erkennen (neu, gelöscht)

Ein Thema von BlueStarHH · begonnen am 21. Jul 2023 · letzter Beitrag vom 25. Jul 2023
Antwort Antwort
Seite 1 von 2  1 2      
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
850 Beiträge
 
Delphi 11 Alexandria
 
#1

Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 10:54
Hallo,

ich nutze die StringList Printer.Printers aus der Unit Vcl.Printers. Delphi füllt diese bei der ersten Nutzung und danach wird sie nicht mehr geändert.

Wenn mein Programm nun ausgeführt wird und der Anwender währenddessen einen neunen Drucker installiert oder einen löscht, passt der Inhalt von Printer.Printers nicht mehr zu den real vorhandenen Druckern. Entweder klappt das Drucken dann gar nicht oder der Ausdruck findet auf dem falschen Drucker statt.

Wie kann ich diese Liste neu einlesen? Und wie kann ich erkennen, ob an den Drucker etwas geändert wurde? Gibt es da ein Event/Message? Im schlimmsten Fall würde ich dem Anwender dann einfach eine Meldung anzeigen, dass er mein Programm neu starten soll. Da bei nächsten Start die Drucker dann neu eingelesen werden. Danke!
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 11:08
Hast du statt der glorifizierten globalen Variable Vcl.Printers.Printer() mal Vcl.Printers.TPrinter.Create() versucht? Da sollte dann die aktuelle Druckerliste drinstehen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 11:20
Eigentlich reagiert Delphi an vielen Stellen auf System-Messages (Broadcasts) und aktualisiert Vieles.
Nur scheinbar hier nicht. Ich finde auch sonst nirgendwo ein efresh in der Printers-Unit, sowie sonst nirgendwo ein Printer.Refresh im Delphi-Code.


Überall im Code findet man Kommentare ala with Printers do // <- this rebuilds the FPrinters list .
An dieser Stelle weitergesucht, kannst du also Printer.FreePrinters; ausführen und beim nächsten Zugriff [s]ist[/] wird diese Liste aktuell.
Bzw. ginge dann auch direkt Printer.Refresh; .

Bei Google suchenwindows message printer changed
Bei Google suchenwindows message printers updated
Lieferte jetzt nichts, aber du kannst ja mal via TApplicationEvents.OnMessage schauen, ob bei dir eine spezifische Message eintrifft, wenn du an den Druckern was änderst.
$2B or not $2B
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
850 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 11:29
Hast du statt der glorifizierten globalen Variable Vcl.Printers.Printer() mal Vcl.Printers.TPrinter.Create() versucht? Da sollte dann die aktuelle Druckerliste drinstehen.
Danke, mit Vcl.Printers.TPrinter.Create() klappt es schon mal immer den aktuellen Stand einzulesen.

Jetzt brauche ich nur noch ein Event/Message, mit dem ich erkennen kann, dass sich bei den Druckern was geändert hat. Ich habe ganz dunkel in Erinnerung, dass es da eine Windows-Message gab. Ich meine das war irgendwas indirektes. Also so eine allgemeine Message wie "Irgendwas an den Systemeinstellungen" wurde geändert. Mehr fällt mir aber nicht ein und ich finde mit Google auch nichts.
  Mit Zitat antworten Zitat
Benutzerbild von ULIK
ULIK

Registriert seit: 25. Sep 2006
Ort: Regensburg
427 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 11:53
Probiers mal mit WM_DEVICECHANGE. Dann über den Devicenamen prüfen, ob die Änderung relevant ist (auch USB beachten!)

Code:
   if DeviceName.StartsWith('\\?\HID#') then
    begin
      // Ein HID-Gerät wurde ein-/ausgehängt, das kann ein Digitizer sein:
      // Flag setzen, sodass wir via Timer die Geräte neu einlesen können.
      _ProcessDeviceChange(paASHIDDeviceChanged);
    end else
    if DeviceName.StartsWith('\\?\USB#') then
    begin
      // Ein USB-Gerät wurde ein-/ausgehängt: Flag setzen, sodass wir OnIdle die Geräte neu einlesen können.
      _ProcessDeviceChange(paASUsbDeviceChanged);
    end
    else if DeviceName.StartsWith('\\?\SWD#PRINTENUM') then
    begin
      // Ein Drucker wurde neu eingerichtet oder gelöscht: Druckerliste aktualisieren.
      _ProcessDeviceChange(paASPrinterDeviceChanged);
    end;
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
850 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 12:13
Probiers mal mit WM_DEVICECHANGE. Dann über den Devicenamen prüfen, ob die Änderung relevant ist (auch USB beachten!)

Code:
   if DeviceName.StartsWith('\\?\HID#') then
    begin
      // Ein HID-Gerät wurde ein-/ausgehängt, das kann ein Digitizer sein:
      // Flag setzen, sodass wir via Timer die Geräte neu einlesen können.
      _ProcessDeviceChange(paASHIDDeviceChanged);
    end else
    if DeviceName.StartsWith('\\?\USB#') then
    begin
      // Ein USB-Gerät wurde ein-/ausgehängt: Flag setzen, sodass wir OnIdle die Geräte neu einlesen können.
      _ProcessDeviceChange(paASUsbDeviceChanged);
    end
    else if DeviceName.StartsWith('\\?\SWD#PRINTENUM') then
    begin
      // Ein Drucker wurde neu eingerichtet oder gelöscht: Druckerliste aktualisieren.
      _ProcessDeviceChange(paASPrinterDeviceChanged);
    end;
Danke! WM_DEVICECHANGE wird ausgelößt. Dabei ist da Message.WParam immer 7 und Message.LParam ist immer 0. Wie komme ich damit auf "DeviceName" für
Code:
DeviceName.StartsWith('\\?\SWD#PRINTENUM')
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 12:39
Wie komme ich damit auf ...
MSDN: MSDN-Library durchsuchenWM_DEVICECHANGE -> 7= DBT_DEVNODES_CHANGED -> lParam= Ein Zeiger auf eine Struktur, die ereignisspezifische Daten enthält -> [MSDN]DBT_DEVNODES_CHANGED[MSDN]

https://learn.microsoft.com/de-de/wi...m-devicechange
https://learn.microsoft.com/de-de/wi...vnodes-changed

vielleicht? PAnsiChar(pDBT_DEVNODES_CHANGED(wParam).lParam)
$2B or not $2B

Geändert von himitsu (21. Jul 2023 um 12:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 21. Jul 2023, 13:13
Wie wäre es mit WM_SETTINGCHANGE? Das Ereignis sollte glaube ich immer gefeuert werden und hier zeig ich wie Du den aktuellen Basis-Druckernamen bekommen könntest:
Delphi-Quellcode:
uses ...Vcl.Printers...

...
    procedure WMSettingChange(var Message: TMessage); message WM_SETTINGCHANGE;
...

implementation

procedure TForm12.WMSettingChange(var Message: TMessage);
begin
  Printer.PrinterIndex := -1;
  Label1.Caption := Printer.Printers[Printer.PrinterIndex];
end;
Hilft das?
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
THY4243

Registriert seit: 15. Dez 2012
Ort: München - Untermenzing
45 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 25. Jul 2023, 09:55
Es gibt dazu den Ansatz, das über einen Thread zu lösen.

Auf einer französichen Delphiseite findet sich dazu ein sehr gutes Beispiel. Unter der Überschrift "Surveillance d'un serveur d'impression" und dem direkten Link:
https://nono40.developpez.com/sources/source0071/ zu finden.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

AW: Änderungen an Druckeren erkennen (neu, gelöscht)

  Alt 25. Jul 2023, 16:10
Wozu ein Thread?
  • das Auslesen geht doch schnell
  • außerdem ist das globale Printer-Objekt nicht threadsave und auch durch die GDI an den Hauptthread gebunden


  • Ja, kann kann diese Message an Application oder einer Form empfangen
    und das Auslesen in einen Thread auslagern (aber nicht mit dem globalen Printer-Objekt)
  • oder man kann sich im Thread ein eigenes unsichtbares TopLevel-Form, bzw. eine MessageOnly-Form erstellen -> CreateWindow,CreateWindowEx
    im Thread dessen Message-Loop behandeln, dort darüber auf diese Message reageren und dann alles im Thread machen
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz