Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.01.23;
Скачать: [xml.tar.bz2];

Вниз

Форма из DLL   Найти похожие ветки 

 
Петров Денис   (2003-01-13 12:28) [0]

Доброе время суток.

Проблема: создаю форму из DLL через TForm.CreateParented (владелец формы не всегда VCL"ный). Вроде бы все в порядке, но, если переключаться между окнами, открытыми в системе, не по Alt+Tab, а, например, щелкая мышью по панели задач, то моя форма не отображается, а главное окно приложения, которое ее создало, остается свернутым. Причем это происходит как в случае с не-VCL владельцем формы, так и с VCL. А если еще эта форма отображается часто (т. е. имеет место процесс "показать-выполнить действия-спрятать", который происходит в цикле), то вообще начинаются чудеса. Окно-владелец может легко свернуться, моя форма может свободно исчезать с экрана и тому подобные неприятности.
Все это проихсодит, когда в системе открыто больше одного окна. С одним открытым окном вроде бы все нормально.
Стиль формы - fsNormal, стиль границы - bsSingle, все иконки отключены. Форму показываю через TForm.Show (модально ее показывать нельзя).

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


 
passm   (2003-01-13 14:02) [1]

Петров Денис © (13.01.03 12:28)> Попробуй при загрузке DLL (LoadLibrary) передать Application.Handle из приложения. Но не забудь восстановить при выгрузке DLL.
Т. е.
Library...
...
function GetApplicationHandle: HWND; stdcall;
begin
Result:= Application.Handle
end;

procedure SetApplicationHandle(const Hanldle: HWND); stdcall;
begin
Application.Handle:= Handle
end;

Project...
...
type
TGetApplicationHandleProc = function: HWND; stdcall;
TSetApplicationHandleProc = procedure(const Hanldle: HWND); stdcall;
var
Hl: THandle;
Ha: HWND;
GetApplicationHanldeProc: TGetApplicationHanldeProc;
SetApplicationHandleProc: TSetApplicationHandleProc;
begin
...
Hl:= LoadLibrary(...);
if Hl <> 0 then
begin
GetApplicationHandleProc:= GetProcAddress(Hl, "GetApplicationHandle");
SetApplicationHandleProc:= GetProcAddress(Hl, "SetApplicationHandle");
if Assigned(GetApplicationHandleProc) and Assigned(SetApplicationHandleProc) then
begin
Ha:= GetApplicationHandleProc;
SetApplicationHandleProc(Application.Handle)
end;
try
{ Твои действия }
finally
if Assigned(GetApplicationHandleProc) and Assigned(SetApplicationHandleProc) then
SetApplicationHandleProc(Ha);
FreeLibrary(Hl)
end { try }
end { if }


 
asmith   (2003-01-13 14:10) [2]

Нижеприведенное относится к ситуации, когда головная программа также написана на D6 (из сообщения это не очевидно). Если это так - поможет сборка всего с runtime packages. Эта тема неоднократно уже здесь обсуждалась.


 
Петров Денис   (2003-01-13 15:56) [3]

passm> Спасибо за идею про Application.Handle. Частично проблема решена, хотя и не так, как в твоем примере - при переключении между окнами моя форма остается наверху и все отображается как надо.

Другая часть проблемы (когда форма используется в цикле), все еще живет, сволочь...
Опишу ситуацию подробнее. DLL, о которой идет речь, COM-сервер, подключенный к "1С". Форма - обычный прогресс-бар, показывает прогресс выполнения какой-нибудь задачи.

Первая часть проблемы решилась так: при подключении "1С" к моей DLL я получаю дескриптор ее главного окна и присваиваю его дескриптору приложения в моей DLL:

...
Application.Handle := GetActiveWindow;
...

То, что GetActiveWindow в момент ее вызова возвратит хэндл главного окна "1С" - это абсолютно точно.
Дальше начинаются проблемы. Есть некоторый циклический процесс - например, проведение документов. При проведении каждого документа "1С" делает следующее:

1. Вызывает форму с прогрессбаром на экран и инциализирует ее начальными значениями. Вот код этой процедуры:

ProgressBarFrm := TProgressBarFrm.Create(Application);

ProgressBarFrm.Caption := Caption;
ProgressBarFrm.Width := Width;
ProgressBarFrm.ProgressBar.Min := Min;
ProgressBarFrm.ProgressBar.Max := Max;
ProgressBarFrm.ProgressBar.Position := Position;
ProgressBarFrm.Description.Caption := "Выполнено " + IntToStr(Position) + " из " + IntToStr(Max);

ProgressBarFrm.Show;

2. В цикле (например, по табличной части проводимого документа) обновляет прогрессбар, показывая, сколько строк документа обработано:

ProgressBarFrm.Description.Caption := "Выполнено " + IntToStr(Position) + " из " + IntToStr(ProgressBarFrm.ProgressBar.Max);
ProgressBarFrm.ProgressBar.Position := Position;

3. По окончании цикла убирает прогрессбар с экрана:

ProgressBarFrm.Free;

Так вот, эти три пунтка выполняются в цикле - цикл по количеству обрабатываемых документов. В момент вызова функции, создающей прогрессбар первый раз, Application.Handle = GetForegroundWindow.
А вот во второй раз это условие почему-то не выполняется. И в цикле наблюдается такая картина: после выполнения ProgressBarFrm.Free активным становится другое окно (почему-то НЕ главное окно "1С"!), и изображение на экране мелькает, потому как переключение на это другое окно надо перерисовать...
Вопрос: почему после удаления окна активным становится не его владелец, а какое-то левое окно?


 
asmith   (2003-01-13 18:05) [4]

А потому, что для формы, созданной в DLL, владелец определяется неправильно - смотри код функции Forms.GetParentForm. Не срабатывает if Control is TCustomForm, если при компиляции не используются пакеты времени выполнения.


 
Петров Денис   (2003-01-13 18:09) [5]

asmith> Блин, да перестраивал я проект с run-time packages. Та же фигня. Это понятно, что владелец определяется неправильно. Вопрос в том, как это победить.


 
Palladin   (2003-01-13 18:32) [6]

Если чесно то при использовании handle и тп
возникают огромные глюки, ибо vcl который в exe совсем не считает что в dll тоже vcl`ьные объекты, так что exeшнику абсолютно паралельно vcl они в dll или нет.
Выход:
либо использовать bpl,
либо создать "кухню" формы в dll и общатся с этой формой через функции обьявеные в разделе
Exports в dll



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.01.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.007 c
3-72103
georgys
2002-12-27 14:12
2003.01.23
Частые ошибки при работе с Базой.


3-72093
Big_Rom
2002-12-28 22:59
2003.01.23
Fastreport


1-72370
Валерыч
2003-01-05 03:23
2003.01.23
Взаимодействие компонентов


1-72372
SeF
2003-01-13 03:06
2003.01.23
биты...


14-72479
Николай Быков
2003-01-05 16:56
2003.01.23
Такая !@#$% приключилась со мной тут на днях.......





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский