Как отобразить элемент управления (например, TListbox) за пределами TForm

Как я могу отобразить список за пределами родительской формы во время выполнения:

введите здесь описание изображения

Изображение получается из IDE при нажатии на список во время разработки. Я хотел бы добиться этого эффекта во время выполнения.


person RaelB    schedule 02.07.2018    source источник
comment
Вы не можете. Вероятно, это изображение перетаскивания, а не сам элемент управления.   -  person Sertac Akyuz    schedule 02.07.2018
comment
Я помню DropDownForm от MustangPeak, который реализовал поведение, подобное ComboBox, как вы, кажется, хотите. Возможно, вы сможете почерпнуть из него некоторые идеи, если вам удастся найти копию.   -  person Uli Gerhardt    schedule 02.07.2018
comment
Вы имеете в виду добиться того же эффекта при перетаскивании элемента управления во время выполнения или сохранить его таким образом?   -  person Victoria    schedule 02.07.2018
comment
Вам нужно, чтобы это была его собственная форма.   -  person Jerry Dodge    schedule 02.07.2018
comment
@Uli и Джерри: Спасибо, это дает мне представление о том, как это сделать.   -  person RaelB    schedule 02.07.2018
comment
Зависит от того, что вы хотите сделать. Отсюда мой комментарий. Либо вам нужно перетаскивание изображения, либо всплывающая форма.   -  person Victoria    schedule 02.07.2018
comment
@Victoria: Я упомянул перетаскивание только потому, что именно так мне удалось получить эту картинку, но это не то, чего я хочу. Я хочу получить всплывающую форму/список.   -  person RaelB    schedule 02.07.2018
comment
Мое замешательство возникло из-за вашего предложения. Я хотел бы добиться этого эффекта во время выполнения. Я думал, что вы хотите перетаскивать элементы управления так же, как это делает конструктор форм IDE.   -  person Victoria    schedule 02.07.2018
comment
Проголосовали против... Почему?   -  person RaelB    schedule 02.07.2018


Ответы (1)


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

введите описание изображения здесь

Здесь Form1 — это основная форма со следующим обработчиком OnClick для Button1:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(nil);
  try
    Form2.Left := ClientOrigin.X + 140;
    Form2.Top := ClientOrigin.Y + ClientHeight - 20;
    Form2.ShowModal;
    Edit1.Text := IntToStr(Form2.ModalResult);
  finally
    Form2.Free;
  end;
end;

Поскольку вторая форма (Form2) не связана (дочерняя и родительская) с Form1, мы должны указать ее местоположение в пикселях экрана, но все же относительно Form1. Поэтому мы используем Form1.ClientOrigin (верхняя и левая часть клиентской области Form1 в качестве экранных координат) в качестве эталона.

Вторая форма, Form2, содержащая TListBox, имеет следующие настройки свойств:

BorderStyle = bsNone
KeyPreview = True (to catch `Enter` key)

и у него есть обработчик события OnKeyUp, написанный как

procedure TForm2.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_RETURN then
    ModalResult := ListBox1.ItemIndex;
end;
person Tom Brunberg    schedule 02.07.2018
comment
Спасибо. Для моих целей лучше вызвать Form2.Show (не модальный) и установить FormStyle в fsStayOnTop. Если Form2 является ShowModal, то Form1 полностью недоступна, что не является идеей наличия Listbox в форме. - person RaelB; 03.07.2018
comment
Я понимаю вашу точку зрения, но тогда вам также нужно решить, как поступить с пользователем, перемещающим форму1, или минимизирующей / максимизирующей, или просто изменяющей ее размер. Я не говорю, что это невыполнимо, но... - person Tom Brunberg; 03.07.2018