实现MyIE的效果,使用下面的吧。把它存成一个Pas文件,然后创建一个Package,包含这个
文件,安装就行了,只需设置Align。
=================================================================
unit MdiTabs;
interface
uses
Windows, Messages, Classes, Controls, Graphics, Forms,
CommCtrl, ComCtrls, ImgList;
type
{ TMDITabs }
TMDITabOption = (amtCaption, amtIcon);
TMDITabOptions = set of TMDITabOption;
TMDITabs = class(TCustomTabControl)
private
FFormIconImages: TImageList;
FClientInstance: TFarProc;
FClientHandle: HWND;
FDefClientProc: TFarProc;
FOwnerForm: TForm;
FSyncTabs: Boolean;
FDestroyingChild: TForm;
FOptions: TMDITabOptions;
procedure AddFormIcon(AForm: TForm);
procedure MDIChildCreated;
procedure MDIChildDestroyed;
procedure MDIChildActivated;
procedure MDIClientProc(var Message: TMessage);
procedure SubClassMDIClient;
procedure SetOptions(const Value: TMDITabOptions);
protected
function CanChange: Boolean; override;
procedure Change; override;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property DisplayRect;
procedure RefreshTabs;
published
property Align default alTop;
property Anchors;
property BevelEdges;
property BevelKind;
property BevelInner;
property BevelOuter;
property BiDiMode;
property Constraints;
property Enabled;
property Font;
property HotTrack;
property MultiLine;
property MultiSelect;
property OwnerDraw;
property ParentBiDiMode;
property Options: TMDITabOptions read FOptions write SetOptions
default [amtCaption, amtIcon];
property ParentFont;
property ParentShowHint;
property PopupMenu;
property RaggedRight;
property ScrollOpposite;
property ShowHint;
property Style default tsButtons;
property TabHeight;
property TabOrder;
property TabPosition;
property TabStop;
property TabWidth;
property Visible;
property OnChange;
property OnChanging;
property OnContextPopup;
property OnDrawTab;
property OnEnter;
property OnExit;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnResize;
end;
procedure Register;
implementation
const
sErrorOwnerMDIFormExpected = 'FormStyle 必须为 fsMDIForm';
procedure Register;
begin
RegisterComponents('WolfSoft', [TMdiTabs]);
end;
constructor TMDITabs.Create(AOwner: TComponent);
begin
inherited;
if (AOwner is TForm) then
if (TForm(AOwner).FormStyle = fsMDIForm) then
inherited Align := alClient
else
raise EComponentError.Create(sErrorOwnerMDIFormExpected)
else
raise EComponentError.Create(sErrorOwnerMDIFormExpected);
FOwnerForm := TForm(AOwner);
Align := alTop;
FFormIconImages := TImageList.Create(Self);
Images := FFormIconImages;
Style := tsButtons;
Height := 23;
FOptions := [amtCaption, amtIcon];
end;
destructor TMDITabs.Destroy;
begin
Destroying;
SetWindowLong(FClientHandle, GWL_WNDPROC, Longint(FDefClientProc));
FreeObjectInstance(FClientInstance);
Images := nil;
FFormIconImages.Free;
inherited;
end;
procedure TMDITabs.Loaded;
begin
inherited Loaded;
if FClientHandle = 0 then
if not (csDesigning in ComponentState) then
SubClassMDIClient;
end;
procedure TMDITabs.SubClassMDIClient;
begin
FClientHandle := FOwnerForm.ClientHandle;
FClientInstance := MakeObjectInstance(MDIClientProc);
FDefClientProc := Pointer(GetWindowLong(FClientHandle, GWL_WNDPROC));
SetWindowLong(FClientHandle, GWL_WNDPROC, Longint(FClientInstance));
end;
procedure TMDITabs.MDIClientProc(var Message: TMessage);
var
i: integer;
begin
if Message.Msg = WM_MDIDESTROY then
for i := 0 to Tabs.Count - 1 do
if TForm(Tabs.Objects).Handle = THandle(Message.wParam) then
begin
FDestroyingChild := TForm(Tabs.Objects);
Break;
end;
Message.Result := CallWindowProc(FDefClientProc, FClientHandle, Message.Msg, Message.WParam, Message.LParam);
case Message.Msg of
WM_MDICREATE:
MDIChildCreated;
WM_MDIDESTROY:
MDIChildDestroyed;
WM_MDIACTIVATE, WM_SETFOCUS:
MDIChildActivated;
end;
end;
procedure TMDITabs.AddFormIcon(AForm: TForm);
var
tempIcon: TIcon;
begin
if (AForm.Icon <> nil) and not AForm.Icon.Empty then
FFormIconImages.AddIcon(AForm.Icon)
else if (Application.Icon <> nil) and not Application.Icon.Empty then
FFormIconImages.AddIcon(Application.Icon)
else
begin
tempIcon := TIcon.Create;
try
tempIcon.Handle := LoadIcon(MainInstance, 'MAINICON');
if tempIcon.Handle = 0 then
tempIcon.Handle := LoadIcon(0, IDI_APPLICATION);
FFormIconImages.AddIcon(tempIcon);
finally
tempIcon.Free;
end;
end;
end;
procedure TMDITabs.MDIChildCreated;
var
ChildForm: TForm;
begin
FSyncTabs := True;
with FOwnerForm do
if MDIChildCount > Tabs.Count then
begin
ChildForm := MDIChildren[MDIChildCount - 1];
if amtCaption in Options then
Tabs.AddObject(ChildForm.Caption, ChildForm)
else
Tabs.AddObject('', ChildForm);
if amtIcon in Options then
AddFormIcon(ChildForm);
TabIndex := Tabs.Count - 1;
end;
FSyncTabs := False;
end;
procedure TMDITabs.MDIChildDestroyed;
var
i: integer;
begin
FSyncTabs := True;
for i := 0 to Tabs.Count do
if TForm(Tabs.Objects) = FDestroyingChild then
begin
Tabs.Delete(i);
Perform(TCM_REMOVEIMAGE, i, 0);
Break;
end;
FSyncTabs := False;
end;
procedure TMDITabs.MDIChildActivated;
var
i: integer;
begin
FSyncTabs := True;
for i := 0 to Tabs.Count - 1 do
if TForm(Tabs.Objects) = FOwnerForm.ActiveMDIChild then
begin
TabIndex := i;
Break;
end;
FSyncTabs := False;
end;
procedure TMDITabs.Change;
begin
if not FSyncTabs then
begin
if (TabIndex > -1) and (TabIndex < FOwnerForm.MDIChildCount) then
with TForm(Tabs.Objects[TabIndex]) do
begin
if WindowState = wsMinimized then
WindowState := wsNormal;
BringToFront;
SetFocus;
end;
inherited;
end;
end;
function TMDITabs.CanChange: Boolean;
begin
if FSyncTabs then
Result := True
else
Result := inherited CanChange;
end;
procedure TMDITabs.RefreshTabs;
var
i: integer;
begin
FFormIconImages.Clear;
for i := 0 to Tabs.Count - 1 do
begin
if amtCaption in Options then
Tabs := TForm(Tabs.Objects).Caption
else
Tabs := '';
if amtIcon in Options then
AddFormIcon(TForm(Tabs.Objects));
end;
end;
procedure TMDITabs.SetOptions(const Value: TMDITabOptions);
begin
if Value <> FOptions then
begin
FOptions := Value;
if [csDesigning, csLoading] * ComponentState = [] then
RefreshTabs;
end;
end;
end.