Qt Creator Session Manager Bug? - c++

The default session works as expected, but when creating a new session, neither the projects nor the editors are restored. The current projects and editors are closed after ‘switch to,’ but nothing is loaded and I am left with blank editor windows (laid out as they were before initiating the switch) and no projects loaded. Any suggestions on how to further debug or otherwise resolve this issue will be greatly appreciated.
(Using Qt Creator 3.2.2 on Windows 8.1)
(I also created a new session called ‘xxx’ and grepped for ‘xxx’ in my project directory as well as AppData/Roaming and AppData/Local and all subdirectories thereof, and did not find the string anywhere.)

I am able to successfully use sessions now. I had previously expected “New” to create a new session with the current state, but I see now that it does not work that way.
If I understand correctly now, the current state is tracked by the currently open session, and saved on switch. Therefore, when one switches to another session, the state of the GUI just before switching is available in the session from which one switched.
A new session is blank, so if a new session is created and then one switches to it, there will be nothing available, so no projects or editors will be loaded and the window arrangement will remain in the same layout as it was before switching (but with empty editors).
To create a new session with the current state, use clone.

Related

Why is IExplorerCommand::Invoke() no longer being called?

I have created a File Explorer context menu extension that uses the IExplorerCommand interface to add menu commands to the Windows 11 context menu.
This has been working fine, but after the last Windows update, it no longer works properly.
Although the menu commands still appear, nothing happens when I click on any of them. I've added logging and I can see that IExplorerCommand::Invoke() is no longer being called.
Strangely, if I select the "Show more options" menu to get the legacy Windows 10 context menu, the commands work fine from that menu, it is only in the new Windows 11 context menu that they don't work.
I have tried running File Explorer in a debugger while selecting my menu commands, and I get lines like this in the output window when I click on the command:
onecore\com\combase\dcomrem\stdid.cxx(726)\combase.dll!00007FF9EB9947F5: (caller: 00007FF9C22E1E38) ReturnHr(2627) tid(67bc) 8001010E The application called an interface that was marshalled for a different thread.
I'm guessing this is the reason why my commands are not being called. Does anyone have any suggestions for what is causing this? Could it be a bug in File Explorer?
I've tried both STA and MTA threading models, and changing this made no difference.
Well, after wasting hours on this I finally have a solution!
My code was based on the PhotoStoreContextMenu sample code here:
https://github.com/microsoft/AppModelSamples/tree/master/Samples/SparsePackages/PhotoStoreContextMenu
This uses the Windows Runtime C++ Template Library (WRL), and defines the base classes used by the class like this:
class TestExplorerCommandBase : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IExplorerCommand, IObjectWithSite>
The change that fixed it for my code was to use WinRtClassicComMix instead of ClassicCom, i.e.
class TestExplorerCommandBase : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IExplorerCommand, IObjectWithSite>
I'm pretty sure this problem started when I installed KB5019509, which is the Windows update that changes File Explorer so that it now has tabs.
Note: this problem only happens for IExplorerCommands created in the plug-in for submenus, the top level commands that are defined in the APPX file work fine.
Also note that although this change does fix the problem with Invoke() not being called, it does introduce a new problem which is that IOleWindow::GetWindow() no longer works so it is not possible to get the parent HWND. (See Calling IOleWindow::GetWindow() from IExplorerCommand::Invoke() is giving error 8001010d (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)).

How to rename the program-name menu-label in a MacOS/X program?

I have a Qt-based GUI program that runs under MacOS/X, and I'd like to be able to change the label of that program's first menu-header, i.e. the label circled in red in this screenshot:
Is there a programmatic way to do that? An objective-C/"native" solution would be sufficient, assuming no Qt-based solution exists.
Some background info (for those who rightly suspect an X/Y issue here): My MacOS/X software distribution includes several different Qt-based programs, and in order to avoid having to distribute multiple redundant copies of the shared libraries they all use, and avoid having to write a custom installer, all of the executables are placed into the Contents/MacOS subfolder of the same .app bundle, as shown in this screenshot:
To run the software, the user clicks on the .app-folder's icon to launch the "main" application, and then there are various buttons/menus in that GUI that can launch the "other" applications as child processes as necessary; and that all works well, except that the child processes' first menu's label is always shown as the name of the "main" application (as listed in CFBundleExecutable tag in the bundle's Info.plist file) rather than the child-program's own name, and I'd like to be able to change that so it shows its own program-name instead.
The following code (Swift, should be trivial to port to ObjC) changes the menu's name:
NSApp.mainMenu?.item(at: 0)?.submenu?.title = "child-program-name"
However, with this approach the menu is no longer displayed in bold once the name is changed since it doesn't match the app's name. In fact, even when changed back to the app's name the menu title is no longer bold. This seems to be a long-standing problem; see set titles of items in my app's main menu?. Unfortunately NSMenu doesn't have an attributedTitle property like NSMenuItem.

Save Workspace MFC C++ MDI

I have a MFC MDI application. The app can have 2 or more dialogs open. I want to implement the "Save Workspace" feature so that the user, when opening the workspace next time, opens the dialogs that were opened when he saved and closed the workspace. How to do this?
The functionality is built into the CMDIFrameWndEx implementation. SaveMDIState stores the current setup, while LoadMDIState restores it. The documentation also explains, how to persist the position and size of the frame window itself, in case that's something you want, too.
Generally this is accomplished by storing the current state of the application into some sort of persistent store. Depending on your architecture this could be a local configuration file (xml, json, etc) stored under the Windows User's profile directory (you could also use the Windows Registry), a remote store such as a database could be used or perhaps such state could be stored into cloud storage. Just depends on how the application currently handles configuration and how universal you want to make the state storage.
You will want to implement some sort or running history of UI state. Storing the currently open windows and their locations when they are loaded, closed and moved. Inject a history tracker into each MDI child that is created. This could be a singleton type in the MDI parent. It should have facility to look up a window by its handle and should store the relevant information in a structure that makes sense for serialization. In each of the afore mentioned events add calls to the tracker with the appropriate changes. The tracker should persist along whatever rules you determine are appropriate.
The load process then requires that the MDI parent interrogate the tracker after it has initialized with what ever stored state existed. Using the stored information (window type and location (and data?)) the MDI parent then opens up the appropriate children at the appropriate locations.

How to save layout settings of MFC application?

I understand there are functions that can easily write windows registry, however I found out that in new MFC project created with wizard, some information (like split bar position, visibility of controls) gets stored automatically (or at least I found no CWinApp::Write* calls in the project). Since I have also older projects that don't have this behaviour I need to figure out how to make this without help of project wizard. Would anyone please know how does this work?
The MFC control state saving magic happens in the 'New' MFC Feature Pack, specifically in the SaveState methods, for example CMFCToolBar::SaveState.
To take advantage of this you'll therefore need to upgrade your Toolbars and Menus to use the newer controls and upgrade your application to inherit from CWinAppEx. I recommend that you use a New MFC Wizard based app as a guide on how to upgrade your old MFC app.
Most of the information is saved in CPane::SaveState(), thus if you want state of some component saved, you need to use classes derived from CPane. (for more info here is the class hierarchy).
The process of saving window states is initiated through CFrameImpl::OnClosingMainFrame(). This function in turn calls CWinAppEx::SaveState() which saves some application settings and then ALL instances of CMFCToolBar (they add themselves to global list of CMFCToolBars in call to OnCreate). In a similar way all dockable panes are saved but the list belongs to your main frame. Then positioin and size of your main frame is saved.
CViews and CFrameWnds are somewhat less favored, for what I found and tried out, the only information saved was visibility.
I used that loooong time ago. If I correctly reminds it, you should save the informations you want in a overridden CWinApp::ExitInstance() before calling base class method, and you load them in CWinApp::InitInstance. Be sure to allow for default values, because at first run, there will be nothing to load, and do not forget to call (or copy) base class.

Adding an item to Internet Explorer's right-click context menu

I'm trying to add a new entry into Internet Explorer's right-click context menu. I understand that this can be achieved by creating an HTML file containing JavaScript, and then linking to this from a location in the registry. I have also read that you can also add the HTML to a resource file and compile it into a DLL (see the Microsoft KB: Adding Entries to the Standard Context Menu). This is where I have started to hit problems.
Here is a bit of background about what I have done so far.
I have the following JavaScript in the file C:\test.htm:
<script type="text/javascript">
alert('Hello, world!');
</script>
I have added a new REG_SZ value 'c:\test.htm' in the registry at the following location:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt
If I now restart IE, my new menu item appears in the context menu. If I select my new menu item, my message box alert appears as expected. So far so good. However, I can't seem to access the script if it's in a DLL. Here are the steps I have taken:
Created a new Visual C++ Class Library project in VS 2005 named 'IETest' in c:\IETest
Imported my C:\test.htm file into the default app.rc resource file. I have changed the ID to be TEST
Compiled the DLL in debug mode
Altered the registry entry to read
res://C:\IETest\debug\IETest.dll/TEST
If I now restart IE and try again, the message box does not appear when I right-click and select my new context menu entry. I have also tried a release build of the DLL without any luck, and also tried replacing the last forward slash with a comma and altering the path single-backslashes to double-slashes.
I can only presume that I've done something wrong when creating my DLL. Can anyone point me in the right direction? Is there any way I can examine the compiled DLL to examine the resources and associated IDs?
Thanks.
Have you tried having the ID be TEST.html? My guess is that IE doesn't know how to handle the file because it doesn't have an extension listed, but this is totally a guess based off the fact that's how certain MS .dlls identify them (i.e. res://c:\windows\system32\shdoclc.dll/navcancl.htm)
The only other thing I can think of is to make sure your resources are of type 23.
ResourceHacker can view the resource files like you want: http://angusj.com/resourcehacker/