Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Не отображается контрол


Автор: Romero 16.5.2008, 13:34
Использую компонент THTMLLite (http://www.pbear.com/).
Для отображения формы окна без перехвата фокуса работает данный код:
Код

  ShowWindow(MessageForm.Handle,SW_SHOWNOACTIVATE);
  ShowWindow(MessageForm.Panel.Handle,SW_SHOWNOACTIVATE);
  ShowWindow(MessageForm.html.Handle,SW_SHOWNOACTIVATE);
  SystemParametersInfo(SPI_GETWORKAREA,0,@WRect,0);
  SetWindowPos(MessageForm.Handle,HWND_TOPMOST,WRect.Right-MessageForm.Width,
    WRect.Bottom-MessageForm.Height,0,0,SWP_NOSIZE or SWP_NOACTIVATE);

Все контролы отображаются, а html (THTMLLite) - не хочет. При этом, когда раньше на его месте стоял RichEdit, то отображалось по этой же схеме все отлично.
Подозреваю, что у недавно принятого мной к использованию компонента неадекватная реакция на ShowWindow (или вообще ее нет), но мозгов не хватает, чтобы это вылечить.
Быть может, уважаемые профи сумеют найти причину такого поведения? Другой способ отображения без активации окна и его контролов вряд-ли найдется (в свое время, когда его искал, все перерыл). А другой компонент для отображения HTML можете и посоветовать - авось, с ним фокус пройдет.

Автор: Poseidon 16.5.2008, 13:47
Цитата(Romero @  16.5.2008,  13:34 Найти цитируемый пост)
А другой компонент для отображения HTML можете и посоветовать - авось, с ним фокус пройдет.
В чем ВебБраузер не угадил?

Автор: Rennigth 16.5.2008, 15:55
Romero, А почему Visible ему не хочешь сделать? Все равно же у тебя VCL...

Добавлено через 54 секунды
Цитата(Romero @  16.5.2008,  13:34 Найти цитируемый пост)
отображения формы окна без перехвата фокуса

или для этого?

Автор: Romero 16.5.2008, 16:01
А его реально сжать по высоте отображенного контента? А отрубить системное контекстное меню?
Дело в том, что мне необходимо только отобразить строку с HTML-содержимым, полноценный браузер категорически не нужен. Плюс сжатие по высоте - в HTMLLite научился делать.

Автор: MetalFan 16.5.2008, 16:01
при использовании WinApi применительно к VCL контролам надо отдавать отчет, что может произойти "рассинхронизация" состояний WinApi и VCL контролов. что может привести к странному поведению оных

Автор: Romero 18.5.2008, 18:50
Rennigth, просто визибл менять не катит, нужно отображение без активизации.

Рассинхронизации не наблюдалось при использовании RichEdit - работало как часы. Думаю, HTMLLite просто как-то неправильно обрабатывает сообщение показа окна. В исходниках порылся - ничего не разглядел, что могло бы повлиять. Быть может, кто-то глянет в сырцы и скажет, чего не хватает или где лишнее?

MetalFan, есть предложения, как выполнить ту же задачу (отображение окна программы без перехвата фокуса) без применения WinAPI к VCL?

Автор: Romero 18.5.2008, 19:13
Хм, обнаружил интересный факт.
Форма, на которой лежит HTMLLite, - не основная, и она не отображается изначально при запуске приложения. То есть, не рисуется, пока я ее не вызову вышеописанным способом.
Так вот, если сначала я для этой формы вызываю Show и Hide, то далее она отображается нужным способом, HTMLLite становится видимым, причем даже каждый компонент отдельно показывать не надо. Выходит, что сначала компоненту нужно прорисоваться (или что он там делает при вызове метода Show для формы его содержащей), а дальше он сможет быть скрыт и показан без проблем.
Как отловить, какое именно действие, совершаемое при Show, помогает? Не "моргать" же мне формой при запуске приложения, чтобы затем корректно ее отображать.

Автор: Romero 2.6.2008, 20:20
Чтож, если нет предложений, буду поступать именно так.

Автор: Rrader 3.6.2008, 13:15
У этого компонента есть своя спецификация в отображении. Попробуй:
Код

Var
  WRect: TRect;
  I: Integer;
Begin
  ShowWindow(MessageForm.Handle, SW_SHOWNOACTIVATE);
  ShowWindow(MessageForm.Panel.Handle, SW_SHOW);
  { Сам HTMLLite }
  ShowWindow(MessageForm.Html.Handle, SW_SHOW);
  { "Children" }
  For I := 0 To MessageForm.Html.ControlCount - 1 Do
    If (MessageForm.Html.Controls[I] Is TWinControl)
    And (MessageForm.Html.Controls[I].ClassName <> 'T32ScrollBar')
    And (MessageForm.Html.Controls[I].ClassName <> 'TScrollBar') Then
      ShowWindow((MessageForm.html.Controls[I] As TWinControl).Handle,
        SW_SHOW);
  SystemParametersInfo(SPI_GETWORKAREA, 0, @WRect, 0);
  SetWindowPos(MessageForm.Handle, HWND_TOPMOST, WRect.Right - MessageForm.Width,
    WRect.Bottom - MessageForm.Height, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE);

Тут важно вот что: если в твоей программе скроллбары точно не требуются и не появятся, то при показе в цикле их нужно исключать, иначе они будут отображены при любом раскладе. Но если они нужны, то проверки надо убрать.
P. S.
Для контролов флаг SW_SHOWNOACTIVATE можно заменить на SW_SHOW

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