Sorry but this seems neverending, I have not yet come accross a proper working example (code). Please somebody put up an example (code) that actually works! thankyou
Printable View
Sorry but this seems neverending, I have not yet come accross a proper working example (code). Please somebody put up an example (code) that actually works! thankyou
Yup, thats what I thought.
What have you tried that didn't work?
Also, if it's owner drawn it might not work...
I have tried everything, hax0rs function looked most promising but returns null strings. Its not owner drawn. This just simply cant be done, nobody can put up working code for this, only reaons why it wont work or code that doesnt work! sucks
You need to be a little more specific about what does not work.
I've read throught the other threads and simply stating that it returns null strings is not of any help.
Do you examine the return code from each API call to determine if any of your functions are returning an error?
The code posted does work, it is just not working in your situation so something specific about your program is not working.
Did you want to get the text of the listview item?
Using WriteProcessMemory and ReadProcessMemory works fine from VB.
From what i've read from others, they say you need to do it from within the external app's process memory. So I made this code that did just that. I tried it on Windows Explorer and it gave me the correct text.
i used c++ and vb.net
for the c++ dll:
now for the vb.net code that calls the dll function installHook():Code:#include "stdafx.h"
#include "Commctrl.h"
#pragma data_seg(".shared")
HWND _hTarget = 0;
HHOOK hook=0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
LVITEM *lvItem;
char lpText[255];
HINSTANCE hInst;
bool flag = true;;
//send LVM_GETITEMTEXT message from within external app's process
int getLVText(HWND hTarget)
{
lvItem = new LVITEM;
lvItem->iSubItem = 0;
lvItem->cchTextMax = 255;
lvItem->pszText = lpText;
int res = SendMessage(hTarget, LVM_GETITEMTEXT, 0, (long)lvItem);
if (res != 0)
{
flag = false;
MessageBox(NULL, lvItem->pszText, "", MB_OK); //messagebox shows the listview item string
return 1;
}
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hInst = (HINSTANCE)hModule;
return TRUE;
}
LRESULT CALLBACK hookproc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(flag) //I put the flag so it only calls getLVText once
{
getLVText(_hTarget);
}
return ::CallNextHookEx(hook, nCode, wParam, lParam);
}
//these codes injects the dll into external app's process
__declspec(dllexport) int _stdcall installHook(HWND hTarget)
{
_hTarget = hTarget;
DWORD tid;
tid = ::GetWindowThreadProcessId(hTarget, 0);
hook = ::SetWindowsHookEx(WH_GETMESSAGE, hookproc, hInst, tid);
if (hook != NULL)
return 1;
return 0;
}
VB Code:
Public Declare Function installHook Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\getListView\Debug\getListView.dll" (ByVal hwnd As Integer) As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim hTarget As Integer 'the handle to the target ListView control, Im sure you could implement the code to get the handle Dim res As Integer = installHook(hTarget) End Sub
I hope getting the text of the listview items is what you wanted because it took me a while to do this. This is probably not the exact code you'll be using in your program, but it should give you an idea of how to get the text of the listview item.
Moeur, was that last comment of yours for me?
My last comment was for anyone looking to do this.
You have shown one way to do it and I was commenting that the original way works well too and does not require C++.
oh. Well, I was just curious how that other way works. If you write the structure in the external process, then you sendmessage() using the pointer that you get from the writeprocessmemory(), which process memory is that pointer pointing to? The calling process or the external process? I'm a bit confused. When I sendmessage(), lets say WM_SETTEXT, the pointer to the buffer containing the string is pointing to an address in the calling process. But the method with WriteProcessMemory() appear to be pointing at an address in the external process.
You are correct, when you call SendMessage with the WM_SETTEXT message, the operating system recognizes the message and marshals the data for you from one process to the next as required.
User-defined messages are not marshalled since the OS does not know about them (since they are user defined).
Many messages that are specific to certain controls like the listview and RichTextbox are user-defined messages and the OS does not marshal them for you.
benmartin101, any chance of the actual dll? and also the code for vb where u put the vb.net code in the button. Thanks, sorry.. know im asking alot!
hum..
Dim res As Integer = installHook(hTarget)
Integer ? should it be string ?
Also the window handle is integar shouldnt that be long
I attached the project with the dll.
Here is the vb.net code to call and use the dll.
VB Code:
Imports System.Runtime.InteropServices Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Public Const WM_CHAR = &H102 Public Declare Function installHook Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\getListView\Debug\getListView.dll" (ByVal hwnd As Integer, ByVal vbhwnd As Integer) As Integer Public Declare Function getItemText Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\getListView\Debug\getListView.dll" (ByVal index As Integer) As IntPtr Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim res As Integer = installHook(listViewHandle, Me.Handle.ToInt32) PostMessage(child, WM_CHAR, 0, 0) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim strPtr As IntPtr = getItemText(itemIndex) '0 based Dim str As String = Marshal.PtrToStringAnsi(strPtr) MsgBox(str) End Sub
Thanks for your effort but I am so confused, forgive my ignorance.
Ok first of all why is your api " hwnd As Integer" and not long????
Also on the first button click, what is:
"PostMessage(child, WM_CHAR, 0, 0) "
I don't see a child variable anywhere... whats going on there??
Just everything about that code doesnt make any sense to me, maybe its cause its in .net
Can anybody transfer this to vb???? belive me I have tried
its integer instead of long because in vb6, long is 4 bytes, while long in vb.net is 8 bytes. To make it work, substitute long with vb.net's integer, which is 4 bytes. The "child" part, you should replace that with the handle of your target listview.
I made changes to dll, so I attach new version.
Here is vb6 code:
VB Code:
Private Const WM_CHAR = &H102 Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long Private Declare Function installHook Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\getListView\Debug\getListView.dll" (ByVal hwnd As Long) As Long Private Declare Function getItemText Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\getListView\Debug\getListView.dll" (ByVal index As Long) As Long Private Declare Function getItemCount Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\getListView\Debug\getListView.dll" () As Long Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" ( _ ByVal lpString1 As String, _ ByVal lpString2 As Long _ ) As Long Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" ( _ ByVal lpString As Long _ ) As Long Private Sub Command1_Click() Dim lvHwnd As Long 'handle to listview Dim res As Integer res = installHook(lvHwnd) PostMessage lvHwnd, WM_CHAR, 0, 0 'this triggers dll to load End Sub Private Sub Command2_Click() Dim lpString As Long Dim strVal As String Dim lenstr As Long Dim itemCount As Long itemCount = getItemCount() 'to get total item in listview lpString = getItemText(0) 'to get text of item; 0-based lenstr = lstrlen(lpString) + 1 strVal = String(lenstr, 0) lstrcpy strVal, lpString MsgBox (strVal) End Sub
Thanks again for all your effort, but it just doesnt seem to work.. it doesnt even return the amount in the listview (returns 0)
can you post the vb code that you are running?
Exact same vb code you posted, except i put:
VB Code:
Private Sub Command1_Click() Dim lvHwnd As Long 'handle to listview lvHwnd = whatever the handle is Dim res As Integer res = installHook(lvHwnd) PostMessage lvHwnd, WM_CHAR, 0, 0 'this triggers dll to load End Sub
And of course changed path to the dll!
I attached a vb project that should let you understand how to make it work. Try it on a windows explorer folder and you'll see it works.(Make sure you drag that icon to the "listview" window and not just the parent window) If you use this program and still not get the listview items, then that listview class your trying to access is different from what i've been trying to access.
Whoooo hoooooooooooo after some messing got it to work!!!! wow I have to say a huge well done to you, I never thought I would see this working (getting listview items)
Heres a few more questions... (do forgive me)
Ok firstly how can I make the dll smaller?
Also, is there a away to get the tooltip text of the listview item as well as the text???
Can you get the listviews item image index ?
Thanksyou so much for all your time and effort and skill!!!!!
I have a question. What exactly are you trying to make?
Nothing really, I have just been looking into this for a year.. just would like to see how much you can actually do/get from a listview
well, if you want to know more about it, then you may want to look into this site:
http://msdn.microsoft.com/library/de...titemcount.asp
and about the dll, I don't know of a way to make it smaller.
Ok, once thing I noticed is if the listview updates/has more/less items.. your code grabs the old items even if u restart ur program
Yes, that's a bug that i've noticed. If you restart your computer, it goes back to normal. Can't really tell why, but as long as you get the idea of getting the item's text.
Nice work Ben!
Here is how you can do it without the dll.
Thanks for that moeur but having problems with the hex part
how are you getting the hWnd of your listview?
If you are using spy++ then the hWnd is in Hex you can just enter that number.
Sorry moeur just used spy++ and it works great, the above bug doesnt happen either (not getting new items), great code and thankyou. Do you know much about the lvmgettooltips? I did a search and only found one post about it (a post I made a while ago), just wondering how to get the items tooltip text and even get the icon it uses maybe.
I tried both the programs posted, they both work for me.. I was wondering if theres anyway to use them on other applications that have things that look like listboxes, but apparently they arent... they dont have the class SystemListView or whatever, and niether code workson them..
The classname of the 'listbox' i want this to work on is "Afx:400000:28:10011:0:0" if that helps
I think 'listbox' is different from 'listview'.
Sorry I meant listview I was probably just using the wrong term.. how can I tell what it is for sure?
thread hijaCK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Afx controls were created before Windows existed. Instead of using a Windows text property, the text is owner-drawn by the control. As far as Windows is concerned, the control has no text--just a picture that happens to look to you like text. I've seen attempts to monitor windows messages to try to detect what characters are being written, but nothing successful. As far as I know, the only way to read the text of an Afx control is using mouse or keyboard events to raise a copy event in the Afx control so that you can get the text from the clipboard or through optical character recognition. :sick:Quote:
Originally Posted by bail3yz
Many thanks for sharing this code. I tried to drag the icon to external listview to obtain the list but i get the follwoing error:Quote:
Originally Posted by benmartin101
http://i5.photobucket.com/albums/y18...7/38f1fdaa.jpg
and it is pointing to
I be happy if u tell me how to fix it.ThanksCode:Screen.MouseIcon = LoadPicture("C:\Program Files\Microsoft Visual Studio\VB98\protune.ico")