I have two projects which run as separate processes, but belong to the same application:
Master (contains TMasterMainForm and TMasterModalForm)
Slave (contains TSlaveForm)
The typical way to use this application is like this:
Master is started and shows the TMasterMainForm.
The user can run the slave by clicking a button in TMasterMainForm.
Master starts the Slave process.
Slave shows the TSlaveForm.
Master sends the TForm.Handle of TMasterMainForm to Slave. (via IPC = WM_COPYDATA)
Step 5 is done so that when Slave is closing it can set the foreground window back to TMasterMainForm. This is done to improve the user experience.
This worked fine until we introduced TMasterModalForm.
TMasterModalForm can be started using another button in TMasterMainForm. It is a separate window, but is shown modal and has the TMasterMainForm as its explicit popup parent.
Now when the TSlaveForm is closed the Slave application calls SetForegroundWindow on the handle of the TMasterMainForm, but this is not correct anymore since there is a modal form (TMasterModalForm) on top of it.
So the question is:
How do I manage setting the foreground window in this non trivial situation?
PS: This is a simplified description, the real application is also doing this foreground window stuff the other way around.
You cannot set the foreground window to the master main form because it is disabled. It is disabled because you are showing a modal form whose owner is that main form.
The obvious solution is to set the foreground window to be the modal form rather than the main form. Since your slave app presumably cannot easily know which window is active, you should re-work your IPC to allow the slave app to ask the master app which window is active, and then make that the foreground window.
A more elegant solution would be to let the master app call SetForegroundWindow. In fact it would probably be simpler just to call Application.BringToFront from the master process. Of course, the slave process would still need to send a message to the master in order to invoke this. The final piece in the puzzle is dealing with the focus-stealing restrictions but you can do that using AllowSetForegroundWindow. You need your slave process to call this passing the ID of the master process.
To solve your problem, I would not call SetForegroundWindow from the slave application, but instead send a custom activate message to the master application. In this message you can pass the desired handle in WParam or LParam. The master application itself can determine whether it can activate that handle, or need to activate the modal form instead. You put the responsibility of activating the right window in the application itself.
PS: You don't need WM_COPYDATA to send a handle. You can just pass in in WParam or LParam of any message you make up. This goes for the handle to send back as I explained above, but also for the handle that is sent to the slave in the first place.
Related
I need a help to communicate from my container single-spa to loaded angular app ( child ). when user click on parent app ( spa-container ) option, that should communicated to child application to change the mode.
it will not happen very frequently. But not able to find a way to communicate from container to loaded angular application.
there is a detail given by spa itself : spa-communication detail but not clear and there is no detailed steps. any one help me?
I'm one of the maintainers of single-spa.
We tend to be light on our opinions in the documentation about how to implement communication between modules because there are a lot of ways to implement it and each comes with pros/cons. In the situation you described it sounds like you might want to explore option #3 from the link you posted.
Custom Browser events
In the parent you fire custom events on the window. API on MDN.
Quick example
// in the parent (usually called the single-spa config or root-config in the documentation)
const event = new CustomEvent("myEvent", {favoriteMovie: 'StarWars'})
window.dispatchEvent(event)
// in the child (or registeredApplication)
window.addEventListener("myEvent", myEventHandlingFunction)
function myEventHandlingFunction(e) {...}
That should at least get you started, there are other options for communication as well and this particular approach isn't going to be the best solution in every situation.
It's also worth noting that customEvents don't work in IE11 unless you include a polyfill.
I'm fairly new to nod-red oder nodejs in generel. But I think with time I got a decent understanding.
At the moment I'm using node-red-dashboard to give my home automation a nice touch and easy controlling interface.
All my devices communicate via MQTT and I organize my rooms (for example) with different tabs in node-red.
Maybe it's just a missunderstanding of mine, but how do I use the same mqtt-connection (or db connection, etc.) throughout different tabs? I've configured a new one for each tab and can see in the log, that individual connections are made for each tab.
The connection from another tab is not shown inside the nodes on another tab.
Maybe you can point me in the right direction.
Cheers,
Patrik
In the mqtt-broker configuration node's edit dialog, there is a select box where you can pick the 'scope' of the node. It defaults to the tab you're currently on, but if you change that to 'global', the config node will be available on all tabs.
As Branch documentation states and my current implementation goes, the branch links are detected in the AppDelegate, a view controller is registered accordingly and then launched from there.
Is there a way I can do this not in the AppDelegate but elsewhere?
My main issue is that if my app is already launched and someone clicks on a Branch Deeplink, it works as it should but takes me back to the launch screen of the app, rather than staying at the currently launched view.
I tried using
[branch initSessionWithLaunchOptions:launchOptions automaticallyDisplayDeepLinkController:NO];
and launching the view controller from elsewhere, but now I don't understand how the "deepLinkingCompletionDelegate" will be called to fetch the data accompanying the link.
Alex from Branch here:
These code snippets don't need to be in your AppDelegate, but they do need to be called in the correct app lifecycle methods. The typical place for these to be defined is the AppDelegate, and it would be a much more advanced implementation to put them anywhere else. Even if you did, the effect would be the same and you wouldn't avoid the issue you've identified.
It sounds like you are using our basic automatic deep link routing approach. What you want to do is build your own custom router, so that you can decide intelligently what to do with the link data. In other words, you'll still receive the link params right away, but you'll be able to decide to not open the launch screen if the app is already running.
I would like to write an application which passes every message it receives to another window. For example, I have an application where user can press some keys, move mouse over it, etc. and I want all these messages passed to, for example, MS Paint.
How do I do this? Any ideas? As far as I know, there may be a problem with sending key strokes to another window, so please advice as well.
EDIT
Okay, maybe I will give you more description of what I'm looking for.
My applications displays a window of another application on the form. Now I would like to control the other window using messages sent to my application's form (like key downs, mouse moves, etc.).
I have been thinking of passing all the messages my form receives to the window of the application I'm kind of 'embedding' into my own. By 'embedding' I mean making the application window display on my form.
Maybe there's another solution to my problem. Please advice.
Thank you for your time.
Some messages (i.e. input messages) arrive through the message queue and the rest are delivered straight to the recipient windows. What you are asking to do therefore requires you to do all of the following:
Implement a top level message loop that retrieves messages from the queue and sends them to the other app.
Reimplement all modal window loops to pass all messages on.
Replace the window procedure for all windows in your process with one that passes all messages on to the other app.
Look for other opportunities for messages to arrive that I have not covered.
I can't imagine that this is really going to be the solution to your problem, whatever that problem is.
Forwarding the messages is definitely possible and easy, but it likely won't do what you are expecting. Take a look here.
Override the form's DefaultHandler() and post every message it gets to the other form. If there are any explicit message handlers in the form or even some controls then you may not see those messages in DefaultHandler().
I have a button on the Childwindow, which should navigate to a Phoneapplication page.
I am using the NavigationService.Navigate(), but it says "NavigationService cannot be used in the current context ".
How to use the NavigationService in a Child Window ??
If it "can't be used in the current context" you may be better off looking at a different way to trigger the navigation rather than trying to do something the system says it can't do.
I'd recommend using a messaging system to send a message to the page hosting the child window and then have that trigger the navigation.
Also note that you should be making navigation requests from the UI thread.