Delphi postmessage установка курсора в чужом окне

Обновлено: 03.05.2024

← →
HF-Trade © ( 2006-06-18 17:22 ) [0]

Здравствуйте господа. Как реализовать вот такой сабж.
(Мне надо чтоб указатель мыши переместился в окне(чужом) относительно его координат.)
Пишу так -

Var
XXX: Hwnd;
X,Y: Integer;
MyMouse: TPoint;

.
Что не правильно делаю?

← →
GanibalLector © ( 2006-06-18 19:14 ) [1]

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


GetCursorPos(P);
P:=ScreenToClient(P); // .

← →
HF-Trade © ( 2006-06-18 19:36 ) [2]

Есть окно ХХХ, я получаю координаты курсора (X,Y), в этом окне. Затем мне нужно чоб при нажатии на кнопку -
Окно ХХХ стало поверх всех, а курсор переместился в точку Х,Y.

Если делать так -

то курсор перемещаеться относительно координат экрана, а мне надо именно окна ХХХ.

← →
Юрий Зотов © ( 2006-06-18 19:54 ) [3]

> HF-Trade © (18.06.06 19:36) [2]

А где Вы перемещаете курсор? В Вашем коде он где был, там и остается.

← →
HF-Trade © ( 2006-06-18 20:23 ) [4]

Прошу прощения - так тоже пробовал

← →
HF-Trade © ( 2006-06-19 15:33 ) [5]

А да, забыл совсем -
Координаты я получаю отдельно. тут просто все в мешанине кинул -

Var
XXX: Hwnd;
X,Y: Integer;
MyMouse: TPoint;

При создании формы -

Получаю координаты (Хот Кей Ctrl+A в TMainMenu) -

При нажатии на кнопку -

Курсор остаеться на на месте.

← →
begin. end © ( 2006-06-19 15:49 ) [6]

> HF-Trade © (18.06.06 19:36) [2]

> Если делать так -
> SetCursorPos(X,Y)
> то курсор перемещаеться относительно координат экрана, а
> мне надо именно окна ХХХ.

Значит, нужно перевести координаты относительно окна в экранные координаты. Для этого есть функция ClientToScreen (модуль Windows).

Репутация: нет
Всего: нет

Нужно имено TRichViewEdit

Репутация: 16
Всего: 459

При помощи функций SendMessage, PostMessage.

Цитата(Toska @ 2.10.2007, 21:28 )
на класс компонета TRichViewEdit?
Цитата(Toska @ 2.10.2007, 21:28 )
А так же как считать от туда данные?


Смотря какие данные. Можно получить только те что предусмотрены окном данного типа (класса в смысле класса окон Windows)

гениальность идеи состоит в том, что ее невозможно придумать

Репутация: нет
Всего: нет

У меня есть такая функция

Код

function ChangeWndFirstEditText(Wnd: HWND; const Text: string):
boolean;
var
EditWnd: HWND;
begin
Result := False;
EditWnd := FindWindowEx(Wnd,0,'TRichViewEdit', nil);
if EditWnd = 0 then
exit; // edit not found
Result := SendMessage(EditWnd, WM_SETTEXT, 0, Integer(PChar(Text))) <> 0;
end;

То что TRichViewEdit не стандартный компонет с этим не связана?

Репутация: 16
Всего: 459

Цитата(Toska @ 2.10.2007, 23:23 )
То что TRichViewEdit не стандартный компонет с этим не связана?

гениальность идеи состоит в том, что ее невозможно придумать

Репутация: 3
Всего: 18

Цитата(Toska @ 2.10.2007, 23:23 )
То что TRichViewEdit не стандартный компонет с этим не связана?

Репутация: нет
Всего: нет

Меня еще вот какой штукой кнули

В какой версии Delphi пишется проект? с офсайта: Processing of WM_GETTEXT, WM_GETTEXTLENGTH, WM_SETTEXT was disabled for Delphi 2005 and 2006, because it conflicted with VCL implementation.

Есть какая нибудт замена этому

Репутация: 3
Всего: 18

Toska, хде ты это взяла. Кто WinAPI отменил.

Добавлено через 1 минуту и 4 секунды
PS у меня все всегда работало. Байки.

Репутация: нет
Всего: нет

BaD_SeCt0R, Для начала ВЗЯЛ

Я тоже думаю что фигня, я же могу послать в Edit, простой TRichEdit и т.д.

Сообственно подскажи как решить мою задачу

Репутация: 16
Всего: 459

Проверка показала что в Delphi 2007 WM_SETTEXT устанавливает свойство Caption, но не сразу, а только после пересоздания окна.

Добавлено через 48 секунд
Но скорее всего Caption не отображается у TRichViewEdit ни где.

гениальность идеи состоит в том, что ее невозможно придумать

Репутация: 3
Всего: 18

Цитата(Toska @ 3.10.2007, 00:40 )
BaD_SeCt0R, Для начала ВЗЯЛ

Экскьюз, у тя пол не указан
Toska, кинь ссылкой чтоли. Я ничего подобного на офсайте не увидел.

Добавлено через 6 минут и 46 секунд

Цитата(Alexeis @ 3.10.2007, 00:43 )
Проверка показала что в Delphi 2007 WM_SETTEXT устанавливает свойство Caption

Alexeis, ты где у эдитов кэпшин видел? И не после пересоздания, а после инвалидэйта вродь как. Не буду утверждать, у самого стоит D7.

Репутация: 16
Всего: 459

гениальность идеи состоит в том, что ее невозможно придумать

Репутация: 7
Всего: 115

А как же RichViewEdit1.Format; после принятия текста?

Репутация: 1
Всего: 9

Репутация: нет
Всего: нет

У меня ни как не получается, думаю нужен какой то другой подход, нежеле SendMessage.

Репутация: нет
Всего: нет

Более и менее разобрался, для передачи использую буфер обмена.
SendMessage(EditWnd, WM_Paste, 0, Integer(PChar(Text))) <> 0;

Может теперь кто подскажет как считать информацию с TRichEdit

Репутация: нет
Всего: нет

Репутация: 16
Всего: 128

Цитата(Toska @ 12.10.2007, 18:12 )
SendMessage(EditWnd, WM_Paste, 0, Integer(PChar(Text)))

Репутация: нет
Всего: нет

MetalFan, Ну да, действительно, это от моих эксперементов осталось. Но работает!

Может подскажешь по лучше решение?

Репутация: 7
Всего: 115

Отправлять текст WM_SetText забирать WM_GETTEXT но нужно кое что учитывать:

При отправке текста WParam должен быть равен длинне отправляемого текста, иначе RV текст не примет.
Пример:

Код

SendMessage(RichViewEdit1.Handle, WM_SetText, Length(edit1.text)+1, Lparam(edit1.text) );

Забор текста осуществляется за счёт WM_GETTEXT но опять таки нужно учитывать WPARAM который указывает на длину копируемого текста, и получается при помощи WM_GETTEXTLENGTH

Код

var
TextCount :integer;
buf : array [1..250] of char;
begin

Для того что бы текст вырывать кусками существует
EM_GETTEXTRANGE lparam которого указывает на начало копирования

Код

var
buf : array [1..250] of char;
begin
SendMessage(RichViewEdit1.Handle, EM_GETTEXTRANGE, integer(@buf), 10 );
Memo1.text:= buf;

Репутация: 16
Всего: 128

RA, все конечно хорошо, но контрол, на сколько я понял, находится в другом процессе. соотв в лучшем случае ничего из вышеприведенного не сработает, в худшем - AV либо в своем, либо в чужом приложении.

Репутация: 7
Всего: 158

Цитата(MetalFan @ 16.10.2007, 10:43 )
контрол, на сколько я понял, находится в другом процессе

Репутация: 16
Всего: 128


+ сначала через OpenProcess получить доступ. после также не забыть освободить память ну и CloseHandle тож не помешает

Репутация: 16
Всего: 128

Репутация: 7
Всего: 115

Цитата(MetalFan @ 16.10.2007, 09:43 )
все конечно хорошо, но контрол, на сколько я понял, находится в другом процессе. соотв в лучшем случае ничего из вышеприведенного не сработает, в худшем - AV либо в своем, либо в чужом приложении.

Батенька хотите верьте хотите нет но мой пример работает.
Проверено!

PS: Я исходник этого компонента смотрел в области обработки вышеупомянутых мессаг.

Репутация: 16
Всего: 128

Цитата(RA @ 16.10.2007, 15:56 )
Батенька хотите верьте хотите нет но мой пример работает.
Проверено!

Репутация: 7
Всего: 115

Цитата(MetalFan @ 16.10.2007, 16:06 )
работает, если RV создан и находится в ТВОЕМ приложении

А также в чужом

Репутация: 3
Всего: 23

Цитата(MetalFan @ 16.10.2007, 17:06 )
работает, если RV создан и находится в ТВОЕМ приложении

Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois

Репутация: 16
Всего: 128

Репутация: 7
Всего: 158

Цитата(RA @ 16.10.2007, 16:56 )
Батенька хотите верьте хотите нет но мой пример работает.

Репутация: нет
Всего: нет

Проверьте пожалуйста, ни чего не получается.

Добавлено через 6 минут и 9 секунд

Код

procedure TForm1.Button3Click(Sender: TObject);
var
h,EditWnd: HWND;
begin
h := findwindow(nil, 'Form1');
EditWnd := FindWindowEx(h,0,'TRichViewEdit', nil);
if EditWnd = 0 then begin
ShowMessage('Окно НЕ найдено');
exit;
end;
SendMessage(EditWnd, WM_SetText, Length(edit1.text)+1, Lparam(edit1.text) );

Репутация: нет
Всего: нет

Репутация: 16
Всего: 128

Цитата(dumb @ 16.10.2007, 16:50 )
ядро самостоятельно копирует данные при передаче между процессами

Репутация: 7
Всего: 115

Присоединённый файл ( Кол-во скачиваний: 17 )
RVTEST.rar 3,99 Kb

Репутация: нет
Всего: нет

То что у меня делфя 2006 ни как ни влияет?

Репутация: 16
Всего: 128

Репутация: 7
Всего: 115

Репутация: 16
Всего: 128

Репутация: 7
Всего: 115

Цитата(Toska @ 16.10.2007, 19:38 )
То что у меня делфя 2006 ни как ни влияет?

Скорее всего влияет ибо:


procedure WMGetTextLength(var Message: TMessage); message WM_GETTEXTLENGTH;
procedure WMGetText(var Message: TMessage); message WM_GETTEXT;
procedure WMSetText(var Message: TMessage); message WM_SETTEXT;

Но зато должон работать EM_GETTEXTRANGE

Репутация: нет
Всего: нет

Нифига себе какая фигня, скомпилированный работает

Видимо дествительно та фигня, что я писал в начале топика.

RA, Напиши еще пример на считывание, пожалуйста

Добавлено через 3 минуты и 33 секунды
У тя так понимаю 6 делфя?

Репутация: нет
Всего: нет

попробуй послать сюда

Репутация: 7
Всего: 115

Тоесть RichViewEdit-ы скомпилированные из под делфи старше семёрки не понимают что такое:
WM_GETTEXTLENGTH
WM_GETTEXT
WM_SETTEXT

ЗЫ: Это так задумано автором компонента. Зачем? не знаю .

Добавлено через 6 минут и 55 секунд
Если у тебя есть сорс компонента, можно конечно поэксперементировать, с удалением этих директив. вдруг пропрёт

Репутация: нет
Всего: нет

Фиг с ним, послать можно через буфер.

А вот как считать от туда?

Репутация: нет
Всего: нет

Репутация: нет
Всего: нет

Репутация: нет
Всего: нет

Помогите разобраться с методом через VirtualAllocEx/WriteProcessMemory/ReadProcessMemory/VirtualFreeEx
можно с примером

Репутация: нет
Всего: нет

Тут еще вопрос возник. По поводу работы с RichViewEdit
Организовать все выше перечисленное удалось. Спасибки! Очень помогли.
Я на другом застрял. Как мне поставить курсор в первоначальное положение, там где он был, до вставки WM_SETTEXT
Как я понял нужно юзать что-то вроде. EM_GETSEL, EM_SETSEL
Но у мну ошибка вылетает если отправляю EM_GETSEL в RichViewEdit
Подскажите, как с этим боротся, или есть какой-то другой способ перевести курсор в конец строки

Репутация: 7
Всего: 158

Цитата(HellFire @ 6.3.2008, 02:33 )
Но у мну ошибка вылетает если отправляю EM_GETSEL в RichViewEdit

wParam и lParam сделай nil, а значения бери из возвращаемого функцией результата - из dword'а два word'а вытащить, надеюсь, сможешь.

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.


0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »

[ Время генерации скрипта: 0.2624 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Для того, чтобы сделать что-нибудь над каким-либо окном нужно сначала получить его дескриптор, т.е. его положение в оперативной памяти. Для этого нужно использовать функцию FindWindow. Ей нужно указать всего два параметра: сначала класс искомого окна, затем его заголовок. Ну с заголовком проблем вообщем-то нет - его мы видим, но вот как определить класс. ведь он скрыт от глас пользователя. В действительности мы может указать только заголовок окна, а вместо класса ставим nil.

Для начала запустите стандартную программу "Блокнот" - и что же мы видим? В блокноте в заголовке окна отслеживается имя текущего файла. Изначально, т.к. файла нет в использовании, заголовок блокнота выглядит так: "Безымянный - Блокнот". Постараемся по этому критерию найти окно блокнота. Выглядеть это будет так:

if FindWindow( nil , 'Безымянный - Блокнот' ) <> 0 then

ShowMessage( 'Окно найдено' )

ShowMessage( 'Окно НЕнайдено' );

Далее попробуем передвинуть это окно

h := findwindow( nil , 'Безымянный - Блокнот' );

SetWindowPos(h, HWND_BOTTOM, 1 , 1 , 20 , 20 , swp_nosize);

Опять находим блокнот. Его дескриптор помещаем в переменную класса HWND[С английского Handle Window - дескриптор окна]. Далее используем функцию SetWindowPos для задания позиции. В качестве параметров нужно указать:

Дескриптор окна, которое хотим переместить

Идентификатор окна, которое предшествует перемещаемому окну в Z-последовательности. Z-последовательность это порядок, в котором формировались окна. Данный параметр указывает с какого именно окна необходимо начинать писк. В качестве значений может принимать либо дескриптор какого-либо окна в системе, либо одно из нижеследующих значений:

HWND_BOTTOM Начало Z-последовательности

HWND_NOTOPMOST Первое окно которое располагается не "поверх все окон"

HWND_TOP Вершина Z-последовательности

HWND_TOPMOST Первое окно которое располагается "поверх все окон"

Позиция окна по горизонтали

Позиция окна по вертикали

Спецификаторы изменения позиции и размеров окна[флаги]. Для задания значения можно комбинировать следующие константы

SWP_DRAWFRAME Прорисовка фрейма вокруг окна.

SWP_HIDEWINDOW Скрывает окно.

SWP_NOACTIVATE Не активизирует окно. Если же этот флаг не будет поставлен, окно активизируется и будет перемещено поверх всех окон. А вот встанет ли окно даже выше тех окон, которым задано HWND_TOPMOST или нет зависит от параметра hWndInsertAfter.

SWP_NOCOPYBITS Если этот спецификатор не будет установлен, тогда содержимое клиентской области окна будет скопировано и вставлено во вновь отобразившееся окно после его перемещения.

SWP_NOMOVE Сообщает, что нужно игнорировать параметры задания позиции окну.

SWP_NOOWNERZORDER Сообщает, что не следует изменять позицию окна владельца в Z-последовательности.

SWP_NOREDRAW Не перерисовывает окно.

SWP_NOREPOSITION Такой же как и SWP_NOOWNERZORDER.

SWP_NOSIZE Сообщает, что нужно игнорировать параметры задания размеров окну.

SWP_SHOWWINDOW Отображает окно.

Если данная функция выполнится успешно, она возвратит отличное от нуля значение. Ну, вот, теперь мы можем передвигать и изменять в размерах чужие окна. Для того, чтобы изменить заголовок окна напишем следующий код:

SetWindowText(FindWindow( nil , 'Безымянный - Блокнот' ),

'Дарова, ламерюга, типа ты попал. ' );

Функции setwindowtext нужно указать только два параметра: это дескриптор нужного окна и новое значение для заголовка. Вот вообщем-то и всё!

Есть ещё одна интересная функция ShowWindow, которая позволяет скрывать или отображать окна. Использовать её нужно так::

ShowWindow(FindWindow( nil , 'Безымянный - Блокнот' ), sw_hide);

В скобках указываем сначала над каким именно окном хотим издеваться, а затем что именно мы хотим с ним сделать. В качестве возможных действий можем указать:

SW_HIDE Скрывает окно и активизирует другое.

SW_MAXIMIZE Разворачивает окно.

SW_MINIMIZE Сворачивает окно.

SW_RESTORE Активизирует и выводит окно. Если окно было развёрнуто или свёрнуто - восстанавливает исходный размер и позицию.

SW_SHOW Активизирует и выводит окно с его оригинальным размером и положением.

SW_SHOWDEFAULT Активизирует с установками, заданными в структуре STARTUPINFO, которая была передана при создании процесса приложением запускающим нужную программу.

SW_SHOWMAXIMIZED Выводит окно в развёрнутом виде.

SW_SHOWMINIMIZED Выводит окно в виде пиктограммы на панели задач.

SW_SHOWMINNOACTIVE Выводит окно в свёрнутом виде на панели задач и не передаёт ему фокус ввода, т.е. окно, которое до этого было активно остаётся активно по прежнему.

SW_SHOWNA Отображает окно в его текущем состоянии. Активное окно остаётся активным по прежнему.

SW_SHOWNOACTIVATE Выводит окно в его последнем положении и с последними используемыми размерами. Активное окно остаётся активным по прежнему.

SW_SHOWNORMAL Выводит окно. Если оно было свёрнуто или развёрнуто - восстанавливает его оригинальные размеры и позицию

Но вся сложность действий заключается в том, что в заголовке Блокнота отслеживается имя текущего файла и использовать значение "Безымянный - Блокнот" мы можем не всегда : (. Тем более это не только в случае с блокнотом. Но есть выход: ведь функции FindWindow для поиска окна мы указываем не только заголовок нужного окна, но ещё его класс. Какой же это выход скажете вы, заголовок окна мы видим, значит знаем, что указывать - а класс окна. в действительности тоже может найти приложив немного усилий!

В пакет Delphi входим специальная утилита для отслеживание всех активных процессов, она называется WinSight32. Вот ею мы и воспользуемся. Запустите её, покопайтесь в списке процессов, ищите строку где значится текущий заголовок нужного окна, например Блокнота, и в левой части этой строки в фигурных скобках вы найдёте имя класса окна. Для блокнота это будет "Notepad". Теперь зная имя класса окна мы можем переписать поиск окна таким способом:

ShowWindow(FindWindow( 'Notepad' , nil ), sw_hide);

Теперь мы вместо заголовка окна указываем значение nil, игнорируя данный параметр.

Есть ещё один замечательный способ передачи команд окнам.- функция PostMessage. Ей в качестве параметров нужно указать:

NULL Ведёт себя как функция PostThreadMessage с переданным ей dwThreadId параметром.

Репутация: 1
Всего: 1

Код

//Нажать стрелку вниз
PostMessage(h,WM_KEYDOWN,VK_DOWN,0);
PostMessage(h,WM_KEYUP,VK_DOWN,0);

Далее через 50 милисекунд посылаю нажатие горячей клавиши, ну оно не срабатывает:

Код

sleep(50);

Что тут может быть не так подскажите пожалуйста?

Репутация: 1
Всего: 1

Проверял через keybd_event все работает на ура (((, ну тогда окно должно быть всегда активно, ну это уже не то что нужно (((.

Код

//Альт + F
keybd_event(VK_MENU, 0,0,0);
keybd_event(ord('F'), 0,0,0);
keybd_event(ord('F'), 0,KEYEVENTF_KEYUP,0);
keybd_event(VK_MENU, 0,KEYEVENTF_KEYUP,0);

Репутация: 1
Всего: 1

Ребят ну может кто нибудь даст совет? или хотя бы скажет что все нормально, просто магнитная аномалия поэтому горячая клавиша не срабатывает ))).

Репутация: 29
Всего: 191

Есть возможность прикрепить чужое приложение? Есть соображения, почему не работает. Если возможности нет, будем юзать план В.

Репутация: 1
Всего: 1

Скорее всего нет такой возможности. А что за план В такой?

Репутация: 1
Всего: 1

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.


0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »

[ Время генерации скрипта: 0.1208 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Репутация: 1
Всего: 1

Код

//Нажать стрелку вниз
PostMessage(h,WM_KEYDOWN,VK_DOWN,0);
PostMessage(h,WM_KEYUP,VK_DOWN,0);

Далее через 50 милисекунд посылаю нажатие горячей клавиши, ну оно не срабатывает:

Код

sleep(50);

Что тут может быть не так подскажите пожалуйста?

Репутация: 1
Всего: 1

Проверял через keybd_event все работает на ура (((, ну тогда окно должно быть всегда активно, ну это уже не то что нужно (((.

Код

//Альт + F
keybd_event(VK_MENU, 0,0,0);
keybd_event(ord('F'), 0,0,0);
keybd_event(ord('F'), 0,KEYEVENTF_KEYUP,0);
keybd_event(VK_MENU, 0,KEYEVENTF_KEYUP,0);

Репутация: 1
Всего: 1

Ребят ну может кто нибудь даст совет? или хотя бы скажет что все нормально, просто магнитная аномалия поэтому горячая клавиша не срабатывает ))).

Репутация: 29
Всего: 191

Есть возможность прикрепить чужое приложение? Есть соображения, почему не работает. Если возможности нет, будем юзать план В.

Репутация: 1
Всего: 1

Скорее всего нет такой возможности. А что за план В такой?

Репутация: 1
Всего: 1

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.


0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »

[ Время генерации скрипта: 0.1085 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Читайте также: