I could create a new timer with SetTimer(hwnd, id, elpase, proc), but i cannot assure that the timer for the id does not exist.
Is there a way to know whether a timer for the id exist?
I presume you mean SetTimer (Win32 doesn't have a CreateTimer). http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx
From the published Win32 API there is no way to find out if a timer for a particular window already exists.
Bear in mind that each Window (hwnd) can have an independent timer with the same id. I presume you are not in control of the window and therefore don't know which (if any) other timer ids are in use?
If you are really concerned about overwriting someone else's timer, why not just create a child window within the parent hwnd and create a timer in there?
Related
Asynchronous usage of RegNotifyChangeKeyValue is simple enough: pass it an event object and wait for the event to be signalled.
What is not so clear, however, is the correct way to cancel a notification request. For example, if a timeout has been set on the wait like so:
RegNotifyChangeKeyValue(hKey, false, REG_NOTIFY_CHANGE_LAST_SET, regEvent.SafeWaitHandle, true);
regEvent.WaitOne(TimeSpan.FromMinutes(30))
If the timeout occurs without the notify firing, this notification is left presumably pending and waiting to fire. This is worse if the notify and wait is within a loop, potentially registering many notifications (one for each expired timeout).
Do I simply close both the event handle (regEvent) and the registry key handle (hKey)? Is there anything else I need to call, e.g. directory change notifications have FindCloseChangeNotification, is there an equivalent here?
I'm currently using P/Invoke with C#, but I do not believe that should make a difference - any answer should be focused on the requirements and usage of the Windows API. This would be much the same question if I had used RegNotifyChangeKeyValue/CreateEvent/WaitForSingleObject from VC++.
Closing the open Registry key is enough. When the key is closed, the event is signaled. This is documented behavior. So, simply be sure to close the Registry key before freeing the event.
I am fixing a MFC applivation written in C++. It is a GUI and it communicates with an external module connected to the PC via USB.
I want to avoid using a separate thread. Is there a way I can add things to the mainloop so that it runs continously rather than being event based?
I want the mainloop to make a call to a function runCommStack() in every loop.
Some possible approaches:
You can use CWnd::SetTimer to set a timer.
You can override CWinApp::OnIdle (called by CWinApp::Run).
You can override CWinApp:Run, copying and modifying the original MFC's CWinApp:Run. This definitely is not the easiest solution.
You can create a background thread.
It depends on the requirements of runCommStack(). Is this function running long times? Then you probably won't want to run it in the GUI thread. Does runCommStack need to get called every n milliseconds? Then it might also be better to run it in it's own thread. In other cases you can just use the timer or OnIdle approach.
Regarding solution 1: as Tim pointed out WM_TIMER messages are low priority messages and will not be passed to the application while other higher-priority messages are in the message queue. See also Determine priority of a window message.
With solution 2 you should remind that OnIdle will only be called if no window message is available. So this is quite the same as solution 1 (in fact a little worse).
Also keep in mind that solutions 2 and 3 might result in your runCommStack not getting called if a dialog's DoModal() is called or if a message box is displayed. This is because during MessageBox() the control is not returned to CWinApp::Run().
I'ld implement solution 1 or 4.
When there are no messages (like keys, mouse, repaint) arriving the main loop suspends the program, waiting for the next message. So the idea of adding a call to the main loop will give you very erratic operation. For example, minimizing your window will stop all the USB communication.
Using SetTimer and calling your runCommStack function in a WM_TIMER handler will probably be much more satisfactory.
You can use idle processing with CWinApp::OnIdle; this will work if reading your USB device takes only a short amount of time, otherwise the user interface will be blocked during long reads.
But using a separate thread is definitely a better method.
The problem is that the WaitForMultipleObjects(Ex) returns just smallest index of all the signalled objects in an array. I would like to know what exactly event objects (created using CreateEvent) are in signalled (or non-signalled) state.
I think it is not possible but decided to ask just to make sure I'm not missing anything =)
For each object whose state you want to test, call WaitForSingleObject with a timeout of zero. If it returns WAIT_OBJECT_0, then the object is signaled. Otherwise, it's not.
Unless you have an auto-reset event, waiting for an object to become signaled does not alter its state.
Keep in mind that the state you detect with WaitForSingleObject isn't necessarily the same state the object had when WaitForMultipleObjects returned. More objects might have become signaled in the meantime, and other objects might have become non-signaled.
Is there any Win32 API to check if a given handle belongs to the current process?
From a window handle you can use GetWindowThreadProcessId Function to get process id.
From a process handle you get the id with GetProcessId Function.
I don't know how easy is to get a process handle from some other handle. But I believe it'll have to do with kernel objects enumeration.
A handle can "belong" to more than one process (Inherited handles in child process etc)
I wish to launch a separate thread for handling window messages (via a blocking GetMessage loop), but still create the windows in the initial thread, afterward.
Within the separate thread, as soon as it launches, I am calling PeekMessage with PM_NOREMOVE to ensure a message queue exists (is this necessary?), followed by..
AttachThreadInput(initial thread id,GetCurrentThreadId(),true)
..before finally entering the message loop
I am not yet using a mutex or cs to ensure this is happening in time, but am merely using a Sleep statement in my initial thread for the sake of simplicity.
Regardless, window messages do not appear to be intercepted by the separate thread.
I am a little unsure as to whether I am doing this correctly, and would appreciate any possible guidance. Both threads are in the same process
Thank you all
That's not what AttachThreadInput does. Even after you attach your input queue to another thread, Windows still have thread affinity. Messages in the queue for a given window can only be removed from the queue by that window's thread.
What AttachTheadInput does is to make two threads share an input queue. This allows them to query information about the input state and know that the other thread will get the same answer for the same query. For instance, one thread could call GetAsyncKeyState and know that the answer reflected the key state for the other thread.
It allows two or more threads to have the same relationship to the input queue and each other as processes had in Windows 3x. This is the reason that this API exists; so that complex multiprocess applications could be ported from Win 3x to Win95/WinNT.
It seems the best way to instigate window creation from the main thread, while having messages for them handled in a separate, looping thread is to use a custom message, that can be sent to the separate thread - Thus allowing it to create the window, but still allowing that action to be invoked from the initial thread:
1) Allocate a custom message, and create a structure to hold the window initialisation parameters:
message_create_window = WM_USER + 0;
class Message_create_window{
Message_create_window(...);
};
2) Instead of calling CreateWindow(Ex), use something similiar to the following, passing in the relavant window creation parameters:
PostThreadMessage(
thread.id,
message_create_window,
new Message_create_window(...),
0
);
3) Handle the custom message in the message pump of your ui handling thread, extract the creation parameters, & free afterwards:
MSG msg;
GetMessage(&msg,0,0,0);
...
switch(msg->message){
...
case message_create_window:{
Message_create_window *data=msg->wParam;
CreateWindowEx(data->...);
delete data;
}break;
...
This does, however, have the following side-effects:
The window will be created asynchronously. If it is required that the initial thread block until the window is created (or, indeed, that the window's existence can ever be asserted) then a thread synchronisation tool must be used (such as an event)
Care should be taken when interacting with the window (it is a multithreaded application, after all)
If there are any major holes in this answer, or this seems like a terrible approach, please correct me.
(This is still my question, & I am trying to find the best way to accomplish this)