Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Icons from syslistview32?

Posted on 2004-11-14
16
Medium Priority
?
708 Views
Last Modified: 2010-08-05
Hi all!

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

Thanks!
0
Comment
Question by:rogerrr
  • 7
  • 6
  • 3
16 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 12592128
read them into what ? into a TImageList ? give more detail
0
 

Author Comment

by:rogerrr
ID: 12592474
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 12592584
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:rogerrr
ID: 12594974
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 12596483
huh ? there's one system imagelist .. the shell "reads" from it
what do you want anyway ?
0
 

Author Comment

by:rogerrr
ID: 12597444
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 12598046
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 12598054
I just noticed something really funny .. ah well ..
0
 

Author Comment

by:rogerrr
ID: 12598892
'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
 
LVL 34

Expert Comment

by:Slick812
ID: 12610360
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
 

Author Comment

by:rogerrr
ID: 12615626
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
 
LVL 34

Expert Comment

by:Slick812
ID: 12617903
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
 

Author Comment

by:rogerrr
ID: 12619696
Hello!

Yes, the returned value it's true.
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 1000 total points
ID: 12621550
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
 

Author Comment

by:rogerrr
ID: 12624959
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 12625248
whatever
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses
Course of the Month20 days, 17 hours left to enroll

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question