在做Mis項目過程中,有時需要讓用戶自己來實現窗體控件的布局,比如酒店管理中就需要對餐廳餐桌位置進行布局。要實現這種功能,必須做好三件事:
1、設置進入控件邊緣的光標形狀;
2、改變控件的大小及位置;
3、保存窗體控件的位置及狀態,窗體下次啟動時重新設置它們的這些信息。具體步驟如下:
1、修改控件光標。只需要在進入控件的時候,將screen的cursor屬性設置成對應形狀即可,控件都有一個OnMouseMove事件,在這個事件中調用它就可以實現。我已經將它封裝成函數如下:
procedure CursorControl(Control: TControl; Shift: TShiftState; X, Y, Prec: integer);
begin
//光標在控件的最左側
if (X<=Prec) and (Y>Prec) and (Y<Control.Height-Prec) then Control.Cursor := crSizeWE
// 光標在控件的最右側
else if (X>=Control.Width-Prec) and (Y>Prec) and (Y<Control.Height-Prec) then Control.Cursor := crSizeWE
// 光標在控件的最上側
else if (X>Prec) and (X<Control.Width-Prec) and (Y<=Prec) then Control.Cursor := crSizeNS
// 光標在控件的左上角
else if (X<=Prec) and (Y<=Prec) then Control.Cursor := crSizeNWSE
// 光標在控件的右上角
else if (X>=Control.Width-Prec) and (Y<=Prec) then Control.Cursor := crSizeNESW
// 光標在控件的最下側
else if (X>Prec) and (X<Control.Width-Prec) and (Y>=Control.Height-Prec) then Control.Cursor := crSizeNS
// 光標在控件的左下角
else if (X<=Prec) and (Y>=Control.Height-Prec) then Control.Cursor := crSizeNESW
// 光標在控件的右下角
else if (X>=Control.Width-Prec) and (Y>=Control.Height-Prec) then
Control.Cursor := crSizeNWSE
// 光標在控件的客戶區(移動整個控件)
else if (X>5) and (Y>5) and (X<Control.Width-5) and (Y<Control.Height-5) then Control.Cursor := crSizeAll
else Control.Cursor := crDefault;//恢復默認光標
end;
2、修改窗體控件的大小和位置。其實有一種最簡便的方法那就是向控件發送相應的消息即可。我也已將它封裝成一個函數,在控件的OnMouseDown事件中調用即可。函數如下:
procedure ManipulateControl(Control: TControl; Shift: TShiftState; X, Y, Prec: integer);
var
SC_MANIPULATE: Word;//保存對應消息值
begin
// 光標在控件的最左側
if (X<=Prec) and (Y>Prec) and (Y<Control.Height-Prec) then SC_MANIPULATE := $F001
// 光標在控件的最右側
else if (X>=Control.Width-Prec) and (Y>Prec) and (Y<Control.Height-Prec) then SC_MANIPULATE := $F002
// 光標在控件的最上側
else if (X>Prec) and (X<Control.Width-Prec) and (Y<=Prec) then begin
SC_MANIPULATE := $F003
// 光標在控件的左上角
else if (X<=Prec) and (Y<=Prec) then SC_MANIPULATE := $F004
// 光標在控件的右上角
else if (X>=Control.Width-Prec) and (Y<=Prec) then SC_MANIPULATE := $F005
// 光標在控件的最下側
else if (X>Prec) and (X<Control.Width-Prec) and (Y>=Control.Height-Prec) then SC_MANIPULATE := $F006
// 光標在控件的左下角
else if (X<=Prec) and (Y>=Control.Height-Prec) then SC_MANIPULATE := $F007
// 光標在控件的右下角
else if (X>=Control.Width-Prec) and (Y>=Control.Height-Prec) then SC_MANIPULATE := $F008
// 光標在控件的客戶區 ( 移動整個控件 )
else if (X>5) and (Y>5) and (X<Control.Width-5) and (Y<Control.Height-5) then SC_MANIPULATE := $F009
else SC_MANIPULATE := $F000;
if Shift=[ssLeft] then
begin
ReleaseCapture;
Control.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);//向控件發送改變光標消息
end;
end;
3、保存和恢復窗體控件的大小及位置。通過對窗體的Component元件進行遍歷,然後將它們的位置及大小屬性值寫入INI文件中,窗體下次啟動時再通過讀取INI文件恢復窗體控件的這些屬性即可。關於這個解決辦法網上有很多,還有現成的控件不用寫一行代碼就可實現的,限於篇幅在此我就不再累述了。有興趣的朋友不防一試。所有代碼在WIN2000/DELPHI7下測試通過。