Icons from syslistview32?

Hi all!

How can i read all icons from a  syslistview32?
(SYSLISTVIEW32 it's important!)

Thanks!
rogerrrAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Lee_NoverCommented:
read them into what ? into a TImageList ? give more detail
0
rogerrrAuthor Commented:
Yes! Into an imagelist. I tried to apply some method but my attempt was unsuccessful. I tried for example:
SendMessage and LVM_GETIMAGELIST; ListView_GetImagelist but my imagelist is empty...

0
Lee_NoverCommented:
this loads the system imagelist into a TImageList named Images
check for other params (icon size and type)

uses ShellApi;

procedure TForm1.FormCreate(Sender: TObject);
var sfi: TSHFileInfo;
begin
     Images.Handle:=SHGetFileInfo('', 0, sfi, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
     Images.ShareImages:=true; // so we don't destroy the system image list !
end;
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

rogerrrAuthor Commented:
Hello!

Thanks but i want to read icons from a listview control. For example from desktop's syslistview32. I don't know how can i get list items iImage index. My supposition is:

First i must to get items iImage index and after (if i know these indexes) i must to select these numbers from the system's cached icons list....
0
Lee_NoverCommented:
huh ? there's one system imagelist .. the shell "reads" from it
what do you want anyway ?
0
rogerrrAuthor Commented:
Hello!

'check for other params (icon size and type)' :-)
You're in the right!!! Sorry! :-(
First i received only 5 icons but after a little bit code correction this method was good.

I found a code with i can read syslistview32 labels.
http://igp.org.ua/vmcl/?id=view_article&aid=1

SourceCode: http://igp.org.ua/vmcl/files.pub/articles/00000001/DIP_Example1.zip

I want to complete this code to get images too but when i  read iImage index the result will be 0. Why? What's the perfect resolution to get image indexes? What i must to use LVM_GETIMAGELIST or LVM_GETITEM?

Thank you!
0
Lee_NoverCommented:
why LVM ? you're not working with an imagelist directly
or in the correct flags ofcourse (SHGFI_SYSICONINDEX), the second thing is if you're querying a file it MUST exist !
you must provide a real path ... or alternatively set the ItemID
I ask you again .. what are you trying to achieve ?
if you want to get the desktop items then check my EE answer here:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21152235.html
0
Lee_NoverCommented:
I just noticed something really funny .. ah well ..
0
rogerrrAuthor Commented:
'I ask you again .. what are you trying to achieve ?'

I'm not interested in desktop unconditionally! My target object is a syslistview32 control!

Another example.

const
  PROCESS_ACCESS = PROCESS_VM_OPERATION or PROCESS_VM_READ or
  PROCESS_VM_WRITE;
  type
  PProcData = ^TProcData;
  TProcData = record
    Item: TLVItemA;
    Txt: packed array [0 .. 1023] of AnsiChar;
    ItemRect: TRect;
  end;
var
  LV: HWND;
  Cnt, I: Integer;
  ProcID: DWORD;
  ProcessHandle: THandle;
  Data: TProcData;
  RemoteProcData: PProcData;
  Res: Boolean;
  LI: TListItem;
  ColWid: Integer;
begin
  ListBox1.Clear;
  if hvalue=nil then hValue:=TStringList.Create else hValue.Clear;
  LV:=FindWindow('CabinetWClass',nil);
  LV:=FindWindowEx(LV,0,'SHELLDLL_DefView',nil);
  LV:=FindWindowEx(LV,0,'SysListView32',nil);
  ProcID := 0;
  GetWindowThreadProcessId(LV, @ProcID);
  ProcessHandle := OpenProcess(PROCESS_ACCESS, False, ProcID);
  try
    RemoteProcData := VirtualAllocEx(ProcessHandle, nil,
   SizeOf(RemoteProcData^), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
    try
      Cnt := ListView_GetItemCount(LV);
      for I := 0 to Cnt - 1 do
      begin
        FillChar(Data, SizeOf(Data), 0);

        with Data.Item do
        begin
          iSubItem := 0;
          pszText := @RemoteProcData^.Txt;
          cchTextMax := SizeOf(RemoteProcData^.Txt) - 1;
        end;
        Res := WriteProcessMemory(ProcessHandle, RemoteProcData,
          @Data, SizeOf(Data), PLongWord(nil)^);

        SendMessage(LV, LVM_GETITEMTEXT, I, LPARAM(@RemoteProcData^.Item));

        SendMessage(LV, LVM_GETITEMRECT, I, LPARAM(@RemoteProcData^.ItemRect));

        Res := ReadProcessMemory(ProcessHandle, RemoteProcData,
          @Data, SizeOf(Data), PLongWord(nil)^);

        ListBox1.Items.add(Data.Txt);
      end;
    finally
        Res := LongBool(VirtualFreeEx(ProcessHandle, RemoteProcData,
        0, MEM_RELEASE));
    end;
  finally
    CloseHandle(ProcessHandle);
  end;




(Run MyComputer or Control Panel -View\Details-  and execute this code)

If i set the value of iSubItem then i can read every column but i can't display listview's icons in my application. I need to use this way to get these items because the system contains other syslistview32 too where isn't opportunity to detect a real path.


Do you have any idea to get the number of an LVItem.iImage?

Thank you!
0
Slick812Commented:
hello  rogerrr , ,  as I was in Windows XP and the SysListView32 was NOT in the explorer windows, but they had the   DUIViewWndClassName   instead, which did not respond to any SysListView32 messages or functions, it seems that you have done most of what is needed for this in your calls for VirtualAllocEx and getting some access to the other processes mem. .

anyway, the code for the imagelist and List Item imageList index number are from my other code uses -

ZeroMemory(@ListItem, SizeOf(ListItem));
ListItem.mask := LVIF_IMAGE; // set mask for the info to be placed into the ListItem
ListView_GetItem(hLV, ListItem);

hSmImgList := ListView_GetImageList(hLV, LVSIL_SMALL); // get ImageList, usually the same as the system icon ImageList
hSmIcon := ImageList_GetIcon(hSmImgList, ListItem.iImage, ILD_SELECTED); // get icon handle

 - - - - - - - - - - - - - - - - - -  - -

I can not test it right now, but here is my guess at how to place in your code



FillChar(Data, SizeOf(Data), 0);
with Data.Item do
        begin
        // you might need to get the iItem index inhere somehow
        //iSubItem := 0;
        mask := LVIF_IMAGE;
       // pszText := @pRemoteData^.Txt; // not needed here
        //cchTextMax := SizeOf(pRemoteData^.Txt) - 1;
        end;
      if not WriteProcessMemory(hProcess, pRemoteData,
          @Data, SizeOf(Data), BytesWritten) then
        begin
        ShowMessage('ERROR - WriteProcessMemory did not work');
        Exit;
        end;
     if ListView_GetItem(hLV, pRemoteData.Item) then
       begin
       hSmIcon := ImageList_GetIcon(hSmImgList, pRemoteData.Item.iImage, ILD_SELECTED);
       if hSmIcon <> 0 then
         DrawIconEx(Canvas.handle,340,20,hSmIcon, 0,0, 0, 0, DI_NORMAL);
       end;

     // SendMessage(hLV, LVM_GETITEMTEXT, I, LPARAM(@pRemoteData^.Item);));

     // SendMessage(hLV, LVM_GETITEMRECT, I, LPARAM(@pRemoteData^.ItemRect));

 - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - -  - - - -

maybe this will help?
0
rogerrrAuthor Commented:
Hello!

I'm silly and i can't manage it. :-(  I tried your code but indexes they will be 0. I searched for a new control you can find under Task Manager window (first tab).

LV:=FindWindow('#32770',nil);
LV:=FindWindowEx(LV,0,'#32770',nil);
LV:=FindWindowEx(LV,0,'SysListView32',nil);

If you have any free time please apply your code on this control and if will be successful please share a clear-out code with me. Thank you!

I increased points from 125 to 250! :-)

P.S.: You're my last hope!
0
Slick812Commented:
I may have time to test later, I will ask -

did the test  -

 if ListView_GetItem(hLV, pRemoteData.Item) then

return true? did this ListView_GetItem function succeed?
0
rogerrrAuthor Commented:
Hello!

Yes, the returned value it's true.
0
Slick812Commented:
not much time now to test but, , I forgot to place my use of data  after the ReadProcessMemory, so this may be more able to be working -


      FillChar(Data, SizeOf(Data), 0);
      with Data.Item do
        begin
        iItem := 1;
        //iSubItem := 0;
        mask := LVIF_IMAGE or LVIF_TEXT;
        pszText := @pRemoteData^.Txt;
        cchTextMax := SizeOf(pRemoteData^.Txt) - 1;
        end;
      if not WriteProcessMemory(hProcess, pRemoteData,
          @Data, SizeOf(Data), BytesWritten) then
        begin
        ShowMessage('ERROR - WriteProcessMemory did not work');
        Exit;
        end;
      GotIt := False;
      if ListView_GetItem(hLV, pRemoteData.Item) then GotIt := True;

      if not ReadProcessMemory(hProcess, pRemoteData,
                    @Data, SizeOf(Data), BytesWritten) then
        begin
        ShowMessage('ERROR - ReadProcessMemory did not work');
        Exit;
        end;

       if GotIt then
       begin
       ListBox1.Items.add(IntToStr(Data.Item.iImage));
       hSmImgList := ListView_GetImageList(hLV, LVSIL_NORMAL);
       hSmIcon := ImageList_GetIcon(hSmImgList, Data.Item.iImage, ILD_NORMAL);
       ListBox1.Items.add(IntToStr(hSmIcon));
       if hSmIcon <> 0 then
         DrawIconEx(Canvas.handle,340,50,hSmIcon, 0,0, 0, 0, DI_NORMAL);
       end;

      ListBox1.Items.add(Data.Txt);

 - - - - - - - - - - - - - - - - - - - - - -
sorry busy today
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rogerrrAuthor Commented:
Hello!

Super! It's in good working order! Indexes of iImage are positive. (I checked it with an iconcache lister.) Thank you ever so much!
0
Lee_NoverCommented:
whatever
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.