Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Вставить свои данные в поле чужой программы


Автор: X-Vlad 5.5.2006, 10:47
Привет всем.

У меня вот таой вот вопрос или даже просьба.

Мне нужно вставить в чужую программу в поле readonly свои данные, как это можна зделать?
Если можна пример. 
Помогите плз.

Зарание благодарен.
 

Автор: Snowy 5.5.2006, 11:07
Под 
Цитата(X-Vlad @  5.5.2006,  10:47 Найти цитируемый пост)
поле readonly
подзразумевается поле Edit или место в памяти?
 

Автор: Rouse_ 5.5.2006, 11:12
WM_SETTEXT 

Автор: X-Vlad 5.5.2006, 11:20
Цитата

подзразумевается поле Edit или место в памяти?


поле Edit.

Если можна дайту пример. Ибо никогда с таким не стыкался smile 

Автор: Alexeis 5.5.2006, 11:23
Только что написал для memo
Код

procedure TForm2.btn1Click(Sender: TObject);
var
  h1, h2: hwnd;
begin
  h1 := FindWindow('TForm1', nil);
  h2 := FindWindowEx(h1, 0, 'TMemo', 0);
  SendMessage(h2, WM_ENABLE, 1, 0);
  EnableWindow(h2, true);

  Memo1.SelectAll;
  Memo1.CopyToClipboard;
  SendMessage(h2, WM_PASTE, 0, 0);

  SendMessage(h2, WM_ENABLE, 0, 0);
  EnableWindow(h2, false);
end;


Добавлено @ 11:26 
'TForm1' - искомое окно
'TMemo' - поле редактирования 
Окно вначале переводим в активный режим, затем текст из своего мемо помещаем в буфер обмена
Вставляем в нужное мемо
И делаем его опять неактивным.

Добавлено @ 11:29 
Я надеюсь как найти имя класса окна чужого приложения 
и его Child а знаете... 

Автор: X-Vlad 5.5.2006, 11:37
Цитата

Я надеюсь как найти имя класса окна чужого приложения 
и его Child а знаете...  


незнаю smile никогда таким незанимался ((((( 

Автор: Alexeis 5.5.2006, 11:49
В поставку Delphi входит програма WinSight.exe
у меня она здесь
"D:\Program Files\Borland\Delphi7\Bin\WS32.EXE"

или можно воспользоваться от visual c++ , Spy++.exe - она еще удобней.

Меню Search->FindWindow далее хватаем "прицел" мышкой и кидаем на нужый контрол. Програма в окошке покажет то что надо
 

Автор: Rouse_ 5.5.2006, 11:52
Ну уж хэндл то можно и без этого определить smile
Код

var
  Pt: TPoint;
begin
  GetCursorPos(Pt);
  Caption := IntToStr(WindowFromPoint(Pt));
 

Автор: Alexeis 5.5.2006, 11:53
Поле Class - это класс окна 
Поле Caption, заголовок - можно написать вместо nil(0) в
FindWindow
FindWindowEx

Операцию надо проделать как для контрола так и для главного окна.
Первый FinWindow - ищет главное окно, второй его "дитё" 

Автор: Rouse_ 5.5.2006, 11:53
А, ну и класс окна по хэндлу smile
GetClassName 

Автор: Snowy 5.5.2006, 11:55
А можно просто взять InqSoft Window Scaner и сделать с этимой программой все, что душа пожелает без всякого кода. 

Автор: Rouse_ 5.5.2006, 11:55
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls;

type
  TMainForm = class(TForm)
    TreeView1: TTreeView;
    procedure FormCreate(Sender: TObject);
    procedure Sys_Windows_Tree(Node: TTreeNode; AHandle: HWND);
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

////////////////////////////////////////////////////////////////////////////////
//
//  Стартовая функция, запускаем рекуссию используя хэндл рабочего стола
//

procedure TMainForm.FormCreate(Sender: TObject);
var
  StartHandle : THandle;
begin 
  StartHandle := GetDeskTopWindow;
  Sys_Windows_Tree(nil, StartHandle);
end;

////////////////////////////////////////////////////////////////////////////////
//
//  Рекурсивная функция, строит дерево всех открытых окон, кнопок, едитов и т.д.
//  В качестве входных данных получает узел дерева и Хэндл окна
//

procedure TMainForm.Sys_Windows_Tree(Node: TTreeNode; AHandle: HWND);
const
  MAX = 128;
var
  szClassName, szCaption: array[0..MAX - 1] of Char;
  Result    : String;
  szFileName : array[0..255] of Char;
  PID, TID: Cardinal;
  szLayoutName: array[0..MAX - 1] of Char;
begin
  //Запускаем цикл пока не закончатся окна
  while AHandle <> 0 do
  begin
    //Получаем имя класса окна
    GetClassName(AHandle, szClassName, MAX);
    //Получаем текст (Его Caption) окна
    GetWindowText(AHandle, szCaption, MAX);
    // Получаем имя модуля
    if GetwindowModuleFilename(AHandle, szFileName, SizeOf(szFileName)) = 0 then
      FillChar(szFileName, 256, #0);
    // ID потока и процесса
    TID := GetWindowThreadProcessId(AHandle, PID);
    // языковую раскладку процесса
    AttachThreadInput(GetCurrentThreadId, TID, True);
    VerLanguageName(GetKeyboardLayout(TID) and $FFFF, szLayoutName, MAX);
    AttachThreadInput(GetCurrentThreadId, TID, False);

    Result := Format('%s [%s] Caption = %s, Handle = %d, PID = %d, Layout = %s',
      [String(szClassName), String(szFileName), String(szCaption),
      AHandle, PID, String(szLayoutName)]);

    //В следующей процедуре, в скобках, добавляем результат
    //в дерево, получаем хэндл дочернего окна и с результатами
    //выполнения этих двух функций выполняем процедуру Sys_Windows_Tree
    Sys_Windows_Tree(TreeView1.Items.AddChild(Node, Result),
      GetWindow(AHandle, GW_CHILD));
    //Получаем хэндл следующего (не дочернего) окна
    AHandle := GetNextWindow(AHandle, GW_HWNDNEXT);
    //Handle := 0;
  end;
end; 


end.
 

Автор: Alexeis 5.5.2006, 11:58
Rouse_, Зачем что-то писать когда за тебя уже написали лучше! Spy++ делает тоже самое. 

Автор: Rouse_ 5.5.2006, 11:59
alexeis1, зачем тогда вообще что-то писать? 

Автор: X-Vlad 5.5.2006, 12:04
Цитата

procedure TForm2.btn1Click(Sender: TObject);
var
  h1, h2: hwnd;
begin
  h1 := FindWindow('TForm1', nil);
  h2 := FindWindowEx(h1, 0, 'TMemo', 0);
  SendMessage(h2, WM_ENABLE, 1, 0);
  EnableWindow(h2, true);

  Memo1.SelectAll;
  Memo1.CopyToClipboard;
  SendMessage(h2, WM_PASTE, 0, 0);

  SendMessage(h2, WM_ENABLE, 0, 0);
  EnableWindow(h2, false);
end;


в форме программы куда я хочу пихнуть данные три едита.. когда выполняю этот код - бросает в последний эдит. Как мне выбрать эдит?
Хендл эдита я знаю - "1051С" как терь это использовать? 

Автор: Rouse_ 5.5.2006, 12:08
Цитата(X-Vlad @  5.5.2006,  13:04 Найти цитируемый пост)
Как мне выбрать эдит?

GetNextWindow(AHandle, GW_HWNDNEXT);
потом проверяй класс окна через GetClassName и если это EDIT делай SendMessage 

Автор: Alexeis 5.5.2006, 12:20
Я писал так - это работает для одного едита
Цитата

h2 := FindWindowEx(h1, 0, 'TMemo', 0);

если их болше то нужно использовать
h2 := FindWindowEx(h1, 0, 'TMemo', 'Заголовок нужного edita'); 

Автор: X-Vlad 5.5.2006, 12:35
Цитата(alexeis1 @  5.5.2006,  11:20 Найти цитируемый пост)
если их болше то нужно использовать
h2 := FindWindowEx(h1, 0, 'TMemo', 'Заголовок нужного edita');  


как узнать заголовок? 

Автор: Alexeis 5.5.2006, 12:56
я же писал, Spy++ дает данные:
Цитата

1)Поле Class - это класс окна 
2)Поле Caption, заголовок - можно написать вместо nil(0) в
FindWindow
FindWindowEx
   

Автор: X-Vlad 5.5.2006, 13:16
Цитата(alexeis1 @  5.5.2006,  11:56 Найти цитируемый пост)
я же писал, Spy++ дает данные:

Цитата

1)Поле Class - это класс окна 
2)Поле Caption, заголовок - можно написать вместо nil(0) в
FindWindow
FindWindowEx


   


в TEdit нету Caption оно пустое
 

Автор: Alexeis 5.5.2006, 13:26
Тогда хуже!
Тогда надо делать как говорит Rouse_
Как я понял он предлагал по содержимому окна.
Сам с таким не работал, но примерчик на delphiworld нашел
Код

var
  wnd: HWND;
  caption: string;
begin
  repeat
    SetLength(caption, GetWindowtextLength(wnd));
    GetWindowText(wnd, @caption[1], length(caption) + 1);

    if (trim(caption) = 'Form caption') then
      ClickOnForm(wnd, 'Button name');
    wnd := GetNextWindow(wnd, GW_HWNDNEXT);
  until wnd = 0;


Я думаю более рабочий пример надо попросить у Rouse_ 

Автор: X-Vlad 5.5.2006, 14:15
Всем кто ответил - большое спасибо!

Чтото я все равно немогу разобратся smile

В чужой программе есть форма на которой несколько TEdit.
Кто нить может привести рабочий пример в котором будет возможность во все эти эдиты вставить заданый текст?

У меня с ВинАпи проблемы, а времени разбиратся нету smile да и на рабочих примерах впринципе разбиратся легче.

Зарание благодарен. 

Автор: Rouse_ 5.5.2006, 16:37
Код

procedure FillAllEdits(const AppCaptionName, Value: String);
var
  szClassName: array[0..MAXCHAR - 1] of Char;
  AHandle: THandle;
  ClassName: String;
begin
  AHandle := FindWindow(nil, PChar(AppCaptionName));
  if AHandle = 0 then
  begin
    ShowMessage('Application not found.');
    Exit;
  end;
  AHandle := GetWindow(AHandle, GW_CHILD);
  repeat
    GetClassName(AHandle, szClassName, MAXCHAR);
    ClassName := String(CharUpper(@szClassName[0]));
    if (ClassName = 'EDIT') or (ClassName = 'TEDIT') then
      SendMessage(AHandle, WM_SETTEXT, 0, Integer(@Value[1]));
    AHandle := GetNextWindow(AHandle, GW_HWNDNEXT);
  until AHandle = 0;
end;

procedure TForm13.Button1Click(Sender: TObject);
begin
  FillAllEdits('Form13', 'qwe');
end;
 

Автор: X-Vlad 6.5.2006, 09:47
Rouse_,  +1 Большое спасибо. 
Получилось smile  smile  smile 


Всем кто принимал участие в дескусии большое спасибо!  ;)  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)