Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Система, Windows API > Кнопка не кнопка и без хендла!


Автор: MaxXx_2 05.11.14, 04:37
Здравствуйте! Помогите разобратся. Нужно в фоновом режиме нажать на кнопку. Весь процесс я знаю. Но дело в том, что случился форс-мажор =) Spy++ не видит этот элемент. Скачал програмку wndinfo тоже не видит ни чего. С дельфи ВинСайт32 сканировал, тоже не видит. Что ЭТО? Выглядит как кнопка и выполняет функции кнопки, но сама не кнопка и не панель вообще как будто ни чего нету. Программа называется WPF v.6.69. Любая кнопка в самой программе. Там их много очень и ни одна не определяется.
Они лежат на TabSheet но когда на них наводиш программа вообще не видит их. Хотя в самой программе нажимаются. Помогите разобратся пожалуйста. Скачать WPF можно где угодно. 1.png (, : 562)

Автор: leo 05.11.14, 05:21
Цитата MaxXx_2 @
Что ЭТО? Выглядит как кнопка и выполняет функции кнопки, но сама не кнопка и не панель вообще как будто ни чего нету

В дельфи\VCL такая кнопка называется TSpeedButton. Это не оконный, а чисто графический контрол, который рисуется на канве родительского окна (как TLabel, TBevel и т.п.), которое передает ему на обработку нажатия\движения мыши, когда мышиный курсор находится в пределах BoundsRect этого контрола. У TLabel тоже есть события обработки мышиных нажатий, поэтому из нее также можно сделать подобие кнопки, добавив рамку в виде TBevel и изменяя ее вид с выпуклого на вдавленный и наоборот по событиям OnMouseDown\Up

Автор: MaxXx_2 05.11.14, 05:41
Ага спасибо. Ну а как програмно отправить нажатие на кнопку, которой не существует?

Автор: MaxXx_2 05.11.14, 05:49
Пишу вот так вот. Предварительно дохожу до панели на которой кнопка и потом ищю любой СпидБатон. Нету таких говорит вообще.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    procedure TForm1.Button1Click(Sender: TObject);
    var
    w1, w2, w3, w4 :THandle;
    begin
    W1 := FindWindow('TPanel', ' WÐ v6.69F');
    if W1 <> 0 then
    ShowMessage('+ Panel')
    else
    ShowMessage('- Panel');
     
    W2 := FindWindowEx(W1, 0, 'TPageControl', nil);
    if W2 <> 0 then
    ShowMessage('+ PageControl')
    else
    ShowMessage('- PageControl');
     
    W3 := FindWindowEx(W2, 0, 'TTabSheet', ' Proxy PC ');
    if W3 <> 0 then
    ShowMessage('+ TabSheet')
    else
    ShowMessage('- TabSheet');
     
    W4 := FindWindowEx(W3, 0, 'TSpeedButton', nil);
    if W4 <> 0 then
    begin
    ShowMessage('Yes SpeedButton');
    SendMessage(w4,WM_LBUTTONDOWN,0,0);
    SendMEssage(w4,WM_LBUTTONUP,0,0);
    end
    else
    ShowMessage('No SpeedButton');
    end;


Добавлено
Нашел информацию, что оказывается нажать на SpeedButton в чужом окне нереально! Как выйти из положения? ХотКей для них нет, меню нет.

Автор: neut ral 05.11.14, 06:30
Цитата MaxXx_2 @
Пишу вот так вот...
FindWindow...

Вам же сказали что это не оконные контролы

нажать можно: SetCursorPos + mouse_event

Автор: MaxXx_2 05.11.14, 07:03
Нарыл на просторах такой вот кусочек:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    PostMessage(h, WM_LBUTTONDOWN, 0, MAKELPARAM(x,y));
    PostMessage(h, WM_LBUTTONUP, 0, MAKELPARAM(x,y));

h - хэндл формы, на которой лежит кнопка (ну или того настоящего окна, на которой она лежит в общем случае)
x, y - клиент-координаты формы в которые попадает кнопка.

Но он не работает. Где я ошибку допустил? В итоге получилось вот так?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    begin
    W1 := FindWindow('TPanel', ' WÐ v6.69F');
    if W1 <> 0 then
    ShowMessage('+ Panel')
    else
    ShowMessage('- Panel');
     
    W2 := FindWindowEx(W1, 0, 'TPageControl', nil);
    if W2 <> 0 then
    ShowMessage('+ PageControl')
    else
    ShowMessage('- PageControl');
     
    W3 := FindWindowEx(W2, 0, 'TTabSheet', ' Proxy PC ');
    if W3 <> 0 then
    begin
    PostMessage(w3, WM_LBUTTONDOWN, 0, MAKELPARAM(200,500));
    PostMessage(w3, WM_LBUTTONUP, 0, MAKELPARAM(200,500));
    ShowMessage('+ TabSheet')
    else
    ShowMessage('- TabSheet');
    end;


Потом решил просто проверить в Паинте нажатие на пустое место кисточкой. И тоже ни чего не произошло:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    procedure TForm1.Button1Click(Sender: TObject);
    var
    w1, w2:THandle;
    begin
    w1 := FindWindow('MSPaintApp', Безымянный - Paint');
    if W1 <> 0 then
    ShowMessage('Нашел MSPaintApp')
    else
    ShowMessage('Нету MSPaintApp');
     
    W2 := FindWindowEx(W1, 0, 'Afx:00000000FF4C0000:0:0000000000010003:0000000000000010:0000000000000000','');
    if W2 <> 0 then
    begin
    PostMessage(w2, WM_LBUTTONDOWN, 0, MAKELPARAM(300,300));
    PostMessage(w2, WM_LBUTTONUP, 0, MAKELPARAM(300,300));
    ShowMessage('Нашел рисовалку');
    end
    else
    ShowMessage('Не нашел рисовалку');
    end;

Автор: min@y™ 06.11.14, 12:22
Цитата MaxXx_2 @
Скачать WPF можно где угодно.

Гуглил минуты 3, не нашёл, надоело, выклади.

Автор: MaxXx_2 06.11.14, 12:41
Прошу прощения. Вот эта штука:
http://mmoru.com/board/showthread.php?t=464736
Вот прямая на программу: http://rghost.ru/52752794

Автор: min@y™ 06.11.14, 12:55
Поковырять ехе-шник не удалось, он пожат пакером.
Короче, раз это TSpeedButton или любой другой TGraphicControl, то послать ему клик не получится.
Надо найти хэндл окна, на котором он лежит (в данном случае - TTabSheet.Handle), высчитать (визуально или хз как ещё) BoundRect этих кнопок и посылать клик-мессадж (вернее MouseDown/Up) уже ихнему родителю.

З.Ы. Антивирус в твоём архиве нашёл 2 малваря.

Автор: Rouse_ 06.11.14, 15:57
Цитата min@y™ @
Короче, раз это TSpeedButton или любой другой TGraphicControl, то послать ему клик не получится

Получится, только не через PostMessage, а через mouse_event
Нужно только знать координаты, по которым отправлять сообщение.
В данном случае, как я понимю, координаты кнопок не изменяемые, поэтому просто берем координаты окна, на канвасе которого отображены эти псевдокнопки и рассчитываем необходимые оффсеты.

Автор: min@y™ 06.11.14, 16:02
Цитата Rouse_ @
только не через PostMessage, а через mouse_event

да, но родительское окно должно быть в фокусе.

Автор: MaxXx_2 06.11.14, 18:17
Щас поковыряю екзешник на пакер, если не сально мощьный протектор я распакую и там посмотрим, что к чему.

Автор: min@y™ 06.11.14, 18:24
Цитата MaxXx_2 @
Щас поковыряю екзешник на пакер, если не сально мощьный протектор я распакую и там посмотрим, что к чему.

боюсь, паковали не ради уменьшения рамера ехе-шника.

Автор: MaxXx_2 06.11.14, 18:51
PEiD показывает Microsoft Visual C++ v6.0 DLL * но Olly не открывает его. Хотя программа очень старая и скорее всего запакова слабым пакером. Надо чуть чуть глебже капнуть постаратся. Dede дамп снимает вроде.

Автор: min@y™ 06.11.14, 18:54
На кнопки нажимать это 1хрен не поможет.

Автор: trident 18.12.14, 03:27
Можно подгрузить DLL, из которой найти обьект TApplication, далее через RTTI перебирая компоненты найти этот SpeedButton и вызвать обработчик OnClick

Добавлено
Даже не Application, а сразу обьект главной формы получить по ее хендлу и дaльше искать SpeedButton

Автор: Optimus11 31.08.20, 10:24
Цитата trident @
Можно подгрузить DLL, из которой найти обьект TApplication, далее через RTTI перебирая компоненты найти этот SpeedButton и вызвать обработчик OnClick

Добавлено
Даже не Application, а сразу обьект главной формы получить по ее хендлу и дaльше искать SpeedButton

Здравствуйте,

А не могли бы Вы пожалуйста чуть подробней объяснить, как это делается или направить в нужное русло,что почитать на эту тему ? Если не сложно.

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