Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Вниз

ToolBar в MDI   Найти похожие ветки 

 
EvgeniyR ©   (2004-04-09 08:42) [0]

Есть MDI-приложении, сделал что-бы при открытии дочерних окон на главной форме внизу появлялся ToolBar с кнопками (как, например в 1:С 7.7 - 8):
--------------------------------------------
ToolButton := TToolButton.Create(FormOwner);
  with ToolButton do
    begin
      Parent := ToolBar1;
      Style := tbsCheck;
      Grouped := true;
      Down := true;
      OnClick := ChildButtonClick;
    end;
------------------------------------
При нажатии на кнопки активизируется соответствующая форма:
TChildForm(TToolButton(Sender).Owner).BringToFront;
------------------------------------
Все работает прекрасно, но как сделать, что бы при активизации формы "вручную", нажималась соответствующая кнопка на ToolBar"е?
Заранее спасибо.


 
Rule ©   (2004-04-09 10:13) [1]

2EvgeniyR ©   (09.04.04 08:42)

Отлавливай событие формы онактивайт и нажимай соответствующую кнопку (естественно каждая кнопка должна быть пристегнута к каждому окну)


 
Игорь Шевченко ©   (2004-04-09 11:16) [2]

Можно.
unit main;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, ExtCtrls, UserMessages, Buttons;

type
 TfMain = class(TForm)
   MainMenu: TMainMenu;
   New1: TMenuItem;
   Child1: TMenuItem;
   Iterate1: TMenuItem;
   Window1: TMenuItem;
   ilehorizontal1: TMenuItem;
   ilevertical1: TMenuItem;
   Cascade1: TMenuItem;
   ButtonsPanel: TPanel;
   Childwithicon1: TMenuItem;
   procedure Child1Click(Sender: TObject);
   procedure ilehorizontal1Click(Sender: TObject);
   procedure ilevertical1Click(Sender: TObject);
   procedure Cascade1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure Childwithicon1Click(Sender: TObject);
   procedure ButtonsPanelResize(Sender: TObject);
 private
   FButtons : TList;
   FClientInstance : TFarProc;
   FPrevClientProc : TFarProc;
   procedure ClientWndProc(var Message: TMessage);
   procedure AddButtonToPanel (AWindowHandle : HWND);
   procedure RemoveButtonFromPanel (AWindowHandle : HWND);
   procedure UmMDIActive (var Message : TMessage); message UM_MDIACTIVE;
   procedure RedrawButtons;
   procedure WindowButtonClick (Sender : TObject);
   procedure DrawWindowButton (AButton : TSpeedButton; ADown : Boolean);
 end;

var
 fMain: TfMain;

implementation
uses
 Child, ChildWithIcon;

{$R *.dfm}

const MaxButtonWidth = 140;

procedure TfMain.Child1Click(Sender: TObject);
begin
 with TfChild.Create(Application) do
   Show;
end;

procedure TfMain.ilehorizontal1Click(Sender: TObject);
begin
 TileMode := tbHorizontal;
 Tile;
end;

procedure TfMain.ilevertical1Click(Sender: TObject);
begin
 TileMode := tbVertical;
 Tile;
end;

procedure TfMain.Cascade1Click(Sender: TObject);
begin
 Cascade;
end;

procedure TfMain.UmMDIActive (var Message : TMessage);
var
 I : Integer;
begin
 for I:=0 to Pred(FButtons.Count) do
   with TSpeedButton(FButtons[I]) do
     if Tag = Message.WParam then
       DrawWindowButton (TSpeedButton(FButtons[I]), true)
     else if Tag = Message.LParam then
       DrawWindowButton (TSpeedButton(FButtons[I]), false);
end;

procedure TfMain.FormCreate(Sender: TObject);
begin
 FButtons := TList.Create;
 FClientInstance := MakeObjectInstance(ClientWndProc);
 FPrevClientProc := Pointer(GetWindowLong(ClientHandle,
   GWL_WNDPROC));
 SetWindowLong(ClientHandle, GWL_WNDPROC,
   LongInt(FClientInstance));
end;

procedure TfMain.ClientWndProc(var Message: TMessage);
begin
 with Message do
   case Msg of
   WM_MDICREATE:
     begin
       Result := CallWindowProc(FPrevClientProc,
         ClientHandle, Msg, wParam, lParam);
       AddButtonToPanel (Result);
     end;
   WM_MDIDESTROY:
     begin
       RemoveButtonFromPanel(wParam);
       Result := CallWindowProc(FPrevClientProc,
         ClientHandle, Msg, wParam, lParam);
     end;
   else
     Result := CallWindowProc(FPrevClientProc,
        ClientHandle, Msg, wParam, lParam);
   end;
end;

procedure TfMain.FormDestroy(Sender: TObject);
begin
 FButtons.Free;
end;

procedure TfMain.AddButtonToPanel (AWindowHandle : HWND);
var
 mdiButton : TSpeedButton;
 AText : array[0..MAX_PATH] of char;
begin
 GetWindowText(AWindowHandle, AText, SizeOf(AText));
 mdiButton := TSpeedButton.Create(Self);
 with mdiButton do begin
   Tag := AWindowHandle;
   Parent := ButtonsPanel;
   Width := 70;
   Height := 22;
   Left := FButtons.Count * (Width + 2) + 8;
   Top := 4;
   GroupIndex := 1;
   AllowAllUp := true;
   Glyph.Width := 16;
   Glyph.Height := 16;
   Glyph.TransparentColor := clCaptionText;
   Layout := blGlyphLeft;
   Margin := 2;
   OnClick := WindowButtonClick;
   FButtons.Add(mdiButton);
 end;
 RedrawButtons;
end;

procedure TfMain.RemoveButtonFromPanel (AWindowHandle : HWND);
var
 I : Integer;
begin
 for I:=0 to Pred(FButtons.Count) do
   if TSpeedButton(FButtons[I]).Tag = Integer(AWindowHandle) then begin
     TSpeedButton(FButtons[I]).Free();
     FButtons.Delete(I);
     Break;
   end;
 RedrawButtons;
end;

procedure TfMain.RedrawButtons;
var
 ButtonWidth : Integer;
 I : Integer;
begin
 ButtonsPanel.Invalidate();
 if FButtons.Count = 0 then
   Exit;
 ButtonWidth := (ButtonsPanel.Width - 16 - (FButtons.Count * 2)) div
FButtons.Count;
 if ButtonWidth > MaxButtonWidth then
   ButtonWidth := MaxButtonWidth;
 for I:=0 to Pred(FButtons.Count) do
   with TSpeedButton(FButtons[I]) do begin
     Width := ButtonWidth;
     Left := I * (Width + 2) + 8;
   end;
end;

procedure TfMain.WindowButtonClick(Sender: TObject);
begin
 with Sender as TSpeedButton do
   PostMessage(ClientHandle, WM_MDIACTIVATE, Tag, 0);
end;

procedure TfMain.DrawWindowButton(AButton: TSpeedButton; ADown : Boolean);
var
 AText : array[0..255] of char;
 Icon : TIcon;
 IconHandle : THandle;
 AWindowHandle : THandle;
begin
 AWindowHandle := THandle(AButton.Tag);
 GetWindowText(AWindowHandle, AText, SizeOf(AText));
 AButton.Caption := AText;
 AButton.Down := ADown;
 IconHandle := GetClassLong(AWindowHandle, GCL_HICONSM);
 if IconHandle = 0 then
   IconHandle := GetClassLong(AWindowHandle, GCL_HICON);
 if IconHandle = 0 then
   IconHandle := SendMessage(AWindowHandle, WM_GETICON, ICON_SMALL, 0);
 if IconHandle = 0 then
   Iconhandle := SendMessage(AWindowHandle, WM_GETICON, ICON_BIG, 0);
 if IconHandle = 0 then
   IconHandle := Application.Icon.Handle;
 if IconHandle <> 0 then begin
   Icon := TIcon.Create;
   Icon.Handle := IconHandle;
   try
     DrawIconEx(AButton.Glyph.Canvas.Handle, 0, 0, Icon.Handle,
          AButton.Glyph.Width, AButton.Glyph.Height, 0, 0, DI_NORMAL);
   finally
     Icon.ReleaseHandle;
     Icon.Free;
   end;
 end;
end;

procedure TfMain.Childwithicon1Click(Sender: TObject);
begin
 with TfChildWithIcon.Create(Application) do
   Show;
end;

procedure TfMain.ButtonsPanelResize(Sender: TObject);
begin
 RedrawButtons;
end;

end.


 
Игорь Шевченко ©   (2004-04-09 11:17) [3]

unit UserMessages;

interface
uses
 Messages;
const
 UM_MDIACTIVE = WM_USER + 555;

implementation

end.


Дочерние окна:

unit Child;

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

type
 TfChild = class(TForm)
   ListBox: TListBox;
   procedure FormCreate(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   procedure WM_MDIACTIVATE (var Message : TMessage); message WM_MDIACTIVATE;
 end;

var
 fChild: TfChild;
 GlobalChildCount : Integer = 0;

implementation
uses
 UserMessages;

{$R *.dfm}

procedure TfChild.FormCreate(Sender: TObject);
begin
 Inc(GlobalChildCount);
 Caption := Format("%d", [GlobalChildCount]);
end;

procedure TfChild.WM_MDIACTIVATE (var Message : TMessage);
var
 Buf : array[0..255] of char;
begin
 if THandle(Message.WParam) = Handle then begin
   ListBox.Items.Add("Ich bin deactivated :-(");
   if Message.LParam <> 0 then begin
     GetWindowText(Message.LParam, Buf, sizeof(Buf));
     ListBox.Items.Add (Format("%s is more lucky guy", [Buf]));
   end;
   SendMessage (Application.MainForm.Handle, UM_MDIACTIVE, Message.WParam,
     Handle);
 end else if THandle(Message.LParam) = Handle then begin
   ListBox.Items.Add("Hurray! I am active again!");
   if Message.WParam <> 0 then begin
     GetWindowText(Message.WParam, Buf, sizeof(Buf));
     ListBox.Items.Add (Format("%s is gone loser", [Buf]));
   end;
   SendMessage (Application.MainForm.Handle, UM_MDIACTIVE, Handle,
     Message.LParam);
 end;
end;

procedure TfChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Action := caFree;
end;

end.


 
EvgeniyR ©   (2004-04-09 12:02) [4]

Я, наверно, неправильно выразился. Кнопки(работают как радио кнопки) создаются и уничтожаются при уничтожении формы, при нажатии на них - выносятся наверх соответствующии дочернии формы. Надо что бы при "ручной" активизации формы, "топилась" (Down := true) соответствующая кнопка на ToolBar"е.


 
lgz   (2004-04-09 14:05) [5]

EvgeniyR ©
У меня есть что-то наподобие панели задач виндовса для приложения с MDI. Там панелька внизу главной формы и TSpeedButton-кнопки создаются, нажимаются и убиваются вместе c MDIChild-окнами. Прислать на мыло?


 
EvgeniyR ©   (2004-04-09 14:16) [6]


> lgz   (09.04.04 14:05) [5]

Да, пожалуйста.


 
Wizard_Ex ©   (2004-04-09 17:54) [7]

Подкину компонент, кстати Игорь Шевченко мне как-то помог именно по этому случаю, за что ему спасибо.
Компонент называется TMDIPanel,
регистрируется на панель Win32, полностью самодостаточен. Ничего больше писать не надо и особенно оконные функции изменять.
Только модератор удалит наверно, а хотелось бы код в студию


 
Wizard_Ex ©   (2004-04-09 18:06) [8]

Почему кладовка не работает?
Итого код в студию (объедините в один юнит)
{******************************************}
{                                          }
{               TMDIPanel                  }
{                                          }
{         Copyright(c) Wizard_Ex           }
{                                          }
{  Спасибо Galera за помощь в написании    }
{  части кода (Portion Copyright Ж-)       }
{                                          }
{  Отдельное спасибо Игорю Шевченко        }
{  за помощь в разрешении проблемы         }
{  с получением иконки                     }
{                                          }
{******************************************}

// извините, но код написан на коленке, в нем есть сопли, и самое главное он неплохо работает, блин, не смотря ни на что
// for free use only

// докладывать не будем, не будем,... а проблему решать будем...
// "Мама не горюй"

unit MDIPanel;

interface
uses Classes, SysUtils, Menus, Forms, Controls, Graphics, Dialogs, Buttons,
    ExtCtrls, Messages, Windows, RxCtrls {JvxCtrls}; //

type

 TMDIPanel = class(TPanel)
 private
   Form: TForm;
   OldWndClientProc: Pointer;
   InstanceWndClientProc: Pointer;
   FFlat: boolean;
   FDefaultButtonWidth: integer;
   procedure SetFlat(const Value: boolean);
   procedure Restructure(Needed : boolean = False);
   procedure SetDefaultButtonWidth(const Value: integer);
   procedure WMSize(var Message: TWMSize); message WM_SIZE;
   procedure WMEXITSIZEMOVE(var Message: TMessage); message WM_EXITSIZEMOVE;
 protected
     procedure WndClientProc(var Message: TMessage); virtual;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
 published
   property Flat : boolean read FFlat write SetFlat;
   property DefaultButtonWidth : integer read FDefaultButtonWidth write SetDefaultButtonWidth;
 end;
 
 TMDIButton = class(TRxSpeedButton)    // у RX кнопки в Caption троеточие в конце пишется - красиво блин ;-0
// Могут быть варианты:
//  TMDIButton = class(TJvxSpeedButton)   //  используется библиотека Jedy  - в uses раскоментарьте JvxCtrls
//  TMDIButton = class(TSpeedButton)      // используется стандартный SpeedButton
 private
   AHandle: THandle;
   OldChildWndProc: Pointer;
   InstanceChildWndProc: Pointer;
   PopupMenu: TPopupMenu;
   procedure ChildWndProc(var Message: TMessage);
   procedure ClickActivate(Sender: TObject);
   procedure CloseMDIWindow(Sender: TObject);
   procedure MaximizeMDIWindow(Sender: TObject);
   procedure MDIButtonMouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure MinimizeMDIWindow(Sender: TObject);
   procedure OnPopupMenu(Sender: TObject);
   procedure RestoreMDIWindow(Sender: TObject);
   procedure CascadeMDIWindow(Sender: TObject);
   procedure IconArrangeMDIWindow(Sender: TObject);
   procedure TileHorMDIWindow(Sender: TObject);
   procedure TileVertMDIWindow(Sender: TObject);
   procedure MinimizeAllMDIWindow(Sender: TObject);
   procedure CloseAllMDIWindow(Sender: TObject);
   procedure ClientSizeMDIWindow(Sender: TObject);
   procedure ClientSizeAllMDIWindow(Sender: TObject);
 public
   constructor CreateBtn(sHandle: THandle; AOwner: TComponent); virtual;
   destructor Destroy; override;
 end;

procedure Register;

implementation

{ TMDIPanel }

procedure Register;
begin
 RegisterComponents("Win32", [TMDIPanel]);
end;

{Выдираем иконку всеми возможными средствами}
// Thanks to Игорь Шевченко
function GetIconFromWindow(hWnd:HWND):HICON;
var
 Ico:HICON;
begin
 Ico:=0;
 SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG, 1000, LongWord(ico));
 if (ico = 0) then ico := GetClassLong(hwnd, GCL_HICONSM);
 if (ico = 0) then SendMessageTimeout(hwnd, WM_GETICON, ICON_BIG, 0, SMTO_ABORTIFHUNG, 1000, LongWord(ico));
 if (ico = 0) then ico := GetClassLong(hwnd, GCL_HICON);
 
 {вот именно эта строка работает за всех, кто бы знал}
 if (ico = 0) then SendMessageTimeout(hwnd, WM_QUERYDRAGICON, 0, 0, SMTO_ABORTIFHUNG, 1000, LongWord(ico));
 
 if (ico = 0) then ico:=LoadIcon(0,IDI_APPLICATION);
 Result:=Ico;
end;

constructor TMDIPanel.Create(AOwner: TComponent);
var
 Component: TComponent;
begin
 inherited;
 Align:=alBottom;
 Caption:="";
 ShowHint:=True;
 Height:=27;
 BorderWidth:=1;
 BevelInner:=bvLowered;
 BevelOuter:=bvRaised;
 Flat:=True;
 DefaultButtonWidth:=165;

 if not (csDesigning in ComponentState) then
 begin
   Component := Owner;
   while Assigned(Component) and not (Component is TForm) do Component:= Component.Owner;
   if not Assigned(Component) then exit;
   Form := Component as TForm;

   if Form.Handle=Form.ClientHandle then ; //бда, а был ли мальчик

   if (not (csDesigning in ComponentState)) and (Form.FormStyle=fsMDIForm) then
   begin
     InstanceWndClientProc := MakeObjectInstance(WndClientProc);
     OldWndClientProc := Pointer(GetWindowLong(Form.ClientHandle, GWL_WNDPROC));
     SetWindowLong(Form.ClientHandle, GWL_WNDPROC, Longint(InstanceWndClientProc));
   end;
 end;
end;


 
Wizard_Ex ©   (2004-04-09 18:07) [9]

Далее
destructor TMDIPanel.Destroy;
begin
 inherited;

end;

procedure TMDIPanel.SetFlat(const Value: boolean);
begin
 FFlat := Value;
end;

procedure TMDIPanel.WndClientProc(var Message: TMessage);
var mdiButton : TMDIButton;
      Icon: TIcon;
   ACaption: array[0..255] of Char;
begin
 case Message.Msg of
   WM_MDICREATE:
     begin
       Message.Result := CallWindowProc(OldWndClientProc, Form.ClientHandle, Message.Msg, Message.WParam, Message.LParam);

       mdiButton:=TMDIButton.CreateBtn(Message.Result, Self);
       mdiButton.Parent:=Self;
       if ControlCount>1 then
       begin
         mdiButton.Left:=Controls[ControlCount-2].Left+Controls[ControlCount-2].Width+1;
         mdiButton.Width:=Controls[ControlCount-2].Width;
       end else
           begin
             mdiButton.Left:=BevelWidth+BorderWidth+1;
             mdiButton.Width:=FDefaultButtonWidth;
           end;
       mdiButton.Top:=BevelWidth+BorderWidth+1;
       mdiButton.Height:=Height-BevelWidth*2-BorderWidth*2-2;
       mdiButton.GroupIndex:=10;
       mdiButton.Down:=True;
       mdiButton.Layout:=blGlyphLeft;
       mdiButton.Margin:=0;
       mdiButton.Flat:=FFlat;
       
       // шо це таке, га  (с украинским акцентом)
       
       GetWindowText(Message.Result, ACaption, 255);
//        mdiButton.Caption:=ACaption;
//        mdiButton.Hint:=ACaption;

       Icon := TIcon.Create;
       Icon.Handle := GetIconFromWindow(Message.Result);

       mdiButton.Glyph.Width := 16;
       mdiButton.Glyph.Height := 16;

       // ну-ка сделаем из большого слона маленького причем 16 на 16
       DrawIconEx(mdiButton.Glyph.Canvas.Handle,0,0,Icon.Handle,16,16,0,0,DI_NORMAL);
       Icon.ReleaseHandle; // однако нужна еще, иконка-то
       Icon.Free;

       Restructure;  // всем строиться

       Exit;
     end;
   WM_MDIREFRESHMENU :
     begin
       GetWindowText(GetTopWindow(Application.MainForm.ClientHandle), ACaption, 255);
     end;
   WM_DESTROY:
     begin
       SetWindowLong(Form.ClientHandle, GWL_WNDPROC, Longint(OldWndClientProc));
       FreeObjectInstance(InstanceWndClientProc);
     end;
 end;
 Message.Result:= CallWindowProc(OldWndClientProc, Form.ClientHandle, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TMDIPanel.Restructure(Needed : boolean = False);
var I : integer;
   AllButtonWidth : integer;
   AWidth : integer;
begin
// вот это код ;-(
 if ControlCount=0 then exit;
 AllButtonWidth:=0;
 for I:=0 to ControlCount-1 do AllButtonWidth:=AllButtonWidth+Controls[i].Width;
 AllButtonWidth:=AllButtonWidth+BevelWidth*2-BorderWidth*2+ControlCount;
 AWidth:=Round((Width-(BevelWidth*2+BorderWidth*2+ControlCount))/ControlCount);
 for I:=0 to ControlCount-1 do
 begin
   if (AllButtonWidth>(Width+1)) or Needed then Controls[i].Width:=AWidth;
   if (Controls[i].Width>DefaultButtonWidth) then Controls[i].Width:=DefaultButtonWidth;
   if I=0 then Controls[i].Left:=BevelWidth+BorderWidth+1
     else Controls[i].Left:=Controls[i-1].Left+Controls[i-1].Width;
 end;
end;

procedure TMDIPanel.SetDefaultButtonWidth(const Value: integer);
begin
 FDefaultButtonWidth := Value;
end;

procedure TMDIPanel.WMSize(var Message: TWMSize);
begin
 inherited;
 Restructure(True);
 // думаю это повесить на событие когда изменение размера уже завершилось (на WMEXITSIZEMOVE)
 // а то так накладно
end;

procedure TMDIPanel.WMEXITSIZEMOVE(var Message: TMessage);
begin
 inherited;
 // но что-то не работает
end;

{ TMDIButton }

constructor TMDIButton.CreateBtn(sHandle: THandle; AOwner: TComponent);
var
 mi: TMenuItem;
begin
// если будете менять местами команды не забудьте заглянуть в TMDIButton.OnPopupMenu(Sender: TObject);
// очень рекомендую

 inherited Create(AOwner);
 AHandle:=sHandle;
 OnClick := ClickActivate;

 PopupMenu := TPopupMenu.Create(Self);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Каскадом";
 mi.OnClick := CascadeMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Встык горизонтально";
 mi.OnClick := TileHorMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Встык вертикально";
 mi.OnClick := TileVertMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Упорядочить значки";
 mi.OnClick := IconArrangeMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Минимизировать все";
 mi.OnClick := MinimizeAllMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Закрыть все";
 mi.OnClick := CloseAllMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "-";
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Активизировать";
 mi.OnClick := ClickActivate;
 mi.Bitmap.Handle := LoadBitmap(0, PChar(OBM_CHECK));
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "-";
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Восстановить";
 mi.OnClick := RestoreMDIWindow;
 mi.Bitmap.Handle := LoadBitmap(0, PChar(OBM_RESTORED));
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Минимизировать";
 mi.OnClick := MinimizeMDIWindow;
 mi.Bitmap.Handle := LoadBitmap(0, PChar(OBM_REDUCED));
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Максимизировать";
 mi.OnClick := MaximizeMDIWindow;
 mi.Bitmap.Handle := LoadBitmap(0, PChar(OBM_ZOOMD));
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "-";
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Клиентский размер";
 mi.OnClick := ClientSizeMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Клиентский размер у всех";
 mi.OnClick := ClientSizeAllMDIWindow;
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "-";
 PopupMenu.Items.Add(mi);

 mi := TMenuItem.Create(Self);
 mi.Caption := "Закрыть окно";
 mi.OnClick := CloseMDIWindow;
 PopupMenu.Items.Add(mi);

 PopupMenu.OnPopup := OnPopupMenu;

 OnMouseDown:=MDIButtonMouseDown;

 InstanceChildWndProc := MakeObjectInstance(ChildWndProc);
 OldChildWndProc := Pointer(GetWindowLong(AHandle,GWL_WNDPROC));
 SetWindowLong(AHandle, GWL_WNDPROC, Longint(InstanceChildWndProc));
end;


 
Wizard_Ex ©   (2004-04-09 18:08) [10]

И еще:

procedure TMDIButton.MDIButtonMouseDown(Sender: TObject;
 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var T : TPoint;
begin
 if Button=mbRight then
 begin
   GetCursorPos(T);
   PopupMenu.Popup(T.X, T.Y);
 end;
end;

destructor TMDIButton.Destroy;
begin
 SetWindowLong(AHandle, GWL_WNDPROC, Longint(OldChildWndProc));
 FreeObjectInstance(InstanceChildWndProc);
 inherited;
end;

procedure TMDIButton.OnPopupMenu(Sender: TObject);
var I : integer;
begin
 I:=7;
 if GetTopWindow(Application.MainForm.ClientHandle)=AHandle then
   PopupMenu.Items[I+0].Enabled := False
 else
   PopupMenu.Items[I+0].Enabled := True;

 if IsIconic(AHandle) then begin
   PopupMenu.Items[I+2].Enabled := True;
   PopupMenu.Items[I+3].Enabled := False;
   PopupMenu.Items[I+4].Enabled := True;
 end
 else begin
   PopupMenu.Items[I+3].Enabled := True;
   if IsZoomed(AHandle) then begin
     PopupMenu.Items[I+2].Enabled := True;
     PopupMenu.Items[I+4].Enabled := False;
   end
   else begin
     PopupMenu.Items[I+2].Enabled := False;
     PopupMenu.Items[I+4].Enabled := True;
   end;
 end;
end;

procedure TMDIButton.ChildWndProc(var Message: TMessage);
var AMDIPanel : TMDIPanel;
begin
 case Message.Msg of
 WM_GETTEXT:
   begin
     Message.Result:= CallWindowProc(OldChildWndProc, AHandle, Message.Msg, Message.WParam, Message.LParam);
     Caption := PChar(Message.LParam);
     Hint := PChar(Message.LParam);
     Exit;
   end;
 WM_MDIACTIVATE:
   begin
     if HWND(Message.LParam)=AHandle then Down := True;
     if HWND(Message.WParam)=AHandle then Down := False;
   end;
 WM_DESTROY:
   begin
     PopupMenu.Free;
     AMDIPanel:=TMDIPanel(Parent);
     Free;
     AMDIPanel.Restructure(True);
   end;
 end;
 Message.Result:= CallWindowProc(OldChildWndProc, AHandle, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TMDIButton.CascadeMDIWindow(Sender: TObject);
begin
 SendMessage(Application.MainForm.ClientHandle, WM_MDICASCADE, 0, 0);
end;

procedure TMDIButton.TileHorMDIWindow(Sender: TObject);
begin
 SendMessage(Application.MainForm.ClientHandle, WM_MDITile, MDITILE_HORIZONTAL, 0);
end;

procedure TMDIButton.TileVertMDIWindow(Sender: TObject);
begin
 SendMessage(Application.MainForm.ClientHandle, WM_MDITile, MDITILE_VERTICAL, 0);
end;

procedure TMDIButton.IconArrangeMDIWindow(Sender: TObject);
begin
 SendMessage(Application.MainForm.ClientHandle, WM_MDIICONARRANGE, 0, 0);
end;

procedure TMDIButton.MaximizeMDIWindow(Sender: TObject);
begin
 ShowWindow(AHandle,SW_MAXIMIZE);
end;

procedure TMDIButton.ClientSizeMDIWindow(Sender: TObject);
var Rect : TRect;
begin
 inherited;
 LockWindowUpdate(AHandle);
 try
     if isZoomed(AHandle) then ShowWindow(AHandle,SW_RESTORE);
     Windows.GetClientRect(Application.MainForm.ClientHandle,Rect);
     with Application.MainForm.ActiveMDIChild do
     if not ((Left=0) and (Top=0) and (Width=Rect.Right) and (Height=Rect.Bottom)) then
     begin
       Left:=0;
       Top:=0;
       // begin Как ни странно без этих строк не обойтись
       Width:=Rect.Right-80;  
       Height:=Rect.Bottom-80;
       // end

       Application.ProcessMessages;
       Windows.GetClientRect(Application.MainForm.ClientHandle,Rect);
       Width:=Rect.Right;
       Height:=Rect.Bottom;
     end;
 finally
   LockWindowUpdate(0);
 end;
end;

procedure TMDIButton.ClientSizeAllMDIWindow(Sender: TObject);
var Rect : TRect;
   I : integer;
   cHandle : THandle;
begin
 inherited;
 Screen.Cursor:=crHourGlass;
 LockWindowUpdate(Application.MainForm.ClientHandle);
 try
   for i:=0 to Application.MainForm.MDIChildCount-1 do
   begin
     cHandle:=Application.MainForm.MDIChildren[I].Handle;
     if isZoomed(cHandle) then ShowWindow(cHandle,SW_RESTORE);
   end;
{    if Application.MainForm.VertScrollBar.IsScrollBarVisible         // какая-то бредовая идея ей богу
     or Application.MainForm.HorzScrollBar.IsScrollBarVisible then}  // ...ные скролбары
   begin
     Windows.GetClientRect(Application.MainForm.ClientHandle,Rect);
     for i:=0 to Application.MainForm.MDIChildCount-1 do
     with Application.MainForm.MDIChildren[I] do
     begin
       Left:=0;
       Top:=0;
       // begin Как ни странно без этих строк не обойтись
       Width:=Rect.Right-80;
       Height:=Rect.Bottom-80;
       // end
     end;
   end;

   Application.ProcessMessages;  // ну так, на всякий случай, а то без этого кажись не работает
   Windows.GetClientRect(Application.MainForm.ClientHandle,Rect);
   for i:=0 to Application.MainForm.MDIChildCount-1 do
   with Application.MainForm.MDIChildren[I] do
   begin
     Left:=0;
     Top:=0;
     Width:=Rect.Right;
     Height:=Rect.Bottom;
   end;
 finally
   LockWindowUpdate(0);  // понеслась
   Screen.Cursor:=crDefault;
 end;
end;

procedure TMDIButton.ClickActivate(Sender: TObject);
begin
// здесь реализуем поведение как в Windows если активно, то минимизироваться
// если не активно то активизироваться
 if IsIconic(AHandle) then
 begin
   ShowWindow(AHandle,SW_RESTORE);
   Exit;
 end;

 if (GetTopWindow(Application.MainForm.ClientHandle)=AHandle) then
 begin
   ShowWindow(AHandle,SW_MINIMIZE);
 end
   else begin
          if not IsIconic(AHandle) then
          begin
            BringWindowToTop(AHandle);
          end;
          if isZoomed(GetTopWindow(Application.MainForm.ClientHandle)) then
          begin
            BringWindowToTop(AHandle);
            ShowWindow(AHandle,SW_MAXIMIZE)
          end
             else ShowWindow(AHandle,SW_RESTORE);
        end;
end;

procedure TMDIButton.CloseMDIWindow(Sender: TObject);
begin
 SendMessage(AHandle,WM_CLOSE,0,0);
end;

procedure TMDIButton.MinimizeMDIWindow(Sender: TObject);
begin
 ShowWindow(AHandle,SW_MINIMIZE);
end;

procedure TMDIButton.MinimizeAllMDIWindow(Sender: TObject);
var I : integer;
   isIcon : boolean;
begin
 // Minimize All работает по принципу кнопки ShowDesktop в Windows,
 // минимизирует если не свернуты
 // и наоборот
 isIcon:=True;
 for i:=TMDIPanel(Parent).ControlCount-1 downto 0 do
  if not IsIconic(TMDIButton(TMDIPanel(Parent).Controls[i]).AHandle) then
  begin
    isIcon:=False;
    Break;
  end;
 if not isIcon then
 for i:=TMDIPanel(Parent).ControlCount-1 downto 0 do
   ShowWindow(TMDIButton(TMDIPanel(Parent).Controls[i]).AHandle,SW_MINIMIZE)
   else
     for i:=0 to TMDIPanel(Parent).ControlCount-1  do
       ShowWindow(TMDIButton(TMDIPanel(Parent).Controls[i]).AHandle,SW_RESTORE);
end;

procedure TMDIButton.CloseAllMDIWindow(Sender: TObject);
var I : integer;
begin
 for i:=TMDIPanel(Parent).ControlCount-1 downto 0 do
 SendMessage(TMDIButton(TMDIPanel(Parent).Controls[i]).AHandle,WM_CLOSE,0,0);
end;

procedure TMDIButton.RestoreMDIWindow(Sender: TObject);
begin
 ShowWindow(AHandle,SW_RESTORE);
end;

end.


 
Wizard_Ex ©   (2004-04-09 18:16) [11]

В итоге кидаете этот компонент на главную форму MDI и забываете как это вообще работает (в смысле не тревожитесь - забывать не надо, понимать надо)
Большое пожалуйста.

P.S.
Кстати когда-то я его в кладовку кажется выкладывал


 
EvgeniyR ©   (2004-04-12 09:25) [12]

Огромное спасибо Wizard_Ex, Игорь Шевченко.


 
Wizard_Ex ©   (2004-04-12 17:12) [13]

Работает?
Разобрался?



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.03 c
4-1078768072
Wasp
2004-03-08 20:47
2004.05.02
Форма в DLL


4-1078450068
sucer
2004-03-05 04:27
2004.05.02
Как корректно уничтожить поток(Thread)?


3-1081251387
Sergey-ZZZ
2004-04-06 15:36
2004.05.02
Конвертация DBF в MSSQL


1-1081943575
Алексей2
2004-04-14 15:52
2004.05.02
Как "превратить" строку в имя переменной?:


1-1081804770
LORDMAXX
2004-04-13 01:19
2004.05.02
Как обратится из под Windows к секторам HDD





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский