Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
Storing and using Windows Handle ( WId ) in registry
I wish to store the Window handle of a running instance of an application in the registry, the WId of a widget.
I need this to ensure that if another application starts, it can check the registry to know whom it is supposed to send a message to, using sendMessage() windows API.
How do I achieve this?
The type of a Windows handle , HWND, of which WId is a typedef..is a void pointer.
How do I store information of this type in a registry setting, and then retrieve to use it again?
Please help me with this.
I'll be obliged. Thanks.
The way you want to do it is unsafe and actually wrong!
Why don't you use global windows mutex and then check it on startup, if you found one you can enumerate processes, get instance and do what you want...
In you example, if application crashes or your PC crashes and reboots, the registry entry will be still there, and if you try to use it your application will crash and this will mean -> deadlock...
Thanks for your reply.
I am creating a global mutex to make the instances of the application aware of each other.
However, once aware, the newly launched application will need to send a message to the already running one.
I thought of getting the window handle and sending it that way.
How else can I send the running instance a message?
( this is not a case of QtSingleApplication - there are limitations of it which would hinder my application ).
Using registry to exchange data between processes is certainly not a right way to do things. Use one of IPC mechanisms, e.g. QSharedMemory: http://qt-project.org/doc/qt-4.8/ipc-sharedmemory.html It's not that difficult :)
Right! Qt way will be QSharedMemory!
Hmm...OK. I'll try the shared memory part...
However, in general, if I wish to make use of HWND/WId ( window handles ), please tell me how to do so. i.e. how to store them, in which data structures.
HWND is a pointer to a structure in memory. So if you will use QSharedMemory you can store it as HWND itself. Or you can store pointer to the pointer casted to long type:
HWND hWnd = ...;
long pp_hWnd = (long)&hWnd;
HWND hWnd2 = ((HWND)pp_hWnd);
You can even convert long to string and store it as string... You can do actually what ever you want...
You need to tell more about what you're doing, because it's not wise to advise you anything with no knowledge about your applications' architecture.
[quote author="AcerExtensa" date="1359105828"]You can do actually what ever you want...[/quote]
yeah, like "format c:" as ultimate solution :D We need more info to give proper advise.
I have an application.
I launch an instance A, of the application.
Next, I launch an instance B. It needs to know whether A is running ( I achieve that via mutex).
If A is running, B needs to send a message to A, so A can take a call on whether to refresh itself with B's information, or should B close down.
This is complicated by the fact, that if two windows are open, A and B, then a third C would need to broadcast the information to A and B, and both would take a decision, on what C would need to do.
So someone should send a message, and someone should send a message back.
Is there a reason why you're not just using QtSingleApplication?
Are your A, B, C windows instances of the same application, or are these different apps? If the same, then QtSingleApplication may help, if different, then we shall see about viable options.
Yes, instances A, B and C are indeed of the same application. I did research QtSingleApplication thoroughly, but it didn't suit my application.
In my application, the information needed to be displayed could be of 2 types. The type is not known when the application starts and has to be queried.
Assume A starts, and it is of type 1. Assume B starts and it is of type 2..no problem there. Now..assume C starts, it has to be either of type 1 or 2. So in this case, C needs to close down, and inform both A and B of the new information ( as one of them,of the same type as C, would need to refresh itself with the new information ). Now with QtSingleApplication, I cannot actually broadcast this information. It would only use sendMessage() to intimate the first running instance, in this case, A, and not B. However, it could very well be B, which would be of the same type as C and needs the new information.
Owing to this..I decided...Let A launch and be of type 1, and create Mutex1. Let instance B launch and be of type 2, so it creates Mutex2.
Now if C launches, and if it is of either type, it will try to create that particular mutex. If it fails, it knows that it has a similar instance running. Now..all I need is to send THAT instance a message, and for that instance to be able to retrieve that information to refresh itself with the new information.
Well, you could use QtSingleApplication only to get a first message to your other (first) instance. That first message could contain, say, a network port on which the instance is listening for connections. The first instance can then connect to that port and chat with your second instance all it wants, including telling about other instances running already.
There are many other IPC solutions you can think of. Only using network sockets are a very obvious solution. Using a TCP connection, you get two-way communication directly. If you have only two types, simply make each type listen on a different port. The first instance of that type to start will succeed to open the port, the second will fail. The second instance can then connect to the port instead of opening it for listening, and communicate whatever it needs to to the first instance. You even get notification on the connection dying, so you know that your first instance had a problem and your second instance can now assume the role of first instance.
So, if you could kindly tell me if this flow is correct :-
Instance A starts and tries to create a mutex of type 1. If successful, it knows it's the only one running, and it creates a shared memory.
Instance B starts and creates a mutex of type 2 ( if it is of type 2 indeed, let's say ).
Instance C starts, and let's assume it is of type 1 . It tries to create a mutex of type 1 but fails. It therefore knows, there's someone else of the same type. It then tries to attach itself, by name, to the shared memory created by instance A ( it knows the name). And writes something into it.
Meanwhile A keeps polling the shared memory every so often to get the new data, and so refreshes itself?
Is this flow correct, please?
Also, if someone could help me with another small nugget..
I've a QList, of a custom type.
QList <Item> ItemList;
Where Item is
But when I try and access this QList like an array and assign a value to a particular member...
ItemList [ counter ].A = <some string>
It reports an access violation error.
What seems to be the trouble? Is it because the QList hasn't been initialized?
Like I said: I would not do that. Unless you have very big chunks of data to transport (that would make using shared memory a good idea), I think using shared memory and polling that is not a very good design. Using a network socket will give you both the mutex functionality (there can be only one application listening on a particular port) as well as the communication channel on one go.
On your second question: yes. A QList only is as big as the the number of items you put in it*. If you want more array-like behaviour, use QVector instead. That one you can initialize to a particular size. In the future, please ask new questions in a new topic.
Right. I'll try that.
Just one small thing ( in view of my timeframe, I don't have a lot of time to experiment, so don't want to look at something wrong.,)..
The Socket we're talking of, is QTcpSocket? Or QLocalSocket?
I doubt it matters much, but since you're talking about things on the same system, I guess picking QLocalServer & QLocalSocket would make sense. However, the documentation states:
On Windows two local servers can listen to the same pipe at the same time, but any connections will go to one of the server.[/quote]
So, you cannot use that to figure out if there is already another instance running. To do that, you'd have to go for the QTcpServer/QTcpSocket instead, or still use that system wide mutex.
Thank you for your help. Really appreciate it.