抓取对象的类名和属性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.
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.
如copy(‘south’,2,3)返回out
copy(‘south',1,2)返回so
所以你可以用这个
不知道你是不是这个意思
用COM要知道注册的位置和接口啊!!问题一大堆啊!
TO deminxh(demi)
你好意我心领了,不过好象发错地方了 :)
麻烦摘一段代码贴上来好吗?能把书发过来更好;我会加500分的。
谢了!
谢了,麻烦贴上来让我研究一下,希望有所启发。
---------#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);
};
//---------------------------------------------------------------------------
#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;
}
//---------------------------------------------------------------------------
/**************************************************************************** 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;
}
//---------------------------------------------------------------------------一个奇怪的问题:你只有一颗星,哪来这么多的分进行提问啊???
点击一个对象时并不会调用这个的。
好像是用这两个接口可以:ISHELLVIEW 或IFOLDERVIEW
@="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}"
2、如果用户单击一个文件,那肯定是在SysListView32控件上进行单击,调用函数
WindowFromPoint可以得到这个SysListView32的句柄。
3、得到句柄就容易了,向这个控件发送各种消息
SendMessage(句柄,LVM_XXX,???,???);
或者使用宏
ListView_SetXXXX(...);
可以得到文件名。问题的关键在于怎么判断用户是在一个SysListView32上单击而不是在SysTreeView32上单击: 可以通过WindowFromPoint函数得到单击时鼠标底下的窗口的句柄,然后再调用函数GetClassName(句秉,...)得到那个控件的类名,剩下的就跟简单了。如果还不太明白请继续发贴。
后面我想应该是对SYSLISTVIEW的分析,但是困难有两个:1:在DELPHI中有
ISHELLVIEW接口(不知道是不是该用这个),可是接口太难用了,没有成功过
2、如果是发送消息的话。这些消息都发送到窗口句柄上了。
有些函数有用。我的思路是想:先ENUMlistVIEWS 下一步再有GETSELECT来得到选中的对像。 关键问题还有:1、注册位置,要保证能被EXPLOREr调用。应该不是简单的COM注册。2、DELPHI的这个接口资料不多,我找不到参考。
//直到帮你搞定,因为在帮你的同时,我的水平也得到很大地提高
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));
}
}
而这也正是我几天一直被困挠的问题。
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太差劲,只能写到这种程度了.
{
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;欢迎继续贴!!!
你的DELPHI代码中一定也没RUN过,像FILENAME:=item.paztext;在DELPHI中就不对,而且像ITEM。MASK也有关系,其实这些都是小问题。主要的问题已解决;看来这500分是你的了,晚一点我会送上。这算不算是大手笔啊,呵呵,班主会以为你作弊,封了你就完了。!!
现在愁的是要发五个贴才有500分啊! :(
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是个好地方!!单独发五个帖子送分还真有点那个!!!