Конференция "Начинающим" » Скопировать данные с помощью API функций [D7, WinXP]
 
  • Krozzz (13.02.09 19:00) [0]
    Есть две программы. В каждой по компоненту Edit. Подскажите, как поместить информацию из Edit"а одной программы в Edit другой (и если вместо Edit будет Label)?
  • Сергей М. © (13.02.09 21:41) [1]
    Обе программы дельфийские ?
  • Германн © (14.02.09 00:28) [2]

    > Скопировать данные с помощью API функций

    Это не на форумах надо спрашивать. Это надо изучать по книгам, причём достаточно серьёзным. Если речь идёт про WinAPI функции, то нужно абсолютно точно понимать, что никаких "компонент" они не знали, не знают и знать не хотят. Они знают только "окна" (windows).

    P.S. А дельфийский компонент TLabel, к примеру, никакого окна не имеет.
  • Krozzz (14.02.09 09:05) [3]

    > Обе программы дельфийские ?

    Да
  • Сергей М. © (14.02.09 17:29) [4]
    И обе твоей разработки, т.е. исходники доступны ?
  • Krozzz (14.02.09 18:56) [5]

    > И обе твоей разработки, т.е. исходники доступны ?

    Программы примитивные:
    в первой только компонент Edit1, во второй Edit1 и Button1.
    При нажатии на Button1 данные из Edit1 1й программы должны скопироваться в Edit1 2й.
  • Сергей М. © (14.02.09 19:14) [6]
    Ответь на вопрос ..
  • Krozzz (14.02.09 19:15) [7]

    > исходники доступны

    доступны
  • Сергей М. © (14.02.09 20:18) [8]
    Тогда см., например, сообщение WM_COPYDATA
  • Сергей М. © (14.02.09 20:21) [9]
  • Krozzz (14.02.09 21:46) [10]
    Спасибо. Нашел в хелпе delphi api пример как передать строку с помощью WM_COPYDATA:
    приложение получатель:
    ...
    TMyForm1 = class(TForm)
     private
       ...
       procedure ReceiveMessage (var Msg: TMessage); message WM_COPYDATA;
       ...
    end;
    ...

    implementation

    ...

    procedure TMyForm.ReceiveMessage;
    var
     pcd : PCopyDataStruct;
    begin
     pcd := PCopyDataStruct(Msg.LParam);

     Caption := PChar(pcd.lpData);
    end;

    приложение отправитель:

    procedure TFormXXX.Button1Click(Sender: TObject);
    var
     cd : TCopyDataStruct;
    begin
     cd.cbData := Length(Edit1.Text)+1;
     cd.lpData := PChar(Edit1.Text);
     SendMessage ( FindWindow('TMyForm1', nil),
           WM_COPYDATA,  0, LParam(@cd));
    end;

    Правда тут кнопка в программе-отправителе. Если не в тягость, как сделать
    так, чтобы кнопка не посылала, а получала строку?
  • Сергей М. © (14.02.09 22:25) [11]
    Никак.
    Прежде чем что-то получать, надо чтобы это "что-то" было сначала отправлено, иначе получать нечего)
  • Krozzz (14.02.09 22:33) [12]

    > Никак.Прежде чем что-то получать, надо чтобы это "что-то"
    > было сначала отправлено, иначе получать нечего)

    Т.е. нелзя сделать так, чтобы кнопка находила строку в другой программе, посылал ее в свою программу и потом сама получала?
  • Krozzz (14.02.09 22:36) [13]

    >  потом сама получала?

    Точнее получала программа, в которо кнопка, и размещала в каком-нибудь, скажем, Label или Edit?
  • Denis__ © (14.02.09 22:53) [14]
    Пусть посылает сообщение, приняв которое та, другая программа отправляет строку...
  • Сергей М. © (14.02.09 23:02) [15]

    > Krozzz


    Можно лишь в частных случаях
  • Krozzz (14.02.09 23:15) [16]

    > Можно лишь в частных случаях

    Какими должны быть условия?
  • Krozzz (14.02.09 23:21) [17]
    Извиняюсь, забыл сказать, что программу, из которой копируется строка, тестовая, т.е. на практике надо будет считать строку из программы, в которой будет много элементов (естественно и тот, с которого надо считать) и добавить или убавить элементы к ней нельзя.
  • Сергей М. © (14.02.09 23:26) [18]
    Ну, как минимум, контрол-источник должен быть представлен собственным окном.
  • Krozzz (14.02.09 23:29) [19]

    > Ну, как минимум, контрол-источник должен быть представлен
    > собственным окном.

    т.е. все-таки надо добавить в прогу-источник дополнительный элемент?
  • Сергей М. © (14.02.09 23:31) [20]
    Не обязательно, но возможно.
  • Krozzz (14.02.09 23:36) [21]

    > но возможно
    без него?
    Если можно, то можете выложить примерный код?
  • Германн © (15.02.09 01:14) [22]

    > Krozzz   (14.02.09 19:15) [7]
    >
    >
    > > исходники доступны
    >
    > доступны
    >

    Ой врёшь!
    Всё что тобой написано после этого поста свидетельствует о совсем ином.
  • Сергей М. © (15.02.09 20:44) [23]
    "Выкладываю" - WM_GETTEXT
  • Krozzz (15.02.09 22:36) [24]
    procedure TForm1.Button1Click(Sender: TObject);
    var
    wnd:hwnd;
    a:string;
    begin
     wnd:=FindWindow('TFormN','FormN');
     wnd:=FindWindowEx(wnd,0,'TLabel','Label1');
     SendMessage(wnd,WM_GETTEXT,100, LParam(@a));
     Edit1.Text:=a;
    end;


    Все равно не копирует(
  • Германн © (16.02.09 00:23) [25]

    > Все равно не копирует(


    > P.S. А дельфийский компонент TLabel, к примеру, никакого
    > окна не имеет.
    >
  • Юрий Зотов © (16.02.09 11:58) [26]
    > Krozzz   (15.02.09 22:36) [24]
    > wnd:=FindWindowEx(wnd,0,'TLabel','Label1');

    Как можно найти окно TLabel, если никакого окна у TLabel нет совсем?
    Причем TLabel - это далеко не единственный компонент без окна.

    Универсальная схема может быть такой:
    - регистрируем 2 собственных сообщения - запрос и ответ;
    - при нажатии на кнопку вторая программа посылает первой запрос, в параметрах которого указывает, что она хочет получить;
    - в ответ первая программа посылает второй результат запроса.
  • clickmaker © (16.02.09 12:46) [27]
    > wnd:=FindWindowEx(wnd,0,'TLabel','Label1');
    > SendMessage(wnd,WM_GETTEXT,100, LParam(@a));

    во-первых, TLabel никогда не найдешь
    во-вторых, не выделена память под a
  • Krozzz (16.02.09 20:09) [28]

    > - в ответ первая программа посылает второй результат запроса.

    первую программу изменять нельзя.
  • Сергей М. © (16.02.09 20:11) [29]

    > первую программу изменять нельзя


    Ну тогда распрощайся с затеей.
  • Krozzz (16.02.09 20:35) [30]

    > Ну тогда распрощайся с затеей.

    Обидно ;(
    Ну ладно...
    Закрывайте тему
  • @!!ex © (16.02.09 22:03) [31]
  • Германн © (17.02.09 00:30) [32]

    > Krozzz   (16.02.09 20:35) [30]
    >
    >
    > > Ну тогда распрощайся с затеей.
    >
    > Обидно ;(
    > Ну ладно...
    > Закрывайте тему

    Об этом я тебе уже говорил в том первом твоём вопросе, который был закрыт.
    Но зачем было врать? "Krozzz   (14.02.09 19:15) [7]"
    Ну и напоследок.
    [2] я постил не просто от нечего делать.
  • Германн © (17.02.09 00:39) [33]
    Да и ещё насчёт вранья.
    Учитывая, что сразу несколько уважаемых мастеров проявили необъяснимую для меня благосклонность к твоему вопросу, весьма возможно, что твоё враньё привело к тому, что решение так и не было найдено.
    Примите и прочь.
  • korneley © (17.02.09 01:02) [34]

    > Германн ©   (17.02.09 00:39) [33]
    > ...весьма возможно, что твоё враньё привело
    > к тому, что решение так и не было найдено.

    Дык, в общем случае, и нет такого... Сказал бы автор сразу: "Хочу из Эдитов разных, вместо звёздочек, буковки паролей реальные получать" :) Итог, думаю, был бы тем же. Но быстрее :)))
  • Германн © (17.02.09 01:12) [35]

    > korneley ©   (17.02.09 01:02) [34]
    >
    >
    > > Германн ©   (17.02.09 00:39) [33]
    > > ...весьма возможно, что твоё враньё привело
    > > к тому, что решение так и не было найдено.
    >
    > Дык, в общем случае, и нет такого... Сказал бы автор сразу:
    >  "Хочу из Эдитов разных, вместо звёздочек, буковки паролей
    > реальные получать" :) Итог, думаю, был бы тем же. Но быстрее
    > :)))
    >

    Нет. Я о том, что автор свой единственный приведённый пример посвятил TLabel. Но если он очевидно соврал, когда говорил, что исходники доступны, то мог соврать и о том, что "Обе программы дельфийские".
  • korneley © (17.02.09 01:27) [36]

    > Krozzz   (14.02.09 23:21) [17]
    > Извиняюсь, забыл сказать, что программу, из которой копируется
    > строка, тестовая, т.е. на практике надо будет считать строку
    > из программы, в которой будет много элементов (естественно
    > и тот, с которого надо считать) и добавить или убавить элементы
    > к ней нельзя.

    Это многое объясняет.
  • Германн © (17.02.09 01:31) [37]

    > korneley ©   (17.02.09 01:27) [36]
    >
    >
    > > Krozzz   (14.02.09 23:21) [17]
    > > Извиняюсь, забыл сказать, что программу, из которой копируется
    > > строка, тестовая, т.е. на практике надо будет считать
    > строку
    > > из программы, в которой будет много элементов (естественно
    > > и тот, с которого надо считать) и добавить или убавить
    > элементы
    > > к ней нельзя.
    >
    > Это многое объясняет.

    Это только запутывает.
    Примите и прочь.
  • Krozzz (17.02.09 16:17) [38]
    Решил проблему спомощью GetWindowText().
    Извиняюсь, если был некорректен в вопросах.
    Всем, кто помогал - спасибо!
    (кроме, разве что, Германн"а.
    Вы, кроме как критиковать ничего не умеете?..
    Я не врал, я вначале проверял на тестовой программе. Просто потом появилось желание проверить на сторонней программе).
  • Юрий Зотов © (17.02.09 20:08) [39]
    > Krozzz   (17.02.09 16:17) [38]
    > Решил проблему с помощью GetWindowText().

    Есть серьезные сомнения, что таким образом Вы ее действительно решили. Без шуток. Не знаю всех условий Вашей реальной задачи, но в общем случае GetWindowText проблему, обозначенную в сабже, не решает. Поэтому, не исключено, что Вам только кажется, что Вы ее и в самом деле решили - из-за недостаточного объема тестирования.
  • Krozzz (17.02.09 20:41) [40]

    > Есть серьезные сомнения, что таким образом Вы ее действительно
    > решили. Без шуток. Не знаю всех условий Вашей реальной задачи,
    >  но в общем случае GetWindowText проблему, обозначенную
    > в сабже, не решает. Поэтому, не исключено, что Вам только
    > кажется, что Вы ее и в самом деле решили - из-за недостаточного
    > объема тестирования.<Цитата>
    >  
    >
    >

    В общем случае не решает, но мне достаточно один раз скопировать содержимое Edit и на этом остановиться (хотя при изменении содержимого того Edit"а в запущенной программе, данной функции уже не хватает).
  • Юрий Зотов © (17.02.09 21:05) [41]
    > Krozzz   (17.02.09 20:41) [40]

    Похоже, Вы все же заблуждаетесь. Вот выдержки из описания GetWindowText:

    If the target window is owned by another process and has a caption, GetWindowText retrieves the window caption text. If the window does not have a caption, the return value is a null string.

    To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.


    А ведь про WM_GETTEXT Вам сказали уже давно...
  • Krozzz (17.02.09 23:06) [42]

    > Похоже, Вы все же заблуждаетесь.

    Вот код. Работает так, как я описал в предыдущем посте.
    procedure TForm1.Button1Click(Sender: TObject);
    var wnd:hwnd;
           b:array [0..127] of char;
    begin
    wnd:=FindWindow('TFormN',nil);
    wnd:=FindWindowEx(wnd,0,'TEdit',nil);
    GetWindowtext(wnd,b,Sizeof(b));
    Edit1.text:=b;
    end;



    С WM_GETTEXT работает при условии внесения изменений в программу-источник (что в моем случае нежелательно).
  • clickmaker © (17.02.09 23:10) [43]
    > [42] Krozzz   (17.02.09 23:06)

    TFormN в другом процессе?
  • Krozzz (17.02.09 23:12) [44]
    clickmaker

    > TFormN в другом процессе?

    Да
  • clickmaker © (17.02.09 23:25) [45]
    и при каких изменениях работает WM_GETTEXT?
  • Юрий Зотов © (17.02.09 23:35) [46]
    GetWindowtext(wnd, @b, Sizeof(b));

    Адрес b, а не просто b. См. описание функции.

    А насчет того, что работает только при каких-то там изменениях - здесь точно путаница. При правильном коде должно работать всегда.
  • Юрий Зотов © (17.02.09 23:41) [47]
    Причем, если верить справке (а с чего бы ей не верить?), то как раз GetWindowText не должно работать никогда (потому что "This function cannot retrieve the text of an edit control in another application"), а вот WM_GETTEXT - как раз всегда. И никакие изменения тут ни при чем.
  • Германн © (18.02.09 01:07) [48]

    > Krozzz   (17.02.09 16:17) [38]
    >
    ...
    > (кроме, разве что, Германн"а.
    > Вы, кроме как критиковать ничего не умеете?..
    >

    Я много чего умею. Но умело скрываю свои умения! :)


    > Юрий Зотов ©   (17.02.09 23:35) [46]
    >
    > GetWindowtext(wnd, @b, Sizeof(b));
    >
    > Адрес b, а не просто b.

    А разве в случае статического массива "b:array [0..127] of char;"
    это не одно и то же?
  • Krozzz (18.02.09 18:49) [49]

    > Юрий Зотов and clickmaker

    Извиняюсь, промахнулся. Изменения надо вносить с WM_COPYDATA.
    Насчет WM_GETTEXT: программа не работала из-за внесения названия
    компонента как 4го параметра в FindWindowEx.
    Вот правильный код:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    wnd:hwnd;
    b:array [0..127] of char;
    begin
    Edit1.text:='';
    wnd:=FindWindow('TFormN',nil);
    wnd:=FindWindowEx(wnd,0,'TEdit',nil);(* при FindWindowEx(wnd,0,'TEdit','Edit1') не работает *)
    Sendmessage(wnd,wm_gettext,sizeof(b),Lparam(@b));
    Edit1.text:=b;
    end;




    > Юрий Зотов
    </I
    > как раз GetWindowText не должно работать никогда

    >
    Код, приведенный в [42], лично у меня работает для символов латиница+цифры (для других не проверял).
  • Германн © (19.02.09 00:37) [50]

    > Насчет WM_GETTEXT: программа не работала из-за внесения
    > названия
    > компонента как 4го параметра в FindWindowEx.
    >


    >
    > Это не на форумах надо спрашивать. Это надо изучать по книгам,
    >  причём достаточно серьёзным. Если речь идёт про WinAPI
    > функции, то нужно абсолютно точно понимать, что никаких
    > "компонент" они не знали, не знают и знать не хотят. Они
    > знают только "окна" (windows).

    Извини, что опять "критикую", но...
 
Конференция "Начинающим" » Скопировать данные с помощью API функций [D7, WinXP]
Есть новые Нет новых   [134435   +4][b:0][p:0.002]