Для тестирования можно взять схему из справки по MST_UseEditCtrl c приделанным debug-ом:
Add(MainForm,314817,336,154)
{
Width=445
Height=261
Caption="Пример использования MST_UseEditCtrl"
Position=1
link(onCreate,10041622:doEnum,[])
}
Add(MST_UseEditCtrl,3498945,329,252)
{
MSTControl="MtS_tbl"
PColor(onCellSize,8421440)
PColor(onEscCell,32768)
link(onCellSize,13620734:doValue,[(375,258)(375,223)])
link(onEnterCell,87120:doEvent1,[])
link(onEscCell,9235417:doEvent,[(374,272)(374,293)])
}
Add(StrList,15034837,399,112)
{
Strings=#15:sdfsdf;aaaaa;;0|15:fzsdfzs;bbbb;;3|14:sdfszz;cccc;;2|15:sdfszz;ddddd;;0|15:sdfszz;eeeee;;1|15:sdfszz;fffff;;3|15:fzsdfzs;gggg;;2|14:sdfszz;hhhh;;0|16:fzsdfzs;iiiii;;3|16:sdfszz;jjjjjj;;1|
}
Add(MT_String,922736,469,154)
{
link(onResult,2904434:doRowAction,[])
}
Add(ArrayEnum,10041622,413,168)
{
link(onItem,922736:doMTString,[])
link(Array,15034837:Array,[])
}
Add(MST_RowAction,2904434,525,154)
{
MSTControl="MtS_tbl"
}
Add(MT_MultiData,2622840,413,259)
{
Point(Data)
link(onData1,9450650:doLeft,[])
link(onData2,9450650:doTop,[])
link(Data,13620734:Value,[])
}
Add(Hub,15922927,476,273)
{
link(onEvent1,9450650:doSetFocus,[])
link(onEvent2,9450650:doBringToFront,[])
}
Add(Hub,87120,385,259)
{
link(onEvent1,2622840:doSeparateMT,[])
link(onEvent2,15922927:doEvent1,[(407,272)(407,279)])
}
Add(DatePicker,9450650,525,252)
{
Left=30
Top=205
Width=90
Font=[MS Sans Serif,6,0,0,1]
Point(doLeft)
Point(doTop)
Point(doSetFocus)
Point(doBringToFront)
Point(DateTime)
Point(doSendToBack)
link(onChange,10029744:doConvert,[(571,258)(571,303)(513,303)(513,321)])
}
Add(DateConvertor,10029744,525,315)
{
Mode=9
Format="dd-MM-yyyy"
Point(Data)
link(onResult,3498945:doSetData,[(571,321)(571,359)(317,359)(317,258)])
link(Data,9450650:DateTime,[])
}
Add(MTStrTbl,9842821,336,112)
{
Left=25
Top=20
Width=360
Height=170
Font=[MS Sans Serif,12,0,0,1]
Name="MtS_tbl"
Columns=#1:1|1:2|1:3|
ColumnWidth=90
}
Add(MT_Memory,13620734,413,217)
{
}
Add(Debug,9235417,392,287)
{
link(onEvent,9450650:doSendToBack,[])
}
unit hiMST_UseEditCtrl;
interface
uses Windows, Messages, Kol, Share, Debug, hiMTStrTbl;
const
HDN_FIRST = -300; { Header }
HDN_ITEMCHANGEDA = HDN_FIRST-1;
HDN_ITEMCHANGEDW = HDN_FIRST - 21;
type
tagNMHEADERA = packed record
Hdr: TNMHdr;
Item: Integer;
Button: Integer;
PItem: PHDItemA;
end;
HD_NOTIFY = tagNMHEADERA;
type
THIMST_UseEditCtrl = class(TDebug)
private
sControl: PControl;
NewLine: integer;
FMSTControl: IMSTControl;
OldMessage: TOnMessage;
redaction: boolean;//test
procedure SetMSTControl(Value: IMSTControl);
procedure snewcuridx(value:integer);
function gnewcuridx: integer;
function fredaction: boolean;
function fctl3d: boolean;
public
_prop_KeyCellEnter: byte;
_prop_DblClick: boolean;
_data_Row: THI_Event;
_data_Col: THI_Event;
_event_onEscCell: THI_Event;
_event_onEnterCell: THI_Event;
_event_onCellSize: THI_Event;
_event_onClientRect: THI_Event;
property _prop_MSTControl: IMSTControl read FMSTControl write SetMSTControl;
property NewCurIdx:integer read gnewcuridx write snewcuridx;
procedure _work_doSetData(var _Data: TData; Index: word);
procedure _work_doClientRect(var _Data: TData; Index: word);
procedure _var_Index(var _Data: TData; Index: word);
procedure _var_Cell(var _Data: TData; Index: word);
procedure _var_SubItem(var _Data: TData; Index: word);
procedure _var_Matrix(var _Data: TData; Index: word);
protected
function _OnMessage(var Msg: TMsg; var Rslt: Integer): Boolean;
end;
implementation
//------------------------------------------------------------------------------
//
function THIMST_UseEditCtrl._OnMessage;
type
TMouseDownPt = packed record
X: Word;
Y: Word;
end;
var
R, ARect: TRect;
Pt: TMouseDownPt;
HTI: TLVHitTestInfo;
Data: TData;
mt: PMT;
l: TListViewOptions;
procedure InitOnEvent;
var
b: integer;
begin
if FRedaction then exit;
redaction := true;//test
R := sControl.LVSubItemRect(NewLine, NewCurIdx);
if NewCurIdx = 0 then
begin
ARect := sControl.LVItemRect(NewLine, lvipLabel);
R.Left := ARect.Left;
R.Right := ARect.Right;
end;
if fctl3d then
b := 2
else
b := 1;
l := sControl.LVOptions;
dtInteger(Data, R.Left + sControl.Left + b);
mt := mt_make(Data);
mt_int(mt, R.Top + sControl.Top + b);
mt_int(mt, R.Right - R.Left - 1);
mt_int(mt, R.Bottom - R.Top - 1);
_hi_OnEvent_(_event_onCellSize, Data);
mt_free(mt);
end;
procedure EscCell;
begin
if not redaction then exit;//test
redaction := false;//test
R := sControl.LVItemRect(NewLine, lvipBounds);
ARect := sControl.LVItemRect(NewLine, lvipLabel);
R.Left := ARect.Left;
InvalidateRect(sControl.Handle, @R, false);
if not FRedaction then
_hi_OnEvent(_event_onEscCell, sControl.LVItems[NewLine, NewCurIdx]);
end;
begin
Result := false;
l:= sControl.LVOptions;
case Msg.message of
WM_NOTIFY:
if (HD_NOTIFY(Pointer(Msg.LParam)^).Hdr.code = HDN_ITEMCHANGEDA) or
(HD_NOTIFY(Pointer(Msg.LParam)^).Hdr.code = HDN_ITEMCHANGEDW) then
InitOnEvent;
WM_RBUTTONDOWN, WM_LBUTTONDOWN:
begin
Pt:= TMouseDownPt(Msg.lParam);
HTI.pt.x := Pt.X;
HTI.pt.y := Pt.Y;
sControl.Perform( LVM_SUBITEMHITTEST, 0, Integer( @HTI ) );
if (HTI.flags <> LVHT_ONITEMSTATEICON) and (HTI.iItem <> -1) then
begin
NewLine := HTI.iItem;
NewCurIdx := HTI.iSubItem;
end;
EscCell;
end;
WM_LBUTTONDBLCLK:
begin
Pt:= TMouseDownPt(Msg.lParam);
HTI.pt.x := Pt.X;
HTI.pt.y := Pt.Y;
sControl.Perform( LVM_SUBITEMHITTEST, 0, Integer( @HTI ) );
if (HTI.flags <> LVHT_ONITEMSTATEICON) and _prop_DblClick and (HTI.iItem <> -1) then
begin
InitOnEvent;
_hi_onEvent(_event_onEnterCell);
end;
end;
WM_HSCROLL, WM_VSCROLL:
EscCell;
WM_KEYDOWN:
begin
Case Msg.WParam of
VK_LEFT, VK_RIGHT:
begin
if (lvoRowSelect in l) then
begin
NewCurIdx := NewCurIdx + Msg.wParam - $26;
if NewCurIdx >= sControl.LVColCount then
NewCurIdx := sControl.LVColCount - 1
else
if NewCurIdx < 0 then NewCurIdx := 0;
EscCell;
end;
end;
VK_UP, VK_DOWN:
begin
NewLine := NewLine + Msg.wParam - $27;
if NewLine >= sControl.Count then
NewLine := sControl.Count - 1
else
if NewLine < 0 then
NewLine := 0;
EscCell;
end;
VK_RETURN:
if _prop_KeyCellEnter = 1 then
begin
InitOnEvent;
_hi_onEvent(_event_onEnterCell);
end;
VK_F2:
begin
InitOnEvent;
_hi_onEvent(_event_onEnterCell);
end;
VK_ESCAPE:
EscCell;
end;
end;
end;
Result := Result or _hi_OnMessage(OldMessage, Msg, Rslt);
end;
procedure THIMST_UseEditCtrl.snewcuridx;
begin
if not Assigned(_prop_MSTControl) then exit;
_prop_MSTControl.setnewcuridx(value);
end;
function THIMST_UseEditCtrl.gnewcuridx;
begin
if Assigned(_prop_MSTControl) then
Result := _prop_MSTControl.getnewcuridx
else
Result := 0;
end;
function THIMST_UseEditCtrl.fredaction;
begin
if Assigned(_prop_MSTControl) then
Result := _prop_MSTControl.getfredaction
else
Result := true;
end;
function THIMST_UseEditCtrl.fctl3d;
begin
if Assigned(_prop_MSTControl) then
Result := _prop_MSTControl.getfctl3d
else
Result := true;
end;
procedure THIMST_UseEditCtrl.SetMSTControl;
begin
if Value = nil then exit;
FMSTControl := Value;
sControl := FMSTControl.ctrlpoint;
FMSTControl.detachwndproc;
OldMessage:= sControl.OnMessage;
sControl.OnMessage := _OnMessage;
end;
procedure THIMST_UseEditCtrl._work_doSetData;
var
dControl: PControl;
begin
if not Assigned(_prop_MSTControl) then exit;
dControl := _prop_MSTControl.ctrlpoint;
dControl.LVItems[NewLine, NewCurIdx] := ToString(_Data);
end;
// Содержит индекс столбца выделенной ячейки
//
procedure THIMST_UseEditCtrl._var_SubItem;
begin
dtInteger(_Data, NewCurIdx);
end;
// Содержит значение выбранной ячейки под курсором
//
procedure THIMST_UseEditCtrl._var_Cell;
var
dControl: PControl;
begin
if not Assigned(_prop_MSTControl) then exit;
dControl := _prop_MSTControl.ctrlpoint;
dtString(_Data, dControl.LVItems[NewLine, NewCurIdx]);
end;
// Содержит индекс выделенной строки
//
procedure THIMST_UseEditCtrl._var_Index;
var
sControl: PControl;
begin
if not Assigned(_prop_MSTControl) then exit;
sControl := _prop_MSTControl.ctrlpoint;
dtInteger(_Data, sControl.CurIndex);
end;
// Матрица строк
//
procedure THIMST_UseEditCtrl._var_Matrix;
begin
if not Assigned(_prop_MSTControl) then exit;
_prop_MSTControl.matrix(_Data);
end;
procedure THIMST_UseEditCtrl._work_doClientRect;
var
Row,Col: integer;
R, ARect: TRect;
dTop, dWidth, dHeight, Data: TData;
b: integer;
sControl: PControl;
begin
Row := ReadInteger(_Data, _data_Row);
Col := ReadInteger(_Data, _data_Col);
if not Assigned(_prop_MSTControl) then exit;
sControl := _prop_MSTControl.ctrlpoint;
R := sControl.LVSubItemRect(Row, Col);
if Col = 0 then
begin
ARect := sControl.LVItemRect(Row, lvipLabel);
R.Left := ARect.Left;
R.Right := ARect.Right;
end;
if fctl3d then
b := 2
else
b := 1;
dtInteger(Data, R.Left + sControl.Left + b);
dtInteger(dWidth, R.Right - R.Left - 1);
dtInteger(dTop, R.Top + sControl.Top + b);
dtInteger(dHeight, R.Bottom - R.Top - 1);
Data.ldata:= @dTop;
dTop.ldata:= @dWidth;
dWidth.ldata:= @dHeight;
_hi_OnEvent_(_event_onClientRect, Data);
end;
end.