Title: Tab Order Wizard for Delphi7
Question: Upgrades a previous Delphi5 article (www.delphi3000.com/articles/article_716.asp?SK=)
Answer:
unit TabWizard; //Adapted from http://www.delphi3000.com/articles/article_716.asp?SK=
interface
uses Classes, ToolsAPI;
type
pCompItem = ^TCompItem;
TCompItem = record
ParentName: string;
SelfName: string;
Left: Integer;
Top: Integer;
TabOrder: Integer;
Comp: IOTAComponent;
end;
type
TTabWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
private
CompList: TList;
procedure SortList;
procedure SetListOrder;
protected
procedure ChildrenCallBack(Param: pointer; aComp: IOTAComponent; var Result: boolean); // stdcall;
procedure MyEnumProc(aParm: pointer; aComp: IOTAComponent; var Result: boolean);
public // IOTAWizard methods
function GetIDString: string;
function GetName: string;
function GetState: TWizardState;
procedure Execute;
public // IOTAMenuWizard method
function GetMenuText: string;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterPackageWizard(TTabWizard.Create);
end;
function TTabWizard.GetName: string;
begin
Result := 'TabWizard';
end;
function TTabWizard.GetState: TWizardState;
begin
Result := [wsEnabled];
end;
function TTabWizard.GetIDString: String;
begin
Result := 'TabWizard';
end;
function TTabWizard.GetMenuText: string;
begin
Result := 'Tab Wizard';
end;
procedure TTabWizard.SetListOrder;
var
i: Integer;
intOrder: Integer;
pComp: pCompItem;
strPrevParentName: string;
begin
pComp := pCompItem(CompList.Items[0]);
pComp.TabOrder := 0;
strPrevParentName := pComp.ParentName;
intOrder := 0;
for i := 1 to pred(CompList.Count) do begin
pComp := pCompItem(CompList.Items[i]);
if pComp.ParentName = strPrevParentName then begin
inc(intOrder);
pComp.TabOrder := intOrder;
end
else begin
strPrevParentName := pComp.ParentName;
pComp.TabOrder := 0;
intOrder := 0;
end;
end;
end;
procedure TTabWizard.SortList;
var
i, j: Integer;
piComponent, pjComponent: pCompItem;
bolSameParent: Boolean;
begin
for i := 0 to pred(CompList.Count) do begin
piComponent := pCompItem(CompList.Items[i]);
bolSameParent := False;
for j := 0 to i - 1 do begin
pjComponent := pCompItem(CompList.Items[j]);
if pjComponent.ParentName piComponent.ParentName then begin
if bolSameParent then begin
CompList.Move(i, j);
Break;
end
end
else begin
if PiComponent.Top CompList.Move(i, j);
Break;
end
else begin
if PiComponent.Top = PjComponent.Top then begin
if PiComponent.Left CompList.Move(i, j);
Break;
end
end;
end;
bolSameParent := True;
end;
end;
end;
end;
procedure TTabWizard.ChildrenCallBack(Param: pointer; aComp: IOTAComponent; var Result: boolean);
var ParamComp: IOTAComponent absolute Param;
var pComp: pCompItem;
begin
if Assigned(aComp) then begin
New(pComp);
if Assigned(ParamComp) then
ParamComp.GetPropValueByName('Name', pComp.ParentName);
aComp.GetPropValueByName('Name', pComp.SelfName);
aComp.GetPropValueByName('Left', pComp.Left);
aComp.GetPropValueByName('Top', pComp.Top);
pComp.Comp := aComp;
CompList.Add(pComp);
aComp.GetChildren(pointer(aComp), ChildrenCallBack);
end;
Result := True;
end;
{}
procedure TTabWizard.MyEnumProc(aParm: pointer; aComp: IOTAComponent; var Result: boolean);
begin
Assert(Assigned(aComp));
aComp.GetChildren(pointer(aComp), ChildrenCallBack);
Result := True;
end;
procedure TTabWizard.Execute;
{}
procedure FreeCompList;
var i: Integer;
begin
for i := 0 to CompList.Count - 1 do
Dispose(CompList.Items[i]);
CompList.Free;
end;
{}
function ModuleIsForm(Module: IOTAModule): IOTAFormEditor;
var i: Integer;
begin
if Assigned(Module) //Form Module will have a DFM and a PAS file associated with it
AND(Module.GetModuleFileCount 1) then begin
i := 0;
while (i if (Module.ModuleFileEditors[i].QueryInterface(IOTAFormEditor, Result) = S_OK) then begin
EXIT; //
end;
inc(i);
end;
end;
Result := nil;
end;
{}
function GetFormEditor: IOTAFormEditor;
var ModuleServices: IOTAModuleServices; //from BorlandIDEServices
Module: IOTAModule;
i: Integer;
begin
ModuleServices := (BorlandIDEServices as IOTAModuleServices);
for i := 0 to pred(ModuleServices.ModuleCount) do begin
Module := ModuleServices.Modules[i];
Result := ModuleIsForm(Module);
if Assigned(Result) then
EXIT; //
end;
Result := nil;
end;
{}
var Editor: IOTAFormEditor;
RootComponent: IOTAComponent;
Cnt: integer;
begin{Execute}
Editor := GetFormEditor();
if Assigned(Editor) then try{finally}
CompList := TList.Create;
RootComponent := Editor.GetRootComponent;
RootComponent.GetChildren(pointer(RootComponent), MyEnumProc);
if CompList.Count 0 then begin
SortList;
SetListOrder;
for Cnt := 0 to pred(CompList.Count) do with pCompItem(CompList.Items[Cnt])^ do
Comp.SetPropByName('TabOrder', TabOrder);
RootComponent.GetChildren(pointer(RootComponent), MyEnumProc);
end;
finally
FreeCompList;
end; end;
end.