|
Thanks for detailed reply Antti. It worked!! I had to implement the whole thing in WIN32 API since the SendMessage took only 3 parameters in MFC and not the window pointer. Also I used WM_LBUTTONDOWN followed by WM_LBUTTONUP to simulate a mouse click.
Regards,
Zahid
|
|
|
|
|
Sir i want to creat a Vc++ system wide hook dll.{{Whatever hook articles available on the internet are intended for advanced developers who know thing or 2 in vc++.}}But students like me who are new to vc++ find it difficult to grasp some ideas.
I want a basic level explanation from some experts who really wants to teach those things to their students.
The hooks i am intended to create is Wh_Getmessage and i have to call that dll from vb6
Say my objective of this hook is say if i a user type A then i have to change to B for any application running.
I am a stranger to vc++ so i need help in how to create this {{system wide}} wh_getmessge hook
1.In vc++ in new what dll i have to chose ]
a.MFC appwizard Dll
b.WIn32 Dynamic link library
What is the difference between these 2 dlls.?
2.What is an header file and what are the things we have to declare here and why we have to declare??
3.How functions in vc++ dll should be declared inorder to call those functions from vb.?
4.Say i am calling SetHook funciton from vb which is in dll then hook is set.
MsgFilterHook = SetWindowsHookEx( WH_GETMESSAGE,(HOOKPROC)MsgFilterFunc, dll_hInstance, threadID );
I am having the hookhandle in MsgFilterHook which i can use to unhook this hook.
Threadid = 0 to create a system wide hook
MsgFilterFunc is my callback function
My doubt is once hook is set , will the system automatically call my callback filter function for any application which process getmessage
Say i have notepad and i am typing A and in my call back function i will get a wm_char = A.NOw if i change to another application say wordpad and type B
then will it be possible to get the wm_char=B message in my callback function.Please Explain me how does this work.
5.Say n no of editor applications are running and i want to disable the character T from going to any application and i have to make T into H how to do this in my callbackfunciton.Issue in this question is how am going to get these hook work for any application which is running.??
Issues
1.How to start creating a dll in vc++6
2.Header file decleration ideas.
3.Export functions declerations.
4.Explanations of how these hook work on a systemwide basis(i understood how dll maps the memory of other applications but wanted codings point of view like what are the parameters come to callback function each time a new application is actvated.)
5.What is #pragma and shared data segment ?How variables should be decalred in the hook dll and how it should be accessed??Please explain at a lower level how this things are implemented why is the need?
Thanks in advance.
|
|
|
|
|
First, I recommend pointing your browser to MSDN and the Win32 Hooks article[^] underneath it. Read it through carefully, because it will answer most of your questions.
If you don't understand the concepts presented in this article, then you should learn more of the functionality of Windows before attempting to create hooks. Codeproject has a collection of fine articles on the issue of hooking. These should help you get started.
Now, about using the hook. Basically, you can create the DLL on any language you please. If it is implemented correctly, you can load the DLL in VB and use a VB program to register the system wide hook. Remember here, that the actual DLL is a container, with which the hook procedure is injected to a foreign process' address space. The loader application is responsible for actually registering the hook.
As for the questions you presented, here is a set of answers.
1. For creating the container DLL, take Win32 Dynamic Link Library project.
2. The creation of a DLL is explained throughoutly in many articles here in CodeProject. Just browse, and look for articles with the level 'Beginner' marked next to them.
3. In order to call a function of a DLL from the loading application, you need to EXPORT it. See the DLL articles for examples. In short, use __declspec(dllexport) calling convention and a module definition file's EXPORTS section.
4. When you register a global hook, your DLL gets cramped into every running process' address space, and the hook is installed to the message pump of every thread on that process. So, yes, all WM_GETMESSAGE call returns will be routed through your hook procedure.
The way it works is that the hook will be the first to receive the created event message. You then process this message, and alter it the way you please, for example in a WM_CHAR message, you would change the virtual key code. Then you post the message forward in the chain list, and it will eventually end up to the thread it was meant for, this time in an altered form.
5. Like above, catch the WM_GETMESSAGE return value, see if it is a WM_CHAR message, and if it is, alter the virtual key code. If you register the hook correctly, the system will worry about it getting properly called.
For the issue questions
1. Select the appropiate project, and implement the DLL code, following any of the many articles available. There are even beginner articles available in CodeProject. If you cannot understand the concepts of these, you should go pick up a book and learn more about Win32 applications first.
2. The header file is not necessary. A DLL MUST have a DllMain-function (entry point) and one or more exported functions or shared data segments. Otherwise it is just extra baggage with nothing useful.
3. To declare an exported function, use __declspec(dllexport) calling convention or a module definition file. See MSDN, search with the __declspec keyword.
4. The hook's working is explained in the MSDN article I posted a link to above. Refer to it for more details.
5. #pragma is a preprocessor definition which can be used to issue commands to the MSVC compiler. In a standard hook DLL, you don't need shared data sections, thus, you don't need #pragma.
When answering, please take some time to formulate and type-check your posts. It is much more convinient to read and answer your questions when they are easy to understand and the points you're after are presented clearly. Use chapters, line changes, spaces, punctuation marks, everything you need to make it easier to read
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thank you very much sir for your Excellent explanations.
I have catagorised my doubts below .Could you help me on that.
Dll Main:
dll_hInstance
HINSTANCE dll_hInstance;
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpVoid )
{
dll_hInstance = hInstance;
return TRUE;
}
SetWindowsHookEx( WH_GETMESSAGE, (HOOKPROC)MsgFilterFunc, dll_hInstance, threadID );
}
In this example i am getting hinstance of the dll from DllMain.
1.Is Dll main function to be called from my application or this function is executed automatically.?
2.if it is to be called from my application then what are the parameters i have to send?
3.What is the significance of this hinstance to be passed to SetWindowsHookEx function as one of the parameter.
in a system wide hook?
4.I have declared this dll_hInstance as global variable and whenever an application get mapped with this dll , is function Dllmain triggers? and do dll_hInstance get initialised?
Comment: in some article they have given ,declaring dllmain is optional and some they have just declared and so i dont get the idea
behind what is the purpose of this dll main and when doing a global hook what is the significance of dll hinstance.?In some article They have given like
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
hinstance = (HINSTANCE)hModule;
hook = NULL;
return TRUE;
}
I couldnt track from the application how this function is called.So i need your help in this topic
___________________________________________________________________________________________________________________________________
HeaderFile For Dll:
Here is an example header file for a DLL:
#ifndef __DLL_H_
#define __DLL_H_
#ifdef MAKE_A_DLL
#define LINKDLL __declspec( dllexport)
#else
#define LINKDLL __declspec( dllimport)
#endif
LINKDLL LRESULT CALLBACK MsgFilterFunc (int nCode, WPARAM wParam, LPARAM lParam );
LINKDLL void SetHook( HWND hWnd, HHOOK &MsgFilterHook );
LINKDLL void RemoveHook( HHOOK &MsgFilterHook );
#endif
In this example:
#define LINKDLL __declspec( dllexport) is given .
1.Is defining like this enable us to use or call these functions from our application.? Could you explain what is the meaning of defining like this?
2.Sir you have suggested that an header file is not necessary then could you give me some ideas how i can declare those functions using declspec( dllexport) and what file i have to add like header file or def file or in dll iteself or ......?
Inclusion of HeaderFiles in Dll:
#include <windows.h>
#include <windowsx.h>
#include "stdafx.h"
1.While creating a dll and in my case it is wh_getmessage hook dll what are the header files i have to include and what is the purpose of including #include "stdafx.h"
2.Is all the header files added in dll should be declared in my application also if i am building my application in vb?
Processing in Filter Funcion:
LRESULT CALLBACK MsgFilterFunc (int nCode, WPARAM wParam, LPARAM lParam )
{
MSG* Msg = (MSG*)lParam;
switch( Msg->message )
{
case WM_COMMAND:
break;
case WM_KEYDOWN:
break;
case wm_Char
--------------------------Processing------------------------------------
}
return( (int)CallNextHookEx(NULL, nCode, wParam, lParam ) );
}
The nCode parameter is a hook code that the hook procedure uses to determine the action to perform
if (nCode < 0) // do not process message return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode, wParam, lParam);
1.What are the situations where we have to call CallNextHookEx and what actually happens in calling CallNextHookEx?
2.Say we process the wm_char message and still we have to send the control to CallNextHookEx , after processing this command?
Thanks in advance
|
|
|
|
|
I'll answer your questions likewise.
DllMain
-------
1.DllMain is the entry point function of the DLL application. When you use LoadLibrary or AfxLoadLibrary to load the DLL into a process, this entry point is used to start the execution of the DLL. It is much like a 'main' function for a normal C++ application.
2. No parameters necessary, it is called automatically and Windows will provide the parameters.
3. The instance you pass to SetWindowsHookEx tells the function the name of the module where the hook filter function resides. You get this instance handle from a call to LoadLibrary or AfxLoadLibrary, as it's return value.
4. You've got it somewhat incorrect: you do not need to save the instance handle of the DLL in DllMain. Once more: when you want to create a global hook, you create two applications. The first app is a DLL, which exports the hook filter function. The second is a loader application which loads the DLL, obtains a pointer to the filter function and calls SetWindowsHookEx with these parameters.
You can use your custom implementation of DllMain to keep a reference or loading count, for example. Like, for the first time your DLL is loaded (by the loader app), you save the handle of the loader application. Then, your loader app registers a global hook, and the DLL keeps score to how many processes it is attached to (including the loader app). When this score reaches zero, the DLL can, for example, signal the loader application that it can unregister the hook and unload the application.
But it's good policy to implement it, even if you didn't do anything else there than just return TRUE.
Headerfile for DLL
------------------
1. In order for a function to be available for external applications, it must be exported from the application. This is more common with DLLs than with EXEs, although possible in both. You can define a function exportable by adding the __declspec(dllexport) into it's calling convention. For example, the following would cause the function 'ExportedFunc' to become available to loading applications
__declspec void ExportedFunc(void);
Using this, however, requires that you add the function name and a free ordinal to the module definition file, like
EXPORTS
ExportedFunc @1
The ordinal number can be any integer from 1 to X, where X is the amount of functions you wish to export.
In the calling application, you would require to declare a pointer-to-function type, then use GetProcAddress to get the address of the exported function. For example, the following typedef would create a new type, which is "a pointer to a function returning void and taking no parameters"
typedef void (*TypeName)(void);
Creating a variable of this type would then be
TypeName MyFunc = (TypeName) GetProcAddress(...);
2. See above. In order to succesfully and safely export functions from a DLL, use both the __declspec calling convention and a module definition file entry. When you create a new Win32 DLL project using the App Wizard, a module definition file is created for you. Just add the function name precisely as it's name is defined in the .cpp file into the EXPORTS section.
3. The stdafx.h file is created by the App Wizard. In order to build Windows applications, certain common headers (like >windows.h<) are required. The stdafx.h and stdafx.cpp are just dummy files to include common header files.
4. No. If you use __declspec and the EXPORTS section entry, you do not need to include the header files to any applications beside the actual DLL.
Processing in filter function
-----------------------------
1. You should always call the CallNextHookEx. This function is used to pass the message forwards in the hook chain. If you wish to intercept a message, that is, you do not want the message to reach it's intended target, then you don't need to call the next hook. HOWEVER, if you install a system-wide hook, you MUST CALL the next hook, otherwise your computer will hang, as no messages are getting through. In that case, Windows will appear frozen, and the only way to remedy that is a reboot.
If the nCode value is smaller than zero, then you must call the next hook instantly, without doing any processing for the message.
Calling the next hook causes the next hook in the hook chain to get a chance to process the message. If there's only one hook (your global hook) beside the standard message handler of an application, this would mean that you pass the message to this handler, and the application which you hooked behaves like it is meant to behave.
2. Hook procedures are mainly used for modifying a message's contents. You can always skip calling the next hook, but like said, this might result in system-wide crash or errorneous functionality. Windows OS is designed to be event-driven: when you click a mouse button on a window, a message is sent to that window. If you use a message hook to intercept and dispose of the message before it reaches it's target, the window (and it's application) are never notified of the mouse click, and respectfully, do nothing as a result.
Think of this like trying to move your mouse, but the cursor wouldn't budge. Someone might've hooked and is silently disposing of all your WM_MOUSEMOVE messages to the desktop window. So, the desktop will never be notified that you have moved the mouse, no matter how much you'd wiggle it. From a user point of view, this is the most frustrating behaviour Windows can offer, so be very careful when creating your hooks...
I wrote a small workspace containing two projects, a DLL and a Loader. The DLL contains a system-wide WH_GETMESSAGE hook, and the loader is used to load it. The DLL is made with the Win32 DLL wizard, and the loader is a standard dialog-based MFC application. You can download the zip-file from here[^]
Read the comments carefully in the code, perhaps they help you out. Feel free to use the application as a base to build your own solution upon. It is made with Visual Studio .NET 2003, so if you don't have it, just use Notepad or something to explore the files
You can test the app by running the MFC application found from Hookinh/HookLoader/Debug directory.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Hello Thank you very much sir for the dll.
Now i have created the system wide hook dll using your dll as base.
So no problem in that and it work beautifully well.
The problem now i have is i have tried so many methods to find which character is pressed in wmChar
but i dont find any way to get that char for checking it
if ( msg->message == WM_CHAR )
{
It dont work for both funcitons
//if ( WM_CHAR=='A' )
//{ MessageBox(NULL,"A","TEST",MB_OK); }
UINT nchar = lParam;
if ( nchar=='A' )
{ MessageBox(NULL,"A","TEST",MB_OK); }
}
Sir Could you help
|
|
|
|
|
Ok, this problem is easy to solve. I suggest that you read the entire explanation with careful thought. By reading your reply, I must say that you have not completely understood how a filter function works. This explanation should help you out.
Go through the filter function again which resides in file 'HookDLL.cpp'. You can see that in this function, we get a pointer to the message structure in the lParam variable. This means, that the message - which was generated by some event X and is currently travelling towards the destined application - it's address is saved to the lParam variable. So, our first task is to acquire this pointer by doing a variable-to-pointer conversion. This is accomplished with
MSG* msg = (MSG*) lParam;
Ok, now our local variable msg is a pointer to a message structure. This structure is actually the message, which is passing towards the destined application. The message structure contains members which define the contents of the message. You can find the definition of this structure from MSDN here[^].
Like it says there, the member message of this structure contains the message identifier. Good, so, the next thing we do is that we check if this message is of type WM_CHAR . This is done here:
if ( msg->message == WM_CHAR )
{
...
}
As you can see, we use the msg pointer to access the message member of the MSG structure. Now, looking at the WM_CHAR definition in MSDN here[^], you can see that when a WM_CHAR message is posted, the wParam member specifies the character code (virtual key code) of the given key. For the virtual key codes list, see MSDN reference table here[^].
To access this member, we would need to use our pointer again. So let's do it:
UINT virtKeyCode = (UINT) msg->wParam;<DIV>
if ( virtKeyCode & VK_A )
{
}
if ( virtKeyCode & VK_B )
{
}
.. etc..
So, the problem you had back there, in your code, is that you look for the key code in the wrong place. Considering the filter function again, the key code DOES NOT reside in the local lParam variable found from the parameter list of the filter function. It resides in the wParam variable of the MSG structure, which's address is stored in the local lParam variable.
Once more:
1. The lParam variable in the parameter list of the filter function will contain the address of the MSG structure of the intercepted message
2. To access the message's contents, convert this variable to a MSG-pointer, and access the appropriate member of the structure as necessary.
In addition, remember that the key codes posted with WM_CHAR are VIRTUAL KEY CODES. For example, the 'A' key would be 'VK_A'. 'B' key would be 'VK_B'. See the above MSDN link for all these key codes listed in one table.
Hope this helps you out,
Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Sorry Sir I have done a small mistake and i corrected it after that
TCHAR testch = static_cast<tchar>( msg->wParam );
switch (testch)
{
case 'a':
I did this way and it worked and sorry for giving you trouble in way of wrongly implemented codings.
Any way it may be helpful for some young programmers like me in future to figure out they may go wrong here.
You have been one of the influencing person for me for i never seen anybody has so helping like you and i really appreciate your help for young students like me.
I really looking forward to your help further in my project and i try to do the project my self, the most but i will seek your help if i am in trouble.
I put this above comment in this forum to let other students like me to know who are the right persons to ask doubt for and who can provide you the right codings and idea for you.
Thank you very much sir,
vimal
|
|
|
|
|
Hello Sir
I need your help in these areas
1.I have created a dll and mapped into other applications and it changes the character what i want to send.
Now the problem i have is, i have to have a variable which is global to all the application.
Say for example i have a variable in dll
callled MYAPP
in my callback function i am checking
if (MYAPP=0)
{
Then do this process A
}
else(MYAPP=1)
{
Then do this process B
}
I have plan to change this variable MYAPP from my application as either
MYAPP= 0 for certain conditions
MYAPP=1 for certain conditions
Sir could you provide my some solutions how to declare this variable in dll and how i can use this varaible in my application to access that variable
I also need how to declare this varaible in header files also.
thanks in advance
|
|
|
|
|
Hello sir
in using wh_getmessage hook i have these problems
I need to type cast msg->wParam =VK_BACK
and post new characters using POSTMESSAGE api
problem i am having is if use postmessage then posted message 's character also coming again to my filter function
with the character code which i have send
ie say i type a then i type b , now i change b-> backspace and
postmessage(c ,b)
since i have changed b to backspace ,, the character which i posted ie c and b are also coming to filter function
since i dont change c to some other character no problem but since i have changed b to backspace the postmessage(b) also changes to backspace
how to prevent posted message not coming back to my filter function
i tried with a boolean but it dont work properly
so could you give me some idea sir how to implement this one
thanks in advance
with regards
vimal
|
|
|
|
|
Can any one please tell me how to create a Tree view for displaying directory structure in vc++.i want to create the tree view like a "windows explorer" program.
|
|
|
|
|
http://www.codeproject.com/useritems/drivebrowsingtree.asp
The World is getting smaller and so are the people.
|
|
|
|
|
Hi..
In c++ how can i create a new object of a class depending on the contents of the string. Suppose a function is there which takes input argument as a string which is nothing but a class name and that function will return me a new object of that class. something like...
char strClassName[] = "CTest";
CTest* pTest = new ??
now what will be replaced with ?? and i want to use that strClassName string.
class CTest is an example i can replace that with any class name. Whatever the class name appears in the strClassName that class's object should get created. Something like RUNTIME_CLASS macro in MFC. in this macro it uses ## to parsing token. Same thing i want to achieve not using MFC. how can i do that.
Thanks
Ravi
|
|
|
|
|
Its a simple use of logic i guess..
Class Class1 : public CBase
{
public:
void WhoAmI() //virtual fucntion in base class.
{
printf("i am class1");
};
};
Class Class2 : public CBase
{
void WhoAmI() //virtual fucntion in base class.
{
printf("i am class2");
};
};
char szClassName[] = "Class1";
void main()
{
CBase *pClass;
if(!strcmp(szClassName,"Class1"))
{
pClass = new Class1;
}
else
....
pClass->WhoAmI();
...
}
The World is getting smaller and so are the people.
|
|
|
|
|
It requires more thought that that. The RUNTIME_CLASS macro in MFC uses the runtime information gathered by MFC to create new objects.
In plain C++, the most effective approach would be to analyse the string the user has posted, and create a new object based on this info. For an example:
void* ptrObject = NULL;<DIV>
if ( _stricmp(strClassname, "CTest") == 0 )
{
ptrObject = reinterpret_cast<CTest*>(ptrObject);<DIV>
ptrObject = new CText(...);
}
<DIV>
... Use the object ...
<DIV>
delete ptrObject;
This code piece will analyze the input and create a new object based on the input. The void-pointer is used because we want the pointer to be global for the function, but we do not know it's type until we analyze the string. Be especially careful that you initialize the pointer to NULL before doing the cast conversion. Otherwise your compiler might throw you a warning.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
hi,
I'm a VietNamese student, now i'm doing a project with the ower-draw
control and I want to create a dialog that like your RGN Generator.
Would you please tell me how to create A RGN Generator text with the
burning fire around it and a button with the text circling it.
Thanks
|
|
|
|
|
Hello Guys,
Is it advisable to design a new control derived from CWnd like CButtons in stuff?
Can any one give me or direct me to a sample that has done it so that i can understand the complexity involved.
Thanx in advance.
Yo!
|
|
|
|
|
Search for CRulerWnd/ CRulerWindow in codeproject,which allows to create/use custom control Ruler(Scale)
Warm Regards,
KKR
|
|
|
|
|
Thanx Mate,
Regards,
Prakash.;)
The World is getting smaller and so are the people.
|
|
|
|
|
How can I crack an encryped *.zip file or an encrypted Word document? as we have known, decryption needs its algorithm and its key, but we don't know the encryption algorithm of it, I want to try the key one by one by using a hacker dictionary,
how can I do it? I want someone will help me~
I am a Chinese boy
|
|
|
|
|
Prolly wrong place to ask that question...
The word of the day is legs, let's go back to my house and spread the word
|
|
|
|
|
Hahaha man you are so sick...Password are put so that ppl like you dont read them.
|
|
|
|
|
don't put your nose into stinking things!
Don't try it, just do it!
|
|
|
|
|
ive used GetDIBits to get the bitmaps images RGB data into a
byte array
so effectively i can modify the rgb values of the image by just modifying the bits in the byet array buffer.
i tried creating a function
SetPixelColor(LPBYTE imgBuf,int column,int row,DWORD dwColor)
{
}
that is supposed to set the dwColor for pixel at row and column specified
however im having problems in mapping the row and column to the 1D LPBYTE buffer
please advice??
or is there any other alternative APIs
|
|
|
|
|
How can i change the text in the status bar for an SDI document >
|
|
|
|
|