Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.31;
Скачать: CL | DM;

Вниз

"Всплывающее окно"   Найти похожие ветки 

 
RASkov   (2006-11-12 22:34) [0]

Как сделать окно всплывающим? Измучился я с этим окном. В этой области знаний не хватает. Разбирал примеры от Алексея Румянцева с ComboBox"ами. Запутался в корень. Вообщем нужно сделать свою попап форму. Все мои эксперементы были над TCustomControl. Вот примерно так делал:

 TMyPopup = class(TCustomControl)
 private
   FChek: TCheckBox;
   FPopupVisible: Boolean;
   procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
   procedure WMKillFocus(var Message: TMessage); message WM_KILLFOCUS;
 protected
   procedure CreateParams(var Params: TCreateParams); override;
   procedure CloseUp(Accept: Boolean); dynamic;
 public
   constructor Create(AOwner: TComponent); override;
   procedure Show(const P: TPoint);
   property PopupVisible: Boolean read FPopupVisible;
 end;
.............

constructor TMyPopup.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 Width := 84;
 Height := 100;
 FCheck := TCheckBox.Create(Self);  //Чисто ради эксперимента.
 FCheck.Parent := Self;
 FCheck.Width := 80;
 FCheck.Left := 2; FCheck.Top := 2;
 FCheck.Show;
 FPopupVisible := False;
end;

procedure TMyPopup.CreateParams(var Params: TCreateParams);
begin
 inherited;
 with Params do begin
  Style := Style or WS_BORDER;
  ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
  AddBiDiModeExStyle(ExStyle);
  WindowClass.Style := CS_SAVEBITS;
 end;
end;

procedure TMyPopup.CloseUp(Accept: Boolean);
begin
 if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
 if Accept then begin
  SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
     SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  //Visible:=False;
  FPopupVisible:=False;
 end;
end;

procedure TMyPopup.CMCancelMode(var Message: TCMCancelMode);
begin
 if (Message.Sender <> Self) then CloseUp(True);
end;

procedure TMyPopup.WMKillFocus(var Message: TMessage);
begin
 inherited;
 CloseUp(True);
end;

procedure TMyPopup.Show(const P: TPoint);
begin
 if not PopupVisible then begin
  SetWindowPos(Handle, 0, P.X, P.Y, 0, 0,  SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
  FPopupVisible := True;
  Invalidate;
  Windows.SetFocus(Handle);
 end;
end;


И конечно же это не работает:(
Как сделать:
1 - Что бы область показа не ограничивалась клиентской областью формы?
  (Т.е. если щелкнуть в нижней области формы то мое окно показывается и обрезается краем формы, у формы появляются "скролы")
2 - Как правильно его прятать? Должно прятаться при потере фокуса...
Вообщем должно вести себя (показываться/прятаться) почти как попап меню, за исключением того, что при щелчке мышью внутри моего окна, можно было управлять закрытием онного (PopupMenu закрывается всегда).

Пример вызова был таким:
procedure TForm1.FormContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
begin
 MyP.Show(MousePos); //или MyP.Show(ClientToScreen(MousePos));
end;
где MyP: TMyPopup

Приведенный код для наглядности, и может в корне не верен(я уже запутался что и как). А вообщем идея из примеров Румянцева. Никогда ранее не занимался подобным:) Спасибо.


 
Ketmar ©   (2006-11-12 22:49) [1]

а зачем ты ему parent"ом свою форму назначаешь? вот и "скрывается". desktop ему в parent"ы. дальше, думаю, сам поймёшь.


 
RASkov   (2006-11-13 01:16) [2]

Это тоже из тех же примеров Румянцева:

procedure TMyPopup.CreateWnd;
begin
 inherited;
 Windows.SetParent(Handle, 0);
 //CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
end;

Только хуже стало...
Как нужно правильно сделать? Я так понимаю тут всё к одному связано - ошибся в одном месте и все полетело.
Методом перебора параметров в SetWindowsPos таких как HWND_XXX и стилей в CreateParam.... вообщем сижу в луже.
Вот делаю как у Румянцева (у него хорошо получилось с комбобоксами - выпадающий список можно сделать на основе любого винконтрола) и вот сообственно мой попап - это и есть его выпадающий список, но запутался и не пойму в чем:(

На данный момент (с SetParent) чекбокс, который создается на моем "окне", становится недоступнум и вообще окно недоступно. Т.е. появляется один раз и висит ни на что не реагируя:( Так же нехорошая фича присутствует - если первый(единственный) раз мое окно отобразить в нижнем правом углу формы и потом попробывать изменить размеры формы, что бы как бы мое окно осталось справа от формы, то у формы прокрутка появляется, как будто мое окно на форме.

SetWindowPos(Handle, HWND_TOP, P.X, P.Y, 0, 0,  SWP_NOACTIVATE or SWP_NOSIZE or SWP_SHOWWINDOW);
SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_HIDEWINDOW);
Нужно ли совместно делать Visible:=True/False;?


 
Ketmar ©   (2006-11-13 01:26) [3]

CreateParentedControl() не пробовал? ну очень мне лениво VCL вспоминать. %-) и зачем тебе SetWindowPos() сдался? и вообще -- возьми да напиши на API. %-)


 
RASkov   (2006-11-13 01:45) [4]

Вообщем тут без литры не разберешься, вот еще заметил, что у меня
 MnP:=TMyPopup.Create(Self);
//  MnP.Parent:=Self; <-!!!

Вообщем один раз ^ написал и внимания не обращал, но если закомментировать, то вообще ничего не работает:( Ладно, буду до последнего ковырять исходники с комбиками, может и получится выдернуть тот самый злопалучный список и превратить его в отдельный(независимый) класс, может и в компонент.
Хотя... если у кого есть какие мысли по этому поводу, пишите, может быстрее разберусь с этим "плавучим окном в стиле попап меню". Спасибо.


 
RASkov   (2006-11-13 01:49) [5]

> [3] Ketmar ©   (13.11.06 01:26)
> и зачем тебе SetWindowPos()

Ну там в этих примерах... вообщем не мне сдался, я чесно пытался стырить:)

> CreateParentedControl() не пробовал?

Нет. Спасибо, попробую и этот вариант.

> напиши на API. %-)

Вот только так и останется наверное. Буду вспоминать того чего незнаю:)


 
Наиль ©   (2006-11-13 16:25) [6]

Если размер EXE не принципиален, то можно делать на чистом VCL.
1. Создаёшь PopupForm=class(TForm)
2. PopupForm.BorderStyle=bsNone
3. Всплытие:
3.1 Задать положение PopupForm (SetBounds)
3.2 PopupForm.Show
4. Скрытие
4.1 PopupForm.OnDeactivate=begin; hide; end;
4.2 или просто Hide

Не проверял, но даже если здесь имеются ошибки, то общий смысл верен.
В противном случае, тебе поможет только чистый API.


 
RASkov   (2006-11-14 01:12) [7]

> [6] Наиль ©   (13.11.06 16:25)

Спасибо, но так будет теряться фокус у основной формы. Мне бы хотелось как можно более сымитировать попап меню. Т.е. сделать окно таким как делается оно у выподающих списков например. Оно не отбирает фокус и может выходить за рамки формы. Должно прятаться когда теряет фокус или при определенных условиях в самом окне.

> В противном случае, тебе поможет только чистый API.

Не хотелось бы, т.е. пока незнаю... Возможно нужно поколдовать с CreateParam(Wnd) правильно.
Сейчас пока некогда этим заниматься но на неделе поробую что нибудь решить. Отпишусь если (не)получится.



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

Текущий архив: 2006.12.31;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.052 c
4-1156131902
ZLOFENIX
2006-08-21 07:45
2006.12.31
Получение нажатых клавиш


2-1165787910
ZiTRaX
2006-12-11 00:58
2006.12.31
Проблемы с отображением содержимого таблиц


15-1165853094
Мистер Т
2006-12-11 19:04
2006.12.31
Компонгент "Календарь"


15-1165743020
Derk
2006-12-10 12:30
2006.12.31
Несколько файлов при открытии проекта


4-1156229437
n0name
2006-08-22 10:50
2006.12.31
RichEdit как в Delphi IDE