2010-12-14 6 views
0

Dans Delphi, j'utiliser la ligne suivante (et d'autres, presque identiques) pour ajouter des éléments au menu du système des formes:AppendMenu ne fonctionne pas lorsque ModalPopupMode = pmAuto

AppendMenu(GetSystemMenu(Self.Handle, False), MF_BYPOSITION, cSetScreenResolution1024x768, PChar('1024x768')); 

Cela fait partie d'une classe que toutes les autres formes héritent, et cela fonctionne très bien la plupart du temps, mais j'ai remarqué que lorsque les formulaires sont ouverts en mode modal, les menuitems personnalisés ne sont pas là. Lorsque le même formulaire est ouvert en mode modalité, il fonctionne très bien. J'ai passé un certain temps à comprendre pourquoi, et j'ai trouvé que si ModalPopupMode = pmAuto je reçois cette erreur. Quand c'est pmNone, les choses fonctionnent très bien.

Quelqu'un peut-il expliquer pourquoi cela se produit? Et peut-être donner des conseils sur la façon de le résoudre? J'utilise ModalPopupMode = pmAuto pour corriger d'autres problèmes, donc ce n'est pas une bonne alternative pour revenir à pmNone.

Pour reproduire, il suffit de faire un petit projet avec deux formes. Déposez deux boutons sur le premier formulaire, l'un pour ouvrir la deuxième forme modalement, l'autre pour l'ouvrir. Mettez cette ligne dans la création de la deuxième forme:

AppendMenu(GetSystemMenu(Self.Handle, False), MF_BYPOSITION, 10000, PChar('1024x768')); 

Il fonctionnera maintenant comme prévu. Maintenant, définissez les applications ModalPopupMode sur pmAuto, et observez que le menuitem supplémentaire dans le menu système a disparu lors de l'ouverture modale du formulaire.

alternative (? Et peut-être plus facilement) copier ces fichiers "5":

Project1.dpr

program Project1; 

uses 
    Forms, 
    Unit1 in 'Unit1.pas' {Form1}, 
    Unit2 in 'Unit2.pas' {Form2}; 

{$R *.res} 

begin 
    Application.ModalPopupMode := pmAuto; 
    Application.Initialize; 
    Application.MainFormOnTaskbar := True; 
    Application.CreateForm(TForm1, Form1); 
    Application.Run; 
end. 

unit1.pas

unit Unit1; 

interface 

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

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    Button2: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

uses Unit2; 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    with TForm2.Create(nil) do 
    try 
    ShowModal; 
    finally 
    Free; 
    end; 
end; 

procedure TForm1.Button2Click(Sender: TObject); 
begin 
    with TForm2.Create(Application.Mainform) do 
    begin 
    show; 
    end; 
end; 

end. 

Unit1.dfm

object Form1: TForm1 
    Left = 0 
    Top = 0 
    Caption = 'Form1' 
    ClientHeight = 337 
    ClientWidth = 635 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    PixelsPerInch = 96 
    TextHeight = 13 
    object Button1: TButton 
    Left = 8 
    Top = 8 
    Width = 75 
    Height = 25 
    Caption = 'Modal' 
    TabOrder = 0 
    OnClick = Button1Click 
    end 
    object Button2: TButton 
    Left = 8 
    Top = 39 
    Width = 75 
    Height = 25 
    Caption = 'Modeless' 
    TabOrder = 1 
    OnClick = Button2Click 
    end 
end 

UNIT2.PA S

unit Unit2; 

interface 

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

type 
    TForm2 = class(TForm) 
    procedure FormCreate(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

implementation 

{$R *.dfm} 

procedure TForm2.FormCreate(Sender: TObject); 
begin 
    AppendMenu(GetSystemMenu(Self.Handle, False), MF_BYPOSITION, 10000, PChar('Test')); 
end; 

end. 

Unit2.dfm

object Form2: TForm2 
    Left = 0 
    Top = 0 
    Caption = 'Form2' 
    ClientHeight = 337 
    ClientWidth = 635 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    OnCreate = FormCreate 
    PixelsPerInch = 96 
    TextHeight = 13 
end 

Répondre

4

Le constructeur n'est pas l'endroit idéal pour manipuler la poignée de la fenêtre d'un formulaire. Le handle d'un contrôle peut être recréé pendant la durée de vie du formulaire.

Vous ne devez utiliser la poignée de la fenêtre qu'après avoir pris connaissance que le formulaire a une poignée de fenêtre. Remplacez la méthode CreateWnd de votre formulaire et mettez votre code AppendMenu là. Cette méthode est appelée une fois que le handle du formulaire a été créé, chaque fois que le handle du formulaire est créé. Vous pouvez donc le voir appelé plusieurs fois pour le même formulaire. Certaines propriétés de votre formulaire changent probablement lors de sa création, ce qui entraîne la recréation de la fenêtre. En fait, votre commande AppendMenu peut exacerber le problème en forçant le formulaire à créer sa fenêtre avant qu'elle ne soit prête. (La lecture de la propriété Handle force l'existence de la poignée si elle n'est pas déjà présente.)

+1

'TCustomForm.ShowModal' a reçu un appel à' RecreateWnd' en fonction du 'PopupMode' du formulaire et du 'ModalPopupMode' de l'application. –

+0

Merci. Je n'étais pas au courant. Merci Sertac aussi. –

Questions connexes