Hola mi amigo.
Cita:
Empezado por newtron
Hola a tod@s.
Hay una aplicación en VB6 de la cual tengo, desde mi programa delphi, que leer y escribir strings desde y hacia unos controles de texto. He estado echando un vistazo y este hilo que resuelve el amigo ecfisa hace más de lo que me hace falta pero la verdad es que se me hace un poco espeso de descifrar.
|
No creo que haya soluciónes triviales para resolver lo que buscas...
Estuve pensando como podría simplificar el código del mensaje que citas mas (
arriba), y se me ocurre que lo mas adecuado es encapsularlo en una clase y ponerlo en una unidad, eso tal vez no lo haga mas simple, pero le dá seguridad, reusabilidad y claridad en su utilización.
Código Delphi
[-]
unit uChildWndText;
interface
uses Windows, SysUtils, Classes, Messages;
type
TChildWndText = class
private
FParentHandle: HWND;
FWndList: TStrings;
FWndText : array[0..8192] of Char;
function FGetText(Index: Integer): string;
procedure FSetText(Index: Integer; Value: string);
public
constructor Create(const WndParentName: string);
destructor Destroy; override;
property WindowList : TStrings read FWndList;
property ChildrenText[Index: Integer]: string read FGetText write FSetText;
end;
implementation
function CallbackFn(aHandle: HWND; WndList: TStrings): LongBool; stdcall;
var
bufName: array[0..255] of Char;
begin
Result := True;
if GetClassName(aHandle, bufName, 256) <> 0 then
WndList.AddObject(bufName, TObject(aHandle));
end;
constructor TChildWndText.Create(const WndParentName: string);
begin
inherited Create;
FParentHandle := FindWindow(nil, PChar(WndParentName));
if FParentHandle = 0 then
raise Exception.Create('No se encontró una ventana con ese título');
FWndList := TStringList.Create;
EnumChildWindows(FParentHandle, @CallbackFn, LPARAM(FWndList));
end;
destructor TChildWndText.Destroy;
begin
FWndList.Free;
inherited;
end;
function TChildWndText.FGetText(Index: Integer): string;
begin
if (Index < 0) or (Index > FWndList.Count-1) then
raise Exception.Create('Índice fuera de rango');
SendMessage(HWND(FWndList.Objects[Index]),
WM_GETTEXT, SizeOf(FWndText), Integer(@FWndText));
Result := FWndText;
end;
procedure TChildWndText.FSetText(Index: Integer; Value: string);
begin
if (Index < 0) or (Index > FWndList.Count-1) then
raise Exception.Create('Índice fuera de rango');
if Value <> FWndList[Index] then
begin
StrPCopy(FWndText, Value);
SendMessage(HWND(FWndList.Objects[Index]),
WM_SETTEXT, SizeOf(FWndText), Integer(@FWndText));
end;
end;
end.
Eso te permite, por ejemplo, cargarlo en un ComboBox como en el enlace que mencionas:
Código Delphi
[-]
...
implementation
uses uChildWndText;
var
ChildText : TChildWndText;
procedure TForm1.FormCreate(Sender: TObject);
begin
ChildText := TChildWndText.Create('Form1');
ComboBox1.Items.Assign(ChildText.WindowList);
ComboBox1.ItemIndex := 0;
end;
procedure TForm1.btnGetTextClick(Sender: TObject);
begin
Memo1.Text := ChildText.ChildrenText[ComboBox1.ItemIndex];
end;
procedure TForm1.btnSetTextClick(Sender: TObject);
begin
ChildText.ChildrenText[ComboBox1.ItemIndex] := Memo1.Text;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ChildText.Free;
end;
Pero si conoces los nombres, como mencionas, también de forma directa:
Código Delphi
[-]
procedure TForm1.Button1Click(Sender: TObject);
var
inx: Integer;
str: string;
begin
str:= 'NUEVO TEXTO';
with TChildWndText.Create('Form1') do
try
inx := WindowList.IndexOf('TEdit');
if MessageDlg(Format('Texto actual: %s ¿ Cambia por: %s ?',
[ChildrenText[inx],str]), mtConfirmation, [mbYes,mbNo],0) = mrYes then
ChildrenText[inx]:= 'Nuevo Texto';
finally
Free;
end;
end;
También te puede venir muy bién la sugerencia de
escafandra que hace uso de la posición del mouse y te ahorra la enumeración al hacer la selección de forma directa.
Saludos
