begin process at 2012 02 12 19:00:35
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C

 > 

Windows

 > 

Multimédia

 > 

Encapsuler une fenêtre windows


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Encapsuler une fenêtre windows

lundi 1 décembre 2008 à 11:50:59 | Encapsuler une fenêtre windows

jdex

Bonjour à tous! Je souhaiterais comme le titre l'indique, encapsuler une fenêtre windows dans mon interface GTK+. Je voulais savoir si cela était possible ? En utilisant par exemple , SetParent() ou d'autres fonctions de l'API Win32. Je suis débutant en la matière... Merci d'avance pour vos réponse.
lundi 1 décembre 2008 à 12:44:55 | Re : Encapsuler une fenêtre windows

rt15

Membre Club Administrateur CodeS-SourceS
Salut,

Tu peux spécifier la parent dans CreateWindow, pas besoin de SetParent.

Quant à savoir si cela fonctionnera dans du GTK+, c'est une autre histoire...
lundi 1 décembre 2008 à 12:45:46 | Re : Encapsuler une fenêtre windows

rt15

Membre Club Administrateur CodeS-SourceS
Ah pardon, c'est peut être pas toi qui l'a crée la fenêtre.
lundi 1 décembre 2008 à 14:12:45 | Re : Encapsuler une fenêtre windows

jdex

Quelle réactivité !   Alors en fait, je lance un programme à partir de mon interface, par un CreateProcess(). Celui ci m'affiche une fenêtre une fenêtre toute conne avec simplement une image dedans. J'aimerais la coller dans un GtkScrolledWindow.

lundi 1 décembre 2008 à 20:46:09 | Re : Encapsuler une fenêtre windows

rt15

Membre Club Administrateur CodeS-SourceS
Quelques éssais sur le sujet. Après l'exécutable encapsulé est plus ou moins consentant... Ici je tente d'encapsuler la calculatrice. Elle a la facheuse tendance à s'afficher même démarrée en SW_HIDE. Le premier refresh n'est aussi pas très propre... Sortir la fenêtre de l'écran pour la forcer à se redessiner. Notepad et mspaint donne de bons résultats.

Attention : risque de boucle infini lors de recherche de la fenêtre de l'application lancée. Déjà, ajouter un test WaitForSingleObject (De 0) sur le processus peut bien limiter les risques (Sortie de boucle si le processus crève).

Application complète, unicode ou non, compilation testée sous VC6 et gcc (Code::Blocks).

#define UNICODE

/*
Pour compiler sous gcc en release, ajouter :
-nostartfiles -nodefaultlibs -nostdlib
dans les options du lieur.
*/

/* Suppression de la CRT sous VC */
#ifdef NDEBUG
#pragma comment(linker, "/NODEFAULTLIB")
#endif

/* Gestion de la compilation en unicode */
#ifdef UNICODE

#define _T(x) L ## x
typedef unsigned short TCHAR;

#else

#define _T(x) x
typedef char TCHAR;

#endif

#include "windows.h"

HINSTANCE _hThisInstance;                  /* Handle du module                */
HWND _hWnd;                                /* Handle de la fenêtre            */
HWND _hCalcHwnd;                           /* Handle de la fenêtre de calc    */
DWORD _nCalcPid;                           /* PID de la calculatrice          */
TCHAR* _lpAppName = _T("Embedded calc");   /* Nom de l'appli                  */

/**
 * Affiche le message d'erreur associé à la dernière erreur Win32
 *
 * @return Le code de la dernière erreur
 */
DWORD __stdcall ShowLastError()
{
  DWORD nLastError;           /* Code de la dernière erreur                   */
  TCHAR* lpMessageBuffer;     /* Message d'erreur associé                     */

  /* Récupération du numéro de l'erreur */
  nLastError = GetLastError();

  /* Formatage du message */
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                NULL, nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR) &lpMessageBuffer, 0, NULL);

  /* Affichage du message */
  MessageBox(NULL, lpMessageBuffer, _T("ERROR"), MB_OK | MB_ICONERROR);

  return nLastError;
}

/**
 * Traitement des messages
 */
LRESULT __stdcall WindowProcedure(HWND hWnd, UINT nMessage,
                                  WPARAM wParam, LPARAM lParam)
{
  switch (nMessage)
  {
    case WM_DESTROY:
      /* On signale que le thread va s'arrêter */
      PostQuitMessage(0);
      break;
    default:
      /* Application du traitement par défaut */
      return DefWindowProc(hWnd, nMessage, wParam, lParam);
  }
  return 0;
}

/**
 * Initialise la fenêtre principale de l'appli
 */
void __stdcall InitWindow()
{
  WNDCLASSEX wincl;       /* Classe de la fenêtre utilisée                    */

  /* Création de la classe de fenêtre */
  wincl.cbSize = sizeof(WNDCLASSEX);
  wincl.style = 0;
  wincl.lpfnWndProc = WindowProcedure;
  wincl.cbClsExtra = 0;
  wincl.cbWndExtra = 0;
  wincl.hInstance = _hThisInstance;
  wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
  wincl.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  wincl.lpszMenuName = NULL;
  wincl.lpszClassName = _lpAppName;
  wincl.hIconSm = NULL;

  /* Enregistrement de la classe */
  if (RegisterClassEx(&wincl) == 0)
    ExitProcess(ShowLastError());

  /* Création de la fenêtre */
  _hWnd = CreateWindowEx(0, _lpAppName, _lpAppName,
                         WS_OVERLAPPED | WS_SYSMENU |
                         WS_MINIMIZEBOX | WS_VISIBLE,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         600, 400,
                         HWND_DESKTOP, NULL, _hThisInstance, NULL);
  if (_hWnd == 0)
    ExitProcess(ShowLastError());
}


/**
 * Callback d'énumération des fenêtre pour trouver celle de la calculatrice
 */
BOOL __stdcall RetrieveCalcWindow(HWND hwnd, LPARAM lParam)
{
  DWORD nPid;   /* Récupération du PID associé à la fenêtre                   */
  BOOL bFound;  /* Fenêtre trouvée ?                                          */

  GetWindowThreadProcessId(hwnd, &nPid);
  if (nPid == _nCalcPid)
  {
    _hCalcHwnd = hwnd;
    bFound = TRUE;
  }
  else
    bFound = FALSE;

  /* On arrête l'énumération si on a trouvé */
  return ! bFound;
}

/**
 * Met une calculatrice dans la fenêtre
 */
void __stdcall EmbedCalc()
{
  STARTUPINFO startupInfo;                /* Configuration du démarrage       */
  PROCESS_INFORMATION processInfo;        /* Informations sur le processus    */
  char* lpInfos;                          /* Nettoyage de startupInfo         */
  TCHAR lpCommandLine[20];                /* Pour l'unicode                   */
  DWORD nI;

  /* Nettoyage de startupInfo */
  lpInfos = (char*)&startupInfo;
  for (nI = 0; nI < sizeof(STARTUPINFO); nI++)
  {
    *lpInfos = 0;
    lpInfos++;
  }

  /* Initialisation de startupInfo */
  startupInfo.cb = sizeof(STARTUPINFO);
  startupInfo.dwFlags = STARTF_USESHOWWINDOW;
  startupInfo.wShowWindow = SW_HIDE;

  /* La ligne de commande doit être modifiable en unicode */
  lstrcpy(lpCommandLine, _T("calc"));

  /* Lancement de la calculatrice */
  if (CreateProcess(NULL, lpCommandLine, NULL, NULL,
                    FALSE, CREATE_DEFAULT_ERROR_MODE,
                    NULL, NULL, &startupInfo, &processInfo) == 0)
    ExitProcess(ShowLastError());

  Sleep(2000);

  /* Fermeture des handles inutiles */
  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);

  _hCalcHwnd = 0;
  _nCalcPid = processInfo.dwProcessId;

  /* Récupération d'un handle sur la fenêtre de la calculatrice */
  while (_hCalcHwnd == 0)
  {
    EnumWindows(RetrieveCalcWindow, 0);
    Sleep(1);
  }

  /* Affectation du style de la calculatrice */
  SetWindowLong(_hCalcHwnd, GWL_STYLE, WS_CHILD);

  /* Mise en place de la calculatrice dans notre fenêtre */
  SetParent(_hCalcHwnd, _hWnd);

  /* On réaffiche dans notre fenêtre */
  SetWindowPos(_hCalcHwnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
  ShowWindow(_hCalcHwnd, SW_SHOW);

  RedrawWindow(_hWnd, NULL, NULL, RDW_INVALIDATE);
}

/**
 * Point d'entrée du programme
 *
 * @return Code d'erreur du processus
 */
#ifdef NDEBUG
int __cdecl WinMainCRTStartup()
#else
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPSTR lpCmdLine, int nShowCmd)
#endif
{
  MSG messages;           /* Réception des messages envoyés à l'application   */

  /* Récupération du handle du module */
  _hThisInstance = GetModuleHandle(NULL);

  InitWindow();

  EmbedCalc();

  /* Boucle de traitement des messages */
  while (GetMessage(&messages, NULL, 0, 0))
  {
    /* Traduit certains messages */
    TranslateMessage(&messages);

    /* Distribution des messages aux fenêtres */
    DispatchMessage(&messages);
  }

  /* Code d'erreur en sortie */
  return messages.wParam;
}

lundi 1 décembre 2008 à 20:51:14 | Re : Encapsuler une fenêtre windows

rt15

Membre Club Administrateur CodeS-SourceS
J'y pense... Si c'est juste pour une image, tu peux peut être faire une impression écran de la fenêtre. BitBlt ne fonctionne cependant que si la fenêtre est visible... Sinon, tu peux essayer WM_PRINT et WM_PRINTCLIENT, mais rien ne dit que l'application que tu lances ne les supporte...

Ah oui au fait... Presque une heure avant le premier message, c'est plutôt "lent" pour CS.
mardi 2 décembre 2008 à 14:15:26 | Re : Encapsuler une fenêtre windows

jdex

Merci bien pour cette réponse complète Je vais analyser le code et te poser une question si il y a des point d'ombre ^^. Sinon je trouve que c'est plus rapide que le forum de Développez!
mardi 2 décembre 2008 à 16:05:28 | Re : Encapsuler une fenêtre windows

jdex

Alors j'ai testé ton appli qui a l'air de fonctionner, mais il y a un hic avec l'application que je dois lancer. En effet, la fenêtre de mon image s'encastre dans la windows que tu as crée (d'ailleur il manque une partie de la fenêtre), mais impossible d' interagir avec cette fenêtre. Dans un contexte normale, je dois pouvoir sélectionner des zones de l'image à l'aide de la souris, ou encore passer à l'image suivante en appuyant sur Espace, ou Echap pour quitter ce programme. Or aucune de ces fonctionalités ne semble marcher, ce qui est plutôt étrange vu que la calculatrice , elle semble fonctionner.
mardi 2 décembre 2008 à 16:44:16 | Re : Encapsuler une fenêtre windows

rt15

Membre Club Administrateur CodeS-SourceS
"(d'ailleur il manque une partie de la fenêtre)"
Pour ça tu peux ajuster 600 et 400 dans CreateWindow.

Ou utiliser GetClientRect sur la fenêtre encapsulée, puis AdjustWindowRect pour savoir quelle taille donner à ta fenêtre encapsuleuse et finalement SetWindowPos pour adapter la receveuse à la reçue.

Concernant le fait que l'application est gelée... Je n'ai pas la moindre idée de ce qui se passe et de ce qu'il faudrait faire pour contourner ce problème. Peut être que les messages ne parviennent plus à la fenêtre encapsulée. Ou peut être que l'application test si elle est au premier plan, style un appel à GetForeGroundWindow et une comparaison avec le handle de sa fenêtre.

Si tu as Visual Studio, tu as aussi spy++, qui permet d'espionner les messages et de parcourir l'arborescence de fenêtre d'une application. Cela peut éventuellement t'aider à trouver un indice sur ce qu'il se passe.
mercredi 3 décembre 2008 à 10:34:58 | Re : Encapsuler une fenêtre windows

rt15

Membre Club Administrateur CodeS-SourceS
Le Sleep(2000) de mon code ne sert à rien si ce n'est à le rendre plus lent.

Le processus calc.exe reste actif après l'arrêt de mon programme. WM_CLOSE sur la fenêtre de la calculatrice semble insuffisant... Reste la solution malheureusement un peu violente du TerminateProcess.

1 2

Cette discussion est classée dans : windows, fenêtre, encapsuler


Répondre à ce message

Sujets en rapport avec ce message

Créer un lien sous fenêtre windows [ par JMGR ] Comment peut - on créer un lien vers un site sous une fenêtre Windows ?(avec les MFC par ex.)a+ Capture d'événement fenêtre sous windows [ par annplop ] Bonjour,le réalise une application pilotant une autre application cette dernière envoie des fenêtres que je souhaiterais capturer, ensuite je souhaite Maximiser une fenêtre sans windows. [ par AlexMAN ] Re all, En ce moment, j'ai pas mal de pb comme vous avez pu le remaquer sur le forum, donc voilà, encore une question : Comment puis je faire pour max Fenêtre OpenGL sous Windows et maillage en cpp [ par keziah23li98 ] Salut,Cela fait quelques temps qu'avec un collègue nous avons mis au point des algorithmes d'optimisation surfacique de maillage 3D. Seulement l'utili Comment créer une fenêtre Windows [ par lebarn ] Bonmatin, bonaprèsmidi, bonsoir, bonnuit, bonmidi, etc ...Comment peut-on créer un fenêtre Windows ? Car j'ai de nombreux problème et je ne comprends Recopier une zone mémoire dans une fenêtre windows [ par brosse_adan ] Bonjour à tous!mon sujet était peut-être pas super bien choisi, mais bon, j'avais pas mieux... et en plus, mon pb est compliqué à exposer!! :)voilà, j activation fenêtre après lancement automatique sous windows 2000 [ par polkas ] Bonjour,Je développe un Ecran de Veille demandant un Password qui peut être activer par l ' utilisateur ou lancer automatiquement sous Windows 2000Pro Menu dans une fenêtre windows [ par quentin2111 ] bonsoir à tous,je débute en c++ et j'ai découvert il y a un bout de temps les fameux tutoriaux d'errikke, qui sont très bien ! j'ai néanmoins un petit Fenêtre d'application windows [ par Degue39 ] SALUT TT LE MONDEJe voudrai faire, dans Dev C++, dans une fenêtre windows : un formulaire Mai je n'arrive pas à paramètrer le remplissage de la fenêtr Windows management [ par moreau_l ] Bonjour à tous, J'ai trois questions à poser concernant Windows et sa gestion : -  Comment peut-on retirer la barre bleu (celle qui contient la croi


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,264 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales