CRichEditCtrl from resource loads 1.0 instead of 2.0 - c++

I'm trying to update my application to use RichEdit 2.0; it's been using 1.0 since forever. Per the Microsoft documentation, I've changed AfxInitRichEdit() to AfxInitRichEdit2(), and I changed the class in the resource file from RICHEDIT to RichEdit20A (which is correct for this application). There is only one richedit in the resource file.
The application fails when I try to do anything with the window that includes this richedit. The dialog creation fails somewhere inside of ::CreateDialogIndirect(), and although I put breakpoints in CRichEditCtrl::Create and also on the class I derive from it, those breakpoints do not trip.
Out of frustration I tried calling AfxInitRichEdit() again and also calling AfxInitRichEdit2(). The application works! The breakpoints I put in do trip--but only on controls I create dynamically, not the one from the resource file. And when I run Active Window Spy, I see that the richedit created from the resource file somehow has a class of RICHEDIT even though I explicitly said RichEdit20A, and yet the dynamic ones are RichEdit20A as intended.
_RICHEDIT_VER is 0x210, and I'm using Visual Studio 2013.
I just can't figure out why CreateDialogIndirect() is making a RICHEDIT control--or trying to make one and failing, if I don't call AfxInitRichEdit()--instead of a RichEdit20A in spite of explicit instructions to the contrary. Any ideas?

Well, I feel stupid. There's a script that runs as part of the build process to update some resources, and for some reason that script has sometimes gotten confused between the debug and release versions, and copied resources from the release build into the debug build. I don't know why that happens and it's an issue for another day, but the upshot is the .rc file I had changed was getting replaced with another one.
Building the release version with the changes, and then building the debug version again, solved the problem.

Related

VS2022 Community crashes when adding Class to MFC Dialog

I am facing a very consistent and persistent problem with Visual Studio 2022 Community Edition.
In an MFC project I open the Resource File and add a new Dialog. Then I place some standard controls and rename the dialog resource from its default name to a new ID.
Then I save and try to assign a Class to the dialog by right-clicking on the dialog and choosing 'Add Class'. Then the 'Add MFC Class' window appears, I enter the Class Name and click [OK].
It appears it creates the class on the File System and then VS2022 crashes completely!
I have disabled all addins in case an addin could be causing the problem but it happens every (almost) every time even without plugins. The only time I manage to get it to work is if I save, close all code editors, exit VS2022, restart it and immediately try to add the class. Another piece of information is that I have changed the MFC dialog template with a different one but it does not seem to bother it when I get it to work. Also intelliSense is completely disabled.
How can I debug this and identify the root cause of this crash?
There's a fair chance that you can't do anything in an effective fashion. VS2022 isn't an open source project, where you can easily pinpoint a crash to a specific line of code and fix it yourself.
But the good thing is that you don't need to. Just use the feedback channel VS2022 provides:
Usually a Microsoft employee will reply within a few days and maybe a fix will be included in the next preview version. Only now and then it can take some month to get a bug resolved.

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)).

Filling text in qwidget using win32 api

I have a problem. I am using C++ to develop an application in Win32 that among other scopes automatize some user input process in an external app in order for the user to be ready to operate.
Particularly I would like to use Win32 API to fill some text in a Qt QWidget control. I wrote a DLL in pure C to get this task done. I tested it on a MFC application and it works very well.
Anyway I could not get it to work for Qt QWidget controls.
I was able to get the right handle via the EnumChildWindows function (stored in the struct Field).
SendMessage(Field.hFound,WM_SETTEXT,(WPARAM)NULL,(LPARAM)_T("bla bla bla"));
But the SendMessage doesn't seem to work because maybe the control (most probably a QLineedit) supports other messages to get this job done.
Is there any specification for these events, I googled a lot but I could not find anything suitable.
What is the most straightforward way to get this code working? Is there an Event table mapping for Qt I could use? Do I have to use some Qt headers and link it against a DLL (this could be a problem because of licensing)?
Thanks in advance.
Qt, at least 4.8 and 5.x, uses foreign controls. None of the widgets, beyond the window, have native handles. Your EnumChildWindows is most likely not finding what you think it's finding.
If you don't have access to the Qt application's source code, there's nothing else you can do, short of injecting your own code into the running application. If the application is dynamically linked, you can figure out what version of Qt it's using, and what compiler it was compiled with, and the likely set of Qt configuration options. You can then compile your own code with the same compiler and using same Qt version, and inject it into the running application. You can then enumerate visible windows, and their children, and find the control you're after.

CRichEditCtrl not working properly in shared dll written using MFC?

I am writing a DLL written in MFC to be used by other application.
project settings:
1. Use MFC in static library
2. preprocessor : AFXDLL
3. MD Build
I have also used AFX_MANAGE_STATE (AfxGetStaticModuleState()) before calling
CWinApp which internally calls InitInstance and DLL main.
This Dialog has tab in it and I am able to see only the first tab all other tab are coming as blank. When I am running the same DLL as exe (with required changes) its working fine.
Also DLL is crashing when i am calling AfxGetApp() ?
I suppose major problem is due to DOMODAL(). Can anyone tell what might be the issue of tab control not working?
Update I found out that CRichEditCtrl was the problem. In dialog tab I had this as well when I removed this It worked fine. Can anyone know the reason of this..
I have used AfxInitRichEdit2() before in InitiInstance()
I am new to MFC so let me know if you need any more info
You have to call AfxInitRichEdit() before the rich edit control is used.
Do you call AfxInitRichEdit2 in InitInstance of the EXE?
Try putting it in the DLL's InitInstance too!

QDrag destroyed while dragging

I have a Windows/Linux Qt 4.3 application that uses drag and drop in a QTreeView. I have two very similar applications which use the same set of Qt libraries. Drag and drop works in both on Linux but in only in one on Windows.
In the application that does not work the QDrag object gets deleted as soon as the mouse is moved. It is deleted by a DeferredDelete event from the event queue which is still processed in Qt during a drag. I do not know how to see what is causing the QDrag object to get deleted prematurely.
I can not figure out a good way to debug this problem. I have compared the source and cannot find anything obvious. I have tried using the code from one of the applications in the other application.
Any suggestions?
Update:
The reason the QDrag operation failed is because COM was not initialized successfully so the call to DoDragDrop in QDrag::exec returned immediately. QApplication tried to initialize COM by calling OleInitialize in qt_init but it failed with the error "Cannot change thread mode after it is set".
The interesting thing is that this happens even when OleInitialize is the first thing done in main so the thread mode is getting set initially by some external dependency. One of the differences between the applications that work on Windows is that the one that fails also contains .NET code so maybe that is the problem.
Solved:
This problem is a COM/CLR interop issue. The CLR sets the apartment state to MTA when it initializes and then when Qt attempts to initialize COM it fails. This problem and an old solution are discussed by Adam Nathan in Gotcha with STAThreadAttribute and Managed C++. In Visual Studio 2005 you can set the /CLRTHREADATTRIBUTE:STA compiler option in Configuration Properties > Linker > Advanced to set the threading attribute to STA without needing to create a new entry point.
I have no idea what can cause this, but I would try to find out by subclassing QDrag, overwrite deleteLater() (well, reimplement it, but as it's a slot, it will get called anyway), use this instead of a QDrag and put a breakpoint in deleteLater().