Mega Code Archive

 
Categories / Delphi / Forms
 

Adjust the Tab Order with the Wizard

Title: Adjust the Tab Order with the Wizard Question: How to use open tool api to set tab order? Answer: This time I show a wizard, which use Delphi Open Tools API to auto adjust tab order on a form. After the wizard has done, the tab order of all the control in the form will be set from left to right, from top to bottom. My friend Hong Liang writes this unit. I got the permit with him, you can use it freely. Here is the source code of Autotab.pas: unit AutoTab; interface uses Windows, Dialogs, ExptIntf, ToolIntf, FileCtrl, SysUtils, EditIntf, classes; type POrderComponent = ^TOrderComponent; TOrderComponent = record ParentName: string; SelfName: string; Left: Integer; Top: Integer; TabOrder: Integer; end; TAutoTab = class (TIExpert) private procedure SortList; //sort ComponentList procedure SetListOrder; //set TabOrder's value public function GetStyle: TExpertStyle; override; function GetName: string; override; function GetAuthor: string; override; function GetComment: string; override; function GetPage: string; override; function GetGlyph: HICON; override; function GetState: TExpertState; override; function GetIDString: string; override; function GetMenuText: string; override; procedure Execute; override; end; procedure Register; var ComponentList: TList; implementation procedure Register; begin RegisterLibraryExpert(TAutoTab.Create); end; function TAutoTab.GetStyle: TExpertStyle; begin Result := esStandard; end; function TAutoTab.GetName: String; begin Result := 'Auto Set TabOrder Wizard' end; function TAutoTab.GetAuthor: string; begin Result := 'LightHong'; end; function TAutoTab.GetComment: String; begin Result := 'First expert'; end; function TAutoTab.GetPage: string; begin Result := ''; end; function TAutoTab.GetGlyph: HICON; begin Result := 0; end; function TAutoTab.GetState: TExpertState; begin // always enabled, never checked Result := [esEnabled]; end; function TAutoTab.GetIDString: String; begin // must be unique Result := 'LightHong.BlankWizard' end; function TAutoTab.GetMenuText: String; begin Result := '&Auto Set TabOrder Wizard' end; function ChildrenCallBack(Param: Pointer; ComponentInterface: TIComponentInterface): Boolean stdcall; var pComponent: POrderComponent; begin if ComponentInterface nil then begin New(pComponent); pComponent.ParentName := string(Param); ComponentInterface.GetPropValueByName('Name', pComponent.SelfName); ComponentInterface.GetPropValueByName('Left', pComponent.Left); ComponentInterface.GetPropValueByName('Top', pComponent.Top); ComponentList.Add(pComponent); ComponentInterface.GetChildren(PChar(pComponent.SelfName), ChildrenCallBack); end; Result := True; end; function MyEnumProc(Param: Pointer; const FileName, UnitName, FormName: string): Boolean stdcall; var aFormModule: TIModuleInterface; aFormInterface: TIFormInterface; aFormComponent: TIComponentInterface; aChildComponent: TIComponentInterface; strFile, strName: string; i, j: Integer; PComponent: POrderComponent; begin if FormName = '' then begin Result := True; Exit; end; strFile := toolservices.getcurrentfile; strFile := ExtractFileName(strFile); Delete(strFile, Pos('.', strFile), Length(strFile) - Pos('.', strFile) + 1); if UnitName = strFile then begin aFormModule := ToolServices.GetFormModuleInterface(FormName); aFormInterface := aFormModule.GetFormInterface; aFormComponent := aFormInterface.GetFormComponent; aFormComponent.GetPropValueByName('Name', strName); if not Assigned(Param) then //?componentList; aFormComponent.GetChildren(PChar(strName), ChildrenCallBack) else begin //set componentlist order // showmessage('set order'); for i := 0 to ComponentList.Count - 1 do begin PComponent := POrderComponent(ComponentList.Items[i]); for j := 0 to aFormComponent.GetComponentCount - 1 do begin aChildComponent := aFormComponent.GetComponent(j); aChildComponent.GetPropValueByName('Name', strName); if PComponent.SelfName = strName then begin aChildComponent.SetPropByName('TabOrder', PComponent.TabOrder); Break; end; end; end; end; aFormModule.Free; aFormInterface.Free; aFormComponent.Free; end; Result := True; end; procedure FreeComponentList; var i: Integer; begin for i := 0 to ComponentList.Count - 1 do Dispose(ComponentList.Items[i]); ComponentList.Free; end; procedure TAutoTab.Execute; var Order: Pchar; begin New(Order); ComponentList := TList.Create; try ToolServices.EnumProjectUnits(MyEnumProc, nil); // showmessage('sort'); SortList; // showmessage('set'); SetListOrder; // showmessage('change'); ToolServices.EnumProjectUnits(MyEnumProc, Order); finally FreeComponentList; Dispose(Order); end; ShowMessage('Auto Set TabOrder Finished'); end; procedure TAutoTab.SetListOrder; var i: Integer; intOrder: Integer; PComponent: POrderComponent; strPrevParentName: string; begin if ComponentList.Count = 0 then Exit; PComponent := POrderComponent(ComponentList.Items[0]); PComponent.TabOrder := 0; strPrevParentName := PComponent.ParentName; intOrder := 0; for i := 1 to ComponentList.Count - 1 do begin PComponent := POrderComponent(ComponentList.Items[i]); if PComponent.ParentName = strPrevParentName then begin Inc(intOrder); PComponent.TabOrder := intOrder; end else begin strPrevParentName := PComponent.ParentName; PComponent.TabOrder := 0; intOrder := 0; end; end; end; procedure TAutoTab.SortList; var i, j: Integer; piComponent, pjComponent: POrderComponent; bolSameParent: Boolean; begin for i := 0 to ComponentList.Count - 1 do begin piComponent := POrderComponent(ComponentList.Items[i]); bolSameParent := False; for j := 0 to i - 1 do begin pjComponent := POrderComponent(ComponentList.Items[j]); if pjComponent.ParentName piComponent.ParentName then begin if bolSameParent then begin ComponentList.Move(i, j); Break; end end else begin if PiComponent.Top begin ComponentList.Move(i, j); Break; end else begin if PiComponent.Top = PjComponent.Top then begin if PiComponent.Left begin ComponentList.Move(i, j); Break; end end; end; bolSameParent := True; end; end; end; end; end. ( A little history about the unit: After I have finished my component TCcTab that translate Enter to Tab, I found to adjust tab order of a form manually cost me many time. If a program sort it, I can do little work. So I ask Hong Liang (English name LightHong) to write it, he does it. When I ask him to paste some articles in here, he said it's too difficult for him to write articles in English. So I do it. Hong Liang is very good at Component writing, Database, MIDAS, Open Tools API, you can connect it with lighthong@sina.com)