Hola,
Ejem... pero, esto no es nuevo... quiero decir, lo que hace "CnPack" y otros "expertos" es usar la API que ofrece Delphi, precisamente, para que este tipo de programas puedan interactuar con el propio entorno. Este API tiene el nombre de "Open Tools API", y, por ejemplo,
en Delphi.About se encuentran varios artículos al respecto.
Así que la función "IdeSetEditorSelectedLines()" probablemente pertenece a "CnPack" y hace uso de las interfaces que proporciona la "Open Tools API" para hacer su trabajo. Lo que sí es cierto es que impresiona, es decir, cuando yo supe de esto también vi un montón de posibilidades... y, bueno, ahí está "CnPack", por ejemplo, para demostrar que esto es así.
Hace tiempo escribí ciertos "Expertos del ClubDelphi" que no llegué a publicar nunca, y que, precisamente, hacen cierto uso de la "Open Tools API" de Delphi. Adjunto los archivos que tengo por aquí guardados. Y copio a continuación el contenido de una unidad que llamé en un arrebato de originalidad "UtilesIDE.pas":
Código Delphi
[-]
unit UtilesIDE;
interface
uses
Menus, ExtCtrls, ToolsApi;
type
TUtilesIDE = class(TObject)
private
class function EditorActivo(): IOTASourceEditor;
class function BloqueEditorActivo(): IOTAEditBlock;
public
class function MenuPrincipalIDE(): TMainMenu;
class function ControlBarPrincipalIDE(): TControlBar;
class function TextoSeleccionadoEditorActivo(): string;
end;
implementation
uses
SysUtils;
class function TUtilesIDE.MenuPrincipalIDE(): TMainMenu;
var
serviciosNTA: INTAServices;
begin
if Supports(BorlandIDEServices,
INTAServices, serviciosNTA) then
result := serviciosNTA.MainMenu
else
result := nil;
end;
class function TUtilesIDE.ControlBarPrincipalIDE(): TControlBar;
var
i: integer;
begin
result := nil;
if Assigned(MenuPrincipalIDE()) then begin
for i := 0 to MenuPrincipalIDE().Owner.ComponentCount-1 do begin
if (MenuPrincipalIDE().Owner.Components[i] is TControlBar) then begin
result := (MenuPrincipalIDE().Owner.Components[i] as TControlBar);
break;
end;
end;
end;
end;
class function TUtilesIDE.TextoSeleccionadoEditorActivo(): string;
begin
result := '';
if Assigned(BloqueEditorActivo()) then
begin
if BloqueEditorActivo().IsValid then
result := BloqueEditorActivo().Text;
end;
end;
class function TUtilesIDE.BloqueEditorActivo(): IOTAEditBlock;
begin
result := nil;
if Assigned(EditorActivo()) then
begin
if (EditorActivo().EditViewCount > 0) then begin
if Assigned(EditorActivo().EditViews[0]) then
result := EditorActivo().EditViews[0].Block;
end;
end;
end;
class function TUtilesIDE.EditorActivo(): IOTASourceEditor;
var
serviciosModulos: IOTAModuleServices;
begin
result := nil;
if Supports(BorlandIDEServices,
IOTAModuleServices, serviciosModulos) then
begin
if Assigned(serviciosModulos.CurrentModule) then begin
if Assigned(serviciosModulos.CurrentModule.CurrentEditor) then begin
if ((serviciosModulos.CurrentModule.CurrentEditor as IOTASourceEditor).EditViewCount > 0) then
result := (serviciosModulos.CurrentModule.CurrentEditor as IOTASourceEditor);
end;
end;
end;
end;
end.
PD. Se me olvidó comentar que todo lo que yo usé de "Tools API", si no recuerdo mal, se basó en la Jedi Library, es decir, que, en alguna de las unidades conque se cuenta en la "JCL", se encuentran implementadas no pocas funciones y procedimientos que nos pueden servir como interfaz de la interfaz, es decir, que nos hacen más sencillo trabajar con "ToolAPI".