Changer l'application du premier plan

Résolu
cs_LaNono Messages postés 37 Date d'inscription mardi 30 septembre 2008 Statut Membre Dernière intervention 26 avril 2011 - 18 nov. 2008 à 18:00
cs_LaNono Messages postés 37 Date d'inscription mardi 30 septembre 2008 Statut Membre Dernière intervention 26 avril 2011 - 19 nov. 2008 à 10:42
Bonjour tout le monde,

Voilà, j'ai une application en VB.NET 2005 qui doit me permettre de réaliser une capture d'écran d'une application de dessin technique. J'ai réussi à réaliser la capture d'écran. Ce qu'il me reste à faire c'est faire passer l'application de dessin au premier plan sur l'écran afin qu'elle figure sur la capture d'écran.
Est-ce que quelqu'un sait si il est possible depuis mon application de faire passer une autre application au premier plan, pui de remettre mon application au premier plan une fois la capture d'écran effectuée?

J'espère que vous comprendrez ma question
Merci d'avance

Nono

5 réponses

PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
18 nov. 2008 à 19:05
salut,

mets ton appli derrière avec me.bringtofront (ou ce qui ressemble), puis redonne le focus par me.
sendtoback

si tu veux vraiment jouer sur le focus (ou zorder plutôt) de l'autre application, récupère son handle avec FINDWINDOW et passe-la devant avec SETFOREGROUNDWINDOW avec le handle obtenu. un peu plus long à mettre en oeuvre et pas forcément utile, voir première méthode
++

<hr size="2" width="100%" />
Prenez un instant pour répondre à [sujet-SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp 
3
cs_LaNono Messages postés 37 Date d'inscription mardi 30 septembre 2008 Statut Membre Dernière intervention 26 avril 2011 1
19 nov. 2008 à 08:55
Hello PCPT, tout d'abord merci de ta réponse.

je suis en train d'essayé la deuxième solution (avec FindWindow et SetForegroundWindow) qui est plus adaptée à ma situation et j'ai quelques question.

j'utilise les déclarations suivantes :

Declare Auto Function FindWindow Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr

Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

et dans mon code je les utilise de la manière suivante (J'ai commencé par faire des tests sur la calculatrice):

GOelanHWND = FindWindow(vbNullString, "Calculatrice")
System.Windows.Forms.Application.DoEvents()
SetForegroundWindow(GOelanHWND)
System.Windows.Forms.Application.DoEvents()

La calculatrice vient au premier plan mais le message d'erreur suivant apparaît sur la ligne dans Visual Studio:

PInvokeStackImbalance a été détecté
Message: Un appel à la fonction PInvoke 'DocumentationGOelan!DocumentationGOelan.DGSnapshotGOelanManager::SetForegroundWindow' a déséquilibré la pile. Cela peut se produire, car la signature PInvoke managée ne correspond pas à la signature cible non managée. Vérifiez que la convention d'appel et les paramètres de la signature PInvoke correspondent à la signature non managée cible.

Connais-tu ce message d'erreur et sais-tu quelle est mon erreur? j'ai regardé à plusieurs endroit la déclaration de la fonction SetForegroundWindow et j'ai trouvé partout le même prototype de fonction. je ne pense pas que le problème vienne de là.

J'ai une deuxième question concernant les paramètres de la fonction FindWindow. Quel nom doit-on utiliser? celui qui se trouve vraiment dans l'en-tête de la fenêtre que l'on veut traiter, ou le nom de l'application?

Merci d'avance
0
cs_LaNono Messages postés 37 Date d'inscription mardi 30 septembre 2008 Statut Membre Dernière intervention 26 avril 2011 1
19 nov. 2008 à 09:16
Rebonjour,

J'ai trouvé le pourquoi de mon message d'erreur. il vient de l'utilisation du type Long dans la déclaration des variables. j'ai donc remplacer le type du paramètre par un IntPtr et le type de la fonction par un Int32. du coup, plus de message d'erreur, mais malheureusement plus de calculatrice au premier plan non plus.

En gros ça ne vas pas mieux ;-)
quelqu'un a une idée du problème?
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
19 nov. 2008 à 09:45
salut,

ton code est intéressant, je m'explique :
d'abord, je ne fais pas de dotnet, donc je fais divers essais

Declare Auto Function FindWindow...
apparemment (msdn) AUTO sert pour l'ANSI au final, je ne connaissais pas :)

Le modificateur Auto spécifie que Visual Basic doit
marshaler les chaînes d'après les règles de .NET Framework et qu'il doit
déterminer le jeu de caractères de base de la plateforme d'exécution et
éventuellement modifier le nom de procédure externe si la recherche initiale
échoue

quand je teste ton code tel quel, sous VSTS2008 FW3.5, je n'ai pas d'erreur....
tu as peut-être une référence incorrecte.
celà dit ton code ne me semble pas bon pour autant....

ta 2e déclaration n'est pas bonne
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As <strike>Long</strike>IntPtr) As <strike>Long</strike>Integer

ensuite tu utilises VBNULLSTRING en argument.
si je remplace par STRING.EMPTY, le handle n'est pas trouvé...

commence par décocher la référence microsoft.visualbasic, quitte à l'appeler explicitement "le plus rarement possible" si nécessaire

reste à déclarer les API à la dotnet...

çà donne ceci :

        <System.Runtime.InteropServices.DllImportAttribute("user32.dll", SetLastError:= True)> Shared Function SetForegroundWindow(ByVal hwnd As IntPtr) As Integer
    End Function
     <System.Runtime.InteropServices.DllImportAttribute("user32.dll", SetLastError:=True)>  Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function
    Function GetHandleFromCaption(ByVal sCaption As String) As IntPtr
        Return FindWindow(Microsoft.VisualBasic.vbNullString, sCaption)
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim GOelanHWND As IntPtr  = GetHandleFromCaption("Calculatrice")
        If GOelanHWND = 0 Then
            MessageBox.Show("Calculatrice pas trouvée")
        Else
            SetForegroundWindow(GOelanHWND)
        End If
    End Sub

<!-- Coloration syntaxique vb/vba/vb.net : http://charles.racaud.free.fr/code-syntaxing/ -->Coloration syntaxique vb/vba/vb.net

çà me semble correct comme çà..., mais un dotnetien serait plus à même de répondre ;)

quant à FINDWINDOW c'est le caption de la fenêtre oui
++
<hr size ="2" width="100%" />Prenez un instant pour répondre à [sujet-SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_LaNono Messages postés 37 Date d'inscription mardi 30 septembre 2008 Statut Membre Dernière intervention 26 avril 2011 1
19 nov. 2008 à 10:42
Re,

merci de ta réponse, en fait je viens de trouver une solution qui fonctionne et qui est un peu différente de la tienne.


avec les déclarations des API :

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Int32

Private Declare Function SetFocus Lib "user32" (ByVal hwnd As IntPtr) As Int32

Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As IntPtr, ByVal nCmdShow As Int32) As Int32


J'utilise la méthode suivante :

SetForegroundWindow(GOelanHWND)
SetFocus(GOelanHWND)
ShowWindow(GOelanHWND, SW_MAXIMIZE)
System.Windows.Forms.Application.DoEvents()

'ICI, je fais ma capture d'écran


'Et je remet mon application au premier plan
SetForegroundWindow(My.Forms.MyForm.Handle)
My.Forms.MyForm.Show()


Merci encore pour ton aide
Nono
0
Rejoignez-nous