|
-
August 11th, 2005, 11:31 AM
#1
ShellExecuteEx process to HWND handle
Hi everyone. This is the problem. I execute an applicaton with ShellExecuteEx. In the structure SHELLEXECUTEINFO I receive HINSTANCE of the app and HANDLE of the process.
I need HWND of the created window.
I can't use statement "EnumWindow" 'cause the caption text of the created window change every time.
Using spy++ I can't get (I think) useful information: #32770 (Dialog) is the same for other dialogs too, so I can't use it.
Can someone help me?
-
August 11th, 2005, 11:42 AM
#2
Re: ShellExecuteEx process to HWND handle
you can try doing something like this:
Code:
HWND h = ::GetTopWindow(0 );
while ( h )
{
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
if ( hProc == /*your process handle*/ )
{
// here h is the handle to the window
break;
}
h = ::GetNextWindow( h , GW_HWNDNEXT);
}
hope it will help
Cheers
-
August 12th, 2005, 12:00 AM
#3
Re: ShellExecuteEx process to HWND handle
 Originally Posted by golanshahar
you can try doing something like this:
Code:
HWND h = ::GetTopWindow(0 );
while ( h )
{
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
if ( hProc == /*your process handle*/ )
{
// here h is the handle to the window
break;
}
h = ::GetNextWindow( h , GW_HWNDNEXT);
}
hope it will help
Cheers
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
????
no no no.
Code:
if (pid == /*your process id*/)
Best Api Monitor tool.
Trace the target program automatically and monitor the parameters of all API and COM interfaces.
Auto Debug for Windows 4.0
Auto Debug for .Net
http://www.autodebug.com/
-
August 12th, 2005, 01:58 AM
#4
Re: ShellExecuteEx process to HWND handle
Thanks guys, but this is the situation:
golanshahar: your solution does not seem to go
pengch: I can't use your solution 'cause I have not the pid (DWORD) of created process but only an handle (HANDLE ).
If you know another way please tell me. I have to run an external function with RUNDLL32.EXE. Do you know another way to catch the HWND of the created window?
Thanks
-
August 12th, 2005, 01:59 AM
#5
Re: ShellExecuteEx process to HWND handle
 Originally Posted by pengch
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
????
no no no.
Code:
if (pid == /*your process id*/)
you probably didnt understand what i am trying to do here 
first of all if you have seen the question you would have seen that he needs to get the HWND out of HANDLE to the process.
so my code above runs on all top windows and on each one getting out the PID and via ::OpenProcess ( ) getting the handle to the process if the Current HANDLE == to the HANDLE he got from Shellexecute hence the HWND was found.
what you suggested is also work and vaild code
Code:
if (pid == /*your process id*/)
however he doesnt have PID only handle to the process 
Cheers
-
August 12th, 2005, 02:11 AM
#6
Re: ShellExecuteEx process to HWND handle
 Originally Posted by keysman
Thanks guys, but this is the situation:
golanshahar: your solution does not seem to go
pengch: I can't use your solution 'cause I have not the pid (DWORD) of created process but only an handle (HANDLE ).
If you know another way please tell me. I have to run an external function with RUNDLL32.EXE. Do you know another way to catch the HWND of the created window?
Thanks
can you tell me please what exactly not working? can you post your project here so i can take a look?
there is another way btw to ::EnumProcesses(..)
and for each Handle to the process you can use the ::GetGUIThreadInfo(..) and in the GUITHREADINFO you will have the hwnd you looking for.
Cheers
-
August 12th, 2005, 05:50 AM
#7
Re: ShellExecuteEx process to HWND handle
Ok. I can't use EnumProcess 'cause I still working with win9x.
I run Dialup dialog using "rundll32.exe rnaDial,.....".
I have to get HWND of the Dialup dialog.
This is the problem. Can you help me?
-
August 12th, 2005, 05:58 AM
#8
Re: ShellExecuteEx process to HWND handle
I would suggest the following.
1) Open the dialup dialog
2) Use this neat Spy++ tool which comes with VC++ to find out class name and window caption
3) Put a FindWindow() call in your program with class name and window caption as parameter
Please don't forget to rate users who helped you!
-
August 12th, 2005, 06:20 AM
#9
Re: ShellExecuteEx process to HWND handle
under 98 you can use the ::CreateToolhelp32Snapshot(..)
anyway here is a code of mine that using it under 98/me, i added there an if that you should add.
Code:
HINSTANCE h = ::GetModuleHandle ( "Kernel32.dll" );
if ( h == NULL )
h = ::LoadLibrary("Kernel32.dll");
if (h == NULL )
return;
typedef HANDLE (WINAPI *tCreateToolhelp32Snapshot) ( DWORD,DWORD );
typedef BOOL (WINAPI *tProcess32First) ( HANDLE,LPPROCESSENTRY32 );
typedef BOOL (WINAPI *tProcess32Next) ( HANDLE,LPPROCESSENTRY32 );
tCreateToolhelp32Snapshot pCreateToolhelp32Snapshot = (tCreateToolhelp32Snapshot)::GetProcAddress(h,"CreateToolhelp32Snapshot");
tProcess32First pProcess32First = (tProcess32First)::GetProcAddress(h,"Process32First");
tProcess32Next pProcess32Next = (tProcess32Next)::GetProcAddress(h,"Process32Next");
if ( pProcess32Next && pProcess32First && pCreateToolhelp32Snapshot )
{
HANDLE hSnap = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,dwID);
PROCESSENTRY32 PE;
PE.dwSize = sizeof(PROCESSENTRY32);
pProcess32First(hSnap,&PE);
do
{
HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, 0, PE.th32ProcessID);
if (hProc == /*your process handle*/)
{
GUITHREADINFO Gti;
::ZeroMemory ( &Gti,sizeof(GUITHREADINFO));
Gti.cbSize = sizeof( GUITHREADINFO );
::GetGUIThreadInfo(PE.th32ProcessID,&Gti);
// in Gti you will find the handle Gti.hwndActive
break;
}
}
while(pProcess32Next(hSnap,&PE));
::CloseHandle (hSnap);
}
NOTE: i didnt compile it but it should work! 
hope it helps
/EDIT in the sample code above i used dynamic loading cause on win2000 i used EnumProcess(..) so instead using #ifdef i checked via GetVersionEx(..) what type of OS i am running and accroding to that i knew what functions to use, you on the other hand if you use only win98 you can avoid the dynamic loading if you want and call directly the functions.
Cheers
Last edited by golanshahar; August 12th, 2005 at 06:33 AM.
-
August 12th, 2005, 07:40 AM
#10
Re: ShellExecuteEx process to HWND handle
Sorry golanshahar but this does not seem to go too or I mistake something.
With ShelleExecuteEx(&ShExecInfo) i run "rundll32.exe rnaui.dll,RnaDial myconn". And all is right.
ShExecInfo receive (ShExecInfo.hProcess) Handle to the newly started application. This is the one I pass to your code(I use it like my process handle). However this is never find. While debugging I see all process handle and there is noone as same as ShExecInfo.hProcess.
What's up?????
I'm losing every hopes.
-
August 12th, 2005, 09:41 AM
#11
Re: ShellExecuteEx process to HWND handle
dont lose hope dude, it will be solved !!
i dont know why its not working...
BUT we can try other way around like philkr offered before. when the Dialog of dial-up is open make sure its Caption is not changing and if so simply use the ::FindWindow(..) api and it will return you the Handle to the window.
now this must work...if the caption is changing then we will find away maybe via class name to find it.
let me know the outcome...
Cheers
-
August 13th, 2005, 02:54 AM
#12
Re: ShellExecuteEx process to HWND handle
@keysman: I'm curious why my solution (FindWindow) does not work. Can you tell me, please?
Please don't forget to rate users who helped you!
-
August 14th, 2005, 11:49 AM
#13
Re: ShellExecuteEx process to HWND handle
Ok Philkr, sorry If I don't answer fast but I've hard work in this days.
In WinXP/2K there are no troubles, because with EnumWidows I can get the caption of each window, where inside there is the dialup connection name, so I can use StrStr to check if the dialog is that I was running.
In Win9x/Me the question is a bit different. In this kind of OS the dialup connection dialog don't merge the connection name (unlike winXP/2K).
Using Spy++, if you open two or more dialup dialog, you get the same Class value: so FindWindow could get the wrong hwnd. This is bad for me 'cause I have to get exactly the dialup connection dialog I was started.
My problem is get exactly the HWND of dialup dialog that I was started, cause I have to send a message (SendMessage) to this dialog.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|