zoukankan      html  css  js  c++  java
  • Delphi在Listview中加入Eeit控件

    Delphi在Listview中加入Eeit控件
    2010-07-15         作者:李海彬   阅读:1154

             Listview是一个非常有用的控件,我们常常将大量的数据(如数据库里的数据)导入到Listview中,有的时候我们需要编辑Listview里的数据,而它并不提供编辑的功能,怎么样才能使它具有编辑功能呢?你可以试试下面这种方法。

             首先在FORM1中放置一个Listview控件和一个Eeit控件。Edit控件有什么用?当然是用来编辑Listview里的内容,程序的想法是这样的:当鼠标点击了Listview控件后,根据鼠标位置将Edit控件放置到Listview对应的Column里,将对应Item里的内容读入Edit中,在Edit中编辑好后,再将Edit编辑过的信息回写到Item中。

            代码如下:

    unit Unit1;

    interface

    uses
       Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, CommCtrl, StdCtrls, ImgList;

    type
      TForm1 = class(TForm)
        ListView1: TListView;
        Edit1: TEdit;
        procedure Edit1KeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
        procedure Edit1Change(Sender: TObject);
        procedure ListView1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormCreate(Sender: TObject);
        procedure ListView1ColumnDagged(Sender: TObject);
      private
        { Private declarations }

        FListViewWndProc1: TWndMethod;
        procedure ListViewWndProc1(var Msg: TMessage);
      public
        { Public declarations }
      end;

    const MaxColumns=3 ;  //   总Columns-1
    var
      Form1: TForm1;
      edtcol:integer; //记录EDIT1在Columns中的位置,1-  MaxColumns;
      editem:Tlistitem;
    implementation

    {$R *.dfm}

    //拦截LISTVIEW1消息
    procedure  TForm1.ListViewWndProc1(var Msg: TMessage);
    var IsNeg : Boolean;
    begin
     try
      ShowScrollBar(ListView1.Handle, SB_HORZ, false);

      //拖动Listview1滚动条时,将EDIT1隐藏起来
      if(msg.Msg  =WM_VSCROLL) or (msg.Msg=WM_MOUSEWHEEL ) then edit1.Visible :=false;
      if Msg.Msg = WM_MOUSEWHEEL then
       begin
        if listview1.Selected=nil then exit;
        IsNeg := Short(msg.WParamHi) < 0;
        listview1.SetFocus ;
        if IsNeg then
            SendMessage(edit1.Handle,  WM_KEYDOWN,  VK_down,  0)
        else
             SendMessage(edit1.Handle,  WM_KEYDOWN,  VK_up, 0);
      end
      else
       FListViewWndProc1(Msg);
     except
     end;
    end;

    //拦截EDIT的按键消息,对上、下、左、右方向键进行处理------
    procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    var item:tlistitem;
        ix,lt,i:integer;
        rect:Trect;
    begin
    TRY
      //----对上、下、左、右方向键进行处理-----------------
      if(key<>VK_DOWN) AND (KEY<>VK_UP)  AND (KEY<>VK_RIGHT)  AND (KEY<>VK_LEFT)  THEN EXIT;
      IF(KEY=VK_RIGHT) THEN  //键盘右键
       BEGIN
         //按下键盘右键后,判断光标位置是否处于最右边,如果不在最右边,不作处理 EXIT
        if length(edit1.Text)>edit1.SelStart then exit;
         item:=listview1.Selected;
         //计算edit1位于哪个Columns,如果<最大Columns,+1,否则=1,即转到最左边

       if(edtcol

        //从 edtcol值计算出 Columns的位置(Left,width),EDIT1按此设置
         lt:=0;
         for i:=0 to edtcol-1 do lt:=lt+listview1.Columns[i].Width;
         edit1.Left:=lt+1;
         edit1.Width :=listview1.Columns[edtcol].Width;
      END;
        IF(KEY=VK_left) THEN  //键盘左键
       BEGIN
         if edit1.SelStart<>0 then exit;
         item:=listview1.Selected;
         if(edtcol>0) then  edtcol:=edtcol-1 else edtcol:=MaxColumns;
         lt:=0;
         for i:=0 to edtcol-1 do lt:=lt+listview1.Columns[i].Width;
         edit1.Left:=lt+1;
         edit1.Width :=listview1.Columns[edtcol].Width;
      END;
      if(key=VK_DOWN ) then     //键盘下键
       begin
         item:=listview1.Selected;
         if item=nil then exit;
         ix:=item.Index;
         if ix>=listview1.Items.Count-1 then exit;
          SendMessage(listview1.Handle,  WM_KEYDOWN,  VK_down,  0)
       end;
      if(key=VK_UP) then  //键盘上键
       begin
         item:=listview1.Selected;
         if item=nil then exit;
         ix:=item.Index;
         if ix<1 then exit;
         SendMessage(listview1.Handle,  WM_KEYDOWN,  VK_up,  0)
       end;
       listview1.ItemFocused :=listview1.Selected;
       item:=listview1.Selected ;
       edit1.Visible :=false;
       rect:=item.DisplayRect(drSelectBounds);
       edit1.SetBounds(edit1.left,rect.Top-1,edit1.Width,rect.Bottom-rect.Top+2);
       IF edtcol>0 then edit1.Text:=item.SubItems[edtcol-1]
                   else edit1.Text:=item.Caption ;
       edit1.Visible:=true;
       edit1.SetFocus;

    EXCEPT
    END;
    end;


    //编辑控件内容改变后,保存改变到Listview1对应位置
    procedure TForm1.Edit1Change(Sender: TObject);
    begin
    TRY
        if not edit1.Visible then exit;
        listview1.Selected.SubItems[edtcol-1]:=edit1.Text;
    EXCEPT
    END;
    end;
    //在LISTVIEW1上按下鼠标
    procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
     rect:Trect;
     p:tpoint;
     wtmp,i:integer;
    begin
    TRY
      //显示编辑控件
      edit1.Visible:=false;
      //根据鼠标位置,得到所对应行的LISTITEM
      editem:=listview1.GetItemAt(x,y);
      if editem<>nil then
      begin
       //根据鼠标位置,计算出是哪个 Columns.
       p:=editem.Position;
       wtmp:=p.X;
       for i:=0 to listview1.Columns.Count-1 do
       if (x>wtmp) and (x<(wtmp+listview1.Column[i].Width))
         then  break  //找到对应的Columns,打断退出,I确定.
         else  inc(wtmp,listview1.Column[i].Width);
       //根据I的值,取得 Columns的对应位置。在对应位置按其它的SIZE放EDIT1。
       edtcol:=i;
       rect:=editem.DisplayRect(drSelectBounds);
       edit1.SetBounds(wtmp-1,rect.Top-1,listview1.Column[i].Width+1,rect.Bottom-rect.Top+2);
       if edtcol>0 then edit1.Text:=editem.SubItems[i-1]
                   else edit1.Text:=editem.Caption;
       edit1.Visible:=true;
       edit1.SetFocus;
      end;
    EXCEPT
    END;
    end;
    //初始化,加入测试数据.
    procedure TForm1.FormCreate(Sender: TObject);
    var item:tlistitem;
        i:integer;
    begin

     //将edit1的父亲选为LISTVIEW1,用以响应LISTVIEW1消息

     edit1.parent:=Listview1;

     //拦载LISTVIEW1鼠标消息

      FListViewWndProc1:=ListView1.WindowProc;
      ListView1.WindowProc := ListViewWndProc1;
     

      for  i:=0 to 10 do
       begin
          item:=listview1.Items.Add ;
          item.Caption :='123324';
          item.SubItems.Add('32r5aefs');
          item.SubItems.Add('SGASD');
          item.SubItems.Add('3445645');
       end;
    end;

      上面的代码只是最基本的代码,仅可以通过键盘的上、下、左、右键控制EDIT在各个Column中切换,要将它做得更好,还要加入如拦截Column的宽度变化消息,以便Column变宽或变窄后相应的调整EDIT宽度等等。

  • 相关阅读:
    使用springboot缓存
    Something wrong with EnCase v8 index search results
    Is it a full physical image???
    FB的新专利竟要监看使用者的脸
    How to image a CD/DVD ROM and generate hash value
    Mobile game forensics
    物理提取大绝招”Advanced ADB”???
    How to trace the Geolocation of network traffic
    App forensics
    专做手机取证的大厂被人给黑了
  • 原文地址:https://www.cnblogs.com/hssbsw/p/2533092.html
Copyright © 2011-2022 走看看