DLLFORM AVEC STYLE XP NO SCRATCH

cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 - 4 oct. 2005 à 13:00
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 - 14 mars 2008 à 18:01
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/34064-dllform-avec-style-xp-no-scratch

Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
14 mars 2008 à 18:01
Ben moi je n'ai pas XPMan, j'ai Delphi3, et j'utilise une ressource {$R WindowsXP.res} et ca marche très bien le style XP :p (enfin ca ne dépend pas des propriétés de l'écran...).
Juste pour dire que XPMan n'etait pas nécessaire pour avoir des zolis boutons ;)

Cordialement, Bacterius !
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
6 oct. 2006 à 15:24
C'est que j'ai du mal m'exprimer, comme d'hab. Utiliser une fiche fille MDI depuis un exe dans un autre langage je saurais pas faire. (Mais une fiche tout court, ça ne pose aucun problème).
stmic Messages postés 2 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 5 mars 2015
5 oct. 2006 à 17:32
Bonjour,
Je découvre avec ce source des possibilités que je n'avais pas imaginé. Super.

J'ai cru comprendre, de ce que dit RT15, qu'il est possible d'appeler cette DLL depuis un autre langage et donc de se passer du passage de TApplication. Mais à quel moment doit-on coder la modification du handle dans la DLL, SVP ?
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
19 août 2006 à 14:50
Salut,

Pour commencer, bravo pour ce source. Affecté l'objet Application de l'exe à l'objet Application de la dll, je n'y aurais jamais pensé.

A noter que :
Ce n'est pas nécessaire si la dll ne contient pas des fiches MDI.
Il faut que le langage de l'exe propose une classe TApplication.
L'aide de Delphi ne vat pas si loin (Et donc pas assez loin dans le cas du MDI) : Pour écrire une DLL utilisant des fiches VCL, affectez le handle de la fenêtre principale de l'EXE hôte à la propriété Application->Handle de la DLL. Cela fait de la fiche de la DLL une partie de l'application hôte. N'affectez jamais la propriété Handle dans un EXE.

Malheureusement pour moi, ce source ne comble pas mes attentes.

En effet, la fiche contenue dans la dll de ce source comporte 2 Button et un Memo.
Je n'ai jamais eu de soucis en utilisant ses composants dans une dll appelé depuis un exe sous thème XP.
Par contre, il suffit de rajouter un SpeedButton, ou un RadioGroup, ou un GroupBox, ou un StringGrid... sur la fiche de ce source pour se déguster une exception à la fermeture de l'appli.

Pour finir, quelques suggestions d'amélioration du code :

Ligne 46 :
procedure DLLEntryPoint(dwReason: DWORD); stdcall;

L'aide de Delphi fournit une déclaration à peine différente.
Respecter celle-ci permettrait de se passer de pointeur non typé et des @.
(Il ne faut pas oublier de modifier aussi la déclaration de la procédure dans le projet de l'exe).

La structure de sauvegarde donnerait ça :

Type
TDllAppInfo = record
OldApp : TApplication;
OldScr : TScreen;
OldProc : procedure(dwReason: Integer);
end;

Ligne 59 :
DLLProc := DLLApp.OldProc;

On remet l'ancienne procédure en place... Mais n'est ce pas un peu tard ?
Ce code est en effet executé quand la raison est DLL_PROCESS_DETACH, il y a donc peu de chance que l'ancienne procédure soit appelée par la suite...
(A noter que curieusement, DLLApp.OldProc pointe sur rien. DllProc contient en effet nil avant que la dll ne l'échange avec l'adresse de DLLEntryPoint.)

Ligne 60 et 61 :
Application := DllApp.OldApp;
Screen := DllApp.OldScr;

DllApp.OldApp et DllApp.OldScr n'ont jamais été affectés.
Autrement dit on fait pointer les deux objets sur n'importe quoi...
Il se trouve que le record en question contient des zéros, et que ce code revient donc à :
Application := nil;
Screen := nil;

Les affectations :
DllApp.OldApp:= Application;
DllApp.OldScr:= Screen;

ont très certainement été oubliées dans le code d'initialisation.


Ce qui me chagrine dans tout ça, c'est que les points d'entrée semble appelés... des fois.
Le sdk win32 semble pourtant préciser que le système appelle lui même cette routine.

Pour ne pas s'embêter avec ça, on peut passer par des sections d'initalisation et finalisation.

Voilou donc ma petite customisation du code :

==============================================================================
library MyDLL;

uses
SysUtils,
Classes,
Forms,
MyDLLFormWnd in 'Forms\MyDLLFormWnd.pas' {FrmMain};

{$R *.res}

procedure CreateAppMDI(App: TApplication); stdcall;
begin
Application:= App;
if FrmMain = nil then
begin
FrmMain:= TFrmMain.Create(App);
FrmMain.Show;
end;
end;

exports
CreateAppMDI;

begin

end.
==============================================================================
program DLLDemo;

uses
Forms,
uDLLDemo in 'Forms\uDLLDemo.pas' {FrmMainDemo};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TFrmMainDemo, FrmMainDemo);
Application.Run;
end.
==============================================================================
unit uDLLDemo;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, XPMan, Menus;

type
TFrmMainDemo = class(TForm)
MainMenu1: TMainMenu;
MnuPlugin: TMenuItem;
MnuDllTest: TMenuItem;
procedure MnuDllTestClick(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

var
FrmMainDemo: TFrmMainDemo;

procedure CreateAppMDI(App: TApplication); stdcall; external 'MyDLL.dll';

implementation

{$R *.dfm}

procedure TFrmMainDemo.MnuDllTestClick(Sender: TObject);
begin
CreateAppMDI(Application);
end;

end.
==============================================================================
unit MyDLLFormWnd;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TFrmMain = class(TForm)
Btn1: TButton;
Btn2: TButton;
Memo1: TMemo;
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

var
FrmMain: TFrmMain;
OldApplication: TApplication;

implementation

{$R *.dfm}

initialization
FrmMain:= nil;
OldApplication:= Application;
finalization
Application:= OldApplication;
end.
==============================================================================
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
12 août 2006 à 17:37
Grace à Cirec, je viens de découvrir la solution de Shining.
Alors là, je dis bravo.
J'ai longtemps cherché pourquoi on avait une AV en quittant l'application et je n'avais pas trouvé de réponse sur le web anglophone.
Et dire que ce je suis passé à côté de cette perle à l'époque.
Mais que faisais-je donc le 2 octobre 2005 ? mdr
Là, mon cher Shining, ça mérite un trophée.
cs_shining Messages postés 304 Date d'inscription lundi 30 décembre 2002 Statut Membre Dernière intervention 10 mars 2012
5 oct. 2005 à 00:33
"Ta description ne correspond pas à ta source. Les forms contenues dans les Dlls ne seront qu' avec le style XP seulement si le programme qui l' appelle est au style XP.
Si tu enlève la déclaration de l' unité XPMan de l' unité uDLLDemo, ta form dans la dll ne sera plus avec le style XP."

oui effectivement si tu retires XPMan, tu n'auras plus le style XP, ça me semble logique, car sinon j'aurai mis 'Skinner XP', enfin bref dans l'explication finale, il est dit qu'il faut windows XP et biensûr avec le theme XP activé, sinon effectivement il manque deux repertoire dans le zip(j'aime pas winzip, vive winrar), il manque le repertoire DCU et EXE qui doivent être placer dans le même repertoire que DLLDemo.dpr, et il ne faut surtout pas effacer les fichiers de configurations tels que *.dof, *.cfg, car ils contiennent la stratégie de compilation. fichier temporaires->DCU\, DLL + EXE->EXE\.
voilà si ce code sert au moins à une personne bah tant mieux :)
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
4 oct. 2005 à 13:00
Ta description ne correspond pas à ta source. Les forms contenues dans les Dlls ne seront qu' avec le style XP seulement si le programme qui l' appelle est au style XP.
Si tu enlève la déclaration de l' unité XPMan de l' unité uDLLDemo, ta form dans la dll ne sera plus avec le style XP.

Par contre, et c' est ce qui m' interessait dans cette source, c' est la gestion de MDI forms depuis une dll.

Pour ceux qui ne savent pas quoi faire lors des messages d' erreur de compilation, cela vient de la ouput directory et de la unit ouput directory qui sont définis dans les options du projet (onglet Directories/Conditionals).
Rejoignez-nous