抓取对象的类名和属性unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation
var
  PreClassLength, PreTextLength: Integer;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
  ClassName: PChar;
  ptCursor: TPoint;
  hWndOver: HWND;
  Text: PChar;
begin
  GetCursorPos(ptCursor);
  hWndOver := WindowFromPoint(ptCursor);
  GetMem(ClassName, 100);
  GetMem(Text, 255);
  try
    GetClassName(hWndOver, ClassName, 100);
    SendMessage(hWndOver, WM_GETTEXT, 255, LongInt(Text));
    Canvas.FillRect(Rect(5, 20 , PreClassLength + 20, 40));
    Canvas.FillRect(Rect(5, 40 , PreTextLength + 20, 60));
    PreClassLength := Canvas.TextWidth(ClassName);
    PreTextLength := Canvas.TextWidth(Text);
//    if PreClassLength > PreTextLength then
//      Width := Canvas.TextWidth(ClassName) + 20
//    else
//      Width := Canvas.TextWidth(Text) + 20;
    Canvas.TextOut(5, 20, string(ClassName));
    Canvas.TextOut(5, 35, string(Text));
  finally
    FreeMem(ClassName);
    FreeMem(Text);
  end;
end;end.

解决方案 »

  1.   

    不用HOOK只要编写OnMouseMove就可以了
      

  2.   

    大家理解错了,要在资源管理器中就是窗口中点击,取得是系统中鼠标点 的文件名,不是本程序的文件名或类名。要么用钩子,要么用SHELL接口。
      

  3.   

    陈省那本《DELPHI深入探索》有一个SHELL的例子,很详细
      

  4.   

    用函数copy
    如copy(‘south’,2,3)返回out
     copy(‘south',1,2)返回so
    所以你可以用这个
    不知道你是不是这个意思
      

  5.   

    TO BCB_FANS(四大名捕之追杀令)
     用COM要知道注册的位置和接口啊!!问题一大堆啊!
     
    TO  deminxh(demi)
        你好意我心领了,不过好象发错地方了 :)
      

  6.   

    to cg1120(代码最优化-§人在爱情的空窗期要个梦:
           麻烦摘一段代码贴上来好吗?能把书发过来更好;我会加500分的。
         谢了!
      

  7.   

    我设计过一个这样的COM,只可惜是C++的,你要是想要可以贴给你.
      

  8.   

    to :BCB_FANS(四大名捕之追杀令):
          谢了,麻烦贴上来让我研究一下,希望有所启发。
      

  9.   

    ShellImp.h
    ---------#define INITGUID#include <vcl.h>
    #include <shlobj.hpp>
    #include <windows.h>DEFINE_GUID(CLSID_ShellExtension, 0x4778AFE0, 0x2289, 0x11D0, 0x8A,
      0xEC, 0x0,0xA0, 0xC9, 0xC, 0x92, 0x46);//---------------------------------------------------------------------------
    class TClassFactory : public IClassFactory
    {
     protected:
    long ObjRefCount; public:
    TClassFactory();
    ~TClassFactory();    //IUnknown methods
    STDMETHODIMP QueryInterface(REFIID, LPVOID*);
    STDMETHODIMP_(DWORD) AddRef();
    STDMETHODIMP_(DWORD) Release(); //IClassFactory methods
    STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID*);
    STDMETHODIMP LockServer(BOOL);
    };
    //---------------------------------------------------------------------------
    class TShellExt: public IShellExtInit,public IContextMenu
    {
     protected:
    long ObjRefCount;
    TStrings* SelectedFileList; public:
    TShellExt();
    ~TShellExt();

    //IUnknown methods
    STDMETHODIMP QueryInterface(REFIID, LPVOID*);
    STDMETHODIMP_(DWORD) AddRef();
    STDMETHODIMP_(DWORD) Release(); //IShellExtInit
    STDMETHODIMP Initialize(LPCITEMIDLIST,LPDATAOBJECT,HKEY); //IContextMenu
    STDMETHODIMP QueryContextMenu(HMENU,UINT,UINT,UINT,UINT);
    STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
    STDMETHODIMP GetCommandString(UINT,UINT,UINT FAR *,LPSTR,UINT);
    };
    //---------------------------------------------------------------------------
      

  10.   

    要分两次贴,老提示内容太长://---------------------------------------------------------------------------
    #define NO_WIN32_LEAN_AND_MEAN#include "ShellImp.h"int DllRefCount;// Debug function
    void Trace(AnsiString str)
    {
      MessageBox(GetForegroundWindow(),str.c_str(),NULL,MB_OK);
    }/****************************************************************************       DLL Function Implemention****************************************************************************///---------------------- DllCanUnloadNow ------------------------------------
    STDAPI __declspec(dllexport) DllCanUnloadNow(void)
    {
      return (DllRefCount==0) ? S_OK : S_FALSE;
    }
    //---------------------- DllGetClassObject ----------------------------------
    STDAPI __declspec(dllexport) DllGetClassObject(REFCLSID rclsid,
           REFIID riid,
           LPVOID *ppReturn)
    {
      *ppReturn = NULL;
      /* -----Debug code------
      Trace("Call DllGetClassObject");
      //*/
      if(!IsEqualIID(rclsid, CLSID_ShellExtension))
         return CLASS_E_CLASSNOTAVAILABLE;  TClassFactory *pClassFactory = new TClassFactory();
      if(pClassFactory==NULL)
        return E_OUTOFMEMORY;  HRESULT hResult = pClassFactory->QueryInterface(riid, ppReturn);
      /* -----Debug code------
      if(*ppReturn!=NULL)
      {
        Trace("Succeeded Create TClassFactory");
      }
      else
      {
        Trace("Failed create TClassFactory ");
      }
      //*/
      return hResult;
    }
    /*************************************************************************        Implements TClassFactory****************************************************************************/
    //---------------------------------------------------------------------------
    TClassFactory::TClassFactory()
    {
      ObjRefCount = 1;
      DllRefCount++;
    }
    //---------------------------------------------------------------------------
    TClassFactory::~TClassFactory()
    {
      DllRefCount--;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TClassFactory::QueryInterface(REFIID riid, LPVOID *ppReturn)
    {
      *ppReturn = NULL;
      /* -----Debug code------
      Trace("QueryInterface ClassFactory");
      //*/
      if(IsEqualIID(riid, IID_IUnknown))
        *ppReturn = this;
      else if(IsEqualIID(riid, IID_IClassFactory))
        *ppReturn = (IClassFactory*)this;  if(*ppReturn)
      {
        AddRef();
        return S_OK;
      }
      return E_NOINTERFACE;
    }//---------------------------------------------------------------------------
    STDMETHODIMP_(DWORD) TClassFactory::AddRef()
    {
      return ++ObjRefCount;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP_(DWORD) TClassFactory::Release()
    {
      if(--ObjRefCount)
      {
        return ObjRefCount;
      }
      delete this;
      return 0;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TClassFactory::CreateInstance(LPUNKNOWN pUnknown,
       REFIID riid,
       LPVOID *ppObject)
    {
      HRESULT hResult ;
      TShellExt *pShellExt;
      /* -----Debug code------
      Trace("Call CreateInstance");
      //*/
      *ppObject = NULL;
      if(pUnknown != NULL) return CLASS_E_NOAGGREGATION;  pShellExt = new TShellExt();
      if(pShellExt==NULL) return E_OUTOFMEMORY;  hResult=pShellExt->QueryInterface(riid, ppObject);
      /* -----Debug code------
      if(*ppObject!=NULL)
      {
        Trace("Succeeded Create ShellExt");
      }
      else
      {
        Trace("Failed Create ShellExt");
      }
      //*/
      return hResult;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TClassFactory::LockServer(BOOL)
    {
      return E_NOTIMPL;
    }
    //---------------------------------------------------------------------------
      

  11.   

    CPP内容的第二部分:
    /****************************************************************************       Implements TShellExt ***************************************************************************///---------------------------------------------------------------------------
    TShellExt::TShellExt()
    {
      SelectedFileList=new TStringList();
      ObjRefCount=1;
      DllRefCount++;
    }
    //---------------------------------------------------------------------------
    TShellExt::~TShellExt()
    {
      DllRefCount--;
      delete SelectedFileList;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TShellExt::QueryInterface(REFIID riid,LPVOID* pReturn)
    {
      *pReturn=NULL;
      /* -----Debug code------
      Trace("QueryInterace ShellExt");
      //*/
      if(IsEqualIID(riid,IID_IContextMenu))
        *pReturn=(IContextMenu*)this;
      else if(IsEqualIID(riid,IID_IShellExtInit))
        *pReturn=(IShellExtInit*)this;  if(*pReturn)
      {
        AddRef();
        return S_OK;
      }
      return E_NOINTERFACE;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP_(DWORD) TShellExt::AddRef()
    {
      return ++ObjRefCount;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP_(DWORD) TShellExt::Release()
    {
      if(--ObjRefCount)
      {
        return ObjRefCount;
      }
      delete this;
      return 0;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TShellExt::Initialize(LPCITEMIDLIST pidlFolder,
       LPDATAOBJECT lpdobj,
       HKEY hkeyProgID)
    {
      FORMATETC DataFormat;
      STGMEDIUM DataRet;
      /* -----Debug code------
      Trace("Call Initialize");
      //*/
      DataFormat.cfFormat=CF_HDROP;
      DataFormat.ptd=NULL;
      DataFormat.dwAspect=DVASPECT_CONTENT;
      DataFormat.lindex=-1;
      DataFormat.tymed=TYMED_HGLOBAL;  SelectedFileList->Clear();
      // Get selected file
      if(lpdobj)
      {
        if(SUCCEEDED(lpdobj->GetData(&DataFormat,&DataRet)))
        {
          char fileName[255];
          HDROP hDrop=(HDROP)DataRet.hGlobal;
          int SelCount=DragQueryFile(hDrop,-1,NULL,0);      for(int i=0; i<SelCount; i++)
          {
    DragQueryFile(hDrop,i,fileName,sizeof(fileName));
    SelectedFileList->Add(fileName);
          }
        }
      }
      return NOERROR;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TShellExt::QueryContextMenu( HMENU hMenu,UINT indexMenu,
      UINT idCmdFirst,UINT idCmdLast,
      UINT uFlags)
    {
      /* -----Debug code------
      Trace("QuerryContextMenu");
      //*/
      int idCmd=idCmdFirst;
      AnsiString MenuItemStr="Shell Extension Test...";  InsertMenu(hMenu,indexMenu++,MF_STRING | MF_BYPOSITION,idCmd++,MenuItemStr.c_str());
      /*-----Debug code------
      if(isIns)
      {
        CallCount++;
        Trace("Succeed insert menu");
      }
      else
      {
        Trace("Failed insert menu");
      }
      //*/
      return HRESULT(idCmd-idCmdFirst);
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
    {
      if(!HIWORD(lpcmi->lpVerb))
      {
        //If HIWORD(lpcmi->lpVerb) then we have been called programmatically
        //and lpVerb is a command that should be invoked.  Otherwise, the shell
        //has called us, and LOWORD(lpcmi->lpVerb) is the menu ID the user has
        //selected.  Actually, it's euqal to *menu ID - idCmdFirst* from QueryContextMenu().    int idCmd=LOWORD(lpcmi->lpVerb);
        switch(idCmd)
        {
          case 0:
    AnsiString str;
    for(int i=0;i<SelectedFileList->Count;i++)
    {
      str+=SelectedFileList->Strings[i]+"\r\n";
    }
    MessageBox(NULL,AnsiString(AnsiString("Shell extension test.You can do more thing ")+
    AnsiString("about the following selected file.")+
    AnsiString("\r\n\r\n")+str).c_str(),NULL,MB_OK);
    break;
        }
      }
      return NOERROR;
    }
    //---------------------------------------------------------------------------
    STDMETHODIMP TShellExt::GetCommandString(UINT idCmd,
     UINT uFlags,
     UINT FAR *reserved,
     LPSTR pszName,
     UINT cchMax)
    {
      if(idCmd==0)
      {
        lstrcpy(pszName,"Compress..");
      }
      return NOERROR;
    }
    //---------------------------------------------------------------------------一个奇怪的问题:你只有一颗星,哪来这么多的分进行提问啊???
      

  12.   

    不行啊,你这是和系统菜单扩展吧。    
    点击一个对象时并不会调用这个的。
    好像是用这两个接口可以:ISHELLVIEW 或IFOLDERVIEW
      

  13.   

    编译成功后双击这个文件进行注册就OK了.(注意修改路经)SHELLEXT.REG---------------REGEDIT4[HKEY_CLASSES_ROOT\CLSID\{4778AFE0-2289-11d0-8AEC-00A0C90C9246}]
       @="Shell Extension Sample"
    [HKEY_CLASSES_ROOT\CLSID\{4778AFE0-2289-11d0-8AEC-00A0C90C9246}\InProcServer32]
       @="C:\\Inprise\\CBuilder5\\Projects\\ShellExt\\ShellExt.dll"
         "ThreadingModel"="Apartment"
    [HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\SL2000]
    [HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\SL2000]
       @="{4778AFE0-2289-11d0-8AEC-00A0C90C9246}"
      

  14.   

    Very Sorry,看错需求了,1、想实时知道鼠标单击的消息,可以通过全局Mouse Hook办到。
    2、如果用户单击一个文件,那肯定是在SysListView32控件上进行单击,调用函数
       WindowFromPoint可以得到这个SysListView32的句柄。
    3、得到句柄就容易了,向这个控件发送各种消息
       SendMessage(句柄,LVM_XXX,???,???);
      或者使用宏
       ListView_SetXXXX(...);
      可以得到文件名。问题的关键在于怎么判断用户是在一个SysListView32上单击而不是在SysTreeView32上单击:   可以通过WindowFromPoint函数得到单击时鼠标底下的窗口的句柄,然后再调用函数GetClassName(句秉,...)得到那个控件的类名,剩下的就跟简单了。如果还不太明白请继续发贴。
      

  15.   

    句柄的问题以前都解决了。一般者能获取句柄。我用的一个例子:单击管理器内的一个文件,可以得到该窗口句柄的。
     后面我想应该是对SYSLISTVIEW的分析,但是困难有两个:1:在DELPHI中有
    ISHELLVIEW接口(不知道是不是该用这个),可是接口太难用了,没有成功过
    2、如果是发送消息的话。这些消息都发送到窗口句柄上了。
      有些函数有用。我的思路是想:先ENUMlistVIEWS 下一步再有GETSELECT来得到选中的对像。          关键问题还有:1、注册位置,要保证能被EXPLOREr调用。应该不是简单的COM注册。2、DELPHI的这个接口资料不多,我找不到参考。
      

  16.   

    在C中可能比较容易,可是DELPHI就麻烦多了
      

  17.   

    //下面代码得到选中的文件名,如果还不明白,继续发贴,
      //直到帮你搞定,因为在帮你的同时,我的水平也得到很大地提高
      int ItemCount=ListView_GetItemCount(句柄);  LV_ITEM Item;  for(int i=0;i<ItemCount;i++)
      {
        Item.iItem=i;    ListView_GetItem(句柄,&Item);
        if(Item.state==LVIS_SELECTED)
        {
          Memo1->Lines->Add("Selected FileName="+AnsiString(Item.pszText));
        }
      }
      

  18.   

    顺便说一下,我先前贴的代码实际上是想实现类似WinZip那样的功能.
      

  19.   

    不好了,这里打雷准备下雨了,我要关机了,明天再谈.ByBy.
      

  20.   

    问题没有进展,DELPHI没有类似ListView_GetItemCount(句柄);的方法来进行下去,跟以前一样, 我只能得到句柄,却没办法!:(
    而这也正是我几天一直被困挠的问题。
      

  21.   

    function GetFile(...);
    var 
      ItemCount:Integer;
      Item: LV_ITEM;
      i: Integer;
      
    begin  ItemCount:=ListView_GetItemCount(Handle);
      
      for i=0 to ItemCount-1 do
      begin
        Item.iItem:=i;
        
        ListView_GetItem(Handle,Item);
        if Item.state= LVIS_SELECTED then
          Memo1.Lines.Add("How to write this code???");
      end ;
    end;实在对不起,我的Delphi太差劲,只能写到这种程度了.
      

  22.   

    没有ListView_GetItemCount宏???,那用消息:int Count=SendMessage(Handle,LVM_GETITEMCOUNT,0,0);Item: LV_ITEM;SendMessage(Handle,LVM_GETITEM,0,Item);if Item.state=...可以搞定了吧.
      

  23.   

    我用 LISTVIEW_GETITEMTEXT 取不到文件名 !:( 看来还要你再辛苦一下,
      

  24.   

    老兄,你有没有看我贴的CPP代码啊?--CPPLV_ITEM Item;SendMessage(Handle,LVM_GETITEM,0,(LPARAM)&Item);if(Item.state==LVIS_SELECTED)
    {
      Memo1->Lines->Add("Selected FileName="+AnsiString(Item.pszText);
    }------DelphiItem: LV_ITEM;
    FileName: String;SendMessage(Handle,LVM_GETITEM,0,Item);
    if Item.state=LVIS_SELECTED then
    begin
      //在CPP中FileName=AnsiString(Item.pszText)就可以了, Delphi这样写不知对不对,不对你自己更改吧
      FileName:=Item.pszText;
    end;欢迎继续贴!!!
      

  25.   

    你的CPP代码运行通过了吗?你所写的代码运行一下,一直会有“系统出现错误,ELPLORER 会关闭”出现,我昨天试了半天都是这样,后来改动后,但取对于中文的名字,一定会出现错误。而且不稳定。 
       你的DELPHI代码中一定也没RUN过,像FILENAME:=item.paztext;在DELPHI中就不对,而且像ITEM。MASK也有关系,其实这些都是小问题。主要的问题已解决;看来这500分是你的了,晚一点我会送上。这算不算是大手笔啊,呵呵,班主会以为你作弊,封了你就完了。!!
          现在愁的是要发五个贴才有500分啊! :(
      

  26.   

    那些代码我是都没有运行过!另:你好像说过Delphi没有ListView_GetItemCount宏,实际上是有的,我们都冤枉Delphi了.下面是ComCtrls.pas的原码:
    function TListItems.GetCount: Integer;
    begin
      if Owner.HandleAllocated then Result := ListView_GetItemCount(Handle)
      else Result := 0;
    end;function TListItems.GetItem(Index: Integer): TListItem;
    var
      Item: TLVItem;
    begin
      Result := nil;
      if Owner.HandleAllocated then
      begin
        if Owner.OwnerData then
        begin
          FillChar(Item, SizeOf(Item), 0);
          with Item do
          begin
            mask := 0;
            iItem := Index;
            iSubItem := 0;
          end;
          Result := Owner.GetItem(Item);
        end
        else
        begin
          with Item do
          begin
            mask := LVIF_PARAM;
            iItem := Index;
            iSubItem := 0;
          end;
          if ListView_GetItem(Handle, Item) then Result := TListItem(Item.lParam);
        end;
      end;
    end;
    -----------------------------
    恭喜!!! 问题终于搞定!同时我也谢谢你,因为经过这么一折腾,我的Delphi又增进不少!!!共同提高,CSDN是个好地方!!单独发五个帖子送分还真有点那个!!!