Russian Qt Forum

Компиляторы и платформы => Windows => Тема начата: kambala от Май 24, 2013, 01:44



Название: [РЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Май 24, 2013, 01:44
Здравствуйте. Есть окно чужого приложения, у которого жестко задан минимальный размер. Я хочу снять это ограничение из своего приложения. Насколько я понял, надо установить хук и перехватить WM_GETMINMAXINFO. Как это правильно сделать? Спасибо.

Решение тут (тестовый проект): http://www.prog.org.ru/index.php?topic=24848.msg182586#msg182586


Название: Re: снять ограничение на размер чужого окна
Отправлено: Bepec от Май 28, 2013, 13:10
Готов потыкаться, но есть пара вопросов - чужое окно какое? Qt-шное с макс сайзом ограниченным в качестве подопытного подойдёт? :)


Название: Re: снять ограничение на размер чужого окна
Отправлено: kambala от Май 28, 2013, 13:14
целевое — обычное HWND, не Qt-шное. ответ я вроде нашел как это делать тут (http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.ui/2007-03/msg00160.html) (вместо хука просто переопределяется WndProc целевого окна и нужное сообщение обрабатывается, а остальные направляются окну), но не пробовал еще (несрочно). если есть желание — можешь попробовать :)


Название: Re: снять ограничение на размер чужого окна
Отправлено: Bepec от Май 28, 2013, 13:30
Если уже нашел, скинь ссылочку я поковыряю на послеработы )


Название: Re: снять ограничение на размер чужого окна
Отправлено: kambala от Май 28, 2013, 13:42
разуй глаза ;)


Название: Re: снять ограничение на размер чужого окна
Отправлено: Bepec от Май 28, 2013, 13:44
Она незаметнаааа :D Увидел.


Название: Re: снять ограничение на размер чужого окна
Отправлено: kambala от Май 30, 2013, 23:04
оказывается нельзя изменять оконную процедуру окна, порожденного другим процессом (SetWindowLongPtr возвращает 0).
Цитировать
An application can subclass a system class, but should not subclass a window class created by another process.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Май 31, 2013, 14:28
Ковыряюсь с этим, пока что решения нет, но я на пути к нему :D


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Май 31, 2013, 15:17
вот наткнулся на еще один код (с хуком, и еще там длл принимает участие), вроде как рабочий: https://github.com/nirvdrum/SnapsIE/blob/master/CoSnapsie.cpp


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Май 31, 2013, 15:38
В принципе я до этого начал уже доходить, но путь ещё далёк :)

Пробовали? Но извращение то ещё :D

Не нашёл, правда, я в этом коде место, где функция записывается в адресное пространство чужого приложения. Глядел одним глазком :)

PS хотя это я и сам сделать могу ;)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Май 31, 2013, 17:53
я не совсем понимаю алгоритм. делается отдельная длл, задача которой — повесить хук на стороннее окно и вклинить туда свою реализацию оконной процедуры?


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: panAlexey от Май 31, 2013, 19:51
Здравствуйте. Есть окно чужого приложения, у которого жестко задан минимальный размер. Я хочу снять это ограничение из своего приложения. Насколько я понял, надо установить хук и перехватить WM_GETMINMAXINFO. Как это правильно сделать? Спасибо.
есть такая апликуха WinSpy++ называется.
сорцы в сети валяются, саму апликуху прикладываю.
полезная в хозяйстве штучка, я им заголовки окон извлекаю и прочие штучки выколупываю.
запусти, выбери оркно и поиграйся со стилями, а потом сорцы посмотри.
ПС. на 64 битах глючит - нужно другую версию, это для 32-х.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Май 31, 2013, 19:56
а сильно отличается от микрософтовского spy++?


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: panAlexey от Май 31, 2013, 20:07
а сильно отличается от микрософтовского spy++?
Сильно. Позволяет менять стили.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Май 31, 2013, 20:12
стили это конечно здорово, но мне надо минимальный размер изменить

собрал 64-битную версию из исходников — почти каждое «прицельное» приложение падает при выборе вкладки Class или нажатии на N/A WndProc'а :)

за программу спасибо


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Май 31, 2013, 20:54
Рассматриваю то решение (и единственное возможное, насколько я понимаю).

1) используется замена оконной функции обработки событий (ф-цией SetWindowLongPtr). Эта функция может быть применена только из того потока, который владеет окном.

2) эта функция должна указать адрес функции, которая будет заменой стандартной. Таким образом функция-замена должна быть загружена в адресное пространство потока, владеющего окном.

3) !!!этого момента в коде нет!!! Путём хитрых манипуляций получаем адресное пространство нужного нам потока и перебрасываем туда функцию-замену из своего адресного пространства.

4) используется глобальный хук (в виде dll, подгружаемой во все процессы) на обработчик оконных событий. Хук вызывает калбек функцию в контексте каждого процесса по отдельности.

5) в момент вызова каллбек функции в адресном пространстве нужного нам потока, мы сохраняем адрес текущей функции и заменяем оконную функцию на нашу, которая переброшена нами в адресное пространство нужного нам потока.

6) вуаля. По идее имеем 100% успех, но я не проверял пока на практике данный код. (ток вот за комп сел :D пятница ёмоё!)

PS у меня есть пункты 1,2,4,5. До третьего я сам только начал доходить :)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Май 31, 2013, 22:50
вот оно где собака зарыта оказывается с этим хуком

3) а это разве не оно?
Код
C++ (Qt)
// Microsoft linker helper for getting the DLL's HINSTANCE.
// See http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx for more details.
//
// If you need to link with a non-MS linker, you would have to add code to look up the DLL's
// path in HKCR.  regsvr32 stores the path under the CLSID key for the 'Snapsie.CoSnapsie' interface.
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
...
// Get the path to this DLL so we can load it up with LoadLibrary.
TCHAR dllPath[_MAX_PATH];
GetModuleFileName((HINSTANCE) &__ImageBase, dllPath, _MAX_PATH);
 


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Июнь 01, 2013, 21:18
Насколько я понимаю, это код загрузки dll хука.

Хотя при более пристальном рассмотрении я в недоумении.

Функция DLL находится в cpp... При этом должен становиться глобальный хук, который обязательно должен быть в dll... Не, непонятно вообще как это работает.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Июнь 07, 2013, 11:44
2Bepec: получилось чего?


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Июнь 07, 2013, 12:18
Не, испытания пошли - проект у меня пока лежит. На выходных покопаюсь. Такая вот работа :)

PS дайте какую нибудь подопытную программу с таким ограничением!!! А то я чет не найду подходящую, а точнее жертву.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Июнь 17, 2013, 13:52
up.

PS что в качестве цели ставится? Снятие ограничения с окна, имеющего минимальные и максимальные размеры, или же с окна, у которого нет растягивающейся рамки?


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Июнь 17, 2013, 13:58
снять ограничение на минимальный размер (стоит 800х600), стрелочки растягивания есть


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Июль 01, 2013, 11:58
Дайте мне программу, которую необходимо растянуть :D У меня в принципе готово всё для тестов, только подопытный нужен :D


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Июль 01, 2013, 12:04
целевое окно — Diablo 3, но в принципе подойдет любое с фиксированным размером (можно быстро накидать винапи программу, которая обрабатывает злополучное сообщение). и надо не растянуть, а «стянуть» :)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Июль 02, 2013, 09:19
Ыть дябла три. Я её не видел ниразу :P

Т.е. нужно уменьшить. Оукей посмотрю. (не на дьябле :) )


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Июль 16, 2013, 20:38
2Bepec: получилось что-то?


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Июль 16, 2013, 22:09
Получилось но с оговорками. Всего ограничений на размер окна я насчитал 3 - максимальный размер, установленный флаг нерастягивающихся границ и флаг при изменении геометрии окна. Максимальный размер я смог переопределить. Флаги и границы - нет. Тот же тотал игнорирует мои потуги, правда qt шное моё адекватно реагирует.

PS завтра/послезавтра выкрою время, вспомню что да как и постараюсь привести в удобочитаемый/компилируемый вид.


update: ковыряю опять систему :/ Как всё тут запущено...


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Август 09, 2013, 01:52
пациент скорее жив, чем мертв?


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 09, 2013, 07:01
Скорее спит :)

Последнее на чём я остановился - перехват оконной процедуры из длл получает только сообщения об активации/деактивации окна. К сожалению завал у меня счас на работе - все в отпусках, один я остался хнык-хнык.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: neversleep от Август 17, 2013, 15:08
Тему не читал(только первый пост), по сабжу: внедряемся в нужный процесс, заменяем оконную процедуру и фильтруем сообщения. К сожалению, сейчас проверить не могу, за не имением венды.

Нашёл свой старый код на delphi по внедрению dll в чужой процесс, думаю, разобраться будет не сложно, т.к тут практически чистый winapi.
(а в самой dll реализация подмены оконной ф-ции и тд)

Код
Pascal
procedure TForm1.Button2Click(Sender: TObject);
var
 Dll: String;
 hMem: Pointer;
 dwTmp: DWORD;
 hProcess, hThread: THandle;
 Injected: Boolean;
begin
 Dll := edtDLL.Text;
 if not FileExists(Dll) then
   Exit;
 
 Injected := False;
 
 hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
 if hProcess <> 0 then
 begin
   hMem := VirtualAllocEx(hProcess, nil, Length(Dll) + 1, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
   if hMem <> nil then
   begin
     WriteMem(hProcess, hMem, PChar(Dll), Length(Dll));
 
     hThread := CreateRemoteThread(hProcess, nil, 0,
       GetProcAddress(GetModuleHandle(kernel32), 'LoadLibraryA'), hMem, 0, dwTmp);
 
     if hThread <> 0 then
     begin
       WaitForSingleObject(hThread, INFINITE);
 
       if GetExitCodeThread(hThread, dwTmp) then
         Injected := dwTmp <> 0;
 
       CloseHandle(hThread);
     end;
 
     VirtualFreeEx(hProcess, hMem, 0, MEM_RELEASE);
   end;
   CloseHandle(hProcess);
 end;
 
 if Injected then
   ShowMessage('Injected');
end;


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 17, 2013, 15:17
Говорят это плохо читать только первое сообщение темы :)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: neversleep от Август 17, 2013, 15:32
Говорят это плохо читать только первое сообщение темы :)
Люди всякое болтают :)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 17, 2013, 15:41
Я пока забросил данную тему из-за напряга в жизни :) Да и всю следующую неделю буду на природе без интернета большую часть времени. Печалька.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Igors от Август 17, 2013, 16:27
Ну "не решено" бывает не менее, а то и более полезным, если уметь делать выводы.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: neversleep от Август 21, 2013, 06:31
Сделал не большой набросок, если еще актуально, или мб кому пригодится.


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 10:02
Первый на моей памяти проект Qt который вызывает варнинг QtAssist'a и не открывается. :D


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: neversleep от Август 21, 2013, 11:13
Не знаю даже, чего испугался ваш ассист, ведь "проект" - это как-то немного громко сказно :D Но с учётом того, что он был создан в венде, через день немного отредактирован в линукс в gedit, и без проверки после редактирования выложен в свет, такое не исключено :D

Upd:
Стоп, а распаковать архив пробовали? :D


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 11:53
Эм. Насколько же вы высокого мнения об интеллекте окружающих? :D
Не нравится ему ваш ручной синтаксис :D


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: neversleep от Август 21, 2013, 12:14
Просто не пойму, чего тут сложного, вот и начинаю предполагать страшное :D

Код:
TEMPLATE = lib
CONFIG -= qt

SOURCES += main.cpp

Код:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 12:20
Та мне не страшно. Я уж попробовал - код работоспособный и тот что надо, по идее.

Заодно нашёл у себя ошибку - я не учитывал юникод. Почему то функции без указания A/W не хотят работать :D

Код хорош, только длл делается под одно окно :) В общем домой приеду. Попробую на ланчере вашего дыблы.

update: нашёл ошибку в своём коде. Теперь и моя программулина работает.

to neversleep: не подскажете как выгрузить dll из целевой программы?


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Август 21, 2013, 13:52
neversleep, большое спасибо! работает!

но теперь появилась другая проблема: окно сразу же восстанавливает свой минимальный размер 800х600 как только я отпускаю мышку. но этого не происходит, если задавать размер программно через MoveWindow либо делать окно минимальной высоты. сообщение обрабатываю так:
Код
C++ (Qt)
   case WM_GETMINMAXINFO:
   {
       LPMINMAXINFO pmmi = (LPMINMAXINFO)lParam;
       pmmi->ptMinTrackSize.x = pmmi->ptMinTrackSize.y = 5;
       return 0;
   }


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 14:04
А это для экрана входа работает? Не имею аккаунта на баттлнете :)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Август 21, 2013, 14:06
да, пока тестирую на входе, потом еще в игре проверю


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 14:10
Так то при растягивании и отпускании идут WM_MAXMINSIZE, WM_SIZING, WM_MAXMINSIZE, WM_POSCHANGE. Там комбинированное переопределение может быть.

Вечерком доползу и попробую. :)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: neversleep от Август 21, 2013, 14:21
to neversleep: не подскажете как выгрузить dll из целевой программы?
Почти также, как и загрузить: получить handle модуля для выгрузки, и передать его в параметрах CreateRemoteThread.

EnumProcessModules (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682631%28v=vs.85%29.aspx), GetModuleHandle (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683199%28v=vs.85%29.aspx)

или вызвать GetExitCodeThread после загрузки библиотеки.

Код:
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
     (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "FreeLibrary"), hModule, 0, &tmp);

kambala, видимо где-то еще меняется размер... Bepec уже ответил выше, попробовать поперехватывать сообщения которые возникают при изменении размеров/позиции.



Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 14:43
Кстати вы нарушаете лицензионное соглашение этими махинациями :D Это так, к слову :)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 17:27
Чтоб сообщенька обновилась в треде, новый ответ сделал.

На примере скайпа (дябла у меня почему то вылетает после установки хука, ибо левая сборка) вывод - нужно ещё переопределять WM_WINDOWPOSCHANGING. Именно он производит перерасчёт размеров и возвращает true/false. Так же его сбрасываем в DefWindowProc и программа уже не возвращается к своему размеру.

PS проверьте сами на дябле - у меня проблема о которой написал выше :D

PPS причем странное поведение - все сообщения видимо блокируются вплоть до отрисовки :D Гыг. А с остальными программами всё в порядке.

PPPS надо быть осторожным. Я ужал все доступные окна до минимального размера - пришлось перезагружаться  ;)


Название: Re: [НЕРЕШЕНО] снять ограничение на размер чужого окна
Отправлено: kambala от Август 21, 2013, 17:50
Так то при растягивании и отпускании идут WM_MAXMINSIZE, WM_SIZING, WM_MAXMINSIZE, WM_POSCHANGE. Там комбинированное переопределение может быть.
спасибо за наводку, их тоже попробую обрабатывать
Кстати вы нарушаете лицензионное соглашение этими махинациями :D Это так, к слову :)
программа-бот и так нарушает их, так что не страшно :)
дябла у меня почему то вылетает после установки хука, ибо левая сборка
так а что мешало скачать официальный клиент? на торрентах же валяется
нужно ещё переопределять WM_WINDOWPOSCHANGING
ок, спасибо

исправлю-ка заголовок и первое сообщение темы :)


Название: Re: [РЕШЕНО] снять ограничение на размер чужого окна
Отправлено: Bepec от Август 21, 2013, 17:53
Эммм.. я и не в курсе что официальный есть :D Я вообще пират не поклонник battle.net.

PS все программы на моём компе покорились снятию ограничения кроме пары защищённых игрулин. Ну там просто подменяется HWND, так что для них нужно будет приложить больше усилий. Хотя кому это надо?

update: выкладываю работоспособные исходники.