J'ai un problème, et j'ai essayé de chercher une solution mais ne peut pas réaliser ce que je veux. Désolé si c'est en fait simple, s'il vous plaît pointez-moi juste sur la façon correcte de le faire.VCL/LCL - une forme dans la DLL - aucune fenêtre de la barre des tâches d'application, ne peut pas minimiser la forme principale
Alors! J'ai un programme C qui est un chargeur. Il doit appeler ma DLL écrite en Delphi ou Lazarus (Free Pascal). La DLL est en fait une application GUI autonome: lors du débogage, je la compile sous forme d'EXE et fonctionne.
Mon script de compilation le compile en tant que DLL avec un point d'entrée qui doit l'exécuter tout comme il fonctionne de manière autonome. Je m'attends exactement au même comportement, mais je peux faire des choses différentes (en particulier en réglant l'icône de l'application) si nécessaire.
Loader est un programme de style console mais compilé sans console - pas de fenêtres, rien. Il charge juste DLL et appelle une fonction.
Le problème est que quand je construis même projet par défaut vide avec un formulaire comme un EXE - il aura réellement "maître" Application (.Handle <> 0) fenêtre dans la barre des tâches. Je peux donc définir son titre indépendamment de la légende du formulaire principal.
Mais quand la même chose est à l'intérieur d'une DLL - il n'y a pas de fenêtre d'application (.Handle = 0), le titre sera la forme sous-titres, mais le bug le plus important: une forme ne peuvent pas être réduits au minimum!
Dans Delphi 7, il passe en arrière-plan sous d'autres fenêtres (mais la barre des tâches reste!); dans Lazarus il minimise juste à nulle part (caché, aucun moyen de restaurer plus); les deux sans aucune animation de minimisation.
Autre que cela, ma demande semble se comporter normalement. C'est seulement le problème que j'ai.
OK, je sais que les formes dans les bibliothèques est une mauvaise chose à faire, mais:
Je vais bien instancier « autre » VCL complètement indépendant de l'instance de l'hôte, peut-être même dans différents fil.
Il n'y a pas de VCL dans mon application hôte particulière! Pour moi, il doit travailler exactement comme il le fera dans EXE seul ...
Je cherchai quelque chose Application.Handle dans la DLL, et je comprends maintenant que je dois passer une poignée pour accueillir objet Application, donc DLL sera joint avec d'autres formes d'hôtes, mais je n'en ai aucun! Il est même pas Delphi ... (et application: = TApplication.Create (néant), n'a pas aidé non plus)
Tout de suite me aidera probablement:
A) Comment créer instruisent VCL un objet d'application normal pour moi? Comment ça marche quand dans EXE, peut-être que je peux copier ce code? B) Comment créer une fenêtre maître appropriée à partir de C (styles appropriés, etc.) pour passer son handle à la DLL? Aussi, je crois, dans Free Pascal il n'y a pas d'accès direct à la valeur du handle TApplication, donc je ne pourrais probablement pas l'assigner. C) Comment vivre sans une fenêtre de la barre des tâches, mais avoir ma forme (bonne nouvelle: mon programme a seulement une forme!) Pour minimiser correctement (ou juste en quelque sorte ...)?
Je vous maintenant tous voir un peu de code, donc la voici:
// default empty project code, produces valid working EXE:
program Project1;
uses Forms, Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
+
// that's how I tried to put it in a DLL:
library Project1;
uses Forms, Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
function entry(a, b, c, d: Integer): Integer; stdcall;
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
Result := 0;
end;
exports
entry;
begin
end.
I fonction d'entrée spécialement conçue() pour être appelable avec rundll32, juste pour tester.
Aussi, j'ai essayé de mettre le corps directement à "begin end.
" section d'initialisation - même comportement faux.
// To call a DLL, this can be used:
program Project1;
function entry(a, b, c, d: Integer): Integer; stdcall; external 'Project1.dll';
begin
entry(0, 0, 0, 0);
end.
également, CMD-commande "rundll32 project1.dll entry
" fonctionnera instantanément. (Ouais, de cette façon je pourrais obtenir un handle que Rundll me donne, mais ce n'est pas ce que je veux de toute façon.)
Dernières notes: (a) la DLL doit être compilée dans Lazarus; en fait la première chose que je pensais que c'est un bug dans LCL, mais maintenant quand testé dans Delphi7 je vois la même chose; et puisque le cas de Delphi est plus simple et robuste, j'ai décidé de mettre ici cela; (B) mon chargeur C n'appelle pas LoadLibrary, il utilise TFakeDLL hack (ce fichier OBJ a été modifié pour fonctionner sans wrapper Delphi) et charge ma DLL de la mémoire (donc je n'ai pas un handle à DLL lui-même), mais sinon leur comportement est le même.
J'ai utilisé des formulaires dans dlls dans mon temps D3 pour les utilitaires communs, pouvant également fonctionner indépendamment d'un exécutable contenant une seule ligne, très similaire à votre configuration. N'a pas joué avec l'application ou quoi que ce soit, juste utilisé ShowModal pour lancer le formulaire, qui exécute la boucle de message nécessaire. Bien sûr, il n'y a pas de modalité efficace puisqu'il n'y a pas d'autres formes. Je ne me souviens pas de complications avec les formulaires, ils ont simplement agi normalement. –
@David Heffernan, bonjour! (Se souvenir de moi? ^^). Pourquoi supprimer d'autres tags? Je pense au moins que "delphi" est nécessaire, puisque ce problème est aussi simple dans Delphi DLL. Puis-je ajouter [delphi] de retour? – aleksusklim
@Sertac Akyuz, merci! J'ai ajouté ma propre réponse en fonction de votre solution. – aleksusklim