the_modder
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
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
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
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
ASKER
Can you give a link to DIPS?
ASKER
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).
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).
ASKER
^
Bump.
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
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
ASKER
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_REMOVINGFILEANDFOL DER = 'Datei und Order erfolgreich entfernt.';
ERROR_REMOVINGFILEANDFOLDE R =
'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(L istView, @ProcessId);
Process := OpenProcess(PROCESS_VM_OPE RATION 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.
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_REMOVINGFILEANDFOL
ERROR_REMOVINGFILEANDFOLDE
'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(L
Process := OpenProcess(PROCESS_VM_OPE
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.
ASKER
^
Bump!
Bump!
ASKER
^
^
^
BUMP!
^
^
BUMP!
ASKER
BUMP!
Points increased to 155!
Points increased to 155!
ASKER
Please! Someone!
ASKER
I am leaving for 5 days. Please, someone give me some working code!
ASKER
So, anyone else?
Please, I need this code done by the time I come back!
Points increased to 160.
Please, I need this code done by the time I come back!
Points increased to 160.
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...
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...
ASKER
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.
I need the code to work under XP.
ASKER
^
bump!
Thanks...
bump!
Thanks...
ASKER
Anyone????
ASKER
Bump....
Anyone else?
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(Send er: TObject);
var
W: HWND;
CName: String;
begin
W := WindowFromPoint(Mouse.Curs orPos);
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;
procedure TMainForm.Timer1Timer(Send
var
W: HWND;
CName: String;
begin
W := WindowFromPoint(Mouse.Curs
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?
ASKER
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.
ASKER
I tried the form with your code. Nada (nothing).
ASKER
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... ;-)
ASKER
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?
ASKER
ASKER
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.
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..
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?
Is that what you want?
Is the application always going to be running?
Is it going to be hidden in the tray?
ASKER
I am not using the alpha version. The listview if you use WinDose is hidden under
CpuIdle (TFormAbout)
"" (TPageControl)
"&Timer" (TTabSheet)
"" (TListView)
CpuIdle (TFormAbout)
"" (TPageControl)
"&Timer" (TTabSheet)
"" (TListView)
ASKER
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)
"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...
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...
ASKER
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.
ASKER
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.
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/EnumChildWindo ws. I will whip something up for you.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER