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

API, COM et SDKs Delphi Discussion :

Problème avec API OutText dans une DLL


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut Problème avec API OutText dans une DLL
    Salut à tous,

    Je développe une DLL en Dlephi 6, et je rencontre un problème avec l'API OutText.

    Voici mon code:
    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
     
    var                                         // mes variables globales
            ShowPageHandle: hWnd;           // handle de la page créée
            ShowCanvasHandle: HDC;          // DC du canvas du picture sur la page créé
     
     
    function Test(const funct: integer): integer; stdcall; export;
    var
            FDialog: TForm;
            Image: TImage;
            hnd: hWnd;
    begin
            hnd := FindWindow(nil,'TestWindow');                // je cherche si ma fenêtre existe
            if hnd=0 then begin                                         // si non: cas normal: je la crée
                   FDialog := TForm.Create(nil);                // création de la fenêtre
                   ShowPageHandle := FDialog.Handle;       // mémoriser son handle
                   FDialog.Caption := 'TestWindow';           // installer son titre
                   Image := TImage.Create(FDialog);          // créer une image
                   Image.Parent :=  FDialog;                     // la placer sur ma fenêtre
                   Image.Height := printer.PageHeight/4;    // forcer les dimensions
                   Image.Width := printer.PageWidth/4;
                   ShowCanvasHandle := Image.Canvas.Handle;  // mémoriser de DC de l'image
                            // les fonctions suivantes marchent parfaitement:
                   Image.Canvas.Font.Name := 'Arial';
                   Image.Canvas.Font.Size := 12;
                   Image.Canvas.Pen.Color := clBlack;
                   Image.Canvas.TextOut(0,0,format('Page %d',[PageNumber]));
                   Image.Canvas.Rectangle(100,100,900,900);
                             // les fonctions suivantes NE MARCHENT PAS:
                   SetBkMode(ShowCanvasHandle, TRANSPARENT);
                   TextOut(ShowCanvasHandle,50,50,'Ligne 2',7);
                             // les fonctions suivantes marchent parfaitement:
                   TextOut(image.Canvas.Handle,75,75,'Ligne 3',7);
                   Image.Canvas.TextOut(50,100,'Ligne 4');
                   FDialog.Update;
                   FDialog.Show;
            end else begin
                   showmessage('La fenêtre est déjà ouverte !');
            end;
    end;
    Il s'agit d'un extrait de ma DLL qui contient beaucoupt de fonctions déjà opérationnelles. Mais je n'arrive pas à comprendre pourquoi l'API OutText ne marche pas sur mon DC chargé par Image.Canvas.Handle, alors que la fonction Image.Canvas.OutText marche parfaitement.

    Qu'est-ce que j'ai mal compris ? Merci de votre aide !

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Vérifie si l'objet ne change pas de handle lors de l'application d'une nouvelle font !

  3. #3
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    J'ai ajouté un showmessage comme suit:


    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
     
    var                                         // mes variables globales
            ShowPageHandle: hWnd;           // handle de la page créée
            ShowCanvasHandle: HDC;          // DC du canvas du picture sur la page créé
     
     
    function Test(const funct: integer): integer; stdcall; export;
    var
            FDialog: TForm;
            Image: TImage;
            hnd: hWnd;
    begin
            hnd := FindWindow(nil,'TestWindow');                // je cherche si ma fenêtre existe
            if hnd=0 then begin                                         // si non: cas normal: je la crée
                   FDialog := TForm.Create(nil);                // création de la fenêtre
                   ShowPageHandle := FDialog.Handle;       // mémoriser son handle
                   FDialog.Caption := 'TestWindow';           // installer son titre
                   Image := TImage.Create(FDialog);          // créer une image
                   Image.Parent :=  FDialog;                     // la placer sur ma fenêtre
                   Image.Height := printer.PageHeight/4;    // forcer les dimensions
                   Image.Width := printer.PageWidth/4;
                   ShowCanvasHandle := Image.Canvas.Handle;  // mémoriser de DC de l'image
            showmessage(format('A: handle=%x',[ShowCanvasHandle]));
                            // les fonctions suivantes marchent parfaitement:
                   Image.Canvas.Font.Name := 'Arial';
                   Image.Canvas.Font.Size := 12;
                   Image.Canvas.Pen.Color := clBlack;
                   Image.Canvas.TextOut(0,0,format('Page %d',[PageNumber]));
                   Image.Canvas.Rectangle(100,100,900,900);
                             // les fonctions suivantes NE MARCHENT PAS:
                   ShowCanvasHandle := Image.Canvas.Handle;  // mémoriser de DC de l'image à nouveau
            showmessage(format('B: handle=%x',[ShowCanvasHandle]));
                   SetBkMode(ShowCanvasHandle, TRANSPARENT);
                   TextOut(ShowCanvasHandle,50,50,'Ligne 2',7);
                             // les fonctions suivantes marchent parfaitement:
                   TextOut(image.Canvas.Handle,75,75,'Ligne 3',7);
                   Image.Canvas.TextOut(50,100,'Ligne 4');
                   FDialog.Update;
                   FDialog.Show;
            end else begin
                   showmessage('La fenêtre est déjà ouverte !');
            end;
    end;
    Effectivement, le handle a changé. Je ne comprends pas pourquoi, d'ailleurs. Mais peu importe: maintenant, je le recharge comme dans le code ci-dessus, mais j'ai toujours le même problème. Je charge image.canvas.handle dans la variable ShowCanvasHandle. J'utilise cette variable immédiatement pou rmon API - sans résultat. Le même API juste derrière en passant image.canvas.handle en paramètre fonctionne bien. Est-ce que j'ai un problème de passage de paramètres ? Ma variable ShowCanvasHandle est typé hDC.

    EDIT

    J'ai essayé de multiples façons, mais j'ai toujours le même constat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                   ShowCanvasHandle := Image.Canvas.Handle;  // mémoriser de DC de l'image à nouveau
                   SetBkMode(ShowCanvasHandle, TRANSPARENT);
                   TextOut(ShowCanvasHandle,50,50,'Ligne 2',7);
    ne fonctionne pas, alors que la ligne immédiatement suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
                   TextOut(image.Canvas.Handle,75,75,'Ligne 3',7);
    fonctionnne parfaitement. Où est mon erreur ? je ne comprends pas !

  4. #4
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Je continue à tâtonner, mais le constat reste identique: le device context passé via une variable déclarée pourtant HDC ne marche pas, mais passé par image.canvas.handle ça marche. Est-ce que je n'ai vraiment rien compris ? Juste une précision: j'utilise Delphi 6...

  5. #5
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Est-ce que le problème est trop trivial pour que quelqu'un s'y intéresse, ou est-ce que je suis tombé sur un os ? En tout cas, je suis bloqué, je patauge sans succès. J'apprécierais vraiment qu'une âme charitable m'aide à me sortir de ce mauvais pas !

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Personnellement, je ne mélange que très rarement VCL et API, la VCL est faite de façon à masquer certains éléments, il n'est pas surprenant que le Handle change à chaques modification de l'objet ...

    Dans une DLL de Hook qui affiche dans toutes les fenêtres le nom de leur classe !
    Je n'ai aucun soucis pour un code simple, j'ai jamais essayé de modifier la font !

    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
     
    function HookPaintProc(Code: Integer; RemoveOrNot: WPARAM; MSG: LPARAM): LRESULT; stdcall;
    var
      DC: HDC;
      TextString: ShortString;
    begin
      Result := 0;
     
      with TMsg(Pointer(MSG)^) do
      begin
        if message = WM_PAINT then
        begin
          DC := GetDC(hwnd);
          if DC > 0 then
          begin
            SendMessage(hwnd, message, wParam, lParam); // ne provoque pas de HookPaintProc ... j'aurais cru que ...
            TextString := '';
            GetClassName(hwnd, @TextString[1], 255);
            TextOut(DC, 0, 0, @TextString[1], StrLen(@TextString[1]));
     
            message := WM_NULL;
          end;
        end;
      end;
    end;
     
    function StartPaintHook(): HHOOK; stdcall;
    begin
      Result := SetWindowsHookEx(WH_GETMESSAGE, HookPaintProc, HInstance, 0);
    end;
     
    procedure StopPaintHook(HookPaintHandle: HHook); stdcall;
    begin
      if HookPaintHandle <> 0 then
        UnhookWindowsHookEx(HookPaintHandle);
    end;

  7. #7
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Merci d'avoir répondu - ainsi, je n'ai plus l'impression que personne ne remarque mon message !

    Cependant, mon problème est légèrement différent. J'utilise un TImage comme terrain de jeu pour construire une page contenant à la fois des graphiques et du texte, en gérant tous les attributs (police, couleur, position, ...). Cette construction de fait par des appels successifs à des fonctions dans ma DLL, et le seul moyen de retrouver ma TImage est le handle qui en aucun cas ne doit changer.

    Cela marche bien avec image.canvas.handle et les méthodes du canvas, mais dès que je passe aux API, cela ne marche plus - le handle n'est plus bon. Or, je dois impérativement passer par des API pour la version de production (j'utilise les méthodes du canvas uniquement pour la mise au point). Est-ce que je dois peut-être créer autre chose qu'un TImage pour que cela marche avec les API ? Ou existe-il un moyen quelconque de dériver un handle pour API's à partir d'un canvas.handle ? Je rappelle la séquence qui identifie le problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var                                         // mes variables globales
            ShowCanvasHandle: HDC;          // DC du canvas du picture sur la page créé
            Image: TImage;
    .... 
            ShowCanvasHandle := Image.Canvas.Handle;  // mémoriser de DC de l'image à nouveau
            SetBkMode(ShowCanvasHandle, TRANSPARENT);
            TextOut(ShowCanvasHandle,50,50,'Ligne 2',7);    // ne marche pas
            TextOut(image.Canvas.Handle,75,75,'Ligne 3',7);  // marche

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Pourquoi ne pas changer tes fonctions de DLL pour qu'elles renvoient du texte et c'est l'application qui va dessiner le texte reçue ?

  9. #9
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Parce que justement, un des buts de ma DLL, c'est cela. Je prends en charge toutes les fonctions d'impression d'une application réalisée avec un langage en cours de réalisations n'ayant actuellement pas toutes les fonctionnalités pour gérer les impressions de façon suffisamment puissante. De plus, je veux ajouter une fonction "aperçu" automatique, et c'est à cela que mon TImage était censé servir.

    J'arrive à gérer parfaitement le côté impression, avec choix de l'imprimante et de toutes ses caractéristiques, et d'imprimer textes, graphiques et images avec tous les attributs possibles.

    C'est en ajoutant ma fonction d'aperçu que le problème c'est manifesté. Je voulais créer, de façon interne à ma DLL, un TImage recevant l'image de la page d'impression en cours de construction, et qui serait sauvegardée dans un metafile au moment du changement de page, de sorte à pouvoir la récupérer pour l'aperçu. Toute fonction d'impression serait ainsi doublée par une fonction gérant ce fameux TImage dont je sauvegarde le handle. Les fonctions d'impression étant déclenchées par le programme appelant écrit dans cet autre langage, je n'ai aucune maîtrise sur l'ordre des instructions et leur contenu. Tout doit être fait, fonction par fonction, de façon indépendante, le seul lien étant le TImage (en bien sûr printer.canvas pour l'impression réelle, mais tout ce qui touche les canvas marche bien). Je voulais passer le handle de mon TImage au programme appelant pour qu'il puisses l'utiliser pour l'appel de ma fonction d'aperçu, le cas échéant. Mais bien avant cela, le simple fait d'utiliser un api textout me casse mon handle. Je suis loin de pouvoir utiliser mon aperçu...

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Euh, le plus simple, ça ne serait pas de faire d'intégrer dans la DLL (ActiveX) directement QuickReport ?
    Tu ré-inventes un truc qui existent plein de fois, et l'on sait parfaitement, que l'on passe son temps à réinventer la roue carrée !

    Pourquoi tu n'utilises directement tout le temps "Image.Canvas.Handle" via un accesseur par exemple ...

  11. #11
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Eh bien, la réponse est simple. J'utilise un TImage dans ma DLL provisoirement, pendantla phase de mise au point. A terme, je suis censé recevoir en paramètre à ma fonction, le handle d'un canvas externe déclaré dans le programme appelant et qui n'est pas en Delphi. Comme cela ne marchait pas, j'ai simulé le fonctionnement pas un TImage dans ma DLL, pour constater que cela ne marche pas non plus.

    Le code que j'ai mis en ligne, est la version simplifiée à l'extrême pour mettre mon problème en évidence. Je charge le handle dans une variable. Avec la variable, cela ne marche pas, avec image.canvas.handle directement, cela marche. Or, à terme, je recevrai de handle en paramètre et c'est donc la configuration "variable" qui doit marcher impérativement.

    Je ne veux en aucun cas stocker à terme un TImage dans ma DLL, afin de pouvoir rester réentrant, ce qui est loin d'être le cas maintenant, pendant la phase de mise au point.

    Qu'est-ce qui modifie mon handle ? Le fait de le placer dans une variable doit être permis, après tout. Il y a certainement un truc tout bête que je ne voius pas.

    Je sais qu'il existe un tas de solutions différentes pour ce problème d'aperçu. J'en ai téléchargé et essayé un certain nombre, en freeware ou trialware. Mais dans la quasi-totalité des cas, cela passe par l'ajout d'un composant Delphi, ou d'un contrôle Active-X, et je veux absolument que ma DLL soit auto-suffisante, sans avoir d'autres ressources à distribuer et à installer sur le site de production. D'autres utilisent, comme moi pendant la phase de tests, des objets Delphi variés créés pour l'occasion, et j'en reviens au problème de mon TImage stocké dans la DLL. Je n'ai pas trouvé de solution réelle qui utilise un handle vers un objet existant...

    Ceci explique pourquoi j'essaie de réaliser cela par mes propres moyens, et je suis certain que cela doit être possible.

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 577
    Points : 25 225
    Points
    25 225
    Par défaut
    Tu devrais TOUT faire en API Windows, si c'est une application non Delphi qui fourni le Handle !

    Tu utilise une TImage, tu as créés un problème qui n'existait pas à l'origine, si tu avais créer un Canvas Windows via API dès le début tu n'aurais pas eu ce problème ...

    Sinon, utilise plutôt un TBitmap, qui est un composant non "graphique" (ne s'affiche pas, juste mémoire) au lieu d'un TImage qui est un composant visuel qui doit avoir un Parent pour être stable probablement ...

  13. #13
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Merci beaucoup - je vais explorer ces deux pistes: le canvas Windows créé par API et le TbitMap. Je reviendrai dès que j'aurai des résultats.

    Merci encore !

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    Merci beaucoup - je vais explorer ces deux pistes: le canvas Windows créé par API et le TbitMap. Je reviendrai dès que j'aurai des résultats.

    Merci encore !
    je suis assez surpris par ton problème...je n'ai pas Delphi sous la main pour tester mais je ne comprend pas ton problème...

    affecter le Handle du canvas à une variable ne change pas le handle et il ne devrait pas y avoir de différence entre les deux appels à TextOut...étrange

    maintenant attention, car TImage est une surcouche au TGraphic...a un moment donné il devra créer un TBitmap pour y stocker l'image (TImage.Picture)

  15. #15
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    affecter le Handle du canvas à une variable ne change pas le handle et il ne devrait pas y avoir de différence entre les deux appels à TextOut...étrange
    Cela m'étonne aussi. Cependant, les 4 lignes de code que j'ai publiées ci-dessus sont flagrantes: elles démontrent clairement le problème, à défaut de l'expliquer. Je ne comprends toujours pas.

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    Cela m'étonne aussi. Cependant, les 4 lignes de code que j'ai publiées ci-dessus sont flagrantes: elles démontrent clairement le problème, à défaut de l'expliquer. Je ne comprends toujours pas.
    hihi ben si je sais !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      dc: HDC;
    begin
      dc := Image1.Canvas.Handle;
      TextOut(dc, 10, 20, 'Hello', 5);
      Image1.Repaint;
    end;
    le TextOut se fait bien dans le Bitmap...mais encore faut-il demander à TImage de le redessiner à l'écran

  17. #17
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Ouah, ça, c'est un tuyau ! Je vais essayer cela demain !

    Alors, ce "refresh" se fait automatiquement quand on passe par les méthodes du canvas, mais pas quand on passe par les API ? ca peut être plausible, étant donné que les méthodes du canvas sont censés "wrapper" les API...

    Si cela marche, je vais pouvoir utiliser le handle du canvas que mon application externe me passe en paramètre, à condition de trouver le moyen de provoquer l'équivalent de "image.repaint" par un API sur le handle du canvas !

    Merci pour cette piste !

  18. #18
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 755
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 755
    Points : 13 349
    Points
    13 349
    Par défaut
    J'ai testé ton premier code (modifié pour qu'il compile ) et il fonctionne parfaitement !

    Mais il est intéressant de constater que l'affichage d'une autre fenêtre (ShowMessage ou TForm) modifie bien ce handle

    Ta simulation à l'aide d'un TImage (accès GDI) ne semble pas être la solution. Une gestion en mémoire et un chargement en une fois du TImage serait sans aucun doute meilleur. Un bitmap ou même un TMetaFile puisque c'est ce que tu devras utiliser.

    D'ailleurs, il serait plus logique de travailler sur le MetaFile et de le copier dans le TImage au moment de l'aperçu plutôt que de travailler sur le TImage et ensuite de le sauver dans le MetaFile .

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    Ouah, ça, c'est un tuyau ! Je vais essayer cela demain !

    Alors, ce "refresh" se fait automatiquement quand on passe par les méthodes du canvas, mais pas quand on passe par les API ? ca peut être plausible, étant donné que les méthodes du canvas sont censés "wrapper" les API...

    Si cela marche, je vais pouvoir utiliser le handle du canvas que mon application externe me passe en paramètre, à condition de trouver le moyen de provoquer l'équivalent de "image.repaint" par un API sur le handle du canvas !

    Merci pour cette piste !
    ça ne serait pas logique.

    soit j'invoque ta DLL avec un HDC à l'écran (Form1.Handle) et il n'y a rien à faire...soit j'invoque ta DLL avec un HDC d'imprimante, de bitmap, etc...et il est de MA responsabilité de terminer l'impression/afficher le bitmap, etc...

  20. #20
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 163
    Points
    163
    Billets dans le blog
    1
    Par défaut
    Je clos cette discussion. Je n'ai pas trouvé de solution à ce problème, et j'ai choisi de procéder entièrement différemment, dans l'application. Le handle du canvas ne peut pas être transmis valablement à une DLL et utilisé à cet endroit. Tant pis. En tout cas, merci de votre aide.

Discussions similaires

  1. problème avec l'apostrophe dans une requête
    Par mika0102 dans le forum VBA Access
    Réponses: 7
    Dernier message: 09/03/2019, 16h51
  2. Problème avec un Timage dans une DLL
    Par colorid dans le forum Langage
    Réponses: 6
    Dernier message: 20/05/2011, 12h04
  3. [Delta3d] probléme avec un objet dans une map
    Par astragoth dans le forum Développement 2D, 3D et Jeux
    Réponses: 1
    Dernier message: 27/03/2006, 14h49
  4. Problèmes avec un TWebBrowser dans une DLL
    Par bellamyjc dans le forum Composants VCL
    Réponses: 2
    Dernier message: 12/01/2005, 22h35
  5. Problème avec un LIKE dans une procédure stockée
    Par Oluha dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 22/12/2004, 14h38

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