Preface
In the past few weeks of work, I have been troubled by a headache problem, that is, the ActiveX control written in VB6 has many strange problems in the Delphi environment. After many twists and turns, I finally searched almost all forums and information. , found solutions to problems that occur in different Delphi versions.
One of the inexplicable fatal exceptions in Delphi5
First, let's take a look at the strange behavior of ActiveX controls written in VB under Delphi5.
For example: We used VB to write a control UserTest (for simplicity, we only export one class, the user control), a property TestName, and a method TestMethod. Then compile it into an ActiveX control, register and import it into the Delphi5 development environment (if there is anything unclear about the above steps, please check various reference materials, there must be standard answers), so far, everything seems to be normal.
Then, we are accustomed to dragging and dropping controls onto the form, resizing them, and assigning values to properties in the properties window, or the same in code. It is very normal and easy to use. However, here comes the problem. If you call that TestMethod with enthusiasm, you will get a weird exception "OleError800a01a9", and then the program will exit. Unfortunately, you will not be able to track this exception. In Delphi Either in VB or in VB. Of course, if you are good at assembly, you can follow the Delphi debugging window step by step...
When I first encountered this problem, I was almost angry because neither Microsoft nor Borland had any explanation for the error, nor any information to find. I had to go to several forums that I frequented, of course the most important one was CSDN, and searched for similar questions in the VB version and Delphi version. Unfortunately, there were only similar questions but no answers. A big customer Using this development tool, after testing almost all development tools and development environments on Windows (including desktop and WEB), I forgot about Delphi.
In the remaining two days, I almost ran around the world, calling all my friends and asking if Delphi experts knew about this situation. Finally, I found a link from Google. Unfortunately, I have forgotten it now. The exact location of that link, but I got an almost Magic method (that's what the discoverer calls it):
A method of manually modifying the proxy type library XXX_TLB.PAS (where XXX refers to the class name of the control) file generated by Delphi after importing the VBActiveX control can solve this problem. Example:
There is a control UserControl1 written in VB. After importing it in Delphi, two files are generated. One of them, UserControl1_TLB.PAS, is the file we want to modify.
Find something like this in a file
FintF:_UserControl1;
FunctionGetControlInterface:_UserControl1;
and
PRopertyControlInterface:_UserControl1readGetControlInterface;
GetControlInterface;
as well as
procedureTUserControl1.CreateControl;
procedureDoCreate;
begin
Finf:=IUnknown(OleObject)as_UserControl1;
End;
Begin
IfFinf=nilthenDoCreate;
End;
FunctionTUserControl1.GetControl1Interface:_UserControl1;
Begin
CreateControl;
Result:=Finfl;
End;
Please note: All the _UserControl1 marked in red here must be replaced with _UserControl1Disp. If the compilation is unsuccessful, please replace all the _UserControl1 reported in the compilation warning with _UserControl1Disp and compile. This way when calling the control method The above fatal error will not occur.
Thanks for this great discovery, I can only describe it like this, otherwise I might still be stuck in this circle, or I would have to use another tool to re-develop this control (I can’t imagine how much work this will be, and Or it may have other compatibility issues).
Delphi5 inexplicable fatal exception 2
However, Delphi did not let me go after I circumvented this restriction. Soon, the customer discovered another troublesome problem. In the development environment, an exception would pop up every time the form containing the control was closed at runtime. Error, but it will not happen in the compiled application. Although it will not affect the use of end users, it is a big trouble for developers. Then I tried it using the above example and found that it did not happen. This question. (I went crazy at the time. This was probably caused by some incompatible usage in the code. It was extremely scary to find out whether tens of thousands of lines of code were regular in a day.) In a fit of anger, I blocked the control in my control. All the code, leaving only the user interface itself, and then something strange happened, I didn't write any code, but This error still occurs when loading my control, which makes me happy and surprised. The happy thing is that this problem has nothing to do with my code, so it will be much easier to find. The surprising thing is that it only involves dragging and dropping a few standards in VB. Controls can actually cause such horrible errors. The contradiction between Delphi5 and VB6 is really not that deep. In the next 2 hours, I continued to delete controls on the interface to test who caused this fatal exception.
After 2 hours, I breathed a sigh of relief and found the problem. The fundamental problem is:
If you use container controls like Frame and PictureBox (which can contain other controls inside) in VB user controls, you will not be able to add windowLess controls such as Label, Line, and Image to these controls (that is, no Window controls, they are drawn by VB in real time during runtime), otherwise you will get the error report like the above.
Hidden ActiveX controls in Delphi6 and 7
Precisely because of the horrible experience under Delphi5, I found it still necessary to test whether the same problem exists under Delphi6 and 7 (the previous version is no longer necessary because there are very few users, and Delphi8 has not been officially released yet, so it is not available for the time being. are not considered). The result is: ...no matter how many times I load it, I never find that long-awaited little icon on the ActiveX bar. This result is of course very funny. I can't even load it, let alone whether the test is normal or not.
Similarly, I searched various forums and websites, and found more people asking similar questions in CSDN, but the answer was still zero. In desperation, I had to adjust the options in each Delphi6 and 7...
After 3 hours, 15 minutes and 54 seconds, I found the cause, or the solution, of this damn problem (please forgive me for calling it that, I just couldn’t bear it), which is actually very simple.
Now please follow me: click the Tools menu->EnvironmentOptions->TypeLibrary page, we should find an item: IgnorespecialCoClassFlagsWhenImporting, select it, and then select the CanCreate item, so now, let's try to import that poor ActiveX control (It should be noted here that if you have imported it once, please delete the two generated files, .dcr and .pas files, otherwise it will not be refreshed). If you still can't find the control in the ActiveX column this time, then you have to call Microsoft or Borland and ask when they can get married, haha!
(Also, the above errors that appeared in Delphi5 were not found in Delphi6 and 7)
My test environment is:
Win2K
Delphi5Update1
Delphi6Update2
Delphi7