|
-
Mar 6th, 2007, 01:38 AM
#81
Fanatic Member
Re: Subclass External Programs done for you
The demo works, but...
How do I adapt this to only catch messages sent from the form in the external app? I have tried (somewhat wishfully) passing the forms hwnd in instead of using findwindowex to no avail....
-
Mar 30th, 2007, 06:39 AM
#82
Junior Member
Subclass External Programs done for you
Hi..
This is a great code. The DLL works good. But it cant get the web applications. Is it possible to get data in web application using this DLL?
-
Apr 11th, 2007, 07:04 PM
#83
New Member
Re: Subclass External Programs done for you
Hi,
Very great work! Thanks.
 Originally Posted by moeur
Although the title of this thread mentions "subclassing" it deals with hooking and not subclassing.
If you could actually subclass the external app, then you should be able to block the WM_DESTROY messages.
There is a way to truly subclass an external app. What you need to do is execute the code that initiates the subclassing from within the external process. A simple way to do this would be to first set a hook in the external process, then when the hook procedure is called, it will be running in the external process so you can then subclass the window you want to prevent from closing.
I think that might be why i cannot do what I'm trying to do: I installed a hook and can deal with the message when it occurs. Using CopyMemory I can receive data sent along, but I'd like to *modify* those date, so I need to use CopyMemory again with my modified values.
It "looks like" it to work, as in no crash or anything, but the external app actualy behaves as if I didnot send back any new values
Could this be the reason why, and if so could anyone help me with how to "subclass" an external app then (would another DLL be required instead of this one??), or am I missing something here/should it work fine with such hooks ?
Thanks for your help!
-
Apr 12th, 2007, 09:39 AM
#84
Re: Subclass External Programs done for you
-
Apr 12th, 2007, 09:14 PM
#85
New Member
Re: Subclass External Programs done for you
Thanks!
I've done some more reading & testing, but I'm getting more confused than anything else.
Here's what I'm trying to do: add a menuitem to the menu of another app, eg. notepad, but with "complete control" over it.
Adding the menu and getting it just a few API calls, no problem. But I set it ownerdrawn, because I want to actually draw it myself. And my problem is when dealing with the WM_MEASUREITEM, etc messages. I did it on my VB app and it that went well.
So I tried using your great DLL to set up a hook to get the notepad's messages. I did got the message, but as I mentionned in my previous post setting my data on WM_MEASUREITEM seems to be ignored by notepad :S
So I tried a few different ways, like instead of a CopyMemory I used a OpenProcess/VirtualAllocEx/WriteProcessMemory, because I thought that might have been the problem.
Seems not. I got the same results. But it seems that the data are written (according to lpNumOfBytesWritten for WriteProcessMemory), actually both times: even with a single CopyMemory, I think, because if afterwards I do another CopyMemory to get back the data (like the first time, when I got the menuitem's index, etc) the new width/height I set are returned.
I not an expert of all this, but I tried reading different posts/articles/etc but I have no idea what's happening here. To me it looks like the data are written, yet ignored by notepad??
Even more confusing (to me), I did on WM_DRAWITEM draw my menuitem all red, to see if I could actually draw on notepad or not.
And I can, but I'm not drawing where I should be (on menubar) but below it, within the edit area!! The horizontal position is right though, and the vertical space makes me say it looks like the problem is that I'm not draing on notepad's non-client area!! Like I got the "wrong" hDc or something...
Again, I'm not even sure what I just said make sense, but that's all I can see.
Does anyone ever done something like this? Or has an idea of what's the problem/how to fix this?
Thanks.
-
Nov 19th, 2007, 10:15 AM
#86
New Member
Re: Subclass External Programs done for you
How would I use this to hook all requests to shell32.dll's SHBrowseForFolder API so that the BrowseForFolder window displays shortcuts to folders (or even all files)?
-
Jan 8th, 2008, 09:57 PM
#87
Lively Member
Re: Subclass External Programs done for you
Does your DLL support WH_CBT?
-
Mar 6th, 2008, 11:05 PM
#88
New Member
Re: Subclass External Programs done for you
You may be tired of questions about your post “Subclass External Programs done for you” from Jan 2005. I see that your last post to this thread was just days away from being one year ago. This is probably the best example I have ever seen on line, and is probably the closest to answering my quest. I am desperately seeking a way to read a popup menu (class name "#32768). I can get the handle, I can manipulate it (activate, scroll, select) without a problem. The problem is, I am blind to the text in this type of menu and what I am selecting. I have a post “Read from Popup Menu” looking for something like your dll, ocx. Is it capable of reading this type of menu and or which selection is highlighted? I would be extremely grateful for any help! I have been seeking a solution everywhere and it appears you are my best hope in weeks. I consider myself a reasonably good VB coder but subclassing I just can’t seem to get down.
Last edited by SDG101; Mar 6th, 2008 at 11:14 PM.
-
Sep 28th, 2008, 10:35 AM
#89
Re: Subclass External Programs done for you
Hai,,
hook and unhook when mouse move over the windows
i am getting an error (some time).
Runtime Error "5"
Error Setting Dll Filter. 5 (5&h): Access Denied.
Whats wrong ?
part of my code
Code:
'monitor the following message(s)
.AddMessage WM_LBUTTONDOWN, "WM_LBUTTONDOWN"
.AddMessage WM_MOUSEMOVE, "WM_MOUSEMOVE"
Code:
If uMsg = WM_LBUTTONDOWN Or uMsg = WM_MOUSEMOVE Then
uMsg = WM_NULL
End If
Some time when the mouse move form one window to another, this error happens.
but not all the time .
Last edited by Fazi; Oct 1st, 2008 at 02:18 AM.
-
Nov 4th, 2008, 07:01 PM
#90
New Member
Re: Subclass External Programs done for you
Hello,
First of all, thanks for the great dll.
However, I'm trying to make it run on a Windows Mobile device, with the compact framework 3.5...with no success.. I've managed to modify the VB part but with my limited knowledge in C I was unsuccessful in recompiling the dll for the compact framework. I know that the functions SendMessage and SetWindowsHookEx exist in the CF (even if not documented), so it should be possible to make the project run in CF.
Can someone with VC knowledge help me recompile the dll for the Compact Framework 3.5, please.
-
Feb 4th, 2009, 03:14 PM
#91
New Member
Re: Subclass External Programs done for you
How can I hook into a program's file output. Basically I want to intercept what a program is outputing to a file and modify it before it gets there.
Thanks
-
Mar 4th, 2009, 09:01 PM
#92
-
Mar 8th, 2009, 08:20 AM
#93
New Member
Re: Subclass External Programs done for you
I actually have another dll which doesn't have any bugs, as there are some bugs in the dll that u have used. But I don't have the code for that dll. I have tried a thousand time to search the code of that dll in the internet but have failed. And also that dll let me capture all kind of messages from the notepad window
Last edited by Chanakya69; Mar 8th, 2009 at 08:53 AM.
-
Jan 24th, 2010, 04:02 AM
#94
Frenzied Member
Re: Subclass External Programs done for you
Good Day Mr. Moeur,
I am wondering if it is possible to use your dll, or some version of it, to capture the WM_CREATE message and alter the CREATESTRUCT UDT so that the lpCreateParams would contain a pointer to the MDICREATESTRUCT UDT to make an external program an actual child of a VB MDI application.
Option Explicit should not be an Option!
-
Mar 8th, 2010, 04:22 PM
#95
New Member
Re: Subclass External Programs done for you
Hello Moeur,
when you say: To Get the string value pointed to by lParam you can use a function like this: Public Function StrFromPtr(pStr As Long) As String ...
Where can I do the call to this funcion? In the Form or the module...
Thanks
-
Jun 2nd, 2010, 09:51 AM
#96
Re: Subclass External Programs done for you
In the hook Demo 2 posted(post 2) here, I'm getting a crash when mousing down over the notepads scrollbar.
http://www.vbforums.com/showpost.php...48&postcount=2
To reproduce:
Add some carriage returns, so that the scrollbar is visible.
Press L Button down to scroll on the scrollbar.
Am I using it wrong, or should that be filtered?
-
Jul 29th, 2010, 04:59 AM
#97
Addicted Member
Re: Subclass External Programs done for you
What's the childclassname? And why should it be "Edit" when i hook notepad?
I need to know because when i hook another application with a different Parentcaption i get an error saying i must set handle before setting hook.
I think I am, therefore, I am. I think.
-
Aug 7th, 2010, 10:04 AM
#98
Addicted Member
Re: Subclass External Programs done for you
I think I am, therefore, I am. I think.
-
Jun 9th, 2012, 02:11 AM
#99
New Member
Re: Subclass External Programs done for you
I've a new labtop working with windows 7.
The file hookcontrol.ocx seems to be not compatible with version x86 (32bits) or X86(64bits) of regsvr32.exe.
Is it possible to have an updated version of this ocx file or a way to compile myself on my labtop.
Thanks in advance
-
Jun 10th, 2012, 06:25 PM
#100
Re: Subclass External Programs done for you
Try pressing the Windows key+R, then copy and paste:
Code:
c:\windows\syswow64\regsvr32.exe hookcontrol.ocx
If this doesn't work, what error message are you getting?
-
Aug 31st, 2012, 10:48 PM
#101
Fanatic Member
Re: Subclass External Programs done for you
@moeur
i need to fill fields of an embedded webbrowser in another app from my app, how can i acheive this with your dll?
thanks
-
Oct 11th, 2012, 06:11 AM
#102
New Member
Re: Subclass External Programs done for you
Hi moeur, excellent work.
I tried the .NET version you posted, in VB and C#, but in both cases the events don't fire from the hook. All appears to set up ok, window handle obtained, messages added, etc. An instance of EditHook (clsHook) exists and is visible in watch window. Any ideas if I have missed something? Thanks.
-
Oct 12th, 2012, 10:14 AM
#103
New Member
Re: Subclass External Programs done for you
ADDENDUM it works on a Win32-only machine, but not on a Win64 machine when targeted to x86. IDEAS?
I tried the .NET version you posted, in VB and C#, but in both cases the events don't fire from the hook. All appears to set up ok, window handle obtained, messages added, etc. An instance of EditHook (clsHook) exists and is visible in watch window. Any ideas if I have missed something? Thanks.[/QUOTE]
-
Oct 12th, 2012, 05:37 PM
#104
Re: Subclass External Programs done for you
 Originally Posted by K-C-S
Hi moeur, excellent work.
I tried the .NET version you posted, in VB and C#, but in both cases the events don't fire from the hook. All appears to set up ok, window handle obtained, messages added, etc. An instance of EditHook (clsHook) exists and is visible in watch window. Any ideas if I have missed something? Thanks.
Try using the "Run As Administrator" option when running the program. You might need to do that on both the test program and the actual hook program to get it to work correctly.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Oct 15th, 2012, 02:15 AM
#105
New Member
Re: Subclass External Programs done for you
 Originally Posted by Nightwalker83
Try using the "Run As Administrator" option when running the program. You might need to do that on both the test program and the actual hook program to get it to work correctly.
No, I was running in VS2010 in admin mode anyway. It DOES work on a Win32 machine, but not a Win64 machine (targeted to either x86 or 64bit). I think I read somewhere the unmanaged DLL has to be changed with regard to DWORDs. Shame, I guess I will have to keep looking....
-
Oct 28th, 2018, 10:45 PM
#106
Fanatic Member
Re: Subclass External Programs done for you
 Originally Posted by moeur
The above code is perhaps a little daunting so here is a simplified version for illustrative purposes.
We'll create a project that hooks posted messages and allows the VB user to change those messages before they are passed on to the original process.
First create the C++ dll. It will have three routines accessible to VB, so create your .def file
Code:
//HookDemo.def
LIBRARY MainHook
EXPORTS
InstallFilterDLL @1
UnInstallFilterDLL @2
SetSharedData @5
In your source file, do some basic steup
Code:
//HookDemo.cpp
#include <windows.h>
#include "WINUSER.H"
/*---------------------------------------------
Shared Variables
This data is shared between both prcesses. The
VB App has access to these variables through the
function SetSharedData
---------------------------------------------*/
#pragma data_seg(".shared")
bool ChangeMessage = false;
int Shared_uMsg = 0;
int Shared_wParam = 0;
int Shared_lParam = 0;
HWND hWndVB = 0; //handle to subclassed VB Window
HWND hWndCtrl = 0;//handle to the window we want to monitor
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
//---------------------------------------------
// Global Variables, specific to each process
//---------------------------------------------
HHOOK hmsgHooks = 0; // Hook handle for WH_GETMESSAGE
HINSTANCE hInstance; // Global instance handle for DLL
//--------------------------------------------
// DLL entry-point
//--------------------------------------------
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
hInstance = hinstDLL;//save dll handle for each process
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
OK, Now let's create those three routines
First a routine for setting the hook
Code:
/* set WH_GETMESSAGE hook
Private Declare Function InstallFilterDLL Lib "C:\bin\HookDemo.dll" ( _
ByVal dwThreadID As Long, _
ByVal ExtrnHandle As Long, _
ByVal VBHandle As Long _
) As Long
*/
__declspec(dllexport) int _stdcall InstallFilterDLL(DWORD dwThreadId, HWND ExtrnHandle, HWND VBhandle)
{
if (hmsgHooks==0)
hWndVB = VBhandle;\\save handle to subclassed VB Window
hWndCtrl = ExtrnHandle;//Handle to external window
hmsgHooks = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC) GetMsgProc, (HINSTANCE) hInstance, dwThreadId);
if (hmsgHooks==0) return GetLastError();
return 0;
}
Next a routine for removing the hook
Code:
/* Remove the WH_GETMESSAGE hook
Private Declare Function UnInstallFilterDLL Lib "C:\bin\HookDemo.dll" () As Long
*/
__declspec(dllexport) int UnInstallFilterDLL(void)
{
LRESULT result;
if (hmsgHooks != 0){
result = UnhookWindowsHookEx(hmsgHooks);
if (result == 0) return GetLastError();
hmsgHooks = 0;
}
return 0;
}
And a routine so that VB can change the message data
Code:
/* SetSharedData Allows the VB App to alter the shared data
Private Declare Sub SetSharedData Lib "C:\bin\HookDemo.dll" ( _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long _
)
*/
__declspec(dllexport) void _stdcall SetSharedData(int uMsg, WPARAM wParam, LPARAM lParam)
{
Shared_uMsg = uMsg;
Shared_wParam = wParam;
Shared_lParam = lParam;
ChangeMessage = true;
}
Finally we have to create a routine to forward the messages to the VB App
Code:
/*---------------------------------------------------------------------------
Filter function for the WH_GETMESSAGE
The GetMsgProc hook procedure can examine or modify the message. After the hook
procedure returns control to the system, the GetMessage or PeekMessage function
returns the message, along with any modifications, to the application that
originally called it.
Allows changing the message, but not removal (use WM_NULL instead)
---------------------------------------------------------------------------*/
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MSG *lpMsg;
//return immediately for negative nCodes
if (nCode >= 0){
if (nCode==HC_ACTION){
lpMsg = (MSG *) lParam;
//see if this is the window we are monitoring
if (lpMsg->hwnd == hWndCtrl){
//forward the message to VB App
ChangeMessage=false;
SendMessage(hWndVB, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
if (ChangeMessage==true){//Did VB App make changes to the data?
lpMsg->message = Shared_uMsg;
lpMsg->wParam = Shared_wParam;
lpMsg->lParam = Shared_lParam;
}//end if change message
}//end if correct hWnd
}//end if nCode==Action
}//end if nCode >=0
return(CallNextHookEx(hmsgHooks, nCode, wParam, lParam));
}
This is all you need, now here is how to use it from Visual Basic
You need to subclass something in order to retrieve the messages sent back from the dll.
In this example I have chosen to subclass a checkbox.
I've omitted the sublcassing code since this is explained in detail at various spots in this forum.
First, declare some API functions and our functions
VB Code:
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String _
) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" ( _
ByVal hwnd As Long, _
lpdwProcessId As Long _
) 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 Const GWLP_WNDPROC = (-4)
Private Const WM_CHAR = &H102
'Make sure to change dll path to yours
Private Declare Sub SetSharedData Lib "C:\bin\HookDemo.dll" ( _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long _
)
Private Declare Function InstallFilterDLL Lib "C:\bin\HookDemo.dll" ( _
ByVal dwThreadID As Long, _
ByVal ExtrnHandle As Long, _
ByVal VBHandle As Long _
) As Long
Private Declare Function UnInstallFilterDLL Lib "C:\bin\HookDemo.dll" () As Long
This following routine sets the hook
VB Code:
Private Sub cmdSetHook_Click()
Dim hWndParent As Long
Dim hWndChild As Long
Dim ThreadID As Long
Dim ParentCaption As String
Dim ChildClass As String
Dim ChildCaption As String
ParentCaption = "Untitled - Notepad"
ChildClass = "Edit"
ChildCaption = ""
'subclass the checkbox
Set CSubClsApp = New CSubclass
CSubClsApp.hwnd = Check1.hwnd
CSubClsApp.EnableSubclass
'get handle to parent window
hWndParent = FindWindow(vbNullString, ParentCaption)
While hWndParent = 0
If MsgBox("Open Notepad", vbOKCancel) = vbCancel Then Exit Sub
hWndParent = FindWindow(vbNullString, ParentCaption)
Wend
'get handle to child window
hWndChild = FindWindowEx(hWndParent, 0, ChildClass, ChildCaption)
'get ThreadID
ThreadID = GetWindowThreadProcessId(hWndChild, 0)
'set the hook
If InstallFilterDLL(ThreadID, hWndChild, Check1.hwnd) Then
MsgBox "Cannot Install Hook"
CSubClsApp.DisableSubclass
End If
End Sub
Of Course we don't want our program to crash
VB Code:
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
UnInstallFilterDLL
CSubClsApp.DisableSubclass
End Sub
Finally, we need to write code to handle the hook messages
VB Code:
Public Function NewWndProc( _
ByVal hwnd As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long _
) As Long
'Do your message handling here
'If you want to change the data, do it like this
If uMsg = WM_CHAR Then
'change all keyboard input to 'X'
wParam = Asc("X")
'if you want to discard message, change uMsg to WM_NULL
SetSharedData uMsg, wParam, lParam
End If
'Pass message to the default window procedure
NewWndProc = CallWindowProc(CSubClsApp.OrigWndProc, hwnd, uMsg, wParam, lParam)
End Function
And that's it. This code will hook Notepad and change all keyboard input to 'X's
Next you might want to add a hook to trap sent messages.
This way you can respond to WM_DESTROY messages telling you the external app is shutting down.
Attached is the full code for the above demo.
Note: missing files added to attached file 2/16/05
used demo code can not change a to x?
-
Oct 29th, 2018, 03:49 AM
#107
Re: Subclass External Programs done for you
You reply to a code sample which was posted almost 14 years ago!!
And you don't give any information what you are doing or how you are doing it.
-
May 18th, 2023, 05:02 AM
#108
Re: Subclass External Programs done for you
If all can use VB6 to write code is good, VB6 can also write standard DLL
-
May 18th, 2023, 05:08 AM
#109
Re: Subclass External Programs done for you
 Originally Posted by xiaoyao
If all can use VB6 to write code is good, VB6 can also write standard DLL
https://www.vbforums.com/showthread....=1#post5024345
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
|