首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

获取WIN7桌面图标名称,小弟我已要抓狂,各位大神

2013-11-29 
获取WIN7桌面图标名称,我已要抓狂,求助各位大神!以下方法在WIN7下获取桌面句柄无效:Handle : FindWindow(

获取WIN7桌面图标名称,我已要抓狂,求助各位大神!
以下方法在WIN7下获取桌面句柄无效:
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.



[解决办法]
楼主解决了吗?
[解决办法]
这个跟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测试通过...
[解决办法]
以前也试着写过这些小工具,XP下正常使用但是在我的64位的Win7下就挂了……

热点排行