Форум: "Основная";
Текущий архив: 2006.12.31;
Скачать: [xml.tar.bz2];
Вниз"Всплывающее окно" Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.039 c