Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 20.04.2013, 18:28
PonuHunter PonuHunter вне форума
Прохожий
 
Регистрация: 20.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Буфер обмена winapi

Задача: послать стороннему приложению, (в данном случае игра на directx) в окно ввода, комбинацию клавиш ctrl + v, перед этим скопировав в буфер обмена какой нибудь текст. При этом приложение находится в свернутом состоянии, то есть не получает фокуса. С этим проблем нет, вставка текста работает. Только вот вставляется не тот текст который я копирую в буфер обмена, а тот текст который был в буфере до этого. То есть приложение по непонятно каким причинам игнорирует последнее изменение буфера обмена и в поле ввода копируется текст как будто буфер обмена не изменялся. Как решить эту проблему и заставить приложение копировать текст который я сам помещаю в буфер обмена.

Ниже прилагаю часть кода которая непосредственно отвечает за вставку текста из буфера обмена.

Код:
procedure SendMsg;
begin

// копируем содержимое memo1 в буфер обмена
  Clipboard.Clear;
  Form1.Memo1.SelectAll;
  Form1.Memo1.CopyToClipboard;

// кликаем в поле ввода в окне другой программы для того чтобы оно стало активным для ввода
  PostMessage(Handler, WM_LBUTTONDOWN, MK_LBUTTON, MAKELparam(EditX, EditY));
  sleep(100);
  PostMessage(Handler, WM_LBUTTONUP, 0, MAKELparam(EditX, EditY));
  sleep(1000);

// посылаем окну комбинацию ctrl + v
  keybd_event(VK_CONTROL,0,0,0);
  sleep(100);
  PostMessage(Handler, WM_KEYDOWN, Ord('V'), $002F0001);
  sleep(100);
  PostMessage(Handler, WM_KEYUP, Ord('V'), $C02F0001);
  sleep(100);
  keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
  sleep(100);

// нажимаем ентер
  PostMessage(Handler, WM_KEYDOWN, VK_RETURN, $00000001);
  sleep(100);
  PostMessage(Handler, WM_KEYUP, VK_RETURN, $C0000001);
  sleep(100);

end;

Последний раз редактировалось PonuHunter, 20.04.2013 в 18:31.
Ответить с цитированием
  #2  
Старый 20.04.2013, 19:17
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Я бы делал на винапи все сразу. Пример на плюсах:
Код:
if(OpenClipboard(0))
{
   HGLOBAL hgBuffer;
   wchar_t *chBuffer;
   EmptyClipboard();
   hgBuffer= GlobalAlloc(GMEM_DDESHARE, source.length() * 2 + 2);
   chBuffer= (wchar_t *)GlobalLock(hgBuffer);
   wcscpy(chBuffer, source.data());
   GlobalUnlock(hgBuffer);
   SetClipboardData(CF_UNICODETEXT, hgBuffer);
   CloseClipboard();
}
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #3  
Старый 20.04.2013, 19:24
PonuHunter PonuHunter вне форума
Прохожий
 
Регистрация: 20.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Bargest
Я бы делал на винапи все сразу. Пример на плюсах:
Код:
if(OpenClipboard(0))
{
   HGLOBAL hgBuffer;
   wchar_t *chBuffer;
   EmptyClipboard();
   hgBuffer= GlobalAlloc(GMEM_DDESHARE, source.length() * 2 + 2);
   chBuffer= (wchar_t *)GlobalLock(hgBuffer);
   wcscpy(chBuffer, source.data());
   GlobalUnlock(hgBuffer);
   SetClipboardData(CF_UNICODETEXT, hgBuffer);
   CloseClipboard();
}

Пробовал копировать в буфер обмена с помощью винапи, как в твоем примере - результат тот же, то есть никакого результата. (
Ответить с цитированием
  #4  
Старый 20.04.2013, 19:35
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

а так тоже не прокатывает?
Код:
Clipboard.Text := 'blabla'
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #5  
Старый 20.04.2013, 19:46
PonuHunter PonuHunter вне форума
Прохожий
 
Регистрация: 20.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
а так тоже не прокатывает?
Код:
Clipboard.Text := 'blabla'

У объекта clipboard нет метода text, но это неважно. Проблема не в способе помещения текста в буфер обмена, текст благополучно туда помещается. Проблема в том что когда я пытаюсь копипастнуть его в программу то копируется текст тот который был до того как я изменил содержимое буфера обмена.
Ответить с цитированием
  #6  
Старый 20.04.2013, 19:56
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от PonuHunter
...Проблема в том что когда я пытаюсь копипастнуть его в программу то копируется текст тот который был до того как я изменил содержимое буфера обмена.
Значит не копируется, потому как буфер один на всех и старой инфе храниться больше негде. А вот такой код будет работать?
Код:
type
  TForm1 = class(TForm)
...
procedure SendMsg;
...
procedure Form1.SendMsg;
begin

// копируем содержимое memo1 в буфер обмена
  Memo1.SelectAll;
  Memo1.CopyToClipboard;

// кликаем в поле ввода в окне другой программы для того чтобы оно стало активным для ввода
  PostMessage(Handler, WM_LBUTTONDOWN, MK_LBUTTON, MAKELparam(EditX, EditY));
  sleep(100);
  PostMessage(Handler, WM_LBUTTONUP, 0, MAKELparam(EditX, EditY));
  sleep(1000);

// посылаем окну комбинацию ctrl + v
  keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY, 0);
  keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY, 0);
  keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
  keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

// нажимаем ентер
  PostMessage(Handler, WM_KEYDOWN, VK_RETURN, $00000001);
  sleep(100);
  PostMessage(Handler, WM_KEYUP, VK_RETURN, $C0000001);
  sleep(100);

end;
Ответить с цитированием
  #7  
Старый 20.04.2013, 20:08
PonuHunter PonuHunter вне форума
Прохожий
 
Регистрация: 20.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Значит не копируется, потому как буфер один на всех и старой инфе храниться больше негде.
Текст копируется в буфер обмена. Если я после выполнения процедуры жму ctr + v в любом поле ввода то текст который я поместил в буфер благополучно вставляется в поле. Но когда моя программа отсылает сообщение ctr + v стороннему приложению вставляется текст из не измененного буфера обмена.

Допустим до выполнения моей программы в буфере был текст: 'blablabla', а в процессе выполнения программа помещает в буфер текст 'hahaha'. В итоге, в результате выполнения программы я получаю текст 'blablabla' в окне ввода приложения которому я посылаю комбинацию ctrl + v, а если я сам вставляю текст в скажем блокнот то я получаю 'hahaha'. То есть текст находится в буфере, а значит проблема явно не в способе его помещения туда.


Цитата:
Сообщение от Alegun
А вот такой код будет работать?
Непонял что ты хотел изобразить тут.
Ответить с цитированием
  #8  
Старый 20.04.2013, 20:12
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Советую бросить на форму ещё одну мемку и проверить вставку вот так
Код:
 Memo1.SelectAll;
 Memo1.CopyToClipboard;
 memo2.Clear;
 Memo2.SetFocus;
 keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY, 0);
 keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY, 0);
 keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
 keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

// и дальше по коду
Ответить с цитированием
  #9  
Старый 20.04.2013, 20:24
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

А если делать задержку до отправки Ctrl+V?
Ответить с цитированием
  #10  
Старый 20.04.2013, 20:29
PonuHunter PonuHunter вне форума
Прохожий
 
Регистрация: 20.04.2013
Сообщения: 5
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Freeman
А если делать задержку до отправки Ctrl+V?
не помогло

Цитата:
Сообщение от Alegun
Советую бросить на форму ещё одну мемку и проверить вставку вот так
Код:
 Memo1.SelectAll;
 Memo1.CopyToClipboard;
 memo2.Clear;
 Memo2.SetFocus;
 keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY, 0);
 keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY, 0);
 keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
 keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

// и дальше по коду

Я просто заменил хендлер игры на хендлер окна ввода блокнота и в блокноте все отлично работает, но в игру он копирует старое значение буфера обмена.

Последний раз редактировалось M.A.D.M.A.N., 20.04.2013 в 20:52. Причина: MAD: Пользуемся кнопкой "Редактировать", не устраиваем из форума чат.
Ответить с цитированием
  #11  
Старый 20.04.2013, 23:19
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Наверное действует защита от ClipBoard-а, я так в своих программах делал.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:01.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter