-
Доброе время суток. Конечно про модальные формы было сказанно довольно много, но всё же задам вопрос: Может кому приходилось делать так чтобы модальная форма запоминала свои размеры (top,left,h...,w...).
то есть при следующем открытии сохранённые размеры использовались бы формой.
-
И что в этом такого необычного?
-
Доброе время суток. Вот простой пример с которого пытаюсь сделать в своей программе, только вот не задача не могу применить его. Чтобы не заморачиваться просто прячу форму и снова показываю и при закрытии основного окна закрываю. program Project1;
uses
windows,
kol;
type TOnEvent = procedure( Sender: PObj )of object;
var
form,Button1,
editbox1,editbox2,
form2,Button5,Button6,
Button7,Button8,Button9,
ListBox1:PControl;
HintWND,HintWnd2: HWND;
TI: TToolInfo;
Tips: array[0..9] of PChar = (
'Кнопка Открыть',
'ЭдитБох1',
'ЭдитБох2',
'',
'Сохранить',
'Удалить',
'Очистить',
'Добавить',
'Отмена',
'ListBox1');
procedure mousemove(Dummy:pointer;Sender: PControl; var Mouse: TMouseEventData );
begin
with TI do
begin
cbSize:=sizeof(TI);
uFlags:=TTF_SUBCLASS;
hWnd:=Sender.GetWindowHandle;
uID:=0;
Rect.Left:=Sender.ClientRect.Left;
Rect.Top:=Sender.ClientRect.Top;
Rect.Right:=Sender.ClientRect.Right;
Rect.Bottom:=Sender.ClientRect.Bottom;
hInst:=HInstance;
lpszText:=Tips[Sender.Tag];
form.StatusText[0]:=Tips[Sender.Tag];
end;
if Assigned( Form2 ) then SendMessage(HintWnd2,TTM_ADDTOOL,0,DWORD(@TI)) else
SendMessage(HintWnd,TTM_ADDTOOL,0,DWORD(@TI));
end;
procedure Destr2(Dummy:pointer;Sender:PControl);
begin
DestroyWindow(HintWnd2);
Form.Show;
end;
procedure clickbutton1(Dummy:pointer;Sender:PControl; var mouse:TMouseEventData);
begin
if not Assigned( Form2 ) then
NewForm( Applet ,'');
Form2.Showmodal;
end;
procedure Destr(Dummy:pointer;Sender:PControl);
begin
DestroyWindow(HintWnd);
end;
procedure Close_form(DummySelf,Sender: PControl; var Accept: Boolean);
begin
accept:=true;
end;
procedure Close_form2(DummySelf,Sender: PControl; var Accept: Boolean);
begin
Accept := FALSE;
Form2.Hide;
button1.Focused:=true; end;
Begin
form:=NewForm(Applet,'hide'+#39+'s '+#8470+'1').SetSize(330,240).CenterOnParent;
form.StatusText[0]:=pchar('');
form.tag:=3;
Button1:=NewButton(form,'Form2.Showmodal').autosize(true);
Button1.CenterOnParent; Button1.Tag:=0;
Button1.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
EditBox1:= NewEditBox(form,[]).SetPosition( 10, 34 ).SetSize( 60, 0 );
EditBox1.Color:=clWhite;
EditBox1.Text :=' 10.00 ';
editbox1.Tag:=1;
EditBox1.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
EditBox2:= NewEditBox(form,[]).SetPosition( 10, 58 ).SetSize( 60, 0 );
EditBox2.Color:=clWhite;
EditBox2.Text :=' 10.01 ';
editbox2.Tag:=2;
EditBox2.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
Button1.OnClick:=TonEvent(MakeMethod(nil,@clickbutton1));
HintWnd:=CreateWindowEx(0,TOOLTIPS_CLASS,nil,0,CW_USEDEFAULT,CW_USEDEFAULT,CW_US EDEFAULT,CW_USEDEFAULT,form.GetWindowHandle,0,HInstance,nil);
form.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
form.OnDestroy:=TonEvent(MakeMethod(nil,@Destr));
form.OnClose:=TOnEventAccept(MakeMethod(nil,@Close_form));
Form2:= NewForm(Applet,'hide'+#39+'s '+#8470+'2').SetClientSize( 320, 222 ).CenterOnParent;
Form2.Style := Form.Style and not (WS_MINIMIZEBOX or WS_MAXIMIZEBOX); form2.Tag:=3;
ListBox1 := NewListBox( form2, [ loNoIntegralHeight ] ).SetPosition( 6, 6 ).SetSize( 241, 169 );
ListBox1.Color := clWindow;
ListBox1.CurIndex := 0;
ListBox1.Tag:=9;
ListBox1.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
Button5:= NewButton( form2, 'Сохранить' ).SetPosition( 156,192).SetSize( 74, 0 );
Button5.tag:=4;
Button5.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
Button6:= NewButton( form2, 'Удалить' ).SetPosition( 80,192).SetSize( 72, 0 );
Button6.tag:=5;
Button6.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
Button7:= NewButton( form2, 'Очистить' ).SetPosition( 250,148).SetSize( 68, 0 );
Button7.tag:=6;
Button7.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
Button8:= NewButton( form2, 'Добавить' ).SetPosition(8,192).SetSize( 68, 0 );
Button8.tag:=7;
Button8.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
Button9:= NewButton( form2, 'Отмена' ).SetPosition( 236,192).SetSize( 68, 0 );
Button9.tag:=8;
Button9.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
HintWnd2:=CreateWindowEx(0,TOOLTIPS_CLASS,nil,0,CW_USEDEFAULT,CW_USEDEFAULT,CW_U SEDEFAULT,CW_USEDEFAULT,form2.GetWindowHandle,0,HInstance,nil);
form2.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
form2.OnDestroy:=TonEvent(MakeMethod(nil,@Destr2));
form2.OnClose:=TOnEventAccept(MakeMethod(nil,@Close_form2));
form2.Hide;
Run(form);
end.
-
В своей программе делаю тоже самое
procedure Edit(Sender:pcontrol);
begin
if not Assigned( EditQst ) then
NewForm( Applet ,'');
EditQst.Showmodal;
end;
procedure EditQstClose(Dummy:pointer;Sender: PControl; var Accept: Boolean);
begin
accept:=false; EditQst.hide; QRez.Focused:=true;
end;
и ...
EditQst:=NewForm(applet,'Редактирование вопроса').SetSize( 496,285 ).SetPosition( 327, 248 );
EditQst.Color := TColor(clBtnface);
EditQst.Style := Form.Style and not (WS_MINIMIZEBOX or WS_MAXIMIZEBOX); EditQst.Font.FontName := 'MS Sans Serif';
EditQst.Font.FontCharset := 0;
EditQst.Tag:=2; EditQst.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
EditQst.OnResize:=TonEvent(MakeMethod(nil,@formResize));
PB1 := NewPaintBox(EditQst ).SetPosition(0, 0 ).SetSize(362, 216 );
PB1.Color := TColor(clWhite);
PB1.Tag:=2; PB1.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
L1 := NewLabel( PB1, 'Вопрос:' ).SetPosition( 12, 23 ).SetSize( 50, 0 );
L1.Font.Color := TColor(clblue);
EB1 := NewEditBox( PB1, [ ] ).SetPosition( 68, 18).SetSize( 282, 0);
EB1.Color := clWindow;
EB1.Tag:=5; EB1.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
L2 := NewLabel( PB1, 'Ответы:' ).SetPosition( 8, 53 ).SetSize( 54, 0 );
L2.Font.Color := TColor(clblue);
Bt2 := NewBitBtn( PB1, 'Добавить', [ ], glyphLeft, LoadBmp( hInstance, 'BITBTN2_BITMAP', PB1 ), 1 ).SetPosition( 70, 52 ).SetSize( 84, 22 );
Bt2.Color := TColor(clBtnFace);
Bt2.TextShiftX := 1;
Bt2.TextShiftY := 1;
Bt2.OnClick:=TonEvent(MakeMethod(nil,@Bt2click));
Bt2.Tag:=6; Bt2.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
Bt1 := NewBitBtn( PB1, 'Удалить', [ ], glyphLeft, LoadBmp( hInstance, 'BITBTN1_BITMAP', PB1 ), 1 ).SetPosition( 164, 52 ).SetSize( 78, 22 );
Bt1.Color := TColor(clBtnFace);
Bt1.TextShiftX := 1;
Bt1.TextShiftY := 1;
Bt1.OnClick:=TonEvent(MakeMethod(nil,@Bt1click));
Bt1.Tag:=7; Bt1.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
QuestionCheckList:=newlistview(PB1,lvsDetailNoHeader,[lvoNoScroll,lvoCheckBoxes] ,nil,nil,nil).SetPosition(12,82).SetSize(332,132);
QuestionCheckList.Tag:=2; QuestionCheckList.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
B1 :=NewButton( EditQst, 'Да' ).SetPosition( 216, 224 ).SetSize( 75, 25 );
B1.OnClick:=TonEvent(MakeMethod(nil,@DaBtn));
B1.Tag:=8; B1.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
B2 :=NewButton( EditQst, 'Отмена' ).SetPosition( 304, 224 ).SetSize( 75, 25 );
B2.OnClick:=TonEvent(MakeMethod(nil,@CloseBtn));
B2.Tag:=4; B2.OnMouseMove:=TonMouse(MakeMethod(nil,@mousemove));
HintWnd3:=CreateWindowEx(0,TOOLTIPS_CLASS,nil,0,CW_USEDEFAULT,CW_USEDEFAULT,CW_U SEDEFAULT,CW_USEDEFAULT,EditQst.GetWindowHandle,0,HInstance,nil);
EditQst.OnClose:=TOnEventAccept(MakeMethod(nil,@EditQstClose));
EditQst.hide;
весь код : http://slil.ru/28805632
-
Не знаю, как на KOL, в Windows решается обработчиком одного сообщения: например, та самая модальная форма: unit modal;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfModal = class(TForm)
Edit1: TEdit;
Button1: TButton;
private
procedure WmActivate (var Message: TWMActivate); message WM_ACTIVATE;
end;
var
fModal: TfModal;
implementation
uses Types;
var
IsSaved: Boolean;
SavedPos: TRect;
procedure TfModal.WmActivate(var Message: TWMActivate);
begin
if Message.Active = WA_INACTIVE then
begin
GetWindowRect(Handle, SavedPos);
IsSaved := true;
end
else if IsSaved then
MoveWindow(Handle, SavedPos.Left, SavedPos.Top,
SavedPos.Right - SavedPos.Left, SavedPos.Bottom - SavedPos.Top, true);
inherited;
end;
end.
-
Доброе время суток. Вы имеете ввиду что-то вроде ....
var
IsSaved: Boolean; SavedPos: TRect;
....
function WndProcActiv(Sender: PControl; var M: TMsg; var Rslt: Integer ): Boolean;
begin
Result:=false;
if M.message =WM_NCACTIVATE then
begin
Result:=true;
if Bool(M.wParam) then begin GetWindowRect(EditQst.Handle, SavedPos); IsSaved := true;
end else if IsSaved then
MoveWindow(EditQst.Handle, SavedPos.Left, SavedPos.Top,
SavedPos.Right - SavedPos.Left, SavedPos.Bottom - SavedPos.Top, true)
end;
end;
....
EditQst.AttachProc(@WndProcActiv); Хм... Не получится форма создается и уничтожается runtime
-
В KOL+MCK я использовал событие OnFormCreate. Если MCK не используется, все еще проще: код установки размеров и позиции встраивается просто в тот участок кода, который создаёт форму. В VCL, аналогично я использую OnCreate формы. И никакой разницы, модальная форма или нет.
-
Спасибо. Принято. Вопрос: как избавится от того, что когда форма уже вновь создаваясь и получив нужные (l,t,w,h) всё же не появляется там же где её закрыли, а смещается то влево, то вправо?
-
Искать ошибку.
-
> Хм... Не получится форма создается и уничтожается runtime
не вижу проблемы обработать WM_ACTIVATE у динамически создаваемой формы. В KOL разве нет аналога WindowProc ?
-
Есть OnMessage, он лучше. Так как не требует наследовать новый класс, работает для любого контрола или формы.
НО. The WM_ACTIVATE message is sent to both the window being activated and the window being deactivated. Каждый раз, а не при первой активации после создания.
И. Зачем сначала создавать форму одного размера, выравнивая на ней контролы, а затем менять ее размер, получая кучу сообщений об изменении размеров родительских контролов и перевыравнивая все выровненные дочерние. Когда можно задать размеры сразу при создании.
-
Доброе время суток. Отдохнул один день. Отказался от старого варианта. Посмотрел новый. И всё пошло как надо. ...
var
IsSaved:boolean;SavedPos: TRect;
...
function WndProcActiv(Sender: PControl; var M: TMsg; var Rslt: Integer ): Boolean;
begin
Result:=false;
if M.message =WM_NCMOUSEMOVE then
begin
Result:=true;
if Bool(M.wParam) then begin
GetWindowRect(EditQst.Handle, SavedPos);
IsSaved := true;
end;
end;
end;
...
if not IsSaved then
EditQst:=NewForm(QRez,'Редактирование вопроса').SetSize( 496,305 ).SetPosition( 327, 248 ) else
EditQst:=NewForm(QRez,'Редактирование вопроса').SetSize(SavedPos.Right - SavedPos.Left, SavedPos.Bottom - SavedPos.Top).SetPosition( SavedPos.Left, SavedPos.Top );
...
EditQst.AttachProc(@WndProcActiv);
...
formResize(Sender); ... Всем Спасибо, тема закрыта;)
-
Можно было просто через событие Onmessage без AttachProc(@WndProcActiv) не сразу посмотрел:)
|