Autor Beitrag
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Sa 17.12.05 21:53 
ActionMainMenuBar in einer MDI-Applikation verwenden

ACHTUNG: In dem folgenden Code werden die Original-Sourcen der VCL verändert. Ich übernehme keine Verantwortung für evtl. Probleme. Ein Backup der zu verändernden Dateien sollte das Mindeste sein, was man vor dieser Änderung vornimmt.

Um die ActionMainMenuBar funktionsfähig in einer MDI-Applikation verwenden zu können, hilft unter anderem die unten stehen Änderung an den Codes. Diese sorgt dafür, dass die Buttons für die MDIChilds beim Maximieren derselben sofort angezeigt werden und nicht - wie bei den Originalen der Komponente - erst nach einem Klick auf die Bar sichtbar werden:

In der ActnMenus.pas im Verzeichnis $Delphi7\Source\Vcl\ musst die Funktion CallWndHook durch folgenden Code ersetzt werden:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
function CallWndHook(Code: Integer; WParam: wParam; Msg: PCWPStruct): Longint; stdcall;

procedure UpdateMDIMenuButtons;
var
I: Integer;
Parent: THandle;
ParentForm: TWinControl;
Form: TCustomForm;
begin
    Parent := GetParent(Msg.hwnd);
    if Parent = 0 then exit;
    ParentForm := FindControl(Parent);
    for I := 0 to MenuList.Count - 1 do
    begin
        Form := GetParentForm(MenuList.Menus[I]);
        if (Form = ParentForm) and
        (MenuList.Menus[I] is TCustomActionMainMenuBar) then
        begin
            if (Msg.Message = WM_MDIDESTROY) and (Form is TForm) and
            (TForm(Form).MDIChildCount = 1)  then
            with MenuList.Menus[I] as TCustomActionMainMenuBar do
            MDIChildRestored
            else
            with MenuList.Menus[I] as TCustomActionMainMenuBar do
            GetActiveMDIChild;
            break;
    end;
  end;
end;

begin
    if Code = HC_ACTION then
    case Msg.message of
    // Use of WM_SIZE is required for any Windows version except Themed XP
    WM_MDIGETACTIVE, WM_SIZE,
    WM_MDIDESTROY: UpdateMDIMenuButtons;
    WM_ACTIVATE:
    if ActiveMenu is TCustomActionPopupMenu then
    ActiveMenu.CloseMenu;
    WM_SETTINGCHANGE:
    if Assigned(UpdateActnMenusProc) then
    UpdateActnMenusProc;
end;
Result := CallNextHookEx(MenuCallWndHook, Code, WParam, Longint(Msg));
end;

Weiterhin muss in derselben Datei die Prozedur ExecuteTarget folgendermaßen geändert werden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TInternalMDIAction.ExecuteTarget(Target: TObject);
begin
    case MDIAction of
    maActivate: SendMessage(GetParent(Form.Handle), WM_MDIACTIVATE, Form.Handle, 0);
    maClose: Form.Close;
    maRestore: SendMessage(GetParent(Form.Handle), WM_MDIRESTORE, Form.Handle, 0);
    // Fixed to minimize the form not close it
    maMinimize: Form.WindowState := wsMinimized;
end;
end;


Dieser Beitrag stammt ursprünglich von homepages.borland.co...me=Main.Delphi7#toc9

Allerdings funktioniert das nun meistens nicht auf Anhieb, weil sich in $Delphi7\Lib\ die kompilierte DCU-Datei befindet. Diese sollte nun erstmal gelöscht werden. Danach müssen wir sie aber neu kompilieren. Dazu öffnet Ihr per Start->Ausführen->cmd eine Konsole und begebt Euch in das Unterverzeichnis bin des Delphi7-Ordners.

Dort gebt Ihr dann folgenden Befehl ein:
ausblenden Quelltext
1:
dcc32 ..\Source\Vcl\actnmenus.pas -N..\lib					

Dieser kompiliert die Quellcode-Datei und speichert die dcu direkt im lib-Verzeichnis. Ab dann sollte die ActionMainMenuBar in MDIs funktionieren.

Moderiert von user profile iconjasocul: Beitrag geprüft am 05.05.2006