Comment incorporer un formulaire C ++ non géré dans une application .NET?

J’ai réussi à envelopper ma dll non gérée Borland C ++ et à lancer ses formulaires à partir d’une application C # .NET 4.0. Est-il possible d’intégrer un formulaire à partir de la dll directement dans une application .NET?

Pour clarifier, le formulaire d’origine est déjà utilisé comme contrôle intégré dans un projet Borland C ++. Cela ressemble essentiellement à un contrôle personnalisé, assis sur un panneau dans l’application.

Quand je dis «incorporer», je veux dire placer dans un formulaire de la même manière que vous déposez des boutons, des panneaux, etc. sur un formulaire. Je ne cherche pas seulement à faire un enfant en forme.

Si cela n’est pas possible, la meilleure question serait peut-être de savoir comment incorporer un contrôle personnalisé non configuré dans une application .Net.

Oui, il vous suffit d’utiliser certaines fonctions win32 de bas niveau à partir de user32.dll: SetParent, GetWindowLog, SetWindowLong, MoveWindow. Vous pouvez créer un contrôle de conteneur .NET vide, définir le parent de la fenêtre native sur le contrôle .NET, puis (éventuellement) modifier le style de la fenêtre (c’est-à-dire supprimer les bordures de la fenêtre native) et veiller à le redimensionner avec le Contrôle .NET. Notez que, au niveau géré, le contrôle .NET ignorera qu’il a des enfants.

Dans le contrôle .NET faire quelque chose comme

public void AddNativeChildWindow(IntPtr hWndChild){ //adjust window style of child in case it is a top-level window int iStyle = GetWindowLong(hWndChild, GWL_STYLE); iStyle = iStyle & (int)(~(WS_OVERLAPPEDWINDOW | WS_POPUP)); iStyle = iStyle | WS_CHILD; SetWindowLong(hWndChild, GWL_STYLE, iStyle); //let the .NET control be the parent of the native window SetParent((IntPtr)hWndChild, this.Handle); this._childHandle=hWndChild; // just for fun, send an appropriate message to the .NET control SendMessage(this.Handle, WM_PARENTNOTIFY, (IntPtr)1, (IntPtr)hWndChild); } 

Remplacez ensuite le WndProc du contrôle .NET pour lui permettre de redimensionner le formulaire natif de manière appropriée, par exemple pour remplir la zone client.

  protected override unsafe void WndProc(ref Message m) { switch (m.Msg) { case WM_PARENTNOTIFY: //... maybe change the border styles , etc break; case WM_SIZE: iWid =(int)( (int)m.LParam & 0xFFFF); iHei= (int) (m.LParam) >> 16; if (_childHandle != (IntPtr)0) { MoveWindow(_childHandle, 0, 0, iWid, iHei, true); } break; } } 

Remarque J’ai écrit cette réponse en supposant que l’OP souhaitait intégrer littéralement la DLL native contenant le formulaire dans l’application .NET, et pas seulement modifier son affichage.

Bref non. Vous devez conditionner la DLL C ++ avec votre dissortingbution et importer / envelopper ses fonctions de la même manière que vous le faites maintenant.

Il me semble me rappeler de mes jours Delphi (qui utilise le même back-end de compilateur que Borland C ++) que le concepteur de formulaire génère du code C ++ qui crée une boucle winproc / message, etc. pour chacun des actifs du formulaire via l’API Win32.

Comme tout ce code n’est pas géré, il ne peut pas être compilé dans un assemblage géré. Vous pouvez le porter en C ++ géré, mais cela supprime l’avantage de l’avoir en C ++, et vous êtes bloqué avec un modèle d’exception merdique et toutes les autres parties merveilleuses du C ++. Dans ce cas, vous feriez probablement mieux de le réécrire en C #.

Mais, comme il s’agit d’un logiciel, et que presque tout est possible, voici une solution vraiment boiteuse: incorporer la DLL en tant que ressource binary dans votre application .NET et, au moment de l’exécution, extraire son contenu dans un stream binary, puis chargez-la (je ne sais pas s’il existe un moyen d’exécuter une DLL non gérée à partir de la mémoire, autrement que de sortingcher en la plaçant sur un disque RAM).

La seule chose que cela vous amène est la possibilité de cacher la DLL, mais je ne vois vraiment pas l’intérêt.

Éditer Voulez-vous dire incorporer en tant que montrer en tant que fenêtre enfant, ou incorporer en place le code dans le projet .NET?