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

Вниз

Баг VCL?   Найти похожие ветки 

 
Толик   (2003-07-04 13:50) [0]

Уважаемые мастера!
Столкнулся со следующей проблемой. Необходимо управлять объектом Application посредством отсылки ему неких своих сообщений, типа WM_USER + XXX. Поскольку объект Application ничего не знает о подобных сообщениях, то, в качестве возможного решения, необходимо подменить его оконную процедуру. Например:
(1)

var
DefProc: longword;
const
MM_MYMESSAGE = WM_USER + 1;
procedure MyWndProc(Handle: hWnd; Msg: longword; WParam, LParam: longint); stdcall;

procedure TForm1.Button1Click(Sender: TObject);
begin
//запоминаем старый обработчик
DefProc := GetWindowLong(Application.Handle, GWL_WNDPROC);
//подсовываем новый
SetWindowLong(Application.Handle, GWL_WNDPROC, longword(@MyWndProc));
end;

procedure MyWndProc(Handle: hWnd; Msg: longword; WParam, LParam: longint); stdcall;
begin
case Msg of
MM_MYMESSAGE: //моё сообщение, обрабатываем его
ShowMessage("my message");
else
//другие сообщения обрабатываем по умолчанию
Windows.CallWindowProc(pointer(DefProc), Handle, Msg, WParam, LParam);
end;
end;

Здесь всё работает замечательно. НО! Зачастую бывает полезно в качестве оконных процедур использовать члены класса. Для этих случаев VCL предоставляет пару функций: MakeObjectInstance и FreeObjectInstance. Вот здесь и начинаются проблемы:
(2)

var
DefProc: longword;
const
MM_MYMESSAGE = WM_USER + 1;

procedure TForm1.Button1Click(Sender: TObject);
begin
DefProc := GetWindowLong(Application.Handle, GWL_WNDPROC);
SetWindowLong(Application.Handle, GWL_WNDPROC, longword(MakeObjectInstance(NewAppWndProc)));
end;

procedure TForm1.NewAppWndProc(var AMessage: TMessage);
begin
with AMessage do
case Msg of
MM_MYMESSAGE:
ShowMessage("my message");
else
Windows.CallWindowProc(pointer(DefProc), Application.Handle, Msg, WParam, LParam);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Application.MessageBox("сейчас повисну", "", MB_OK);
end;

Приведённый выше фрагмент кода обрабатывает мои сообщения, но стоит только после подмены оконной процедуры вызвать в главной форме Application.MessageBox(...) или просто минимизировать главную форму, то она тут же перестаёт отвечать на сообщения от мыши или клавиатуры.
М.б. конечно во втором примере у меня где-то ошибка и я зря грешу на MakeObjectInstance? Но похоже не я первый: http://delphiplus.nagano.ru/articles/news/ObjInstFix.html
Хотелось бы узнать мнение экспертов.


 
vuk   (2003-07-04 13:57) [1]

А кто мешает использовать HookMainWindow?


 
Толик   (2003-07-04 14:24) [2]

to vuk © (04.07.03 13:57)
Да, это вариант. Но хотелось бы понять в чём причина проблемы, описанной в «Толик (04.07.03 13:50)». Казалось бы, вполне законный код приводит к каким-то непонятным проблемам. Или не вполне законный?
Или в Borland"е специально и ввели в класс TApplication ф-ю HookMainWindow, зная о проблемах с MakeObjectInstance???


 
ggsoft   (2003-07-04 15:30) [3]


> Толик (04.07.03 13:50)


> то, в качестве возможного решения, необходимо

не (1) или (2), а, как мне кажется,
компонент <ApplicationEvents> с закладки Additional палитры компонентов. Event-OnMessage().


 
Юрий Зотов   (2003-07-04 16:14) [4]

Зачем все это? Есть же событие Application.OnMessage. Просто и надежно.


 
vuk   (2003-07-04 16:29) [5]

to Юрий Зотов:
Разница все же есть. OnMessage вызывается из основного цикла обработки, а хуки основного окна - из WndProc.


 
Толик   (2003-07-04 16:54) [6]

Большое спасибо всем откликнувшимся.
Посмотрю, что из всего вышесказанного наиболее полно подойдёт к решению моей задаче.
Ещё раз спасибо и удачи всем.



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

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

Наверх




Память: 0.46 MB
Время: 0.012 c
3-55464
RH
2003-06-25 13:02
2003.07.17
Работа с dbf-ками


3-55471
AlexA
2003-06-11 12:53
2003.07.17
ApplyUpdates?


14-55822
Darts
2003-07-01 12:09
2003.07.17
Вакансия программиста Borland Basic :))


14-55765
Dimka Maslov
2003-07-02 14:02
2003.07.17
ALC comes back


1-55497
Пубертанец
2003-07-04 09:06
2003.07.17
Как создать объекты производного класса еще в предке?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский