Как показать окно, которое работает как всплывающее меню? - PullRequest
9 голосов
/ 01 февраля 2010

Когда отображается окно A, я хочу показать другое немодальное всплывающее окно B, но:

  1. Я не хочу, чтобы окно A становилось неактивным, потому что окно B становится передним окном;
  2. Я хочу, чтобы, когда окно B было сфокусировано, я опускал элемент управления поля со списком в окне A одним щелчком мыши (как правило, вы должны щелкнуть два раза, один для перемещения фокуса в окне A и второй для снятия поля со списком );

Как вы можете видеть, окно B, которое я хочу, является чем-то вроде более удобного всплывающего окна, такого как всплывающее меню (которое является менее препятствием, чем обычное немодальное окно, когда вы хотите, чтобы оно исчезло, нажав на любое другая часть родительского окна).

Я ясно понимаю мой вопрос? Спасибо.

Ответы [ 6 ]

8 голосов
/ 03 февраля 2010

Самое простое решение, которое я нашел для «1», - это отправить WM_NCACTIVATE в вызывающую форму, как только всплывающая форма активируется (в обработчике WM_ACTIVATE), чтобы вызывающая форма рисовала подпись с активным цвета. Для этого вам понадобится ссылка на форму вызова в всплывающей форме.

Для «2» вы можете освободить всплывающую форму в том же обработчике WM_ACTIVATE, это не будет поглощать клики, которые переходят в форму вызова.

Так что вот так должно перейти в popup-форму;

type
  TForm2 = class(TForm)
    [..]
  private
    FOwner: TForm;
    procedure WmActivate(var Msg: TWMActivate); message WM_ACTIVATE;
  public
    constructor Create(AOwner: TComponent); override;

[...]
constructor TForm2.Create(AOwner: TComponent);
begin
  if not (AOwner is TForm) then
    raise Exception.Create('Owner should be TForm');
  FOwner := TForm(AOwner);
  inherited;
end;

procedure TForm2.WmActivate(var Msg: TWMActivate);
begin
  SendMessage(FOwner.Handle, WM_NCACTIVATE, Ord(Msg.Active <> WA_INACTIVE), 0);
  inherited;
  if Msg.Active = WA_INACTIVE then
    Release;
end;

и укажите форму вызова в качестве владельца всплывающей формы;

procedure TForm1.Button1Click(Sender: TObject);
var
  PopForm: TForm2;
begin
  PopForm := TForm2.Create(Self);
  [..]


Я согласен с Лурсонвинни и Ульрихом . IMO popup-форма сложнее, чем кажется. Хотя в случае SpTBXFormPopupMenu вам придется установить две библиотеки: TB2K и SpTBXLib . По крайней мере, просмотр источников может подсказать, что может быть вовлечено.
2 голосов
/ 01 февраля 2010

Чтобы предотвратить фокусировку окна, необходимо либо указать расширенный стиль окна WS_EX_NOACTIVATE (Windows 2000 и выше), либо обработать WM_MOUSEACTIVATE и вернуть MA_NOACTIVATE.

0 голосов
/ 29 мая 2010

Я сам нашел решение здесь. Спасибо всем!

Сохранять окно неактивным, даже когда активировано

0 голосов
/ 04 февраля 2010

Я нашел тот, который делает почти точно то, что я хочу: TAdvStickyPopupMenu

0 голосов
/ 02 февраля 2010

SpTBXFormPopupMenu из spTBXLib делает работу.

Перейдите на http://www.silverpointdevelopment.com/sptbxlib/index.htm и найдите «Form Popup»

Ключ, похоже, в том, что «всплывающий» контейнер должен наследовать TPopupMenu. Но обработка очень сложная, вы можете увидеть это самостоятельно в коде. Я рекомендую использовать его как есть из пакета, потому что Роберт Ли проделал замечательную работу.

0 голосов
/ 01 февраля 2010

Я могу использовать это, чтобы не потерять фокус:

SetWindowPos(Form2.Handle, HWND_TOP, 0, 0, 0, 0,
  SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE);

Вторая часть, которую я не очень хорошо понял.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...