I'm writing a dll in which a function is used to call :
mouseHook = SetWindowsHookEx(
WH_MOUSE_LL,
MouseHookProc,
0, // tried too with (HINSTANCE) inj_hModule, which is hModule from DllMain
0);
When I put this in DllMain, or in the dll's WndProc (the one working with the messages, for instance in case WM_CREATE: or whatever ), it is working OK.
But I need to put it in a separate function, so I can hook when I call it. When I do it, GetLastError says that it succeeded, but the hook isn't working, MouseHookProc is just never called (I put some trace in it to check).
I also tried with other hInstance values for the 3rd parameter, no success either...
Searching for a solution, I read that low level hooks must be set globally, I must confess that I'm not sure to fully understand that as I think it may be the problem, is some regular function not global and wndproc functions global ??? Not sure.
It is quite frustrating as it works ok when I call it at init, if I don't find a solution quickly maybe I'll dispatch some custom message so I can SetWindowsHookEx when I want but it will still be in the wndproc...
Thanks for helping me and Merry Christmas everyone !!!
Related
I'm using the SetWindowPos function for an automation task to show a window. I know that there are two ways that Windows provides to do this:
Synchronously: SetWindowPos or ShowWindow.
Asynchronously: SetWindowPos with SWP_ASYNCWINDOWPOS or ShowWindowAsync.
Now, I'd like to get the best of both worlds: I want to be able to show the window synchronously, because I'd like it to be done when the function returns. But I don't want the call to hang my process - if it takes too long, I want to be able to abort the call.
Now, while looking for an answer, the only thing I could come up with is using a separate thread and using SendMessageTimeout, but even then, if the thread hangs, there's not much I can do to end it except of TerminateProcess, which is not a clean solution.
I also have seen this answer, but as far as I understand, it has no alternative for native WinAPI.
The answer in the question you linked to simply loops until either the desired condition occurs or the timeout expires. It uses Sleep() every iteration to avoid hogging the processor. So a version for WinAPI can be written quite simply, as follows:
bool ShowWindowAndWait(HWND hWnd, DWORD dwTimeout) {
if (IsWindowVisible(hWnd)) return true;
if (!ShowWindowAsync(hWnd, SW_SHOW)) return false;
DWORD dwTick = GetTickCount();
do {
if (IsWindowVisible(hWnd)) return true;
Sleep(15);
} while (dwTimeout != 0 && GetTickCount() - dwTick < dwTimeout);
return false;
}
Unfortunately I think this is the best you're going to get. SendMessageTimeout can't actually be used for this purpose because (as far as I know anyway) there's no actual message you could send with it that would cause the target window to be shown. ShowWindowAsync and SWP_ASYNCWINDOWPOS both work by scheduling internal window events, and this API isn't publicly exposed.
I had a small debate with a fellow programmer. He uses the following idiom in his code:
HWND hWnd = SomeFunctionWhichReturnsAWindow();
if(hWnd != NULL && hWnd != INVALID_HANDLE_VALUE)
{
// All good
}
else
{
// Error
}
I told him that in my opinion this is a wrong approach, as the HWND type has nothing to do with the INVALID_HANDLE_VALUE definition, but he's sure that this is good code, as a valid handle can never be equal to INVALID_HANDLE_VALUE, and it's in the mood of "better safe than sorry".
So, is it an acceptable and correct idiom?
It is a mistake to compare an HWND against INVALID_HANDLE_VALUE. Although, in practise this is not a mistake that will hurt you.
The only HWND value reserved by CreateWindowEx as being invalid is NULL. Now, it happens to be an implementation detail that INVALID_HANDLE_VALUE cannot ever be a valid HWND, but that is just implementation detail. The function that yields window handles, CreateWindowEx, uses NULL to indicate failure. That's all you need to know.
If you wish to win your argument with your colleague, I suggest you look inside SomeFunctionWhichReturnsAWindow and find out which Win32 API is called to produce the HWND. Then consult the documentation. That will show you that NULL is the reserved invalid value.
For the sake of clarity you absolutely should change the code to test against NULL alone.
INVALID_HANDLE_VALUE is defined as -1. An invalid HWND is defined as 0. No API will ever return HWND(-1) on failure, so checking for INVALID_HANDLE_VALUE is meaningless, it will never happen.
However, there are some APIs that accept reserved non-zero HWND values as input, and thus cannot be used as valid HWND return values, either:
PeekMessage() and GetMessage():
If hWnd is NULL, (Peek/Get)Message retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed.
If hWnd is -1, (Peek/Get)Message retrieves only messages on the current thread's message queue whose hwnd value is NULL, that is, thread messages as posted by PostMessage (when the hWnd parameter is NULL) or PostThreadMessage.
So there is a logical difference between HWND(0) and HWND(-1). And in fact, because of that difference, a valid HWND will never be -1 because a message loop would never be able to retrieve messages for it.
Also SetWindowPos() has some reserved values as well:
hWndInsertAfter [in, optional]
Type: HWND
A handle to the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values.
HWND_BOTTOM
(HWND)1
Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.
HWND_NOTOPMOST
(HWND)-2
Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.
HWND_TOP
(HWND)0
Places the window at the top of the Z order.
HWND_TOPMOST
(HWND)-1
Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated.
CreateWindowEx and the similar functions that return a HWND clearly state that an invalid HWND is 0. Anything other might be valid.
Therefore, checking for INVALID_HANDLE_VALUE is 100% wrong, no matter what you might assume.
Making assumptions such as "this will probably never hurt" are very much dangerous and, although at this time valid, in the future you may be used to assume similar features that are not that innocent.
HWND can't be used in comparison to INVALID_HANDLE_VALUE as this two are two different things. Most resources, such as a file, etc return HANDLE and must be compared to INVALID_HANDLE_VALUE to ensure the resource is okay for use by any function which depends on it. However, HWND refers to handle for windows GUI objects. So is save to compare HWND values to 0 for invalid return handles rather than using INVALID_HANDLE_VALUE which is also -1.
Furthermore, to more information on the HANDLE type, you can check this StackOverflow previous answers to learn more.
A HANDLE is a context-specific unique identifier. By context-specific,
I mean that a handle obtained from one context cannot necessarily be
used in any other aribtrary context that also works on HANDLEs.
For example, GetModuleHandle returns a unique identifier to a
currently loaded module. The returned handle can be used in other
functions that accept module handles. It cannot be given to functions
that require other types of handles. For example, you couldn't give a
handle returned from GetModuleHandle to HeapDestroy and expect it to
do something sensible.
The HANDLE itself is just an integral type. Usually, but not
necessarily, it is a pointer to some underlying type or memory
location. For example, the HANDLE returned by GetModuleHandle is
actually a pointer to the base virtual memory address of the module.
But there is no rule stating that handles must be pointers. A handle
could also just be a simple integer (which could possibly be used by
some Win32 API as an index into an array).
The question is the windows handle is valid or not, Why not just use IsWindow()?
I'm trying to use mmTimer with a callback function, which is a static CALLBACK function.
I know that a static function cannot call a non-static function, thanks to you all guys, except from the case where the static function gets a pointer to an object as an argument.
the weird thing is that my timer works fine in release mode, and when I try to run it in debug mode there is this unhandeled exception that pops up and breaks the program down.
void CMMTimerDlg::TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
CMMTimerDlg* p = (CMMTimerDlg*)dwUser;
if(p)
{
p->m_MMTimer += p->m_TimeDelay;
p->UpdateData(FALSE);
}
}
my questions are : - is there any way to resolve this problem? - If this error occurs on debug mode, who ensures me that it wouldn't happen once i release the program?
there is where the program stops:
#ifdef _DEBUG
void CWnd::AssertValid() const
{
if (m_hWnd == NULL)
return; // null (unattached) windows are valid
// check for special wnd??? values
ASSERT(HWND_TOP == NULL); // same as desktop
if (m_hWnd == HWND_BOTTOM)
ASSERT(this == &CWnd::wndBottom);
else if (m_hWnd == HWND_TOPMOST)
ASSERT(this == &CWnd::wndTopMost);
else if (m_hWnd == HWND_NOTOPMOST)
ASSERT(this == &CWnd::wndNoTopMost);
else
{
// should be a normal window
ASSERT(::IsWindow(m_hWnd));
// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);
when it gets to pMap it stops at that assertion!!!!
here is the static CALLBACK function
static void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
here is how I set the timer
UINT unTimerID = timeSetEvent(m_TimeDelay,1,(LPTIMECALLBACK)TimerProc,(DWORD)this,TIME_PERIODIC);
The problem here is that multimedia timer API unlike many other has restrictions on what you are allowed to do inside the callback. You are basically not allowed much and what you are allowed is to update internal structures, do some debug output, and set an synchronization event.
Remarks
Applications should not call any system-defined functions from inside
a callback function, except for PostMessage, timeGetSystemTime,
timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg,
midiOutLongMsg, and OutputDebugString.
Assertion failures start display message boxes which are not allowed and can eventually crash the process. Additionally, windowing API such as IsWindow and friends are not allowed either and are the first place cause leading further to assertion failures.
The best here is to avoid using multimedia timers at all. In most cases you have less restrictive alternate options.
It only looks like your code works in the Release build, it will not assert() that you are doing it right. And you are not doing it right.
The callback from a multi-media timer runs on an arbitrary thread-pool thread. You have to be very careful about what you do in the callback. For one, you cannot directly touch the UI, that code is fundamentally thread-unsafe. So you most certainly cannot call UpdateData(). At best, you update a variable and let the UI thread know that it needs to refresh the window. Use PostMessage(). In general you need a critical section to ensure that your callback doesn't update that variable while the UI thread is using it to update the window.
The assert you get in the Debug build suggests more trouble. Looks like you are not making sure that the timer can no longer callback when the user closes the window. That's pretty hard to solve cleanly, it is a fundamental threading race. PostMessage() will already keep you out of the worst trouble. To do it perfectly clean, you must prevent the window from closing until you know that the timer cannot callback anymore. Which requires setting an event when you get WM_CLOSE and not call DestroyWindow. The timer's callback needs to check that event, call timeKillEvent() and post another message. Which the UI thread can now use to really close the window.
Threading is hard, do make sure that SetTimer() isn't already good enough to get the job done. It certainly will be if the UI update is the only side-effect. You only need timeSetEvent() when you require an accurate timer that needs to do something that is not UI related. Human eyes just don't have that requirement. Only our ears do.
I use libevent like this,
client->m_event = event_new(listener->m_server->m_server_base, client->m_sockfd, EV_PERSIST, Client::ClientEventCallback, client);
event_add(client->m_event, NULL);
But I don't know how to modify the event of m_event, there seems to be no interface to operate in official manual, i tried to do it like this, but it make a core dump.
short event = event_get_events(m_event);
event_del(m_event);
event_assign(m_event, m_server->m_server_base, m_sockfd, event | EV_WRITE, Client::ClientEventCallback, this);
event_add(m_event, NULL);
core dump ocurs at event_assign, please help me ... how to modify the registed event of the struct event ?
I don't see anything in your code that should make you core dump, but I might inquire as to why you're event_assign'ing again anyways just to add in the EV_WRITE flag. Correct me if i'm wrong, but since your event_new is only specifying EV_PERSIST, I don't think it'll ever fire (so why event_add it at that point?) It seems like you should just be doing
client->m_event = event_new(listener->m_server->m_server_base, client->m_sockfd, EV_PERSIST | EV_WRITE, Client::ClientEventCallback, client);
up top, then when you are ready to write just do
event_add(m_event, NULL);
and when you're done writing
event_del(m_event);
Anyways, like I said I wouldn't think what you're doing should be a problem per-say, but if there is some funky behavior that happens when you add an event with only EV_PERSIST as the event type and then later del/assign it, the above may solve it. (And it'll be less code / more effecient anyways, so might as well :))
since I couldn't find an answer to this question I researched a bit further into the MSDN and I found isChild(). It might give me the answer to that other question.
Now, in order to use isChild() I need to pass the HWND of the parent application that I want to check, in this case my own application.
How do I get the HWND of my own application?
I don't know the title since it changes constantly so I can't use FindWindow().
Thanks
Edit:
Since it's not clear, I'll add more information:
I am not creating a window. I don't have access to the creation of a window. My code is a piece of code that gets compiled together with whatever application the other programmer is coding and I have no access to how the window is created, the title or any other information.
So, how do I get the HWND to the "WINDOW" of the application I am running?
Your application doesn't have a HWND. The window does. An application may have no windows or it may have many, so there is no general function to "Get the application's HWND".
The obvious solution is just to hold on to the handle when you get it. When you create the window, a HWND is returned. Store that.
Use GetTopWindow() and GetNextWindow() to walk through windows z-order.
However, don't think it is necessary, but you can use GetCurrentProcessId() and
GetWindowThreadProcessId(), may be something like following will help you:
HWND FindMyTopMostWindow()
{
DWORD dwProcID = GetCurrentProcessId();
HWND hWnd = GetTopWindow(GetDesktopWindow());
while(hWnd)
{
DWORD dwWndProcID = 0;
GetWindowThreadProcessId(hWnd, &dwWndProcID);
if(dwWndProcID == dwProcID)
return hWnd;
hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
}
return NULL;
}
Can't you just hold onto the handle returned from CreateWindow? If not, why not?
Presumably your code gets called by main application code, otherwise what use is it? In which case I acnnot see why your code's API cannot include some way of informing you of the handle of the application's main window.
As others have already pointed out
In general, an application can have zero or multiple top-level windows.
If you're creating the window yourself you can just remember the HWND somewhere.
But maybe your code is in a DLL, so you didn't actually create the top-level window yourself. So what to do?
I would suggest the following:
Use EnumWindows to enumerate all top-level windows.
Use GetWindowLongPtr to get the HINSTANCE for each top-level window. Compare this against the HINSTANCE of the application, which you can get using GetModuleHandle(NULL). If they're identical, you've found your main window.
Edit: Here is some code. Turns out you also have to use IsWindowVisible because there seem to be quite a few invisible "helper" windows.
HWND hwndMain;
BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam)
{
HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL);
if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst &&
IsWindowVisible(hwnd))
{
hwndMain=hwnd;
return FALSE;
}
else
return TRUE;
}
Then in the place you want to find the window:
hwndMain=NULL;
EnumWindows(EnumWindowProc, 0);
And after this, hwndMain should contain the handle of the window, or NULL if none exists.
Using EnumWindows is a bit burdensome but is recommended over calling GetWindow in a loop because, as MSDN notes: "An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed."
You can inject a DLL in a thread who appeal user32.dll
http://msdn.microsoft.com/en-us/library/ms821625.aspx
This is old for me, but IIRC you should receive the HWND as a parameter in the window proc. You can save it in a global variable somewhere in the beginning.
What about your windows class name?
Is it always different on window creation?
If not you could still you FindWindow().