Handle := FindWindow('progman', nil);
改为以下函数后可以:
procedure findDesktopWnd;
Function MyEnumWindowProc(wnd: HWND; LPARAM: LPARAM): Boolean; stdcall;
var
sndWnd, targetWnd: Cardinal;
begin
sndWnd := FindWindowEx(wnd, 0, 'SHELLDLL_DefView', 0);
if sndWnd = 0 then
begin
Result := true;
Exit;
end;
targetWnd := FindWindowEx(sndWnd, 0, 'SysListView32', 'FolderView');
if targetWnd = 0 then
begin
Result := true;
Exit;
end;
deskTopHandel := wnd;
Result := false;
end;
begin
EnumWindows(@MyEnumWindowProc, 0);
end;
在正确获得桌面句柄后,获取图标位置XP,WIN7的代码都好用
// 取得桌面存放图标的listview句柄
function GetDesktopLvHand: THandle;
begin
//Result := FindWindow('progman', nil);
findDesktopWnd;
Result :=deskTopHandel;
Result := GetWindow(Result, GW_Child);
Result := GetWindow(Result, GW_Child);
end;
// 取得图标的坐标位置
function GetIcoPosition(h: THandle; idx: Integer): TPoint;
var
hpro, pid, dm, i: Cardinal;
p: Pointer;
begin
GetWindowThreadProcessId(h, pid);
hpro := OpenProcess(PROCESS_ALL_ACCESS, False, pid);
if hpro <> 0 then
try
p := VirtualAllocEx(hpro, nil, SizeOf(TPoint), MEM_COMMIT,
PAGE_READWRITE);
ListView_GetItemPosition(h, idx, TPoint(p^));
ReadProcessMemory(hpro, p, @Result, SizeOf(Result), dm);
finally
VirtualFreeEx(hpro, p, 0, MEM_RELEASE);
CloseHandle(hpro);
end;
end;
现在问题来了,XP上好用的一段代码在WIN7下程序会崩溃,查了很资料,也没有办法解释是为什么:
function ListView_GetItemText_Ex(hwndLV: HWND; i, iSubItem: Integer; pszText: PChar; cchTextMax: Integer): Integer;
var
LVItem: TLVItem;
ProcessID, ProcessHD, Temp: DWORD;
MemPoint: Pointer;
begin
GetWindowThreadProcessId(hwndLV, ProcessID);
ProcessHD := OpenProcess( PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, FALSE, ProcessID);
MemPoint := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem) + cchTextMax, MEM_COMMIT, PAGE_READWRITE);
LVItem.iSubItem := iSubItem;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := PChar(Integer(MemPoint) + SizeOf(TLVItem));
WriteProcessMemory(ProcessHD, MemPoint, @LVItem, SizeOf(TLVItem), Temp);
Result := SendMessage(hwndLV, LVM_GETITEMTEXT, i, Integer(MemPoint));
ReadProcessMemory(ProcessHD, Pointer(Integer(MemPoint) + SizeOf(TLVItem)), pszText, cchTextMax, Temp);
VirtualFreeEx(ProcessHD, MemPoint, SizeOf(TLVItem) + cchTextMax, MEM_DECOMMIT);
VirtualFreeEx(ProcessHD, MemPoint, 0, MEM_RELEASE);
end;
function GetIcoItemText(i: Integer): string;
var
TextBuffer: array [0 .. 100] of char;
FDeskTopLvHandle: THandle;
begin
FDeskTopLvHandle := GetDesktopLvHand;
ListView_GetItemText_Ex(FDeskTopLvHandle, i, 0, TextBuffer, 100);
Result := TextBuffer;
end;
经过排查
Result := SendMessage(hwndLV, LVM_GETITEMTEXT, i, Integer(MemPoint));
这句会造成WIN7下程序崩溃。
求各位大神帮看下,谢谢!WIN764位+delphi7.
6 个解决方案
#1
#2
VC
的代码也不行,只能取得图标个数。只是程序没有崩溃而已。谁能指点一下,谢谢!
void CEnumIconsDlg::OnBtnEnumIcons()
{
// bytes to allocate for icon text and LVITEM struct
#define ALLOC_SIZE 200
HWND hWnd; // handle to desktop window
DWORD dwPID; // explorer process ID (associated with desktop)
HANDLE hProcess; // handle to explorer process (associated with desktop)
LPVOID pData; // pointer to LVITEM struct in explorer address space
LPVOID pString; // pointer to icon text in explorer address space
char szText[ALLOC_SIZE]; // char array of icon text in application address space
char* pszMessageBox; // string to display
SIZE_T BytesRead; // for ReadProcessMemory
SIZE_T BytesWritten; // for WriteProcessMemory
BOOL fResult; // for ReadProcessMemory/WriteProcessMemory
LVITEM lvi; // LVITEM struct
int i; // counter for enumeration
int nItemCount; // icon item count
// get desktop window handle
if(((hWnd = FindWindowEx(NULL, NULL, "Progman", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SysListView32", NULL)) == NULL))
{
MessageBox("Could not get desktop window.");
goto Exit;
}
// get item count on desktop
nItemCount = ::SendMessage(hWnd, LVM_GETITEMCOUNT, (WPARAM)0, (LPARAM)0);
// allocate memory for output string
pszMessageBox = (char*) malloc(ALLOC_SIZE * nItemCount);
sprintf(pszMessageBox, "%d items:\n\n", nItemCount);
// get desktop window process ID (explorer.exe)
GetWindowThreadProcessId(hWnd, &dwPID);
// open process to get explorer process handle
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
// allocate memory in explorer's address space
// allocate space for LVITEM struct
pData = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// allocate space for string (i.e. "Network Neighborhood")
pString = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// init LV_ITEM struct
ZeroMemory(&lvi, sizeof(LVITEM));
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.cchTextMax = 500;
lvi.pszText = (char*)pString; // use alloc'd string space
// write the contents of lvi into explorer's address space
fResult = WriteProcessMemory(hProcess, pData, &lvi, sizeof(LVITEM), &BytesWritten);
// enum all icons
for(i = 0; i < nItemCount; i++)
{
// get item's name
::SendMessage(hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pData);
// read back lvi struct (for debugging purposes only)
fResult = ReadProcessMemory(hProcess, pData, szText, ALLOC_SIZE, &BytesRead);
// read text of queried item
fResult = ReadProcessMemory(hProcess, pString, szText, ALLOC_SIZE, &BytesRead);
// append string to output string
strcat(pszMessageBox, szText);
strcat(pszMessageBox, "\n");
}
// output message box with all icon texts
MessageBox(pszMessageBox);
// free alloc'd memory for message box
free(pszMessageBox);
// free alloc'd memory for string and LVITEM structs
if(!VirtualFreeEx(hProcess, pString, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
if(!VirtualFreeEx(hProcess, pData, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
// close process handle
CloseHandle(hProcess);
Exit:
return;
}
的代码也不行,只能取得图标个数。只是程序没有崩溃而已。谁能指点一下,谢谢!
void CEnumIconsDlg::OnBtnEnumIcons()
{
// bytes to allocate for icon text and LVITEM struct
#define ALLOC_SIZE 200
HWND hWnd; // handle to desktop window
DWORD dwPID; // explorer process ID (associated with desktop)
HANDLE hProcess; // handle to explorer process (associated with desktop)
LPVOID pData; // pointer to LVITEM struct in explorer address space
LPVOID pString; // pointer to icon text in explorer address space
char szText[ALLOC_SIZE]; // char array of icon text in application address space
char* pszMessageBox; // string to display
SIZE_T BytesRead; // for ReadProcessMemory
SIZE_T BytesWritten; // for WriteProcessMemory
BOOL fResult; // for ReadProcessMemory/WriteProcessMemory
LVITEM lvi; // LVITEM struct
int i; // counter for enumeration
int nItemCount; // icon item count
// get desktop window handle
if(((hWnd = FindWindowEx(NULL, NULL, "Progman", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SysListView32", NULL)) == NULL))
{
MessageBox("Could not get desktop window.");
goto Exit;
}
// get item count on desktop
nItemCount = ::SendMessage(hWnd, LVM_GETITEMCOUNT, (WPARAM)0, (LPARAM)0);
// allocate memory for output string
pszMessageBox = (char*) malloc(ALLOC_SIZE * nItemCount);
sprintf(pszMessageBox, "%d items:\n\n", nItemCount);
// get desktop window process ID (explorer.exe)
GetWindowThreadProcessId(hWnd, &dwPID);
// open process to get explorer process handle
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
// allocate memory in explorer's address space
// allocate space for LVITEM struct
pData = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// allocate space for string (i.e. "Network Neighborhood")
pString = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// init LV_ITEM struct
ZeroMemory(&lvi, sizeof(LVITEM));
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.cchTextMax = 500;
lvi.pszText = (char*)pString; // use alloc'd string space
// write the contents of lvi into explorer's address space
fResult = WriteProcessMemory(hProcess, pData, &lvi, sizeof(LVITEM), &BytesWritten);
// enum all icons
for(i = 0; i < nItemCount; i++)
{
// get item's name
::SendMessage(hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pData);
// read back lvi struct (for debugging purposes only)
fResult = ReadProcessMemory(hProcess, pData, szText, ALLOC_SIZE, &BytesRead);
// read text of queried item
fResult = ReadProcessMemory(hProcess, pString, szText, ALLOC_SIZE, &BytesRead);
// append string to output string
strcat(pszMessageBox, szText);
strcat(pszMessageBox, "\n");
}
// output message box with all icon texts
MessageBox(pszMessageBox);
// free alloc'd memory for message box
free(pszMessageBox);
// free alloc'd memory for string and LVITEM structs
if(!VirtualFreeEx(hProcess, pString, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
if(!VirtualFreeEx(hProcess, pData, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
// close process handle
CloseHandle(hProcess);
Exit:
return;
}
#3
有人解释了为什么出错和解决了这个问题。不过是汇编版的,我正在研究。
碰到类似的问题的朋友可以参考。
http://masm32.com/board/index.php?topic=1464.0
里面有生成的EXE,确实XP,win7平台均可以提取桌面图标文字。
碰到类似的问题的朋友可以参考。
http://masm32.com/board/index.php?topic=1464.0
里面有生成的EXE,确实XP,win7平台均可以提取桌面图标文字。
#4
楼主解决了吗?
#5
这个跟XP或者Win7没多大关系,32和64位的区别
这儿有个原来写的例子
//----------
引用 CommCtrl
type
TLVItem64 = packed record
mask: UINT;
iItem: Integer;
iSubItem: Integer;
state: UINT;
stateMask: UINT;
_align: LongInt;
pszText: Int64;
cchTextMax: Integer;
iImage: Integer;
lParam: LPARAM;
end;
function GetDesktopLvHand: THandle;
begin
Result := FindWindow('progman', nil);
Result := GetWindow(Result, GW_Child);
Result := GetWindow(Result, GW_Child);
end;
//32位系统------
function GetIconRect32(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := PChar(Integer(pLVITEM) + SizeOf(TLVItem));
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
//ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
ReadProcessMemory(ProcessHD,Pointer(Integer(pLVITEM) + SizeOf(TLVItem)),@ItemBuf, cchTextMax, drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break ;
end;
end;
//VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pLVITEM, SizeOf(TLVItem) + cchTextMax,MEM_DECOMMIT);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
//64位系统------
function GetIconRect64(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem64;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem64),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := Int64(pszText);
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem64), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break;
end;
end;
VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
调用示例:
var prRect:TRECT;
32位:GetIconRect32(GetDesktopLvHand,'回收站',prRect);
64位:GetIconRect64(GetDesktopLvHand,'回收站',prRect);
delphi2010测试通过...
这儿有个原来写的例子
//----------
引用 CommCtrl
type
TLVItem64 = packed record
mask: UINT;
iItem: Integer;
iSubItem: Integer;
state: UINT;
stateMask: UINT;
_align: LongInt;
pszText: Int64;
cchTextMax: Integer;
iImage: Integer;
lParam: LPARAM;
end;
function GetDesktopLvHand: THandle;
begin
Result := FindWindow('progman', nil);
Result := GetWindow(Result, GW_Child);
Result := GetWindow(Result, GW_Child);
end;
//32位系统------
function GetIconRect32(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := PChar(Integer(pLVITEM) + SizeOf(TLVItem));
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
//ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
ReadProcessMemory(ProcessHD,Pointer(Integer(pLVITEM) + SizeOf(TLVItem)),@ItemBuf, cchTextMax, drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break ;
end;
end;
//VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pLVITEM, SizeOf(TLVItem) + cchTextMax,MEM_DECOMMIT);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
//64位系统------
function GetIconRect64(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem64;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem64),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := Int64(pszText);
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem64), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break;
end;
end;
VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
调用示例:
var prRect:TRECT;
32位:GetIconRect32(GetDesktopLvHand,'回收站',prRect);
64位:GetIconRect64(GetDesktopLvHand,'回收站',prRect);
delphi2010测试通过...
#6
以前也试着写过这些小工具,XP下正常使用但是在我的64位的Win7下就挂了……
#1
#2
VC
的代码也不行,只能取得图标个数。只是程序没有崩溃而已。谁能指点一下,谢谢!
void CEnumIconsDlg::OnBtnEnumIcons()
{
// bytes to allocate for icon text and LVITEM struct
#define ALLOC_SIZE 200
HWND hWnd; // handle to desktop window
DWORD dwPID; // explorer process ID (associated with desktop)
HANDLE hProcess; // handle to explorer process (associated with desktop)
LPVOID pData; // pointer to LVITEM struct in explorer address space
LPVOID pString; // pointer to icon text in explorer address space
char szText[ALLOC_SIZE]; // char array of icon text in application address space
char* pszMessageBox; // string to display
SIZE_T BytesRead; // for ReadProcessMemory
SIZE_T BytesWritten; // for WriteProcessMemory
BOOL fResult; // for ReadProcessMemory/WriteProcessMemory
LVITEM lvi; // LVITEM struct
int i; // counter for enumeration
int nItemCount; // icon item count
// get desktop window handle
if(((hWnd = FindWindowEx(NULL, NULL, "Progman", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SysListView32", NULL)) == NULL))
{
MessageBox("Could not get desktop window.");
goto Exit;
}
// get item count on desktop
nItemCount = ::SendMessage(hWnd, LVM_GETITEMCOUNT, (WPARAM)0, (LPARAM)0);
// allocate memory for output string
pszMessageBox = (char*) malloc(ALLOC_SIZE * nItemCount);
sprintf(pszMessageBox, "%d items:\n\n", nItemCount);
// get desktop window process ID (explorer.exe)
GetWindowThreadProcessId(hWnd, &dwPID);
// open process to get explorer process handle
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
// allocate memory in explorer's address space
// allocate space for LVITEM struct
pData = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// allocate space for string (i.e. "Network Neighborhood")
pString = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// init LV_ITEM struct
ZeroMemory(&lvi, sizeof(LVITEM));
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.cchTextMax = 500;
lvi.pszText = (char*)pString; // use alloc'd string space
// write the contents of lvi into explorer's address space
fResult = WriteProcessMemory(hProcess, pData, &lvi, sizeof(LVITEM), &BytesWritten);
// enum all icons
for(i = 0; i < nItemCount; i++)
{
// get item's name
::SendMessage(hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pData);
// read back lvi struct (for debugging purposes only)
fResult = ReadProcessMemory(hProcess, pData, szText, ALLOC_SIZE, &BytesRead);
// read text of queried item
fResult = ReadProcessMemory(hProcess, pString, szText, ALLOC_SIZE, &BytesRead);
// append string to output string
strcat(pszMessageBox, szText);
strcat(pszMessageBox, "\n");
}
// output message box with all icon texts
MessageBox(pszMessageBox);
// free alloc'd memory for message box
free(pszMessageBox);
// free alloc'd memory for string and LVITEM structs
if(!VirtualFreeEx(hProcess, pString, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
if(!VirtualFreeEx(hProcess, pData, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
// close process handle
CloseHandle(hProcess);
Exit:
return;
}
的代码也不行,只能取得图标个数。只是程序没有崩溃而已。谁能指点一下,谢谢!
void CEnumIconsDlg::OnBtnEnumIcons()
{
// bytes to allocate for icon text and LVITEM struct
#define ALLOC_SIZE 200
HWND hWnd; // handle to desktop window
DWORD dwPID; // explorer process ID (associated with desktop)
HANDLE hProcess; // handle to explorer process (associated with desktop)
LPVOID pData; // pointer to LVITEM struct in explorer address space
LPVOID pString; // pointer to icon text in explorer address space
char szText[ALLOC_SIZE]; // char array of icon text in application address space
char* pszMessageBox; // string to display
SIZE_T BytesRead; // for ReadProcessMemory
SIZE_T BytesWritten; // for WriteProcessMemory
BOOL fResult; // for ReadProcessMemory/WriteProcessMemory
LVITEM lvi; // LVITEM struct
int i; // counter for enumeration
int nItemCount; // icon item count
// get desktop window handle
if(((hWnd = FindWindowEx(NULL, NULL, "Progman", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL)) == NULL) ||
((hWnd = FindWindowEx(hWnd, NULL, "SysListView32", NULL)) == NULL))
{
MessageBox("Could not get desktop window.");
goto Exit;
}
// get item count on desktop
nItemCount = ::SendMessage(hWnd, LVM_GETITEMCOUNT, (WPARAM)0, (LPARAM)0);
// allocate memory for output string
pszMessageBox = (char*) malloc(ALLOC_SIZE * nItemCount);
sprintf(pszMessageBox, "%d items:\n\n", nItemCount);
// get desktop window process ID (explorer.exe)
GetWindowThreadProcessId(hWnd, &dwPID);
// open process to get explorer process handle
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
// allocate memory in explorer's address space
// allocate space for LVITEM struct
pData = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// allocate space for string (i.e. "Network Neighborhood")
pString = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// init LV_ITEM struct
ZeroMemory(&lvi, sizeof(LVITEM));
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.cchTextMax = 500;
lvi.pszText = (char*)pString; // use alloc'd string space
// write the contents of lvi into explorer's address space
fResult = WriteProcessMemory(hProcess, pData, &lvi, sizeof(LVITEM), &BytesWritten);
// enum all icons
for(i = 0; i < nItemCount; i++)
{
// get item's name
::SendMessage(hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pData);
// read back lvi struct (for debugging purposes only)
fResult = ReadProcessMemory(hProcess, pData, szText, ALLOC_SIZE, &BytesRead);
// read text of queried item
fResult = ReadProcessMemory(hProcess, pString, szText, ALLOC_SIZE, &BytesRead);
// append string to output string
strcat(pszMessageBox, szText);
strcat(pszMessageBox, "\n");
}
// output message box with all icon texts
MessageBox(pszMessageBox);
// free alloc'd memory for message box
free(pszMessageBox);
// free alloc'd memory for string and LVITEM structs
if(!VirtualFreeEx(hProcess, pString, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
if(!VirtualFreeEx(hProcess, pData, ALLOC_SIZE, MEM_DECOMMIT))
{
MessageBox("VirtualFreeEx failed.");
goto Exit;
}
// close process handle
CloseHandle(hProcess);
Exit:
return;
}
#3
有人解释了为什么出错和解决了这个问题。不过是汇编版的,我正在研究。
碰到类似的问题的朋友可以参考。
http://masm32.com/board/index.php?topic=1464.0
里面有生成的EXE,确实XP,win7平台均可以提取桌面图标文字。
碰到类似的问题的朋友可以参考。
http://masm32.com/board/index.php?topic=1464.0
里面有生成的EXE,确实XP,win7平台均可以提取桌面图标文字。
#4
楼主解决了吗?
#5
这个跟XP或者Win7没多大关系,32和64位的区别
这儿有个原来写的例子
//----------
引用 CommCtrl
type
TLVItem64 = packed record
mask: UINT;
iItem: Integer;
iSubItem: Integer;
state: UINT;
stateMask: UINT;
_align: LongInt;
pszText: Int64;
cchTextMax: Integer;
iImage: Integer;
lParam: LPARAM;
end;
function GetDesktopLvHand: THandle;
begin
Result := FindWindow('progman', nil);
Result := GetWindow(Result, GW_Child);
Result := GetWindow(Result, GW_Child);
end;
//32位系统------
function GetIconRect32(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := PChar(Integer(pLVITEM) + SizeOf(TLVItem));
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
//ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
ReadProcessMemory(ProcessHD,Pointer(Integer(pLVITEM) + SizeOf(TLVItem)),@ItemBuf, cchTextMax, drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break ;
end;
end;
//VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pLVITEM, SizeOf(TLVItem) + cchTextMax,MEM_DECOMMIT);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
//64位系统------
function GetIconRect64(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem64;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem64),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := Int64(pszText);
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem64), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break;
end;
end;
VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
调用示例:
var prRect:TRECT;
32位:GetIconRect32(GetDesktopLvHand,'回收站',prRect);
64位:GetIconRect64(GetDesktopLvHand,'回收站',prRect);
delphi2010测试通过...
这儿有个原来写的例子
//----------
引用 CommCtrl
type
TLVItem64 = packed record
mask: UINT;
iItem: Integer;
iSubItem: Integer;
state: UINT;
stateMask: UINT;
_align: LongInt;
pszText: Int64;
cchTextMax: Integer;
iImage: Integer;
lParam: LPARAM;
end;
function GetDesktopLvHand: THandle;
begin
Result := FindWindow('progman', nil);
Result := GetWindow(Result, GW_Child);
Result := GetWindow(Result, GW_Child);
end;
//32位系统------
function GetIconRect32(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := PChar(Integer(pLVITEM) + SizeOf(TLVItem));
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
//ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
ReadProcessMemory(ProcessHD,Pointer(Integer(pLVITEM) + SizeOf(TLVItem)),@ItemBuf, cchTextMax, drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break ;
end;
end;
//VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pLVITEM, SizeOf(TLVItem) + cchTextMax,MEM_DECOMMIT);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
//64位系统------
function GetIconRect64(hDeskWnd:HWND ;strIconName:String;var lpRect:TRECT):Boolean;
const cchTextMax=512;
var
ItemBuf: array [0 .. 512] of char;
pszText: PChar;
LVItem: TLVItem64;
ProcessID, ProcessHD, drTmp: DWORD;
pLVITEM: Pointer;
pItemRc:^TRect;
nCount,iItem:Integer;
begin
Result :=False ;
GetWindowThreadProcessId(hDeskWnd, ProcessID);
ProcessHD := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False,ProcessID);
if (ProcessHD=0) then Exit
else begin
pLVITEM := VirtualAllocEx(ProcessHD, nil, SizeOf(TLVItem64),MEM_COMMIT, PAGE_READWRITE);
pszText:=VirtualAllocEx(ProcessHD,nil,cchTextMax,MEM_COMMIT,PAGE_READWRITE);
pItemRc:=VirtualAllocEx(ProcessHD,nil,sizeof(TRECT),MEM_COMMIT,PAGE_READWRITE);
if (pLVITEM=nil) then
else begin
LVItem.iSubItem := 0;
LVItem.cchTextMax := cchTextMax;
LVItem.pszText := Int64(pszText);
WriteProcessMemory(ProcessHD, pLVITEM, @LVItem, SizeOf(TLVItem64), drTmp);
nCount:=SendMessage(hDeskWnd,LVM_GETITEMCOUNT,0,0);
for iItem := 0 to nCount - 1 do begin
SendMessage(hDeskWnd, LVM_GETITEMTEXT, iItem, Integer(pLVITEM));
ReadProcessMemory(ProcessHD,pszText,@ItemBuf,cchTextMax,drTmp);
if (ItemBuf=strIconName) then begin
SendMessage(hDeskWnd,LVM_GETITEMRECT,iItem,LPARAM(pItemRc));
ReadProcessMemory(ProcessHD,pItemRc,@lpRect,sizeof(TRECT),drTmp);
Result :=True ;
Break;
end;
end;
VirtualFreeEx(ProcessHD,pLVITEM,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pszText,0,MEM_RELEASE);
VirtualFreeEx(ProcessHD,pItemRc,0,MEM_RELEASE);//释放内存
end;
CloseHandle(ProcessHD);
end;
end;
调用示例:
var prRect:TRECT;
32位:GetIconRect32(GetDesktopLvHand,'回收站',prRect);
64位:GetIconRect64(GetDesktopLvHand,'回收站',prRect);
delphi2010测试通过...
#6
以前也试着写过这些小工具,XP下正常使用但是在我的64位的Win7下就挂了……