Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Leer Edit de otro formulario usando INI (https://www.clubdelphi.com/foros/showthread.php?t=92910)

Dark_Code 11-03-2018 16:49:38

Leer Edit de otro formulario usando INI
 
Hola a todos, quisiera que me ayuden con este problema, lo que quiero hacer es que desde una Consola me lea un edit de otro form aparte.

El código que uso en mi consola es este:

Código:

try
    hkexample:=  leCadINI ('World','example','');
begin
      if hkexample= '1' then
        Pdword(Examen)^:= 456789456;
      end;

En ves del valor asignado "456789456" quiero que me lea el valor de un Edit en el form que tengo.

Las activaciones en mi form lo hago de esta manera en un botón

Código:

procedure TForm1.btn1Click(Sender: TObject);
begin
esEntINI('World','example',1);
end;
end.

Y las funciones que tengo son estas:

Código:

//Lee un booleano de un INI
function leBoolINI (clave, cadena : string; defecto : boolean) : boolean;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := readbool (clave, cadena, defecto);
  finally
    free;
  end;
end;


//Lee un entero de un INI
function leEntINI (clave, cadena : string; defecto : integer) : integer;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := readInteger (clave, cadena, defecto);
  finally
    free;
  end;
end;


//Lee una cadena de texto de un INI
function leCadINI (clave, cadena : string; defecto : string) : string;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := readString (clave, cadena, defecto);
  finally
    free;
  end;
end;

//lee una fecha de un INI
function leFechaINI (clave, cadena : string; defecto : tdatetime) : tdatetime;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := ReadDate (clave, cadena, defecto);
  finally
    free;
  end;
end;

//lee un valor numérico de un INI
function leFloatINI (clave, cadena : string; defecto : double) : double;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := readfloat (clave, cadena, defecto);
  finally
    free;
  end;
end;


//escribe un Booleano en un INI
procedure esBoolINI (clave, cadena : string; valor : boolean);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    writeBool (clave, cadena, valor);
  finally
    free;
  end;
end;


//Escribe un entero en un INI
procedure esEntINI (clave, cadena : string; valor : integer);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    writeInteger (clave, cadena, valor);
  finally
    free;
  end;
end;


//escribe una cadena de texto en un INI
procedure esCadINI (clave, cadena, valor : string);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    writeString (clave, cadena, valor);
  finally
    free;
  end;
end;


//escribe un número en un INI
procedure esFloatINI (clave, cadena : string; valor : double);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    WriteFloat (clave, cadena, valor);
  finally
    free;
  end;
end;


//escribe una fecha en un INI
procedure esFechaINI (clave, cadena : string; defecto : tdatetime);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    WriteDate (clave, cadena, defecto);
  finally
    free;
  end;
end;

Espero de su ayuda, que función tengo que usar y como. Muchas Gracias.

malditango 11-03-2018 21:12:23

en tu code no veo como accedas al fichero, ni leCadINI ni esEntINI
with tinifile.create (changefileext(paramstr(0),'.INI')) do // aqui crea el archivo pero no se en que ubicacion

Casimiro Notevi 11-03-2018 21:20:38

Cita:

Empezado por malditango (Mensaje 525047)
en tu code no veo como accedas al fichero, ni leCadINI ni esEntINI
with tinifile.create (changefileext(paramstr(0),'.INI')) do // aqui crea el archivo pero no se en que ubicacion

Recuerda poner las etiquetas al código, porque ahí no se entiende nada.


Dark_Code 12-03-2018 17:27:35

Cita:

Empezado por malditango (Mensaje 525047)
en tu code no veo como accedas al fichero, ni leCadINI ni esEntINI
with tinifile.create (changefileext(paramstr(0),'.INI')) do // aqui crea el archivo pero no se en que ubicacion

La función que uso en la Consola es este:

Código:

function leCadINI (clave, cadena : string; defecto : string) : string;
begin
  with TiniFile.Create ('c:\Fichero.ini') do
  try
    result := readString (clave, cadena, defecto);
  finally
    free;
  end;
end;

Y en el form utilizo la siguiente función:

Código:

//Lee una cadena de texto de un INI
function leCadINI (clave, cadena : string; defecto : string) : string;
begin
  with TiniFile.Create ('c:\Fichero.ini') do
  try
    result := readString (clave, cadena, defecto);
  finally
    free;
  end;
end;

//Escribe un entero en un INI
procedure esEntINI (clave, cadena : string; valor : integer);
begin
  with TiniFile.Create ('c:\Fichero.ini') do
  try
    writeInteger (clave, cadena, valor);
  finally
    free;
  end;
end;

Espero de su ayuda, Gracias.

escafandra 13-03-2018 00:10:56

Código Delphi [-]
function GetWindowText(Handle: THANDLE): AnsiString;
var
  Buffer: array [0..255] of AnsiCHAR;
begin
  SendMessage(Handle, WM_GETTEXT, 255, Cardinal(@Buffer[0]));
  Result:= Buffer;
end;


Saludos.

Dark_Code 13-03-2018 17:31:02

Cita:

Empezado por escafandra (Mensaje 525057)
Código Delphi [-]
function GetWindowText(Handle: THANDLE): AnsiString;
var
  Buffer: array [0..255] of AnsiCHAR;
begin
  SendMessage(Handle, WM_GETTEXT, 255, Cardinal(@Buffer[0]));
  Result:= Buffer;
end;


Saludos.

En este caso como usaría la función ?, como haria para que me lea el edit de mi otro form ?

Código:

if hkexample= '1' then
        Pdword(Examen)^:= 456789456;
      end;

En ves de este valor "456789456" quiero que me lea el valor que agrego en mi edit que esta en mi form.

escafandra 13-03-2018 19:34:24

Cita:

Empezado por Dark_Code (Mensaje 525069)
En este caso como usaría la función ?, como haria para que me lea el edit de mi otro form ?

Pues depende si ambos formularios son o no se tu aplicación. Si lo son, no es ni cesarario el código que expongo. En caso contrario debes conocer el handle de la ventana cuyo texto quieres leer. ¿Ese Edit es de un programa escrito en Delphi? ¿Como lo distingues? ¿Te sirve encontrarlo con un click de ratón? ¿Que funcionalidad precisas?.
En fin, tu sabes las respuestas y lo que quieres hacer.

Saludos

Dark_Code 19-03-2018 20:02:41

Cita:

Empezado por escafandra (Mensaje 525071)
Pues depende si ambos formularios son o no se tu aplicación. Si lo son, no es ni cesarario el código que expongo. En caso contrario debes conocer el handle de la ventana cuyo texto quieres leer. ¿Ese Edit es de un programa escrito en Delphi? ¿Como lo distingues? ¿Te sirve encontrarlo con un click de ratón? ¿Que funcionalidad precisas?.
En fin, tu sabes las respuestas y lo que quieres hacer.

Saludos

Pueden revisar mi source y hacerlo como deseo.

https://www.sendspace.com/file/evlja6

Disculpen a todos en General por subir el archivo por este medio, solo que no tengo el rango suficiente para subir archivos en este Club.

Gracias a todos por su comprensión :D

escafandra 19-03-2018 22:24:08

Una primera aproximación consistiría en usar archivos de memoria compartida y un hilo en tu dll que los lea continuamente. Más sofisticado sería los mensajes entre threads con PostThreadMessage o la inyección directa cosa que no está en este momento a tu alcance.

Vamos a ver un ejemplo sencillo compartiendo memoria:

Lo siguiente es una clase para facilitar compartir memoria entre procesos:
Código Delphi [-]
unit SharedMemory;

interface

uses
  Windows;


type
  TModos = (mServer, mClient);

  TSharedMemory = class
  private
    Modo: TModos;
    hMap: THANDLE;       //Server
    DataMap: THANDLE;    //Client
    Name: array [0..MAX_PATH] of char;

  public
    Buffer: Pointer;
    constructor Create(MappName: PCHAR; SizeData: DWORD = 0);
    destructor  Destroy; override;
  end;

implementation

procedure MessageError(Title: PCHAR);
var
   pBuffer: pointer;
begin
   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, nil,
   GetLastError, 0, @pBuffer, 0, nil );
   MessageBox(0, pBuffer, Title, MB_OK);
   LocalFree(Cardinal(pBuffer));
end;


constructor TSharedMemory.Create(MappName: PCHAR; SizeData: DWORD);
begin
  lstrcpy(@Name[0], PCHAR(MappName));
  if SizeData <> 0 then
  begin
    Modo:= mServer;
    hMap:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeData, Name);

    // Si el fichero de memoria compartida ya existe, lo cierro.
    if (hMap <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) then
    begin
      CloseHandle(hMap);
      hMap:= 0;
    end;
  end
  else
    Modo:= mClient;

  // Inicializa
  Buffer:= nil;
  DataMap:= 0;

  DataMap:= OpenFileMapping(FILE_MAP_ALL_ACCESS, false, Name);
  if DataMap <> 0 then
    Buffer:= MapViewOfFile(DataMap, FILE_MAP_ALL_ACCESS, 0, 0, 0)
  else
    MessageError('ERROR');

end;

destructor TSharedMemory.Destroy;
begin
  if Buffer <> nil then
    UnmapViewOfFile(Buffer);

  CloseHandle(DataMap);

  if (hMap <> 0) and (Modo = mServer) then
    CloseHandle(hMap);
end;


end.

Ahora el código de tu dll:
Código Delphi [-]
library Project1;


uses
  SysUtils,
  Windows,
  Classes,
  Unit2 in 'Unit2.pas',
  SharedMemory in 'SharedMemory.pas';

{$R *.res}
var
  AtProcessobymr: THandle;
  hId:Cardinal;

  Memory: TSharedMemory;


procedure TrainerFarius;
begin
 while(true) do
 begin
   Sleep(100);
   PDWORD($A04569)^:= PDWORD(Memory.Buffer)^;
 end;
end;

begin
  Memory:= TSharedMemory.Create('_Mi_Memoria_', sizeof(Pointer));
  // Creamos un hilo para la ejecución de TrainerFarius
  CreateThread(nil, 0, @TrainerFarius, nil, 0, PDWORD(0)^);
end.

Y el formulario que envía el dato compartido:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,INIFiles,Unit2, SharedMemory, TLHelp32;

type
  TForm1 = class(TForm)
    edt1: TEdit;
    btn1: TButton;
    lbl1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure btn1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    Memory: TSharedMemory;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
var
  Key:Tinifile;
begin
  Memory:= TSharedMemory.Create('_Mi_Memoria_', sizeof(DWORD));
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  Val: DWORD;
begin
  Val:= StrToInt(Edt1.Text);
  CopyMemory(Memory.Buffer, @Val, sizeof(DWORD));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Memory.Free;
end;

end.

El ejemplo es un esbozo pero es funcional.
Ahora vienes las preguntas del millón ¿Donde quieres inyectar esa dll? ¿Sabes hacerlo?


Saludos.

Dark_Code 22-03-2018 01:05:38

Cita:

Empezado por escafandra (Mensaje 525165)
Una primera aproximación consistiría en usar archivos de memoria compartida y un hilo en tu dll que los lea continuamente. Más sofisticado sería los mensajes entre threads con PostThreadMessage o la inyección directa cosa que no está en este momento a tu alcance.

Vamos a ver un ejemplo sencillo compartiendo memoria....

Saludos.

Muchas Gracias por la atención prestada, y por el compartimiento de su conocimiento. pero lo que quería hacer es a base de INI una manera mas practica, investigando mucho logre hacerlo.

Primero creamos un form donde guardaremos el contenido de un Edit en un fichero INI:

- Creamos el Fichero INI.

Código Delphi [-]
uses
IniFiles;
.........

procedure TForm1.FormCreate(Sender: TObject);
var
Key:Tinifile;
begin
Key:= TiniFile.Create ('c:\Prueba.ini');
Key.EraseSection('WT Prueba');
end;

- Guardamos el contenido de un Edit en un INI a traves de un boton.
Código Delphi [-]
procedure TForm1.btn1Click(Sender: TObject);
begin
Key.WriteString ('WT Prueba','personajes',edt1.text);
end;
end.

Para leer el INI del Edit que hemos guardado, hacemos lo siguiente en otro form.

-Utilizaremos este Unit.


Código Delphi [-]
unit Unit2;

interface
function leEntINI (clave, cadena : string; defecto : integer) : integer;

implementation
uses SysUtils,Classes,INIFiles;


//Lee un entero de un INI
function leEntINI (clave, cadena : string; defecto : integer) : integer;
begin
  with TiniFile.Create ('C:\Prueba.ini') do
  try
    result := readInteger (clave, cadena, defecto);
  finally
    free;
  end;
end;
end.

Ahora colocaremos un Edit para que nos muestre el valor obtenido del INI y un botón.

Código Delphi [-]
uses
INIFiles,Unit2;
.......
.........
procedure TForm1.btn1Click(Sender: TObject);
var
ValorINI:Integer;
begin
ValorINI:=  leEntINI ('WT Prueba','personajes',0);
edt1.Text:= IntToStr(ValorINI);
end;
end.

Todo va perfecto, En el primer exe se guarda muy bien el valor de Edit en un fichero INI, y en el segundo exe se muestra el valor guardado.

Ahora lo que quiero hacer es editar con el valor guardado del Edit en una DLL, lo estoy haciendo de esta forma, pero esta mal en la forma de editar
Código Delphi [-]
PDWORD($A04569)^:= ValorINI;
, espero de su ayuda.

Código Delphi [-]
library Project1;


uses
  SysUtils,
  Windows,
  Classes,
  IniFiles,
  Unit2 in 'XD/Unit2.pas';

{$R *.res}
var
AtProcessobymr:THandle;
hId:Cardinal;
ValorINI:Integer;
procedure TrainerFarius;
begin
  ValorINI:=  leEntINI('WT Prueba','personajes',0);
  PDWORD($A04569)^:= ValorINI;
end;
begin
AtProcessobymr:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
CreateRemoteThread(AtProcessobymr,nil,0,@TrainerFarius,@TrainerFarius,0,hID);
end.

escafandra 22-03-2018 08:51:23

Cita:

Empezado por Dark_Code (Mensaje 525203)
Ahora lo que quiero hacer es editar con el valor guardado del Edit en una DLL, lo estoy haciendo de esta forma, pero esta mal en la forma de editar
Código Delphi [-]
PDWORD($A04569)^:= ValorINI;
, espero de su ayuda.

Tendrás que explicar bien que quiere decir esa frase:
¿Editar qué?
¿Cual es la razón de ser de una dll?
¿Que es esta dirección $A04569? ¿De qué proceso? ¿Es constante?

En el caso de que lo que pretendas en cambiar el valor de cierta dirección de cierto proceso ajeno, debes saber algo de inyecciones, conocer si la dirección apuntada es constante cada vez que se cargue ese proceso y en ese caso, y sólo en ese caso, puedes pretender el cambio seguro del valor de dicho puntero. Si esas son la premisas, ahora debes diseñar bien el cómo y cuando se hace. Esto te obliga a comunicarte certeramente con tu dll y el uso de archivos en disco no es una buena opción cuando se requiere precisión cronológica.

Tu dll no se carga en ningún sitio, no hay inyección, la ultima linea no tiene sentido:
Código Delphi [-]
CreateRemoteThread(AtProcessobymr,nil,0,@TrainerFarius,@TrainerFarius,0,hID);

Dices que no te funciona, la pregunta es ¿Que no funciona? ¿Por qué dices que no funciona?

El código que te pasé funciona tal cual, otra cosa es que la idea inicial sea o no correcta PDWORD($A04569)^:= Valor pero debes tener claro algunas cosas de las dll. Cada proceso carga una copia de la dll. La dirección en cuestión, $A04569, solo afecta al proceso que carga la copia de la dll que lee el valor que quieres usar. En un proceso en ejecución, las direcciones no tienen porqué ser constantes y dependen de cómo y donde ha cargado windows ese proceso.

Saludos.

Casimiro Notevi 22-03-2018 11:29:46

Cita:

Empezado por Dark_Code (Mensaje 525203)
Muchas Gracias por la atención prestada, y por el compartimiento de su conocimiento. pero lo que quería hacer es a base de INI una manera mas practica, investigando mucho logre hacerlo.

Es que eso no tiene nada que ver con lo que se entiende de tu pregunta.
Claramente, la exposición de tu pregunta daba a entender algo muy distinto a lo que querías.


La franja horaria es GMT +2. Ahora son las 18:10:01.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi