IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Demande de retour d'expérience : TPrinter et Thread


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 680
    Billets dans le blog
    65
    Par défaut Demande de retour d'expérience : TPrinter et Thread
    Bonjour,

    Dans le cadre d'un projet, j'ai mis la partie impression de documents dans un Thread. En retour un utilisateur (l'utilisateur principal) m'a indiqué que les impressions ne se faisait pas (ou du moins se perdaient dans les limbes, ça c'est mon interprétation).
    Du coup, après épluchage du code du thread (ou du moins de la fonction appelée) j'ai vu qu'aucun TPrinter (que j'utilise) n'était créé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    function Imprimer(const Annee: String; const Numero: Integer): Boolean;
    // imprimer un Stream { TODO : Non testée }
    var
      NomFichier: String;
      FromPage, ToPage, Page: Integer;
      FirstPage: Boolean;
      AStream: TMemoryStream;
      Bitmap: TBitmap;
      R: TRectF;
      fpdfrun: TFPdf;
      fpdfViewRun: TFPdfView;
      Printer : TPrinter;
    begin
      Result := False;
     // ... chargement du stream (pdf)
        if AStream.Size > 0 then
        begin
          Printer:=TPrinter.Create;
    
          fpdfrun := TFPdf.Create(nil);
          fpdfViewRun := TFPdfView.Create(nil);
          try
            fpdfrun.FileName := NomFichier;
            fpdfViewRun.Pdf := fpdfrun;
            fpdfViewRun.Active := True;
            FromPage := 1;
            ToPage := fpdfrun.PageCount;
            Printer.Title := NomFichier;
            FirstPage := True;
            Printer.BeginDoc;
            try
              for Page := FromPage to ToPage do
              begin
                if FirstPage then
                  FirstPage := False
                else
                  Printer.NewPage;
                fpdfViewRun.PageNumber := Page;
                Bitmap := fpdfViewRun.RenderPage(0, 0, Printer.PageWidth,
                  Printer.PageHeight, ro0, [rePrinting]);
                try
                  R := TRectF.Create(0, 0, Printer.PageWidth, Printer.PageHeight);
                  Printer.Canvas.DrawBitmap(Bitmap, R, R, 1.0, True);
                finally
                  Bitmap.Free;
                end;
              end;
            finally
              Printer.EndDoc;
            end;
          finally
            fpdfViewRun.Active := False;
            FreeAndNil(fpdfViewRun);
            FreeAndNil(fpdfrun);
            FreeAndNil(Printer);
          end;
          Result := True;
        end;
       //  fin d'impression, mise à jour historique ... 
      finally
        AStream.Free;
      end;
    end;
    à la va vite, j'ai rajouté la création d'un TPrinter (code gras, souligné) mais je m'interroge sur
    a) le bien fondé
    b) l'initialisation du TPrinter
    c) la "sécurité" (thread safe) de TPrinter

    Quelqu'un a t-il déjà fait face à ça ?

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    alors l'objet Printer est créé automatiquement par Delphi, par contre, l'API Win32 n'étant pas ThreadSafe, il faut obligatoirement avoir un objet propre à chaque Thread

    The handle pointed to by phPrinter is not thread safe. If callers need to use it concurrently on multiple threads, they must provide custom synchronization access to the printer handle using the Synchronization Functions. To avoid writing custom code the application can open a printer handle on each thread, as needed.
    https://docs.microsoft.com/en-us/win...cs/openprinter

    maintenant je n'ai jamais testé.

    sinon pour faire des PDF j'utilise SynPDF qui n'utilise pas l'imprimante et propose un objet compatible Canvas ce qui simplifie grandement les choses.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 680
    Billets dans le blog
    65
    Par défaut
    Bonjour Paul,

    Ce n'est pas une création de PDF mais bien l'impression d'un fichier PDF (en fait un fichier PDF dans un stream) et j'utilise PdfView comme composant

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 115
    Par défaut
    Un retour de ce type me serait utile aussi !

    Je dois justement faire un serveur d'impression d'étiquette sur SATO (M84Pro 609 et CL4NX 609) pour le moment, l'infrastructure étant à base de CITRIX, je n'aurais probablement pas de thread mais des processus différents avec un répartiteur qui se chargera d'envoyer sur le bon client les impressions concernées

    Mais au cas où l'équipe projet/dev SAP et l'infra SAP change d'avis, le cas toutes les semaines, j'y serais peut-être confronté pour gérer au départ 10 sites avec 60 imprimantes, à terme 70 sites et 500 imprimantes réparti entre la Chine, l'Inde, l'Italie, l'Allemagne et la France directement depuis un ou plusieurs serveurs.




    Mars 2002, J'ai un souvenir D6 + QuickReport, cela ne fonctionnait pas, des OSError 1400... j'imprimais des étiquettes A6 sur une Zebra, par vague, genre 200 étiquettes d'un coup, disons une à deux fois par heure.
    Au final, j'avais remis ça dans un OnIdle (ou Timer) de la fenêtre principale qui récupérait les données d'une FIFO rempli par un Thread


    Printer est un singleton de la VCL
    Créer le sien, je ne l'ai jamais tenté
    Je suis surpris que tu n'invoque pas ensuite SetPrinter pour sélectionner une imprimante (à -1 à la construction du coup cela recherche l'imprimante par défaut via SetToDefaultPrinter)
    Dans mon cas, je devrais aiguiller l'impression car plusieurs formats d'étiquettes donc plusieurs imprimantes
    Est-ce qu'avoir plusieurs objet Printer permet à un programme de gérer plusieurs imprimantes à la fois (je l'espère), voire plusieurs documents sur la même imprimante à la fois (ça j'ai des doutes)

    Dès que j'ai avancé, je fais un retour
    Je pensais paralléliser les impressions pour gagner du temps pour les opérateurs (même si grâce au spooler Windows, on obtient déjà une parallélisation après le EndDoc)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 680
    Billets dans le blog
    65
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Je suis surpris que tu n'invoques pas ensuite SetPrinter pour sélectionner une imprimante (à -1 à la construction du coup cela recherche l'imprimante par défaut via SetToDefaultPrinter)
    c'est une question que je n'ai pas posé par oubli, je compte effectivement mettre quelque part un choix d'imprimante quoique je ne sache pas encore où et quoi mémoriser (nom ou index, encore un choix cornélien )
    en fait la plupart des envois se font par mail mais quelques "malins empêcheurs de tourner en rond" n'ont pas de mail d'où l'envoi vers l'imprimante.

    Toutes mes recherches tendent à indiquer que c'est thread-safe mais et je ne vois pas trop comment je vais tester ce truc encore (j'ai intérêt à mettre mon imprimante en hors ligne durant ces tests !)

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 115
    Par défaut
    J'utilise XPS ou PDF Printer pour simuler les impressions, avec un popup de sélection de fichier (lui il est dans le driver)
    Cela peut parasiter le mode thread
    Moi, j'irais sur site, pour tester 3 imprimantes à la fois pour les vrais tests (et même, si l'occasion se présente, plutôt 10 imprimantes lors des campagnes de réétiquetage, faut que ça tienne la charge)

    Je te recommande de stocker le nom, l'index pouvant changer selon l'apparition ou disparition d'imprimante

    En CITRIX, je gère le nom de l'imprimante + le nom du poste car parfois, perte d'isolation entre les sessions, un client voit des dizaines d'imprimantes et c'est un risque de ne pas utiliser la bonne.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. Demande de retours d'expérience utilisateurs
    Par vanefre dans le forum GED
    Réponses: 0
    Dernier message: 17/07/2012, 17h17
  2. Problème d'antivirus - demande de retour d'expérience.
    Par Masmeta dans le forum Développement Windows
    Réponses: 2
    Dernier message: 16/07/2012, 17h32
  3. Réponses: 5
    Dernier message: 23/07/2010, 08h55
  4. Demande de retour d'expérience sur IML Studio
    Par xav2229 dans le forum SAS STAT
    Réponses: 11
    Dernier message: 08/02/2010, 16h21
  5. [smDBGrid] demande de retours d'expériences
    Par SergioMaster dans le forum Composants VCL
    Réponses: 7
    Dernier message: 27/06/2008, 11h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo