There are some windows where I can't get the text insicde with a WM_GETTEXT, so I tried to replace WndProc with a standard one.
I'm trying to replace the WndProc function from a window that has been created by another application. I'm trying to do it in a thread created by a windows hook to keyboard.
What I've tried without any success (3 different cases):
1. Create a "EDIT" window, get the WndProc and replace the WndProc of the app by the new:
(idea from:
http://www.codeguru.com/Cpp/I-N/ieprogram/security/article.php/c4387[
^])
String ^ReadWindowText(HWND g_hTarget)
{
char buff1[MAX_DATASIZE];
int err;
this->ClearBuffer<char>(buff1, MAX_DATASIZE);
HWND hParent = GetParent(g_hTarget);
HINSTANCE hInstance = (HINSTANCE) GetWindowLongPtr(hParent, GWLP_HINSTANCE);
HWND hwndEdit = CreateWindow(_T("EDIT"), NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, hParent, (HMENU) 111, hInstance, NULL);
if (!hwndEdit) err = GetLastError();
LONG_PTR lpNewProc = GetWindowLongPtr(hwndEdit, GWLP_WNDPROC);
LONG_PTR lastProc = SetWindowLongPtr(g_hTarget, GWLP_WNDPROC, (LONG_PTR)lpNewProc);
if (!lastProc) err = GetLastError();
int len = SendMessage(g_hTarget, WM_GETTEXT, MAX_DATASIZE, (LPARAM) buff1);
len = SendMessage(g_hTarget, WM_GETTEXTLENGTH, 0, 0);
buff1[len] = 0;
SetWindowLongPtr(g_hTarget, GWLP_WNDPROC, (LONG_PTR)lastProc);
return gcnew String(buff1);
};
2. Same as before, this time create a HWND_MESSAGE window
(idea from:
http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29#message_only[
^])
String ^ReadWindowText1(HWND g_hTarget)
{
(...)
HWND hwndEdit = CreateWindow(_T("STATIC"), NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, HWND_MESSAGE, (HMENU) 111, hInstance, NULL);
(...)
};
3. Replace WndProc with my own procedure (in the application that creates the window). I'm not really sure if this could even work, but I wanted to be sure...
(idea from:
http://www.gamedev.net/topic/511138-how-to-get-raw-input-data-from-the-win-32-api-thats-not-dependant-on-a-window/[
^])
delegate LRESULT StaticWindowProcDelegate( HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam );
delegate LRESULT WindowProcDelegate( HWND wnd, WNDPROC wnd_proc, UINT msg, WPARAM wParam, LPARAM lParam );
WindowProcDelegate^ sWindowStore;
LONG_PTR lastProc;
String ^ReadWindowText2(HWND g_hTarget)
{
(...)
sWindowStore = gcnew WindowProcDelegate(this, &LectorHD::WindowProc);
lastProc = GetWindowLongPtr( g_hTarget, GWLP_WNDPROC );
if( !lastProc ) err = GetLastError();
StaticWindowProcDelegate^ swpd = gcnew StaticWindowProcDelegate(this, &LectorHD::StaticWindowProc);
if(!SetWindowLongPtr( g_hTarget, GWLP_WNDPROC, (LONG_PTR) Marshal::GetFunctionPointerForDelegate(swpd).ToPointer()) )
err = GetLastError();
(...)
};
LRESULT StaticWindowProc( HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
return sWindowStore( wnd, (WNDPROC) lastProc, msg, wParam, lParam );
};
LRESULT WindowProc( HWND wnd, WNDPROC wnd_proc, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_GETTEXT:
default: return CallWindowProc( wnd_proc, wnd, msg, wParam, lParam );
}
};
Always same problem: lastProc=0 (err=0) with any application (i've tried 3 different programs, one of them is mine so I'm sure I have'nt replaced WndProc).. I can't get the text from the same windows where I could'nt do with WM_GETTEXT.
Maybe (I suspect) it is a problem of what it says in
http://msdn.microsoft.com/en-us/library/ms644898%28v=vs.85%29.aspx[
^]
"The SetWindowLongPtr function fails if the process that owns the window specified by the hWnd parameter is at a higher process privilege in the UIPI hierarchy than the process the calling thread resides in."
But I'm not sure if it is this, because in the first and second case I create the new window in the HWND that owns g_target (I get hInstance from the parent of g_target, so the processes must be the same for the two windows..) And if it is, I don't know how to assign higher provilege to my process.
Any help is really apreciated!