![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Диалог внутри формы: как сделать лучше?
GrayFace © (2004-01-27 15:25:00)Мне приходится использовать Timer. Иначе вылетает по ошибке. Как можно без него? Вот часть кода:
procedure TForm2.FontDialogShow(Sender: TObject);
begin
Form2.Show;
timer2.Enabled:=true;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if isWindow(FontDialog.Handle) then SendMessage(FontDialog.Handle,wm_close,0,0);
end;
procedure TForm2.FontDialogClose(Sender: TObject);
begin
Form2.Close;
end;
procedure TForm2.Timer2Timer(Sender: TObject);
var x,y:LongWord; p:TPoint; r,r1:TRect;
begin
Timer2.Enabled:=false;
windows.GetWindowRect(FontDialog.Handle,r1);
if not IsWindow(FontDialog.Handle) then exit;
windows.GetClientRect(FontDialog.Handle,r);
p:=ClientToScreen(MakePoint(0,0));
x:=0-p.X+Left;
y:=0-p.Y+Top;
Constraints.MaxWidth:=r1.Right-r1.Left;
Constraints.MinWidth:=r1.Right-r1.Left;
SetWindowPos(FontDialog.Handle,HWND_BOTTOM,x,y,0,0,SWP_NOSIZE or SWP_NOSENDCHANGING or SWP_NOACTIVATE);
end;
procedure TForm2.FormShow(Sender: TObject);
begin
if not isWindow(FontDialog.Handle) then exit;
windows.SetParent(FontDialog.Handle,Panel1.Handle);
end;
YuRock (2004-01-30 22:25:00) [1]> GrayFace
Советую вызвать этот диалог через API (см. исходники TFontDialog.Execute) - тогда сможете сделать все, что угодно.
Но если уж хотите использовать готовое, то вот:
unit Unit1;
interface
uses
Windows, Classes, Controls, StdCtrls, Forms, Messages, Dialogs, SysUtils,
Graphics, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
FontDialog1: TFontDialog;
procedure Button1Click(Sender: TObject);
procedure FontDialog1Show(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
FontDialog1.OnShow := FontDialog1Show;
if FontDialog1.Execute then begin
// Здесь делайте все, что хотите...
end;
end;
procedure TForm1.FontDialog1Show(Sender: TObject);
var
hHandle: HWND;
begin
// Установка родителя диалога
Windows.SetParent(FontDialog1.Handle, Handle);
// Убираем Caption
SetWindowLong(FontDialog1.Handle, GWL_STYLE, GetWindowLong(FontDialog1.Handle, GWL_STYLE) and not WS_CAPTION);
SetWindowLong(FontDialog1.Handle, GWL_EXSTYLE, GetWindowLong(FontDialog1.Handle, GWL_EXSTYLE) and not WS_EX_DLGMODALFRAME);
// Двигаем как надо
MoveWindow(FontDialog1.Handle, 0, 0, ClientWidth, ClientHeight, True);
// "Обманываем" модальность
hHandle := Handle;
repeat
EnableWindow(hHandle, True);
hHandle := GetParent(hHandle);
until hHandle = 0;
end;
end.
Кстати, я уже говорил об этом в [3]!
YuRock (2004-01-30 21:31:00) [2]> Игорь Шевченко
Я же предупреждал в [10] - это мое личное представление об удобстве и красоте
Grinder (2004-01-30 19:38:00) [3]fsStayOnTop для неглавной формы - это ужас. Не работает. Только для текущего проекта и всё.
Игорь Шевченко (2004-01-30 18:30:00) [4]YuRock © (29.01.04 10:29)
> а как вы относитесь к тому, что метод SetFocus (почти всегда)
> вызывает exception, если окно "disabled or invisible"? Постоянно
> приходится пользоваться Windows.SetFocus!
if WinControl.CanFocus then
WinControl.SetFocus
Игорь Шевченко (2004-01-30 18:27:00) [5]YuRock © (28.01.04 19:23)
Не могу согласиться с тем, что приведенные примеры - это корявость программистов Borland.
Я бы посоветовал изучить раздел Tips and Tricks на www.torry.net, там много полезных советов.
Если не ошибаюсь, в свое время на delphipus.da.ru была статья с более убедительными примерами не совсем корректного поведения классов VCL и пути их обхода. Но их было приведено немного, и в повседневной практике они не часто встречаются.
GrayFace (2004-01-30 17:46:00) [6]CreateParanted, возможно, не глючит. Кстати, у кнопки есть CreateParanted. Кто-нибудь знает, как им пользоваться? Кнопка ведь все равно не показывается, пока не поставишь Button1.Parent.
Все-таки, хоть это уже и не важно в данный момент, но я повторяю: Я использую TFontDialog и SetParentю его во 2-ю форму. При Execute он показывается модально. Это я обхожу это, как написал в начале, но это криво. Как сделать нормально?
YuRock (2004-01-29 12:06:00) [7]> Anatoly Podgoretsky © (29.01.04 11:59) [26]
1. (В общем случае) Да, пользователь должен знать об ошибке программиста (если это ошибка программиста). По-этому я стараюсь свести количество ошибок к минимуму (в том числе - количество exception'ов, если, конечно, я их создал не специально).
2. (к конкретному примеру) В 99.99% случаев, если я хочу поставить фокус на невидимое или disabled окно, и это, естественно, не получается, то мне нужно не трогать фокус, т.е. вообще ничего не делать. За что я и ценю Windows.SetFocus (а используй я TWinControl.SetFocus - мне пришлось бы либо делать проверку if Visible and Enabled или вообще исключение обрабатывать - разве не идиотизм?)
Anatoly Podgoretsky (2004-01-29 11:59:00) [8]YuRock © (29.01.04 10:50) [19]
Да нужно, иначе как он узнает об ошибке программиста, если тот ее замаскирует.
YuRock (2004-01-29 11:57:00) [9]> Anatoly Podgoretsky © (29.01.04 11:53) [24]
> Очень ты Борландом не доволен
Я еще раз обращаю внимание всех на то, что я ДОВОЛЕН Борландом (см. самый конец [10]).
Но это не означает, что некоторый код Борланда не поддается критике.
Anatoly Podgoretsky (2004-01-29 11:53:00) [10]YuRock © (28.01.04 17:17) [8]
Почему именно Борланд, что больше никого нет.
Очень ты Борландом не доволен, да плюнь ты на них.
Ежики плакали, кололись, но продолжади есть кактус.
YuRock (2004-01-29 11:47:00) [11]> назовите мне хоть один способ вызова пользователем метода SetFocus
Выполнение (части) программы, в котором есть вызов этого метода. Слава богу, что в моих программах таких "частей" немного...
Плохиш (2004-01-29 11:24:00) [12]
> YuRock © (29.01.04 11:11) [21]
> Понятно
Ничего тебе не понятно
Вы что прилагаете к программам документацию по делфи?
И назовите мне хоть один способ вызова пользователем метода SetFocus.
YuRock (2004-01-29 11:11:00) [13]Понятно... Я раньше думал, что exception'ы иногда бывают и на машинах пользователей, и они емы не нужны... Ну, коль это для программиста, то эти ситуации надо в документациях описывать, понятно...
Т.е. что если непонятное окошко появилось на экране - то это не для Вас, заплативших деньги за программу, а для "программиста, который зачем-то пытается активизировать запрещённые компоненты"...
Что ж, используйте такие методы дальше...
Плохиш (2004-01-29 10:56:00) [14]
> YuRock © (29.01.04 10:50) [19]
> > И правильно делает
> Да... пользователю очень нужно знать об этом...
А при чём здесь пользователь? Система говорит об этом программисту, который зачем-то пытается активизировать запрещённые компоненты.
YuRock (2004-01-29 10:50:00) [15]> И правильно делает
Да... пользователю очень нужно знать об этом...
Плохиш (2004-01-29 10:31:00) [16]
> YuRock © (29.01.04 10:29) [17]
> Да, кстати, мастера, а как вы относитесь к тому, что метод
> SetFocus (почти всегда) вызывает exception, если окно "disabled
> or invisible"?
И правильно делает
YuRock (2004-01-29 10:29:00) [17]Да, кстати, мастера, а как вы относитесь к тому, что метод SetFocus (почти всегда) вызывает exception, если окно "disabled or invisible"? Постоянно приходится пользоваться Windows.SetFocus! Это Вам доставляет удовольствие, а, VMcL?
YuRock (2004-01-29 10:20:00) [18]Удалено модератором
Примечание: Дубль
YuRock (2004-01-29 10:20:00) [19]> VMcL © (29.01.04 09:54) [13]
> Если ничто не помогает, прочтите наконец инструкцию
Ну хватит умничать, форумы не для этого
VMcL (2004-01-29 09:59:00) [20]>> YuRock © (28.01.04 19:23) [10]
>Графические объекты (я имею в виду TLabel, TSpeedButton...).
>Это во-первых тормозит перерисовку окна
Ну если насовать штук 200, то может и тормозят. Это раз. А во-вторых, TStaticText и TBitBtn никто не отменял.
>во-вторых напрочь убивает возможность поиска этих
>"на вид окон" из других программ
Это ужасно. Вот пишу я программу и только и думаю, а вдруг кто-то захочет найти мой контрол по HWND.
Если захочу сделать взаимодействие с др. программами, предусмторю специальные способы.