Componentes.Terceros.SDAC/internal/4.10.0.10/1/Source/Design/DAMenu.pas
2007-10-05 14:48:18 +00:00

646 lines
16 KiB
ObjectPascal

//////////////////////////////////////////////////
// DB Access Components
// Copyright @ 1998-2007 Core Lab. All right reserved.
// DAMenu
//////////////////////////////////////////////////
{$IFNDEF DAMENU_HEADER}
{$I Dac.inc}
unit DAMenu;
{$ENDIF}
interface
{$IFDEF VER7P}
{$WARN UNIT_DEPRECATED OFF}
{$ENDIF}
uses
{$IFDEF CLR}
System.Windows.Forms, Borland.Studio.ToolsAPI, WinUtils,
{$ELSE}
ToolsAPI, Menus,
{$ENDIF}
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
Graphics, Classes, SysUtils;
type
TDAMenu = class;
{$IFDEF CLR}
TAPIMenuItem = IOTAMenuItem;
TDAMenuClickSender = TObject;
TDAMenuClickEvent = procedure (Sender: TDAMenuClickSender; E: EventArgs) of object;
{$ELSE}
TAPIMenuItem = TMenuItem;
TDAMenuClickSender = TObject;
TDAMenuClickEvent = procedure (Sender: TDAMenuClickSender) of object;
{$ENDIF}
TDAMenuItem = class(TCollectionItem)
protected
FSubMenu: TDAMenu;
FCaption: string;
FName: string;
FVisible: boolean;
FNeedDestroyMenuItem: boolean;
FMenuItem: TAPIMenuItem;
procedure SetCaption(Value: string);
procedure SetVisible(Value: boolean);
public
constructor Create(DAMenu: TDAMenu; MenuItem: TAPIMenuItem); reintroduce; overload;
constructor Create(DAMenu: TDAMenu; Caption, Name: string; ClickEvent: TDAMenuClickEvent = nil; Index: integer = -1); reintroduce; overload;
destructor Destroy; override;
property SubMenu: TDAMenu read FSubMenu;
property Caption: string read FCaption write SetCaption;
property Name: string read FName;
property Visible: boolean read FVisible write SetVisible;
end;
TDAMenu = class(TCollection)
protected
FParentItem: TDAMenuItem;
FHInstance: HINST;
FMenuItems: TAPIMenuItem;
FProjectName: string;
FSubMenuProcessed: boolean;
FFAQName: string;
FWizardPosition: integer;
{$IFNDEF LITE}
procedure HelpItemClick(Sender: TDAMenuClickSender{$IFDEF CLR}; E: EventArgs{$ENDIF});
procedure FAQItemClick(Sender: TDAMenuClickSender{$IFDEF CLR}; E: EventArgs{$ENDIF});
{$ENDIF}
public
constructor Create(
ParentItem: TDAMenuItem;
const AProcessSubMenu: boolean = False);
destructor Destroy; override;
function AddSeparator: TDAMenuItem;
{$IFNDEF LITE}
function AddFAQ(Caption, Name, ProjectName {'Mydac', 'Oda', 'Sdac'}: string): TDAMenuItem;
function AddHelp(Caption, Name, ProjectName {'Mydac', 'Oda', 'Sdac'}: string): TDAMenuItem;
{$IFNDEF VER9P}
procedure AddWizard(Caption, Name: string; ClickEvent: TDAMenuClickEvent);
{$ENDIF}
{$ENDIF}
procedure AddWizards;
function Add(Caption, Name: string; ClickEvent: TDAMenuClickEvent = nil; Index: integer = -1): TDAMenuItem;
procedure ProcessSubMenu;
procedure GetSubMenu;
end;
TDAProductMenu = class(TDAMenu)
protected
{$IFDEF CLR}
FMenuItems: IOTAMainMenuService;
{$ENDIF}
FCRMenuName: string;
FServerMenuCaption: string;
FProductMenuCaption: string;
FAboutCaption: string;
FAboutName: string;
FAboutClickEvent: TDAMenuClickEvent;
FCRMenu: TDAMenuItem;
FHasProduct: boolean;
procedure Prepare;
function GetSubMenu: TDAMenu;
{$IFDEF VER9P}
property SubMenu: TDAMenu read GetSubMenu;
{$ENDIF}
public
constructor Create(const ACRMenuName, AAboutCaption, AAboutName: string;
const AServerMenuCaption: string; const AProductMenuCaption: string = ''); overload;
constructor Create; overload;
function AddItems(Instance: HINST): boolean; virtual;
function AddAbout: TDAMenuItem;
property CRMenuName: string read FCRMenuName;
property ServerMenuCaption: string read FServerMenuCaption;
property ProductMenuCaption: string read FProductMenuCaption;
{$IFNDEF VER9P}
property SubMenu: TDAMenu read GetSubMenu;
{$ENDIF}
end;
function RemoveAmpersands(RawCaption: string): string;
implementation
uses
{$IFDEF CLR}
Registry,
{$ENDIF}
{$IFDEF MSWINDOWS}
{$IFNDEF LITE}
DacVcl,
{$ENDIF}
{$ENDIF}
{$IFNDEF LITE}
ShellApi,
{$ENDIF}
{$IFNDEF VER6P}
ActiveX, comobj,
{$ENDIF}
{$IFNDEF LITE}
HelpUtils,
{$ENDIF}
Forms, Dialogs;
{ TDAMenuItem }
constructor TDAMenuItem.Create(DAMenu: TDAMenu; MenuItem: TAPIMenuItem);
begin
inherited Create(DAMenu);
FMenuItem := MenuItem;
FNeedDestroyMenuItem := False;
if FMenuItem <> nil then begin
FName := FMenuItem.Name;
FVisible := FMenuItem.Visible;
{$IFDEF CLR}
FCaption := FMenuItem.Text;
{$ELSE}
FCaption := FMenuItem.Caption;
{$ENDIF}
end;
FSubMenu := TDAMenu.Create(Self);
end;
constructor TDAMenuItem.Create(DAMenu: TDAMenu; Caption, Name: string; ClickEvent: TDAMenuClickEvent = nil; Index: integer = -1);
var
Bmp: Graphics.TBitmap;
{$IFDEF CLR}
MainMenu: TDAMenu;
bitmapHandle: IntPtr;
referenceItemName: string;
Location: OTAMenuItemLocation;
h: HBITMAP;
{$ENDIF}
MenuItem: TAPIMenuItem;
begin
Bmp := nil;
try
if (DAMenu <> nil) and (DAMenu.FHInstance <> 0) then begin
Bmp := Graphics.TBitmap.Create;
try
//Bmp.LoadFromResourceName(FHInstance, UpperCase(Name));
Bmp.LoadFromResourceName(DAMenu.FHInstance, UpperCase(Name));
//Bmp.LoadFromFile('d:\' + Name + '.bmp');
except
Bmp.Free; // Resource not found
Bmp := nil;
end;
end;
{$IFDEF CLR}
MainMenu := DAMenu;
while not (MainMenu is TDAProductMenu) do
MainMenu := TDAMenu(MainMenu.FParentItem.Collection);
if DAMenu.Count = 0 then begin
referenceItemName := DAMenu.FMenuItems.Name;
Location := OTAMenuItemLocation.otamlChild;
end
else
if (Index = -1) or (Index >= DAMenu.Count) then begin
referenceItemName := DAMenu.FMenuItems.ChildMenuItem(DAMenu.Count - 1).Name;
Location := OTAMenuItemLocation.otamlAfter;
end
else
begin
referenceItemName := DAMenu.FMenuItems.ChildMenuItem(Index).Name;
Location := OTAMenuItemLocation.otamlBefore;
end;
bitmapHandle := nil;
if Bmp <> nil then
try
h := Bmp.Handle;
bitmapHandle := IntPtr(Integer(h));
except
bitmapHandle := nil;
end;
MenuItem := TDAProductMenu(MainMenu).FMenuItems.AddMenuItem(
referenceItemName,
Location,
Name,
Caption,
bitmapHandle);
if Assigned(ClickEvent) then
Include(MenuItem.Executed, ClickEvent);
Create(DAMenu, MenuItem);
{$ELSE}
if Index = -1 then
Index := DAMenu.Count;
MenuItem := TAPIMenuItem.Create(nil);
MenuItem.Caption := Caption;
MenuItem.Name := Name;
MenuItem.OnClick := ClickEvent;
if Bmp <> nil then
MenuItem.ImageIndex := (BorlandIDEServices as INTAServices).AddMasked(Bmp, Bmp.TransparentColor);
DAMenu.FMenuItems.Insert(Index, MenuItem);
Create(DAMenu, MenuItem);
{$ENDIF}
FNeedDestroyMenuItem := True;
finally
Bmp.Free;
end;
end;
destructor TDAMenuItem.Destroy;
begin
FSubMenu.Free;
{$IFNDEF CLR}
if Assigned(FMenuItem) then begin
if FNeedDestroyMenuItem then
FMenuItem.Free
end;
{$ENDIF}
inherited Destroy;
end;
procedure TDAMenuItem.SetCaption(Value: string);
begin
{$IFDEF CLR}
FMenuItem.Text := Value;
{$ELSE}
FMenuItem.Caption := Value;
{$ENDIF}
end;
procedure TDAMenuItem.SetVisible(Value: boolean);
begin
FMenuItem.Visible := Value;
end;
{ TDAMenu }
constructor TDAMenu.Create(
ParentItem: TDAMenuItem;
const AProcessSubMenu: boolean = False);
{$IFDEF CLR}
procedure MainMenu;
var
MainMenu: IOTAMainMenuService;
begin
MainMenu := BorlandIDE.GetService(typeof(IOTAMainMenuService)) as IOTAMainMenuService;
Assert(Self is TDAProductMenu);
TDAProductMenu(Self).FMenuItems := MainMenu;
end;
{$ELSE}
procedure MainMenu;
var
MainMenu: TMenu;
begin
MainMenu := (BorlandIDEServices as INTAServices).GetMainMenu;
if MainMenu <> nil then
FMenuItems := MainMenu.Items
else
FMenuItems := nil;
end;
{$ENDIF}
begin
inherited Create(TDAMenuItem);
FWizardPosition := -1;
if ParentItem = nil then
MainMenu;
{$IFDEF CLR}
FParentItem := ParentItem;
if ParentItem = nil then
FMenuItems := TDAProductMenu(Self).FMenuItems.GetFirstMenuItem.ParentMenuItem
else
FMenuItems := ParentItem.FMenuItem;
{$ELSE}
if ParentItem <> nil then
FMenuItems := ParentItem.FMenuItem;
{$ENDIF}
if (FMenuItems <> nil) and AProcessSubMenu
(*{$IFDEF VER9P}and (ParentItem <> nil){$ENDIF}*) // bug with IOTAMenuItem.Count under CLR (DbxOda)
then
ProcessSubMenu;
end;
destructor TDAMenu.Destroy;
begin
Clear;
inherited;
end;
{$IFNDEF LITE}
procedure TDAMenu.HelpItemClick(Sender: TDAMenuClickSender{$IFDEF CLR}; E: EventArgs{$ENDIF});
var
HelpFile, JumpID: string;
begin
{$IFDEF VER8P}
HelpFile := 'ms-help://CoreLab.' + FProjectName;
JumpID := Format('ms-help://CoreLab.%s/%s/overview_%s.htm', [FProjectName, FProjectName, FProjectName]);
{$ELSE}
HelpFile := GetHelpFileName(FProjectName);
JumpID := 'Overview_' + FProjectName;
{$ENDIF}
ShowHelp(HelpFile, JumpID);
end;
{$ENDIF}
function TDAMenu.AddSeparator: TDAMenuItem;
var
guid: TGuid;
s, s1: string;
i, Cnt: integer;
begin
Result := nil;
if FMenuItems <> nil then begin
s := '-';
{$IFDEF CLR}
Cnt := FMenuItems.ChildCount;
{$ELSE}
Cnt := FMenuItems.Count;
{$ENDIF}
if FWizardPosition <> -1 then
Cnt := FWizardPosition - 1;
if Cnt > 0 then
{$IFDEF CLR}
s := FMenuItems.ChildMenuItem(Cnt - 1).Text;
{$ELSE}
s := FMenuItems.Items[Cnt - 1].Caption;
{$ENDIF}
if s = '-' then
Exit;
end;
{$IFDEF VER6P}
if CreateGuid(guid) <> 0 then
RaiseLastOSError;
{$ELSE}
if CoCreateGuid(guid) <> 0 then
RaiseLastWin32Error;
{$ENDIF}
s := GUIDToString(guid);
s1 := 'Separator';
for i := 1 to Length(s) do
case s[i] of
'0'..'9', 'a'..'z', 'A'..'Z':
s1 := s1 + s[i];
end;
Result := Add('-', s1);
end;
{$IFNDEF LITE}
function TDAMenu.AddFAQ(Caption, Name, ProjectName {'Mydac', 'Oda', 'Sdac'}: string): TDAMenuItem;
var
i: integer;
begin
Result := nil;
{$IFDEF VER8P}
FFAQName := ExtractFilePath(GetHelpFileName(ProjectName));
{$ELSE}
FFAQName := ExtractFilePath(Application.ExeName);
{$ENDIF}
i := Length(FFAQName) - 1;
while (i > 1) and (FFAQName[i] <> '/') and (FFAQName[i] <> '\') do
Dec(i);
if i < 3 then
Exit;
FFAQName := Copy(FFAQName, 1, i) {$IFNDEF VER8P}+ ProjectName{$ENDIF} + '\FAQ.html';
if FileExists(FFAQName) then
Result := Add(Caption, Name, FAQItemClick);
end;
procedure TDAMenu.FAQItemClick(Sender: TDAMenuClickSender{$IFDEF CLR}; E: EventArgs{$ENDIF});
begin
ShellExecute(0, 'open', {$IFDEF CLR}FFAQName{$ELSE}PChar(FFAQName){$ENDIF}, '', '', SW_SHOW);
end;
function TDAMenu.AddHelp(Caption, Name, ProjectName {'Mydac', 'Odac', 'Sdac'}: string): TDAMenuItem;
var
HelpFileName: string;
begin
FProjectName := ProjectName;
HelpFileName := GetHelpFileName(ProjectName);
if (ExtractFilePath(HelpFileName) = '') or (FileExists(HelpFileName)) then
Result := Add(Caption, Name, HelpItemClick)
else
Result := nil;
end;
{$IFNDEF VER9P}
procedure TDAMenu.AddWizard(Caption, Name: string; ClickEvent: TDAMenuClickEvent);
begin
TDAMenuItem.Create(Self, Caption, Name, ClickEvent, -1);
if FWizardPosition = -1 then
FWizardPosition := 0
end;
{$ENDIF}
{$ENDIF}
function TDAMenu.Add(Caption, Name: string; ClickEvent: TDAMenuClickEvent = nil; Index: integer = -1): TDAMenuItem;
begin
if (Index = -1) and (FWizardPosition <> -1) then begin
Index := FWizardPosition;
Inc(FWizardPosition);
end;
Result := TDAMenuItem.Create(Self, Caption, Name, ClickEvent, Index);
end;
procedure TDAMenu.ProcessSubMenu;
var
Skip: boolean;
i, j: integer;
MenuItem: TAPIMenuItem;
begin
if FMenuItems <> nil then begin
if not FSubMenuProcessed then
Clear
else
if FMenuItems.{$IFDEF WIN32}Count{$ELSE}ChildCount{$ENDIF} = Count then
Exit;
{$IFDEF CLR}
for i := 0 to FMenuItems.ChildCount - 1 do begin
MenuItem := FMenuItems.ChildMenuItem(i);
{$ELSE}
for i := 0 to FMenuItems.Count - 1 do begin
MenuItem := FMenuItems.Items[i];
{$ENDIF}
Skip := False;
if FSubMenuProcessed then
for j := 0 to Count - 1 do
if TDAMenuItem(Items[j]).Name = MenuItem.Name then begin
Skip := True;
Break;
end;
if Skip then
Continue;
TDAMenuItem.Create(Self, MenuItem);
FWizardPosition := 0;
end;
FSubMenuProcessed := True;
end;
end;
procedure TDAMenu.GetSubMenu;
var
i: integer;
MenuItem: TAPIMenuItem;
begin
if (FMenuItems <> nil) and not FSubMenuProcessed then begin
Clear;
{$IFDEF CLR}
for i := 0 to FMenuItems.ChildCount - 1 do begin
MenuItem := FMenuItems.ChildMenuItem(i);
TDAMenuItem.Create(Self, MenuItem);
end;
{$ELSE}
for i := 0 to FMenuItems.Count - 1 do begin
MenuItem := FMenuItems.Items[i];
TDAMenuItem.Create(Self, MenuItem);
end;
{$ENDIF}
FSubMenuProcessed := True;
end;
end;
procedure TDAMenu.AddWizards;
begin
FWizardPosition := -1;
end;
{ TDAProductMenu }
constructor TDAProductMenu.Create(const ACRMenuName, AAboutCaption,
AAboutName: string; const AServerMenuCaption: string;
const AProductMenuCaption: string = '');
begin
inherited Create(nil, True);
FCRMenuName := ACRMenuName;
FAboutCaption := AAboutCaption;
FAboutName := AAboutName;
FServerMenuCaption := AServerMenuCaption;
FProductMenuCaption := AProductMenuCaption;
{$IFNDEF VER9P}
Prepare;
{$ENDIF}
end;
constructor TDAProductMenu.Create;
begin
inherited Create(nil, True);
end;
procedure TDAProductMenu.Prepare;
var
ThirdParty: TDAMenuItem;
i: integer;
UsedCaption: string;
begin
ThirdParty := nil;
for i := 0 to Count - 1 do begin
if TDAMenuItem(Items[i]).Name = FCRMenuName then begin
FCRMenu := TDAMenuItem(Items[i]);
SubMenu.ProcessSubMenu;
if SubMenu.Count > 0 then
SubMenu.AddSeparator;
Break;
end
else
if (FProductMenuCaption <> '') and (UpperCase(RemoveAmpersands(TDAMenuItem(Items[i]).Caption)) =
UpperCase(RemoveAmpersands(FServerMenuCaption))) then
ThirdParty := TDAMenuItem(Items[i]);
end;
FHasProduct := False;
if ThirdParty = nil then
UsedCaption := FServerMenuCaption
else
UsedCaption := FProductMenuCaption;
if FCRMenu = nil then
FCRMenu := Add(UsedCaption, FCRMenuName, nil, Count - 1{$IFDEF VER9P}{$IFNDEF CLR} - 1{$ENDIF}{$ENDIF})
else begin
FCRMenu.Caption := UsedCaption;
{$IFDEF VER9P}
for i := 0 to SubMenu.Count - 1 do
if RemoveAmpersands(TDAMenuItem(SubMenu.Items[i]).Caption) =
RemoveAmpersands(FAboutCaption) then begin
FHasProduct := True;
Break;
end;
{$ENDIF}
end;
end;
function TDAProductMenu.AddItems(Instance: HINST): boolean;
begin
FHInstance := Instance;
Result := False;
ProcessSubMenu;
{$IFDEF VER9P}
Prepare;
{$ENDIF}
if not FHasProduct then begin
FHInstance := Instance;
SubMenu.FHInstance := Instance;
SubMenu.AddSeparator;
Result := True;
FHasProduct := True;
end
{$IFDEF VER9P}
else
AddAbout.Visible := False
{$ENDIF}
end;
function TDAProductMenu.GetSubMenu: TDAMenu;
begin
Result := FCRMenu.SubMenu;
end;
function TDAProductMenu.AddAbout: TDAMenuItem;
begin
Result := SubMenu.Add(FAboutCaption, FAboutName, FAboutClickEvent);
end;
function RemoveAmpersands(RawCaption: string): string;
var
i: integer;
begin
Result := '';
i := 1;
while i <= Length(RawCaption) do begin
if RawCaption[i] = '&' then begin
Inc(i);
if i > Length(RawCaption) then
Break;
end;
Result := Result + RawCaption[i];
Inc(i);
end;
end;
end.