ActiveX Control - MFC Locale - visual-studio

I have an MFC application developed with Visual Studio 2008 where I use Adobe ActiveX control (I have Adobe Reader X installed). I try to set the zooming rectangle using the setViewRect function and it works perfectly.
Now the problem appears when in my Windows Regional Settings, the decimal symbol is set to comma instead of dot (such as in the German Regional Settings). The parameters of the zooming rectangle seem to be interpreted incorrectly.
I used ProcessMonitor and discovered that when Adobe ActiveX Control is created and its DLL is loaded in my process, it calls setlocale, and hence the application is using the current Windows Regional Settings instead of the default "C" locale. Therefore, the application interprets the numbers in a wrong way.
I tried to reset the locale to "C" right after loading Adobe and this workaround fixed the problem.
Now the problem happened again when I migrated my application to Visual Studio 2010. Apparently Adobe DLL ("c:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroPDF.dll") is developed using Visual Studio 2008. So when it sets the locale, it is done in MSVCR90.dll. When I reset the locale, I did so using the same DLL.
Now as my application is in VS2010, calling setlocale is done in MSVCR100.dll, so it does not affect the locale already set in MSVCR90.dll.
Is there a way to set the locale of the COM object that I am hosting inside my application?
Thank you so much in advance :)

This is just a shot in the dark, but you could try loading MSVCR90.dll with LoadLibrary (since the DLL is already loaded, it'll just give you a HANDLE to it, it won't load it twice), then finding the pointer to its setlocale function with GetProcAddress. Then you will be able to call the setlocale function for this DLL. It's an ugly hack, but it might work.

Related

how to add ocx files in vb4.0 (I am migrating from vb4 to vb6

I am migrating vb4 application to vb6.0 app. I am using windows xp. I want to add ocx controls to the application. Any simple steps to do add ocx controls/files to the application. What are .frm files
Object = "{bla-lablabla-lablabla}#2.0#0"; "THREED20.OCX"
Object = "{blabla-bla-bla-blabla-blablabla}#2.0#0"; "vsview2.ocx"
I want to add these two ocx controls in vb6 ( 16 bit to 32 bit)
You don't state if you already have the OCX files.
To address your first question on how to add OCX controls to your VB6 project. You need to go to Projects -->Components( CtrlT ) then click the Browse button and navigate to where the OCX is located and select it.
As far as the actual OCX Files are concerned there is a Threed20.ocx that is included on the VB6 install media, I believe it is on Disk 2. There is also a registry file that you will need to run to enable design time use of the control. As far as the vsview2.ocx file is concerned if it is not a 32 bit OCX you will need to contact the vendor, who I believe is ComponentSource to get the proper version if you don't currently have it.
And as far is what is a .frm file it is according to this article
A form holds the description of all objects and their properties for each form, as well as the basic code that you have written to respond to the events.

Properties of richtextbox control cannot be set

On one computer 'A' (win vista 32 bit) if I run my program in debug mode all the richtextbox controls throw 'property cannot be set' errors.
I can go on to build the exe (without error ) and the full application OK
But when I then install and run the application on this computer or on computer 'B' (win xp) the same problems occur on both.
However if I run the exact same code in debug mode on computer 'B' there are no errors.
If I build and install the application on computer 'B' it works fine. If I then install this application on computer 'A' it also works fine.
When putting together the application for distribution, both computers use identical copies of richtx32.ocx (it, like the code, is checked out from the same repository).
If I check out previous copies of the code on computer'A' (that used to previously behave OK) they also now exhibit the same problems as the latest version of the code.
I don't have a clue what's going on, please help!
I'm seeing multiple references to the Property cannot be set message being resolved in the version of the Rich Text Control that is distributed in Visual Studio 6.0 Service Pack 4, and another Property cannot be set message fixed in SP5.
First and foremost, make sure that a minimum of SP5 is installed; I'd just go with SP6.
For reference, my Microsoft Rich Textbox Control 6.0 (SP6) is at C:\Windows\System32\RICHTX32.OCX, and is version 6.1.97.82.
I know you said that both machines have the same copy of the control installed; for the sake of completeness, you may want to double-check that the new control was registered after installation.
EDIT:
I exported the HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402} reg key:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}]
#="Microsoft Rich Textbox Control 6.0 (SP6)"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Control]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{0DE86A52-2BAA-11CF-A229-00AA003D7352}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{0DE86A53-2BAA-11CF-A229-00AA003D7352}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{0DE86A57-2BAA-11CF-A229-00AA003D7352}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{40FC6ED4-2438-11CF-A3DB-080036F12502}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{40FC6ED5-2438-11CF-A3DB-080036F12502}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\InprocServer32]
#="C:\\Windows\\system32\\RICHTX32.OCX"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\MiscStatus]
#="0"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\MiscStatus\1]
#="131473"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\ProgID]
#="RICHTEXT.RichtextCtrl.1"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Programmable]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\ToolboxBitmap32]
#="C:\\Windows\\system32\\RICHTX32.OCX, 1"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\TypeLib]
#="{3B7C8863-D78F-101B-B9B5-04021C009402}"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Version]
#="1.2"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\VersionIndependentProgID]
#="RICHTEXT.RichtextCtrl"
A bad richtx32.oca file in the system32 directory seems to have been the cause of this.
Here's what an .oca file does:
Some of the properties of the control are provided by the framework
and some by the control itself. Programmatically, the properties from
the framework and the control all appear as properties of the control.
In order for these properties to appear, Visual Basic creates an
extended type library when the control is loaded into the toolbox.
Because the process of reading the control's type library and creating
the extended type library is time consuming, Visual Basic caches the
extended type library information into an OCA file.
If you delete the OCA file for a control Visual Basic recognized,
Visual Basic will recreate the .OCA file when you load a project
requiring the control. This recreation process comes with a time
penalty.
So it seems that having a bad .oca file in existence can mean that the properties of the control both in the IDE and in the compiled .exe will be affected.
The solution is to delete the .oca file in the system32 folder and then load the project again.

How to avoid crash in MFC SDI application caused by unloaded comdlg32.dll?

We have an application built against MFC9 (VC2008).
The application is an SDI application, and shows a file open dialog during InitInstance(). Showing that dialog causes comdlg32.dll to be loaded. Some minutes later, the comdlg32.dll is unloaded automatically. After this, the next function depending on the DLL will crash.
How can this be avoided? What governs the automatic unloading/loading of the DLL?
Further info:
We don't see this problem on WinXP with the same application.
On Win7, this behavior only occurred since the beginning of this year - maybe some MFC update is related to this?
A small test application does not exhibit the problematic behavior - the comdlg32.dll is re-loaded when needed.
We’ve found a statement by Microsoft that it isn’t recommended to use modal dialogs in InitInstance() of MDI applications (http://support.microsoft.com/kb/173261) - we have an SDI application, though.
We don't directly use comdlg32.dll in any way, only indirectly through the MFC.
You have to call InitCommonControlsEx in your application on startup.
This will initialize the comdlg32.dll and also increase the reference count of the dll, so it won't get unloaded after closing a file-open/save dialog.
You don't say whether you customize your dialog or it is just a straight up file dialog. I think starting with Vista, the common file dialog was changed some. I know if you compare older MFC code with newer, you will see that the MFC code has been changed to take advantage of those changes. For instance, the IFileDialogEvents and IFileDialogControlEvents were implemented in MFC to support the way Vista and later versions of the OS customize file dialogs.
I don't know if I have an answer, but just for grins I would probably make sure I call AfxOleInitialize() sometime in InitInstance() before I tried to call the file dialog.
The other thing I would try for sure (since it works under XP) would be in the constructor of your CFileDialog would be to make sure to set bVistaStyle to FALSE. This ensures m_bVistaStyle is set to FALSE which it is set at when running under XP.

IsWindow(activeX.GetSafeHwnd()) always false after upgrade to VS2010

I have an MFC application that uses an ancient (circa 1999) third-party ActiveX control.
Since upgrading the project from VS2008 to VS2010, I'm having problems...
In the OnSize handler of the parent dialog IsWindow always returns false for the handle returned by control.GetSafeHwnd(), even when GetSafeHwnd() returns a non-NULL value. The rest of the control's parent dialog is displayed fine, but it doesn't seem to respond to any input.
I've seen this article, but GetSafeHwnd() isn't returning NULL in this case (after the first time that it is called, which is before the control is instantiated).
The control does cause the trace message "Control wants to be windowless" to be output when it's loaded. However it also does this when compiled in VS2008, so this may be a red herring. Searching for this message points me to creating a class derived from COleControlSite, and denying the control windowless-ness, but it seems there are no good example of this available, and as I say, it's not clear that this is really the cause of the problem.
I've also found this issue mentioned on MSDN's VS2010 porting page:
"An ActiveX control compiled by using Visual C++ 6.0, when embedded in
a dialog box in a project developed by using Visual C++ 2010, may
cause your program to assert at run time. In this situation, open the
ATL or MFC project associated with the ActiveX control in Visual C++
2010, and recompile it.. The assert will be in the file occcont.cpp,
on this line in source: ASSERT(IsWindow(pTemp->m_hWnd))."
I assume that there's something about VS6-compiled ActiveX controls that causes the window handles to be treated as invalid by the current Win32 implementation of IsWindow. The suggested solution is of course unhelpful as it's a third-party control, and we can't recompile it.
Has anyone managed to get around this?
I've already found solutions for VS2010 projects not running on Windows 2000, and errors linking to ODBC, but don't seem to be able to find anything on this one.
Thanks,
Chris
I didn't find a solution to this in the end - upgraded the controls to a VS2010-compatible version.
For what it's worth: if you don't care whether the control will appear transparent or not, you may force the control to have a window anyway - even though it can operate without a window.
You see, the ActiveX control must first ask the container (the window which will host the control) if it's okay to be activated without a window. This is simply because not all containers support windowless activation.
If this interface (IOleInPlaceSiteWindowless) returns okay then it proceeds with this special windowless activation, if not a window will be created for the control as normal.
Disclaimer:
I don't know if this 'unnecessary' window will make the assertion failure go away. In other words: I don't know if the window handle is passed down 'deep' enough into the AX control.
More about the IOleInPlaceSiteWindowless interface:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682300(v=vs.85).aspx

How to display managed control on native window?

Using C++/CLI, How to display a managed control (eg. System::Windows::Forms::Panel^) on a window created in native code?
An external program calls my native method where i can access it's window via
SubclassWindow(hNativeWindow, MyNativeWindowProc);
Then I create control with something similar to:
MyNameSpace::MyControl^ ctrl = osozKomunikator = gcnew MyControl("SomeText", hNativeWindow);
ctrl->Show();
MyControl is derived from System::Windows::Forms::UserControl and has overriden CreateParams to set Parent to hNativeWindow.
As the result the control flashes and dissapears, does not show at all or shows only after I slow down the execution with the debugger.
Please help.
Windows Forms supports being hosted like ActiveX in native windows since .Net 1.1. The host needs to implement some interfaces, though. MFC 8.0 wrapped around the necessary code in CWinFormsDialog and CWinFormsView. Use MFC's support classes if you can. If you can not, install MFC from Visual C++ 2005 or higher and check the source code of MFC's OLE support classes, like COleControlContainer, COleControlSite, etc.

Resources