![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Свое главное окно сделать дочерним чужого и наоборот
dva20 © (2006-03-20 17:19:00)Как сделать свое главное окно дочерним чужого, при нажатии на кнопку?
Делал примерно так:
var
wHWND: HWND;
begin
wHWND:= FindWindow('CorelDRW 12.0',nil); //Находим дескриптор
//Становится дочерним, но оно только в панели задач и неразворачивается
Form1.ParentWindow:= wHWND;
//Делаем показать, и оно появляется не активным
Form1.Show;
end;
Так, вот, окно показывается, но оно всегда не активное, на контролах типа Edit выделить значения не получается, хотя изменить можно. Caption окна серый, то есть наверное не активный. Окно передвигать можно как и положено дочернему в нутри родительского. Пробовал разные WinAPI-функции, результат - ноль! Такое ощущение, что это окно вообще никаких сообщение не получает.
Вопрос. Как энто дело правильно организовать?
Сергей М. (2006-03-21 15:50:00) [1]
> dva20 © (21.03.06 15:42) [23]
> как
Никак.
Тебе же говорят - твоя задача в ее решении ведет к внедрению кода в чужое АП... А не к тем примитивным трем-четырем строчкам. что ты безрезультатно мучаешь вплоть до сего поста ..
Чтоеще непонятно ?
dva20 (2006-03-21 15:42:00) [2]Так как "подкрутить" тот код (пост 16), чтоб тоже самое выполнялось на клик кнопки в уже работающем приложении (моем)?
Сергей М. (2006-03-21 15:34:00) [3]
> dva20 © (21.03.06 15:21) [21]
> у корела есть свой цикл обработки сообщений
Ключевой момент
dva20 (2006-03-21 15:21:00) [4]
> у корела есть свой цикл обработки сообщений. Он
> крутится в ЕГО адресном пространстве. А у твоей проги
> свой цикл. И крутится от в ТВОЕМ адресном
> пространстве. Поэтому корел не обязан ничего знать о
> твоих эдитах-комбобоксах.
Все верно. Но в вышенаписанном (посте номер 16) коде все работает чики-пуки без всяких на то глюков. Corel делает свое, а я свое. И нет никаких проблем!
Другой способ будет громозже, IMHO.
Вообщем мое приложение взаимодействует через OLE с Corel'ом (считает площадь объектов). Нужно выбрать объекты, затем нажать на кнопочку моего приложения "Расчет", Так вот, когда пользователь выбирает объекты, то мое окно улетает на задний план. Появляются лишние "телодвижения" чтобы его вернуть (лишние кликанья). Можно сделать поверх всех окон, но тогда оно будет мешатся другим запущенным приложениям. Опять же можно свернуть его, но опять лишние кликанья.
Было у меня решение: по таймеру 3 раза в секунду опрашивал Corel - Corel ты свернут? Если да, то тоже сворачивался, так же и наоборот. Но по таймеру - жрет проц... 3-5 процента у корела на машине P4-2.6
Поэтому этот метод не катит.
Отловить сообщение когда корел сворачивается - не знаю как.
Поэтому то что я спрашиваю IMHO мне больше всего подходит:
Дочернее окно всегда "видимое" в Corel'е.
Не вылазит за пределы окна Corel'а.
Нет лишних кликаний.
Вот...
Сергей М. (2006-03-21 14:59:00) [5]
> dva20 © (21.03.06 14:23) [18]
> Извините, но вопрос не в том, зачем, а как?
"Встроить" - это отнюдь не только дать окну нового родителя.
Так что бросай свои нонешние потуги (ни к чему дельному они не приведут) и углубись во внедрение кода в чужое АП.
clickmaker (2006-03-21 14:32:00) [6]
> dva20 © (21.03.06 14:23) [18]
у корела есть свой цикл обработки сообщений. Он крутится в ЕГО адресном пространстве. А у твоей проги свой цикл. И крутится от в ТВОЕМ адресном пространстве. Поэтому корел не обязан ничего знать о твоих эдитах-комбобоксах. Формально ты можешь пришпилить на него окно, но и все. Вся ответсвенность за твою форму лежит на тебе. Никто не гарантирует тебе нормальную работу, ибо это противоречит виндовым принципам как многозадачной ОС и с ИЗОЛИРОВАННЫМИ процессами в плане памяти и пр.
А "зачем" я спрашивал потому что может есть еще какой-то способ получить результат. Ну не хочешь - не надо, приставать не буду больше
dva20 (2006-03-21 14:23:00) [7]
> не, а все равно не понятно. Зачем его именно
> "встраивать" в корел?
Извините, но вопрос не в том, зачем, а как?
clickmaker (2006-03-21 13:47:00) [8]
> dva20 © (21.03.06 13:31) [16]
не, а все равно не понятно. Зачем его именно "встраивать" в корел?
dva20 (2006-03-21 13:31:00) [9]Повторюсь... Наверное чтоб было понятно чего мне нужно.
Вот с этим кодом моя прога встраивается как дочернее окно у Corel'a, все работает как мне надо, то есть окно активно ну и все такое... Но этот код работает только при создании моего приложения:
... = class(TForm)
...
protected
procedure CreateParams(var params: TCreateParams); override;
...
procedure TForm2.Createparams(var params: TCreateParams);
var
wHWND: HWND;
begin
inherited;
wHWND:= FindWindow('CorelDRW 12.0',nil);
params.WndParent := wHWND;
end;
Что мне надо? Запустить свое приложение, ТОЛЬКО ЗАТЕМ на нажатие кнопки или чего другого, на клик короче, чтоб оно "встроилось", стало дочерним у Corel'a без всякой перезагрузки моего приложения. Вот. Думаю понятно написал чего я хочу.
Может как-то "на лету" можно пересоздать FormMain?
Сергей М. (2006-03-21 13:15:00) [10]
> как же с этим кодом? Ведь работает
Ну где же "работает", если сам говоришь, мол, того нет, этого нет, а, мол, надо щоб було ?
clickmaker (2006-03-21 13:09:00) [11]
> dva20 © (21.03.06 13:03) [13]
а чего собственно нужно добиться от корела такими зверскими методами? Может есть решение проще?
dva20 (2006-03-21 13:03:00) [12]
>Ерундой ты занялся.
>
> Созданием доч.окна должен заниматься код того целевого
> процесса, а не твой процесс.
А как же с этим кодом? Ведь работает.
... = class(TForm)
...
protected
procedure CreateParams(var params: TCreateParams); override;
...
procedure TForm2.Createparams(var params: TCreateParams);
var
wHWND: HWND;
begin
inherited;
wHWND:= FindWindow('CorelDRW 12.0',nil);
params.WndParent := wHWND;
end;
Сергей М. (2006-03-21 12:59:00) [13]
> dva20 © (21.03.06 12:19) [11]
Ерундой ты занялся.
Созданием доч.окна должен заниматься код того целевого процесса, а не твой процесс.
Внедряй в АП целевого процесса код, создающий эту форму, - получишь требуемый результат.
dva20 (2006-03-21 12:19:00) [14]Примерно так пытаюсь сделать но ничего не выходит. Не знаю как по другому. Может подскажите?
WindowHWND:= FindWindow('CorelDRAW 12.0', nil);
//Меняем родителя окна
FormMain.ParentWindow:= WindowHWND;
ThreadID := GetWindowThreadProcessID(WindowHWND, nil);
ThisThreadID := GetWindowThreadPRocessId(FormMain.Handle, nil);
if AttachThreadInput(ThisThreadID, ThreadID, True) then
begin
//Окно появляется, но нестановится активным (аналог FormMain.Show)
BringWindowToTop(FormMain.Handle);
//Ничего не дает
SetActiveWindow(FormMain.Handle);
end;
Окно остается не активным. Окно можно передвигать, нажимать кнопки на нем, выбирать значения в ComboBox'e, в то же время значения в Edit не возможно ввести, окно все равно остается не активным.
clickmaker (2006-03-21 11:24:00) [15]
>
> Как его сделать активным?
AttachThreadInput / SetActiveWindow
dva20 (2006-03-21 10:47:00) [16]Делаю вот так:
procedure TForm1.Button1Click(Sender: TObject);
var
wHWND: HWND;
begin
wHWND:= FindWindow(nil, 'Adobe Photoshop'); //Находим дескриптор
//Становится дочерним, но оно только в панели задач и неразворачивается
Form1.ParentWindow:= wHWND;
end;
Если спрашивать свое окно, то оно неактивное!
Если спрашивать:
IsWindowEnabled(FormMain.Handle)
то окно включено.
Спрашиваю:
IsWindowVisible(FormMain.Handle)
то окно видимо, то есть, выдает положительный результат (true). Но присутствие окна только на панели задач. Не развернуть не свернуть его не удается. Хотя если послать
ShowWindow(FormMain.Handle, SW_MAXIMIZE);
то разварачивается на все окно (нового родителя), показывается, но опять же неактивным!флаги типа SW_NORMAL, SW_RESTORE не помагают, окно не "появляется".
Если вызвать просто FormMain.Show; после Form1.ParentWindow:= wHWND; то появляется, опять же не активным.
Как его сделать активным?
clickmaker (2006-03-21 09:40:00) [17]
> ShowWindow(Application.Handle,WS_CHILD);
чего??!
WS_CHILD - это стиль
передается в CreateWindow, можно подменить в CreateParams
dva20 (2006-03-20 19:23:00) [18]Короче, делаю так:
procedure TForm1.Button1Click(Sender: TObject);
var
wHWND: HWND;
begin
wHWND:= FindWindow(nil, 'Adobe Photoshop'); //Находим дескриптор
//Становится дочерним, но оно только в панели задач и неразворачивается
Form1.ParentWindow:= wHWND;
//Это по барабану...
ShowWindow(Application.Handle,WS_CHILD);
//Делаем показать, и оно появляется не активным
//и не становится им никогда :)
Form1.Show;
end;
clickmaker (2006-03-20 19:10:00) [19]Окно-то со стилем WS_CHILD?
Leonid Troyanovsky (2006-03-20 19:10:00) [20]
> dva20 © (20.03.06 18:57) [4]
> но существуют проблемы, которые описал уже.
Существует слишком много проблем, чтобы их здесь описывать.
Поэтому, на практике к таким трюкам не прибегают.
--
Regards, LVT.