git-svn-id: https://svn.code.sf.net/p/kolmck/code@9 91bb2d04-0c0c-4d2d-88a5-bbb6f4c1fa07
This commit is contained in:
264
Addons/ListEdit.pas
Normal file
264
Addons/ListEdit.pas
Normal file
@ -0,0 +1,264 @@
|
||||
unit ListEdit;
|
||||
|
||||
interface
|
||||
uses KOL, Windows, Messages, objects;
|
||||
|
||||
const
|
||||
WM_JUSTFREE = WM_USER + 51;
|
||||
WM_EDITFREE = WM_USER + 52;
|
||||
WM_DBLCLICK = WM_USER + 53;
|
||||
WM_ROWCHANG = WM_USER + 54;
|
||||
|
||||
type
|
||||
|
||||
PListEdit =^TListEdit;
|
||||
TKOLListEdit = PControl;
|
||||
TListEdit = object(Tobj)
|
||||
EList: PList;
|
||||
Enter: boolean;
|
||||
LView: PControl;
|
||||
TabSave: boolean;
|
||||
TabStrt: boolean;
|
||||
OldWind: longint;
|
||||
NewWind: longint;
|
||||
CurEdit: integer;
|
||||
destructor destroy; virtual;
|
||||
procedure SetEvents(LV: PControl);
|
||||
procedure NewWndProc(var Msg: TMessage);
|
||||
procedure LVPaint;
|
||||
procedure LVDblClk;
|
||||
procedure LVChange(Store: boolean);
|
||||
procedure PostFree(var Key: integer);
|
||||
procedure EDChar(Sender: PControl; var Key: integer; Sh: Cardinal);
|
||||
procedure EDPres(Sender: PControl; var Key: integer; Sh: Cardinal);
|
||||
procedure EDentr(Sender: PObj);
|
||||
end;
|
||||
|
||||
function NewListEdit(AParent: PControl; Style: TListViewStyle; Options: TListViewOptions;
|
||||
ImageListSmall, ImageListNormal, ImageListState: PImageList): PControl;
|
||||
|
||||
implementation
|
||||
|
||||
function NewListEdit;
|
||||
var p: PListEdit;
|
||||
begin
|
||||
Result := NewListView(AParent, Style, Options, ImageListSmall, ImageListNormal, ImageListState);
|
||||
Result.CreateWindow;
|
||||
New(p, create);
|
||||
AParent.Add2AutoFree(p);
|
||||
p.LView := Result;
|
||||
p.SetEvents(PControl(Result));
|
||||
end;
|
||||
|
||||
destructor TListEdit.destroy;
|
||||
begin
|
||||
LVChange(False);
|
||||
EList.Free;
|
||||
SetWindowLong(LView.Handle, GWL_WNDPROC, OldWind);
|
||||
FreeObjectInstance(Pointer(NewWind));
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TListEdit.SetEvents;
|
||||
begin
|
||||
EList := NewList;
|
||||
Enter := False;
|
||||
TabStrt := False;
|
||||
OldWind := GetWindowLong(LV.Handle, GWL_WNDPROC);
|
||||
NewWind := LongInt(MakeObjectInstance(NewWndProc));
|
||||
SetWindowLong(LV.Handle, GWL_WNDPROC, NewWind);
|
||||
end;
|
||||
|
||||
procedure TListEdit.NewWndProc;
|
||||
var e: boolean;
|
||||
begin
|
||||
e := EList.Count > 0;
|
||||
case Msg.Msg of
|
||||
WM_LBUTTONDOWN:
|
||||
begin
|
||||
LVChange(True);
|
||||
CurEdit := 0;
|
||||
if e then PostMessage(LView.Handle, WM_DBLCLICK, 0, 0);
|
||||
end;
|
||||
WM_LBUTTONDBLCLK:
|
||||
begin
|
||||
LVDblClk;
|
||||
end;
|
||||
WM_KEYDOWN:
|
||||
begin
|
||||
if Msg.WParam = 13 then begin
|
||||
LVDblClk;
|
||||
end else
|
||||
{ if Msg.WParam = 27 then begin
|
||||
LVChange(False);
|
||||
end else begin
|
||||
LVChange(True);
|
||||
if e then PostMessage(LView.Handle, WM_DBLCLICK, 0, 0);
|
||||
end;}
|
||||
end;
|
||||
WM_NCPAINT:
|
||||
begin
|
||||
LVPaint;
|
||||
end;
|
||||
WM_JUSTFREE:
|
||||
begin
|
||||
LVChange(Msg.WParam <> 27);
|
||||
end;
|
||||
WM_EDITFREE:
|
||||
begin
|
||||
LVChange(Msg.WParam <> 27);
|
||||
if e then PostMessage(LView.Handle, WM_DBLCLICK, 0, 0);
|
||||
end;
|
||||
WM_DBLCLICK:
|
||||
begin
|
||||
LVDblClk;
|
||||
end;
|
||||
WM_PAINT:
|
||||
begin
|
||||
LVPaint;
|
||||
end;
|
||||
end;
|
||||
Msg.Result := CallWindowProc(Pointer(OldWind), LView.Handle, Msg.Msg, Msg.wParam, Msg.lParam);
|
||||
end;
|
||||
|
||||
procedure TListEdit.LVPaint;
|
||||
var i: integer;
|
||||
r: TRect;
|
||||
l: integer;
|
||||
e: PControl;
|
||||
p: TPoint;
|
||||
begin
|
||||
with LView^ do begin
|
||||
SendMessage(Handle, WM_SETFONT, Font.Handle, 0);
|
||||
l := 0;
|
||||
p := LVItemPos[0];
|
||||
for i := 0 to EList.Count - 1 do begin
|
||||
r := LVItemRect(LVCurItem, lvipBounds);
|
||||
r.Left := l + p.X;
|
||||
r.Right := l + LVColWidth[i] + p.X;
|
||||
Dec(r.Top);
|
||||
Inc(r.Bottom);
|
||||
e := EList.Items[i];
|
||||
e.BoundsRect := r;
|
||||
l := l + LVColWidth[i];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TListEdit.LVDblClk;
|
||||
var i: integer;
|
||||
e: PControl;
|
||||
r: TRect;
|
||||
l: integer;
|
||||
a: PControl;
|
||||
p: TPoint;
|
||||
o: TPoint;
|
||||
begin
|
||||
with LView^ do begin
|
||||
if EList.Count <> 0 then LVChange(True);
|
||||
if enter then exit;
|
||||
enter := true;
|
||||
l := 0;
|
||||
a := nil;
|
||||
GetCursorPos(p);
|
||||
p := Screen2Client(p);
|
||||
o := LVItemPos[0];
|
||||
for i := 0 to LVColCount - 1 do begin
|
||||
r := LVItemRect(LVCurItem, lvipBounds);
|
||||
r.Left := l + o.X;
|
||||
r.Right := l + LVColWidth[i] + o.X;
|
||||
l := l + LVColWidth[i];
|
||||
Dec(r.Top);
|
||||
Inc(r.Bottom);
|
||||
e := NewEditBox(LView, []);
|
||||
EList.Add(e);
|
||||
e.BoundsRect := r;
|
||||
e.DoubleBuffered := True;
|
||||
e.Tabstop := True;
|
||||
e.Font.FontHeight := LView.Font.FontHeight;
|
||||
e.Font.FontCharset := 204;
|
||||
e.Text := LVItems[LVCurItem, i];
|
||||
e.OnKeyDown := EDChar;
|
||||
e.OnKeyUp := EDPres;
|
||||
e.OnEnter := EDEntr;
|
||||
e.Show;
|
||||
if a = nil then a := e;
|
||||
if (CurEdit <> 0) then
|
||||
if (EList.Count = CurEdit) then a := e else else
|
||||
if (r.Left <= p.x) and (r.Right >= p.x) then
|
||||
a := e;
|
||||
end;
|
||||
if a <> nil then a.Focused := True;
|
||||
TabSave := TabStop;
|
||||
TabStop := False;
|
||||
TabStrt := True;
|
||||
enter := false;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TListEdit.LVChange;
|
||||
var e: PControl;
|
||||
i: integer;
|
||||
g: boolean;
|
||||
begin
|
||||
with LView^ do begin
|
||||
if enter then exit;
|
||||
enter := true;
|
||||
g := False;
|
||||
for i := 0 to EList.Count - 1 do begin
|
||||
e := EList.Items[i];
|
||||
if Store then begin
|
||||
g := g or (LVItems[LVCurItem, i] <> e.Text);
|
||||
LVItems[LVCurItem, i] := e.Text;
|
||||
end;
|
||||
if e.Focused then CurEdit := i + 1;
|
||||
e.Free;
|
||||
end;
|
||||
EList.Clear;
|
||||
enter := false;
|
||||
if TabStrt then TabStop := TabSave;
|
||||
if g then
|
||||
SendMessage(Parent.Handle, WM_ROWCHANG, LVCurItem, 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TListEdit.PostFree;
|
||||
begin
|
||||
with LView^ do begin
|
||||
if Key = 27 then
|
||||
PostMessage(Handle, WM_JUSTFREE, key, 0);
|
||||
if Key = 13 then
|
||||
PostMessage(Handle, WM_EDITFREE, key, 0);
|
||||
if ((key = 40) and (LView.LVCurItem < LView.LVCount - 1)) or
|
||||
((key = 38) and (LView.LVCurItem > 0)) then begin
|
||||
PostMessage(Handle, WM_EDITFREE, key, 0);
|
||||
PostMessage(Handle, wm_keydown, Key, 0);
|
||||
PostMessage(Handle, wm_keyup, Key, 0);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TListEdit.EDChar;
|
||||
begin
|
||||
case key of
|
||||
13,
|
||||
27,
|
||||
38,
|
||||
40: PostFree(key);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TListEdit.EDPres;
|
||||
begin
|
||||
case key of
|
||||
38,
|
||||
40: key := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TListEdit.EDentr;
|
||||
begin
|
||||
PControl(Sender).SelectAll;
|
||||
end;
|
||||
|
||||
end.
|
Reference in New Issue
Block a user