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

SWT/JFace Java Discussion :

Afficher une application Windows quelconque dans un Composite SWT


Sujet :

SWT/JFace Java

  1. #1
    Rédacteur
    Avatar de _Mac_
    Profil pro
    Inscrit en
    Août 2005
    Messages
    9 601
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 9 601
    Points : 12 977
    Points
    12 977
    Par défaut Afficher une application Windows quelconque dans un Composite SWT
    Bonjour et bonne année à tous.

    Petite question qui concerne principalement Windows (si ça s'applique à tous les autres OS, c'est mieux ). Je développe une application SWT dans laquelle je voudrais intégrer/afficher une application Windows quelconque (donc a priori non obligatoirement OLE) dont le chemin vers l'exécutable sera indiqué par l'utilisateur.

    J'ai pas mal fouillé le Web mais sans franc succès. J'arrive à lancer mon application Windows depuis SWT mais pas moyen de l'afficher dans mon Composite. J'ai testé d'utiliser OS.CreateProcess et OS.ShellExecuteEx mais dans les deux cas, impossible de récupérer un handle valide pour faire un OS.SetParent valide. Savez-vous comment faire ?

    Merci,

    Du détail, du détail, du détail !!!
    Revenons à la source : lisons la documentation et les fichiers de trace, la réponse à notre problème s'y trouve sans doute

  2. #2
    Rédacteur
    Avatar de _Mac_
    Profil pro
    Inscrit en
    Août 2005
    Messages
    9 601
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 9 601
    Points : 12 977
    Points
    12 977
    Par défaut
    Bon, j'ai ultra galéré pour une vraie bêtise (faut peut-être attendre que l'application ait démarré avant d'essayer de la trouver ) mais j'ai finalement trouvé un truc. Un exemple avec Notepad :
    Code Java : 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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.internal.win32.OS;
    import org.eclipse.swt.internal.win32.PROCESS_INFORMATION;
    import org.eclipse.swt.internal.win32.STARTUPINFO;
    import org.eclipse.swt.internal.win32.TCHAR;
    import org.eclipse.swt.layout.FillLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
     
    public class Embedded {
    	public static void main(String[] args) {
    		Display display = new Display();
    		Shell shell = new Shell(display);
    		shell.setLayout(new FillLayout());
    		shell.setText("Appli SWT");
     
    		final Composite c = new Composite(shell, SWT.EMBEDDED);
     
    		String command = "C:\\WINDOWS\\NOTEPAD.EXE";
    		int /*long*/ hHeap = OS.GetProcessHeap();
    		TCHAR buffer = new TCHAR(0, command, true);
    		int byteCount = buffer.length() * TCHAR.sizeof;
    		int /*long*/ lpCommandLine = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
    		OS.MoveMemory(lpCommandLine, buffer, byteCount);
     
    		// Start process
    		STARTUPINFO lpStartupInfo = new STARTUPINFO();
    		lpStartupInfo.cb = STARTUPINFO.sizeof;
    		PROCESS_INFORMATION lpProcessInformation = new PROCESS_INFORMATION();
    		boolean success = OS.CreateProcess(0, lpCommandLine, 0, 0,
    				true, 0, 0, 0, lpStartupInfo, lpProcessInformation);
    		if (lpCommandLine != 0) OS.HeapFree(hHeap, 0, lpCommandLine);
     
    		int handle = getWindowHandleForProcessId(lpProcessInformation.dwProcessId);//OS.FindWindow(null, new TCHAR(0, "Sans titre - Bloc-notes", true));
    		OS.SetWindowLong(handle, OS.GWL_STYLE, OS.WS_VISIBLE | OS.WS_CLIPCHILDREN | OS.WS_CLIPSIBLINGS);
    		OS.SetParent(handle, c.handle);
    		if (lpProcessInformation.hProcess != 0) OS.CloseHandle(lpProcessInformation.hProcess);
    		if (lpProcessInformation.hThread != 0) OS.CloseHandle(lpProcessInformation.hThread);
     
    		shell.setSize(400, 300);
    		shell.open();
    		while (!shell.isDisposed()) {
    			if (!display.readAndDispatch())
    				display.sleep();
    		}
     
    		// Quit the started process
    		OS.PostMessage(handle, /*WM_QUIT*/0x0012, 0, 0);
    		display.dispose();
    	}
     
     
    	private static int /*long*/ getWindowHandleForProcessId(int/*long*/ pid) {
    		while (true) {
    			int dhandle = OS.FindWindow(null, null);
    			if (dhandle > 0) {
    				while (dhandle > 0) {
    					// Interested only in main top windows
    					if (OS.GetParent(dhandle) == 0) {
    						int[] i = new int[1];
    						OS.GetWindowThreadProcessId(dhandle, i);
    						if (i[0] == pid) {
    							return dhandle;
    						}
    					}
    					dhandle = OS.GetWindow(dhandle, OS.GW_HWNDNEXT);
    				}
    			}
    			try {
    				Thread.sleep(100);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    }

    A optimiser absolument, le while (true) est absolument magnifique.

    Clairement c'est pas beau, SWT n'est pas prévu pour ça, on passe par des API internes, Windows qui plus est, mais ça marche. En espérant que ça puisse servir, car j'ai vraiment eu du mal à trouver.

    Du détail, du détail, du détail !!!
    Revenons à la source : lisons la documentation et les fichiers de trace, la réponse à notre problème s'y trouve sans doute

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Interaction] Comment afficher une application Windows Form dans une WPF ?
    Par Lookoum dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 08/09/2008, 16h50
  2. InvalidOperationException dans une application windows ce
    Par redpopo dans le forum Windows Mobile
    Réponses: 4
    Dernier message: 11/03/2008, 11h58
  3. Réponses: 4
    Dernier message: 03/10/2007, 12h59
  4. Réponses: 1
    Dernier message: 12/09/2007, 10h20
  5. Réponses: 5
    Dernier message: 07/06/2006, 12h11

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