Mega Code Archive

 
Categories / Delphi / VCL
 

Edit listbox items in place

Title: Edit listbox items in-place Question: It would be nice to click on a listbox and be able to edit the selected item directly, instead of opening another form or having a parellel edit control. Peter Below, one of the Delphi gods, shows how. Answer: An in-place editor that pops up when you double-click in an item in a listbox. It would probably be feasable to make it active permanently and move it with the selection but you would also have to move it when the listbox is scrolled, for instance, and that would get complicated rather fast. Implementing an in-place editor for a listbox: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; const UM_DESTROYCONTROL = WM_USER +230; type TForm1 = class(TForm) ListBox1: TListBox; procedure ListBox1DblClick(Sender: TObject); private { Private declarations } Procedure EditDone( Sender: TObject ); Procedure UmDestroyControl(Var msg: TMessage); message UM_DESTROYCONTROL; public { Public declarations } procedure EditMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.EditDone(Sender: TObject); begin listbox1.Items[ listbox1.itemindex ] := (Sender As TEdit).Text; PostMessage( handle, UM_DESTROYCONTROL, 0, Integer(Sender)); end; procedure TForm1.EditMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin If not PtInrect( (Sender As TControl).ClientRect, Point(X,y) ) Then EditDone(Sender); end; procedure TForm1.ListBox1DblClick(Sender: TObject); var r: TRect; lb: TListbox; ed: TEdit; begin lb := (sender as TListbox); if lb.ItemIndex ed:= Tedit.Create(self); r:= lb.ItemRect( lb.itemindex ); r.topleft := lb.ClientToScreen( r.topleft ); r.BottomRight := lb.clienttoscreen( r.bottomright ); r.topleft := ScreenToClient( r.topleft ); r.BottomRight := screenToClient( r.bottomright ); ed.text := lb.Items[lb.itemindex]; ed.setbounds( r.left, r.top-2, lb.clientwidth, r.bottom-r.top+4 ); ed.OnExit := EditDone; ed.OnMouseDown:= EditMouseDown; ed.Parent := Self; SetCapturecontrol( ed ); ed.SetFocus; end; procedure TForm1.UmDestroyControl(var msg: TMessage); begin TObject(msg.lparam).Free; end; end. This code is Peter Below's (so you know it works, unlike mine!)