Link to home
Start Free TrialLog in
Avatar of the_modder
the_modderFlag for United States of America

asked on

Get Another Application's ListView

I need to get a list view from another application.

This is how it is buried in it:
CpuIdle (TFormAbout)
 (TPageControl)
 "&Times" (TTabSheet)
    "" (TListView)

So basicly I need to get everything from that list view into my app.

Thanks in advance,
David Burban
Avatar of the_modder
the_modder
Flag of United States of America image

ASKER

Points increased from 100 to 150 because I know that this is not an easy question.
Avatar of DaFox
DaFox

Hi David,

you have to get into the target's process memory. There are 2 possibilities:

1. Use SetWindowsHookEx() to inject a DLL into the memory of the application containing the ListView.
Pro: There are complete samples; most of them set up on an example by Jeffrey Richter (it's called DIPS - Desktop Icon Positioning System, or sth. like that)
Con: You have to use a DLL since you're hooking an external application.

2. Use ReadProcessMemory() to get access to the ListView.
Pro: No DLL is needed!
Con: IMHO it's more complicated and there are not much examples on this method.

Regards,
Markus
Can you give a link to DIPS?
I found a link to DIPS: http://www.moris.ru/~spinoza/default.html .

It does not come with source.

I would like to have a stand alone app, one that hopefully does not need to inject a dll. If that's required then so be it, but I have to acess the info from 2 apps (so it should be able to supply the info to 2 apps at once).
^
Bump.
Hi David,

DIPS is written in VC++.
These two archives contain full Delphi source code:

http://www.luckie-online.de/downloads/luckiedips.zip
http://www.assarbad.org/stuff/!import/nico.old/dipssrc.zip

IIRC they're both nonVCL, I hope you don't care.

Markus
I do not care if they are in nonVLC form. But I can't figure out how to use them.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, CommCtrl;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TDesktopIconInfo = packed record
    Caption: string;
    Position: TPoint;
  end;

  TDesktopIconInfoArray = array of TDesktopIconInfo;
  TIniSections = array of string;

var
  Form1: TForm1;

const

  APPNAME = 'LuckieDIPS';
  VER = '1.2';
  INFO_TEXT = APPNAME + ' ' + VER + #13#10 +
    'Copyright © 2003 Michael .:Luckie:. Puff' + #13#10#13#10 +
    'http://www.luckie-online.de' + #13#10#13#10 +
    'Thanks fly to Nico ;o)';

  INIFILENAME = 'DesktopIconPos.ini';
  BACKSLASH = '\';

  TEXT_LOCATION = 'Speicherort für DesktopIconPos.ini:';
  ERROR_GETDESKTOPHANDLE = 'Fehler bei Ermittlung des Desktophandles!';
  SUCCESS_SAVING = 'Desktopicon Positionen erfolgreich gespeichert in:';
  ERROR_SAVING = 'Desktopicon Positionen konnten nicht gespeichert werden.';
  SUCCESS_RESTORING = 'Desktopicon Positionen wiederhergestellt aus:';
  ERROR_RESTORING =
    'Desktopicon Positionen konnten nicht wiederhergestellt werden.';
  SUCCESS_REMOVINGFILEANDFOLDER = 'Datei und Order erfolgreich entfernt.';
  ERROR_REMOVINGFILEANDFOLDER =
    'Datei und Ordner konnten nicht entfernt werden.';

implementation

{$R *.dfm}
function GetDesktopListView(): HWND;
var
  ClassName: string;
begin
  Result := FindWindow('CpuIdle', Nil);
  Result := GetWindow(Result, GW_CHILD);

  //  Result := GetWindow(Result, GW_CHILD);
  SetLength(ClassName, 40);
  SetLength(ClassName, GetClassName(Result, PChar(ClassName), 39));
  if (ClassName <> 'SysListView32') then
  begin
    MessageBox(0, ERROR_GETDESKTOPHANDLE,
      APPNAME, MB_ICONERROR or MB_OK);
    Result := 0;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  ListView: HWND;
  ProcessId: DWORD;
  Process: THandle;
  Size: Cardinal; // SIZE_T
  MemLocal: Pointer;
  MemRemote: Pointer;
  NumBytes: Cardinal; // SIZE_T
  IconCount: DWORD;
  IconIndex: Integer;
  IconLabel: string;
  IconPos: TPoint;
  DesktopIconInfoArray: TDesktopIconInfoArray;
begin
  // Fensterhandle des Desktop-ListView ermitteln und Prozess oeffnen
  ProcessId := 0;
  ListView := GetDesktopListView();
  GetWindowThreadProcessId(ListView, @ProcessId);
  Process := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
    PROCESS_VM_WRITE, False, ProcessId);
      IconCount := SendMessage(ListView, LVM_GETITEMCOUNT, 0, 0);
end;

end;

I can't figure out why it does not get at least he items count. Could you please load CPUIdle ( http://www.cpuidle.de/ ) and fill in the blanks.

Thanks.
^
Bump!
^
^
^
BUMP!
BUMP!

Points increased to 155!
Please! Someone!
I am leaving for 5 days. Please, someone give me some working code!
So, anyone else?

Please, I need this code done by the time I come back!

Points increased to 160.
Avatar of Eddie Shipman
Try this here...

http://www.datavis.ch/Thomas/Downloads/Delphi/GrabListView.zip

Includes Delphi source code. Remember, that you don't have
to do all this with Win9x. You need to check win versions
before calling this code...
I ran the test app and it did not get ANY listview in any program. It did though list the proper things like TListView and Internet Explorer_Server.

I need the code to work under XP.
^
bump!

Thanks...
Anyone????
Bump....

Anyone else?
Hmmm, it worked for me under XP AND WIn2K. Might be a premissions thing?
Make this change and it works on XP:

procedure TMainForm.Timer1Timer(Sender: TObject);
var
  W: HWND;
  CName: String;
begin
  W := WindowFromPoint(Mouse.CursorPos);
  CName := GetWndClassName(W);
  Caption := CName;
  //
  // For some reason doesn't like F12. Changed to F4 and it worked.
  //
  if (GetAsyncKeyState(VK_F4) and 1) <> 0 then begin
    if SameText(CName, 'SysListView32')
    or SameText(CName, 'TListView') or
    SameText(CName, 'SysTabControl32')
    then begin
      GrabListView(W);
    end;
  end;
end;
What is it with the desktop listview you are trying to do, anyway?
I'm not trying to do anything with the desktop list view. There is a list view in a program called CPUIdle that i need to get.
I tried the form with your code. Nada (nothing).
Thanks! It works! I had to figure out that you had to press F4.
Well, I was wondering when you were going to get it... ;-)
How would I find the window of CpuIdle without using the mouse over thingie?
Use FindWindow or EnumWindows to get the handle and pass it just like WindowFromPoint.
Where do you get this CPUIle program?
So, how would I get the handle of the listview? The thing only displays the listview if my mouse is directly over it.

Points increased to 175.
Well how DO you want to get it? You have to let me know what you want to do eactly. I don't know how
you want to get this data from YOUR program.

What I would do is have a timer and in the Timer's OnTimer, enumWindows to see if the CPUIdle window is
active and if so, then get it just like it does in the example but passing it the handle from the EnumWindows
instead of the one from WindowFromPoint..
I downloaded the Alpha and the only listview I could find was the one on the TaskBar tab.
Is that what you want?
Is the application always going to be running?
Is it going to be hidden in the tray?
I am not using the alpha version. The listview if you use WinDose is hidden under
CpuIdle (TFormAbout)
  "" (TPageControl)
     "&Timer" (TTabSheet)
        "" (TListView)
I downloaded the alpha version. Here is were the list is found. It is detected by WinDowse when the program is in the systemtray (and not open).
"CpuIdle" (TCpuIdleForm)
   "" (TPageControl)
     "&TaskBar" (TTabSheet)
       "" (TListView)
Well, I don't have the other version and can't do it for you.
You are going to have to use EnumWindows and EnumChildWindows to get to the Listview.
Now if the app is minimized to the tray, I don't know...
I can use either the alpha or the stable version. I just need an example. The only differences between the versions is instead of being called TFormAbout it is called TCpuIdleForm and the Timer has been replaced by Taskbar.
https://www.experts-exchange.com/questions/20726000/Getting-Handle-of-an-Object-in-an-external-program.html

I found that. unfortunatly it did not help figure it out.

I don't care which version it is for.
Getting to the litstview isn't that difficult with EnumWindows/EnumChildWindows. I will whip something up for you.
ASKER CERTIFIED SOLUTION
Avatar of Eddie Shipman
Eddie Shipman
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial