Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Änderungen an Druckeren erkennen (neu, gelöscht) (https://www.delphipraxis.net/213386-aenderungen-druckeren-erkennen-neu-geloescht.html)

BlueStarHH 21. Jul 2023 09:54

Änderungen an Druckeren erkennen (neu, gelöscht)
 
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!

Der schöne Günther 21. Jul 2023 10:08

AW: Änderungen an Druckeren erkennen (neu, gelöscht)
 
Hast du statt der glorifizierten globalen Variable
Delphi-Quellcode:
Vcl.Printers.Printer()
mal
Delphi-Quellcode:
Vcl.Printers.TPrinter.Create()
versucht? Da sollte dann die aktuelle Druckerliste drinstehen.

himitsu 21. Jul 2023 10:20

AW: Änderungen an Druckeren erkennen (neu, gelöscht)
 
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
Delphi-Quellcode:
with Printers do  // <- this rebuilds the FPrinters list
.
An dieser Stelle weitergesucht, kannst du also
Delphi-Quellcode:
Printer.FreePrinters;
ausführen und beim nächsten Zugriff [s]ist[/] wird diese Liste aktuell.
Bzw. ginge dann auch direkt
Delphi-Quellcode:
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.

BlueStarHH 21. Jul 2023 10:29

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

Zitat von Der schöne Günther (Beitrag 1524776)
Hast du statt der glorifizierten globalen Variable
Delphi-Quellcode:
Vcl.Printers.Printer()
mal
Delphi-Quellcode:
Vcl.Printers.TPrinter.Create()
versucht? Da sollte dann die aktuelle Druckerliste drinstehen.

Danke, mit
Delphi-Quellcode:
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.

ULIK 21. Jul 2023 10:53

AW: Änderungen an Druckeren erkennen (neu, gelöscht)
 
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;

BlueStarHH 21. Jul 2023 11:13

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

Zitat von ULIK (Beitrag 1524781)
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')

himitsu 21. Jul 2023 11:39

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

Zitat von BlueStarHH (Beitrag 1524782)
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)

KodeZwerg 21. Jul 2023 12:13

AW: Änderungen an Druckeren erkennen (neu, gelöscht)
 
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?

THY4243 25. Jul 2023 08:55

AW: Änderungen an Druckeren erkennen (neu, gelöscht)
 
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.

himitsu 25. Jul 2023 15:10

AW: Änderungen an Druckeren erkennen (neu, gelöscht)
 
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


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:53 Uhr.
Seite 1 von 2  1 2      

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