I've got my program associated with a file extension and clicking on a file of that type in Windows Explorer will open the program and load that file. All's well so far. Now I need to be able to click on another file of the type from WE and load that file into the same instance of the program already running. What happens now when I click on another file is the focus just switches to the program and nothing loads.
When the program isn't running and you click on a file associated with it, the program starts and in the loading of the App instance you check the command line, which is loaded into a CCommandLineInfo structure and the program deals with the command. I can't figure out how to get the second file to load when the program is already running by selecting it in WE (opening a file from within the program has been working fine from the start).
I have looked at WM_ACTIVATE and WM_ACTIVATEAPP which are called when the program gets focus while running, but I don't know how you would get the information about the file just selected in Windows Explorer. I'm probably missing some key terminology in my searches. I can't find any information on how to do this. Maybe I'm slow kid in class today...
Additionally if I select multiple files in Windows Explorer and open them at the same time, it opens multiple instances of the program instead of opening one instance any loading those files into that one instance. Is there any way to handle that?
The Explorer will scan the registry searching for the application name associated with the file extension. When found it reads the shell/open keys and checks if there are entries for command, ddeexec, and DropTarget. Then it will use the found method with the highest priority to pass the data (file names) to your application after starting it if necessary.
Nothing must be installed in the Explorer. You must only create the registry keys and add code to your application to handle the data (the code for basic command handling is already present). Other file browsers should do it like the Explorer.
One reason why IDropTarget was choosen is explained in the link:
This method leverages an application's existing drop target implementation (if one exists), making it easy for applications that already support drag-and-drop through an IDropTarget implementation on their top level window to map that functionality into a verb that ise presented in the explorer.
I don't think Word is still using DDE (while old versions probably used it). It will probably use IDropTarget.
It took me a few days to get back to this, then I ran into a few dead ends before hitting on the solution to get IDropTarget to work for my application. In the end Michael Dunn's article from here on CodeProject:
was the best way forward.
However once I got IDropTarget working, I ended up discovering my original problem had to do with locking my app down to one instance. A couple of years ago when this project was still in its infancy I used PJ Naughter's CSingleInstance class () to check and see if there was an instance of the program already running and if there was, switch to that instance.
A second instance would start when I double clicked on a file associated with the program when an instance was already running. When the second instance is detected, it sends a message to the original instance to take focus and quits. PJ Naughter conveniently created a means to send the command line from the second instance to the first before quitting, so I took advantage of that and now the first instance loads the file correctly on double click.
Implementing IDropTarget in the end turned out to not be necessary, but it will be a nice feature to allow users to drag and drop files into the program.
It also expanded my understanding of COM, which I may need to understand better down the road. I need to do a lot of communication between programs as part of this project and I will need to do a lot more inter-program communication down the road.
Just thought I would post an update for future reference if someone comes across a similar problem in the future and finds this thread.
The behaviour of MFC when writing Multi Threaded Applications, be it as simple as implementing a Progress Bar, still throws surprises at me. Why is MFC so fragile in this aspect. A Progress Barr is not an object we can Set, no, we have to write 'Inside Out' Code, the Dialog starts a Worker Thread, to do the task, and update the Dialog. The two threads then can only communicate via the SDK SendMessage(...)
Now, I admit, I use MFC42. Maybe later MFC libraries have better implementations.
For size and performance reasons, MFC objects are not thread-safe at the object level, only at the class level.
For GUI objects, MFC is mainly a wrapper for the Windows API calls. When modifying GUI elements the corresponding API messages are sent and processed by the control's message loop. So there is no difference between MFC and API applications when changing a GUI element from within a worker thread: Both have to send messages. However, to send a message from another thread, PostMessage should be used instead of SendMessage to inject the message into the queue and process it later by the thread owning the control.
From my point of view using messages to update GUI controls is even simpler than using synchronisation and locking classes for shared objects.
I am familiar with this site, and, although I do not always agree with it's theology, to coin a phrase, have found many useful topics there over time. I am writing a System where Dialogs Time Out, after a period of Non Activity. What's more, it collapses the whole stack of Dialogs, going back to Page1. That all works. As a Convenience to the User, I was going to implement a small Progress Control in the bottom LH Corner to show how many mins or secs left. I would have expected that a DialogBox, with No Activity whatsoever, other than keying or mouseing (i.e. Not in a Lengthy Calculation) should be able to receive messages, to give an indication of time left. The system is supposed to be in an Idle Loop
It's not part of the functionality that will make the system work, it's part of the GUI spark that contributes to make it sellable.
If it has issues, you're probably doing it wrong. The GUI should really only be updated directly from a single thread. If you have any asynchronous updates (i.e. from an independent thread), they should remain asynchronous. There are asynchronous communication methods within the Windows frameworks, use them.
Is this a Fragility a feature of MFC, and from how it wraps the SDK functions, or, is this a Feature that is Central to Windows, (i.e. the SDK suffers from the same problem) I have read several articles about this, and, the Gist is that it is always unsafe to communicate between two threads. This is clearly to conservative, Microsoft manages it quite well in for instance their MS Office Products.
The GUI elements should only be accessed from the main GUI thread. Accessing from another thread sometimes but not always results in an exception. As the others have said, use PostMessage to trigger an update in the GUI thread.
Is it possible to programmatically under Windows force a USB3 port to operate in USB2 mode, and then at a later time to switch it back into supporting USB3 mode? We need to test that a piece of hardware functions with both USB2 and USB3 connections, and would like to do this programmatically to prevent operator errors.
It will switch automatically if you plug a USB 2 device in, as the USB 3 pins will not be live. But most PCs these days have both types so it should be fairly simple to do. The only other way I can think of would be in the BIOS somehow, or to remove the 3.0 driver.
Yes, I know it will switch to USB 2 mode with a USB 2 device. We need to avoid an operator having to plug the device into a USB 3 port, and then moving it to a USB 2 port, as they can be lazy, or make mistakes. We need the switching to be automatic and fast, and some form of switchable hub that connects to USB 2 and USB 3 ports on the PC may be the answer.
Richard, we have a unit that needs to be tested on the production line, prior to shipping to the customer. The unit must work with both USB 2 and USB 3 connections. I won't go into the reasons why we need to test both connections but we do. At present the operator must manually take the USB cable out of the USB 3 socket, and put it into the USB 2 socket, and vice versa, when requested to do so by the test script. This introduces room for error, as they might get confused, and also they might end up damaging the USB socket since they will do this many times each day.
So a better solution is to have a software controlled way to switch between USB 2 and USB 3 connections. Jochen's suggestion is a significant improvement on the current scheme.
Do not trust software emulation where you can easily use real hardware...
In most computer there are both USB2 and USB3 port, and it is very easy to get a expansion card for $5 if you happened to work with a PC without USB2...
Skipper: We'll fix it. Alex: Fix it? How you gonna fix this? Skipper: Grit, spit and a whole lotta duct tape.
You may use an "USB 3 sharing switch" (use that search term). They provide connection of an USB device to two or more computers but may be off course also used to connect to two ports of one computer. These usually have a key to switch the ports and may support auto detection.
If you don't want the operator to press the switch key, you may look for one that supports other switching methods. I found at least one that allows switching using a hotkey when connected to a Windows PC. Your test program might then simulate the hotkey activation.
If the switch has an auto detection it should be also possible to trigger that by disabling one of the PC USB ports. But I have done such with Linux only so far and don't know how to do that with Windows. Note that this method (like the one initially asked) requires administrative privileges.
Last Visit: 31-Dec-99 19:00 Last Update: 26-Jan-21 20:00