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 :

Intégrer un objet Ole WIA dans un panel ou une fenêtre


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre actif
    Intégrer un objet Ole WIA dans un panel ou une fenêtre
    Bonjour,

    Dans une application Delphi Rio en VCL 32 bits, j'utilise pour l'impression un appel Ole au WIA de windows.

    Code d'appel :
    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
    procedure ShowPhotoPrintWizard(Files: TStrings);
    var
      I: Integer;
      CommonDialog: OleVariant;
      Vector: OleVariant;
    begin
      if not Assigned(Files) then Exit;
      CommonDialog := CreateOleObject('WIA.CommonDialog');
      Vector := CreateOleObject('WIA.Vector');
      for I := 0 to Files.Count - 1 do
        Vector.Add(Files[i]);
      CommonDialog.ShowPhotoPrintingWizard(Vector);
      Vector := Unassigned;
      CommonDialog := Unassigned;
    end;


    Tout fonctionne parfaitement, la fenêtre de dialogue de l’objet Ole s'ouvre au dessus de la fenêtre de mon application, mais dans certains cas ce dialogue part dessous mon application.
    A ce moment là, l'utilisateur n'a plus la main et ne peut ni lancer ni abandonner l'impression.

    Est-il possible d'afficher cet objet WIA dans un panel ou une fenêtre de mon appli que je puisse le gérer complètement ?

    Merci

  2. #2
    Expert éminent sénior
    Cela ne se produirait pas le plus souvent en DEBUG ?
    Même MessageDlg peut aussi bloquer en se cachant derrière.

    Ayant aussi ce problème avec 'Excel.Application', j'ai bricolé un SetForegroundWindowAsync pour que le Excel passe devant mais dans le cas du ShowPhotoPrintingWizard, est-il facile de savoir le classe ou le titre de la fenêtre ?

    Je ne l'ai pas sous la main mais j'avais aussi bricolé un truc avec un TThread qui surveillait les TMessageForm pour éviter les problèmes de perte de focus, par exemple, lorsque que l'on change d'application (ALT+TAB, Clic Systray ...), si un TMessageForm était visible, j'ajoutais un effet de clignotement pour que l'utilisateur voit le message (l'utilisateur pouvait navigueur entre 3 EXE pour son travail, lié entre eux par des invocations, passez de l'un à l'autre pouvait va savoir pourquoi passer les MessageDlg en arrière)
    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

  3. #3
    Membre actif
    Non cela ne semble pas se produire plus en debug qu'en fonctionnement normal.
    Lorsque le dialogue WIA est affiché, une manip hors de cette fenêtre semble l'envoyer derrière !
    C'est assez pénible. Il y a aussi les MessageDlg aussi qui ont bien tendance à passer derrière lorsque l'on navigue entre plusieurs applis effectivement.
    Pour eux j'ai résolu la question en faisant de l'affichage sur un Panel directement dans mon appli.

  4. #4
    Rédacteur/Modérateur

    Tu peux gérer le Z-Order; demander à la fenêtre de toujours se placer derrière celle d'impression.
    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
    type
      TForm1 = class(TForm)
      private
        procedure WMWindowPosChanging(var Message :TWmWindowPosChanging); message WM_WINDOWPOSCHANGING;
      end;
     
    procedure TForm1.WMWindowPosChanging(var Message: TWmWindowPosChanging);
    var
      Wnd :hWnd;
    begin
      Wnd := FindWindow('NativeHWNDHost', 'Imprimer les images');
     
      if Wnd <> 0 then
        Message.WindowPos.hwndInsertAfter := Wnd;
    end;

  5. #5
    Membre actif
    Merci Andnotor, c'est exactement ce que je cherchais.
    Cela fonctionne parfaitement pour les premiers tests.
    Merci

  6. #6
    Expert éminent sénior
    Citation Envoyé par Andnotor Voir le message
    Wnd := FindWindow('NativeHWNDHost', 'Imprimer les images');
    Citation Envoyé par ShaiLeTroll Voir le message
    est-il facile de savoir le classe ou le titre de la fenêtre ?
    Voilà, j'ai ma réponse
    et je note ce WM_WINDOWPOSCHANGING, si un jour j'ai des IHM à faire (rarissime), cela doit être plus pratique que ce que j'avais mis en place lors de la maintenance d'un projet existant depuis D7
    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

  7. #7
    Membre actif
    Effectivement c'est facile de trouver la classe et le nom de la fenêtre quand Andnotor le donne !!
    Par contre j'ai déjà vu des applis qui donnent ces infos, mais je ne les ai plus en tête. Si quelqu'un peut me rafraîchir la mémoire : Merci

  8. #8
    Expert éminent sénior
    WindowSpy, en Delphi

    KillApplic (utilise EnumWindows), une adaptation d'un projet Phidels, je m'en suis servi récemment pour le forum
    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

  9. #9
    Rédacteur/Modérateur

    Ici en l’occurrence on a hwndInsertAfter qui va fatalement, une fois, représenter la fenêtre d'impression. GetClassName/GetWindowText nous permettent d'en extraire les informations.

###raw>template_hook.ano_emploi###