Suppose if a window with handle 123456 is closed and another window is opened. Can Windows assign handle 123456 to the new window in the rarest possibility?
There's no guarantee anywhere that Windows won't immediately re-use a handle. In practice, all extant implementations take steps to try to avoid re-using handles.
Related
I would like to have some advice about how to port an old C++ program written for MS-DOS in the early 90s.
This program implements a quite complex text-user interface. The interface code is well separated from the logic, and I don't think it would be too difficult to make it use ncurses.
Being a complete novice, I have a few questions:
The DOS program intercepts interrupt 0x33 to handle mouse events. The interrupt handler store events in a FIFO, which the main program pools periodically. (Every element in the FIFO is a C structure containing information about the nature of the event, the position of the mouse and the state of its buttons.) To keep the logic of the code unchanged, I was thinking of firing a thread which calls getch() asynchronously within an infinite loop and fills the FIFO in the same way the old program did. My idea is that this thread, and only this thread, should access stdin, while the main thread would only have the responsibility to access stdout (through add_wch() and similar). Is ncurses safe to use in this way, or do stdin/stdout accesses need to be always done within the same thread?
The way colors are set in this app is quite byzantine, as it uses the concept of "inherited palettes". Basically, a window usually specifies the background and foreground colors, and every widget within that window sets the foreground only (but a few widgets redefine both fg/bg). I understand that ncurses' attr() always wants to specify colors using pairs, which must be initialized using initp(), and this doesn't play nicely with the logic of this program. I am therefore thinking of using tiparm() to directly send setaf/setbf sequences when the program wants to change the fg/bg color, respectively. (I would lose the ability to run the code on terminals which do not support setaf/setbf, but this would not be a huge loss.) Is it safe to send setaf/setbf control sequences and then call functions like add_wch(), or should the latter be used only in association with attr()?
I could write a few test scripts to check that my ideas work, but I would not be sure that this approach is supposed to work always.
Thanks for any help!
There's a lot of possibilities - but the approach described sounds like terminfo (low-level) rather than curses, except for the mention of add_wch. Rather than tiparm, a curses application would use wattr_set, init_pair, start_color, etc.
ncurses I/O has to be in one thread; while ncurses can be compiled to help (by using mutexes in some places), packagers have generally ignored that (and even with that configuration, application developers still would have work to do).
Further reading:
curses color manipulation routines
curses character and window attribute control routines
curses thread support
Due to XIM and XFT usage, I have to use XDisplay sometimes in my XCB based code.
My question, should I open display at the beginning of my program, and close it at end. Or open and close every time I need to use it?
It is better to open once the XDisplay. At least that is the common practice.
IIRC, XOpenDisplay involves setting up a TCP connect to the X11 server and having a few exchanges to initialize, e.g. for X11 atoms which became standard but not predefined (I'm not sure of the last point)
The SetParent function takes a child and new parent window handle.
This also seems to work when the child window is in a different Windows process.
I have seen a post that claims this is not officially supported, but the current docs don't mention this any more. Is this a flaw in the current docs, or did this behavior change?
HWND WINAPI SetParent(
__in HWND hWndChild,
__in_opt HWND hWndNewParent
);
You can have a parent-child relationship with the windows in different processes. It's tricky to get it to work right in all cases. You may have to debug various strange symptoms.
Normally, windows in separate processes would get their messages from separate input queues using separate message pumps. When you use SendMessage to a window in another process, it's actually posted to the other window's queue, processed there, and the return is effectively marshaled back to the original process. So if one of the processes stops handling messages, you can effectively lock up the other as well. (That's true even within a process when the windows are created on different threads and the thread queues haven't been attached.)
But when you set up the parent/child relationship among windows in different threads, Windows attaches those input queues together, forcing the message processing to be synchronous. You're no longer in the normal case, but you face the same kinds of problems: a hang in the processing for one window effectively hangs the other process.
Watch out for messages that pass pointers in the params. The pointers will not be valid in the receiving process. (There are a couple of exceptions, like WM_COPYDATA, which recreates the data in the receiving process for you. But even those have limitations.)
You have to be especially careful when the windows are being destroyed. If possible, disconnect the parent-child relationship before destroying either window. If it's not possible, then it's probably best to manually destroy the child window before the parent is destroyed. Normally, destroying a parent will cause the children to be destroyed automatically, but it's easy to get hangs when the child is in another process (or un-attached thread).
In newer versions of Windows (Vista+), you can also hit some security speedbumps if the processes run at different integrity levels.
Thanks to IInspectable who pointed out an error in my earlier answer.
Just remove WS_CHILDWINDOW from the child window. It avoid locks.
Sorry, that has not been helped
What are the implications of calling CloseHandle more than once?
The docs say "you shouldn't" but I think I have a realistic case with named pipes where a handle might be closed externally (See end of post).
CloseHandle throws an exception in debug mode in this case, which suggests to me the developers think this is serious, but the docs aren't exactly clear.
(Polite request: Please avoid the answer "just don't!" :-). Of course one should avoid closing a handke more than once, and of course there are good techniques to help with this: I'm just interested in what happens if you don't).
I've heard some people suggest that if the handle was quickly reused by the OS you might end up closing another, different handle.
Is this likely?
How does Windows choose handle IDs?
Is there any guarantee about how regularly a handle value will be reused?
(e.g. TCP ensures that a port number cannot be reused within a certain timeframe).
Can you close handles accross handle types? E.g., could I be thinking I'm closing a pipe but end up closing an Event?
Thanks!
John
(Context to this: I'm using named pipes in a client/server model. It seems to me very difficult to ensure that exactly one party is guaranteed to close the handle, e.g. in process crash/killed case. Perhaps I'm wrong, but certainly the MSDN sample code seems to my mind to allow the client to close the shared handle, and then when the server tries to close it, it is already closed).
Simple enough to check:
HANDLE h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);
CloseHandle(h);
h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);
In my WinXP x64 this produced:
2E8
2E8
So there you have it.
Unlike TCP ports, handles are recycled immediately.
Repeat this experiment with your favorite API or any mix thereof.
You probably have the wrong mental image of a pipe. It has two ends, each represented by a different handle. Yes, CloseHandle has to be called twice to make the pipe instance disappear. But since they are different handles, that can never cause any problem. Also note that handle instances are process specific. Even if they have the same value in both processes, they do not reference the same pipe endpoint.
There are two things that could happen:
You close a handle opened by some other code. That probably doesn't affect your code but it's likely to be catastrophic for the other code.
If you're running with a debugger attached, you crash your application because the OS will raise an exception when it detects an invalid handle being closed.
Neither of these is particularly attractive IMHO.
How can I know if a window belongs to my program? I guess I can use the window handle to get the executable name but that seems like a lot of work and I have to do this repeatedly so I think it might be a performance issue. Is there a simple way to know if a given window handle is from ones own program with win32 or some OS construct? Can't use window titles either due to the nature of this application.
Call GetWindowThreadProcessId and compare the returned process Id against your own (via GetCurrentProcessId) seems simple.