| Introduction |
|
1 | (1) |
|
|
|
1 | (1) |
|
What's Covered in this Book? |
|
|
1 | (1) |
|
What Do I Need to Use this Book? |
|
|
2 | (1) |
|
|
|
3 | (1) |
|
|
|
3 | (4) |
|
How to Download the Sample Code for the Book |
|
|
4 | (1) |
|
|
|
4 | (1) |
|
|
|
4 | (1) |
|
|
|
5 | (1) |
|
Why this System Offers the Best Support |
|
|
5 | (2) |
|
The Importance of Interoperability |
|
|
7 | (12) |
|
Going Forward with Visual Basic .NET |
|
|
8 | (1) |
|
Two Strategies - Migration and Interoperability |
|
|
8 | (1) |
|
|
|
8 | (5) |
|
Major Areas of Incompatibility Between VB6 and Visual Basic .NET |
|
|
9 | (1) |
|
|
|
9 | (1) |
|
Changes Related to Object-Oriented Programming |
|
|
10 | (1) |
|
Radically Different Means for Creating a Web Interface |
|
|
11 | (1) |
|
Functionality Moved from Keywords to the Underlying Framework |
|
|
11 | (1) |
|
Removal of Obsolete Syntax |
|
|
11 | (1) |
|
Good Candidates for Migration to Visual Basic .NET |
|
|
12 | (1) |
|
Bad Candidates for Migration |
|
|
12 | (1) |
|
|
|
12 | (1) |
|
Implications for Interoperability |
|
|
13 | (1) |
|
Design Situations that Need Interoperability |
|
|
13 | (2) |
|
|
|
13 | (1) |
|
|
|
14 | (1) |
|
|
|
14 | (1) |
|
|
|
15 | (1) |
|
Distributed Processing of Data |
|
|
15 | (1) |
|
Major Areas of Interoperability |
|
|
15 | (2) |
|
Calling COM Components from .NET |
|
|
16 | (1) |
|
Calling .NET Components from COM |
|
|
16 | (1) |
|
Sharing Data Access Between Old Code and New |
|
|
16 | (1) |
|
Sharing Configuration Information |
|
|
17 | (1) |
|
Calling Non-COM DLLs with Static Entry Points |
|
|
17 | (1) |
|
|
|
17 | (2) |
|
Using COM Components from .NET |
|
|
19 | (58) |
|
|
|
20 | (12) |
|
|
|
20 | (1) |
|
|
|
20 | (1) |
|
|
|
21 | (1) |
|
|
|
22 | (1) |
|
Sub, Function, and Property Methods |
|
|
23 | (2) |
|
|
|
25 | (1) |
|
|
|
25 | (5) |
|
|
|
30 | (1) |
|
|
|
31 | (1) |
|
|
|
32 | (17) |
|
|
|
32 | (1) |
|
|
|
33 | (3) |
|
|
|
36 | (3) |
|
Primary Interop Assemblies |
|
|
39 | (5) |
|
|
|
44 | (4) |
|
|
|
48 | (1) |
|
|
|
48 | (1) |
|
.NET System Class Library Support |
|
|
48 | (1) |
|
|
|
49 | (26) |
|
|
|
49 | (1) |
|
|
|
50 | (2) |
|
|
|
52 | (1) |
|
|
|
53 | (1) |
|
|
|
54 | (1) |
|
Late Binding with a Wrapper Assembly |
|
|
55 | (1) |
|
Late Binding with Dynamic Creation |
|
|
56 | (1) |
|
Manual Invocation of Methods |
|
|
57 | (1) |
|
|
|
58 | (3) |
|
|
|
61 | (2) |
|
|
|
63 | (1) |
|
|
|
64 | (1) |
|
|
|
64 | (2) |
|
Inspecting a COM Component from .NET |
|
|
66 | (1) |
|
|
|
66 | (3) |
|
|
|
69 | (2) |
|
|
|
71 | (2) |
|
|
|
73 | (2) |
|
|
|
75 | (2) |
|
Using .NET Assemblies from COM |
|
|
77 | (50) |
|
|
|
78 | (22) |
|
|
|
78 | (1) |
|
|
|
78 | (1) |
|
Controlling Object Creation |
|
|
79 | (2) |
|
Adding Methods to the Class |
|
|
81 | (2) |
|
|
|
83 | (1) |
|
|
|
84 | (1) |
|
|
|
85 | (2) |
|
|
|
87 | (1) |
|
|
|
88 | (1) |
|
|
|
89 | (1) |
|
Using the <ComClass()> Attribute |
|
|
90 | (1) |
|
Applying the <ComClass()> Attribute |
|
|
90 | (1) |
|
|
|
90 | (2) |
|
|
|
92 | (1) |
|
Exposing the Class Manually |
|
|
92 | (1) |
|
Understanding Interfaces and Classes |
|
|
93 | (7) |
|
Registering .NET Assemblies with COM |
|
|
100 | (7) |
|
|
|
101 | (1) |
|
|
|
102 | (1) |
|
Using Command-Line Utilities |
|
|
103 | (1) |
|
|
|
104 | (1) |
|
Registering the Assembly Directly |
|
|
105 | (1) |
|
Inserting the Assembly into the GAC |
|
|
106 | (1) |
|
Generating the Type Library Only |
|
|
107 | (1) |
|
Using .NET Objects from COM and Windows |
|
|
107 | (18) |
|
|
|
108 | (1) |
|
|
|
109 | (1) |
|
Creating an Instance of the Class |
|
|
109 | (1) |
|
Calling Methods and Properties |
|
|
110 | (2) |
|
|
|
112 | (1) |
|
|
|
113 | (1) |
|
Creating an Instance of the Class |
|
|
113 | (1) |
|
Specialized Types Unavailable |
|
|
114 | (1) |
|
|
|
115 | (1) |
|
Dealing with Locked Files |
|
|
115 | (1) |
|
|
|
115 | (1) |
|
Implementing a Dispose Method |
|
|
116 | (1) |
|
|
|
117 | (1) |
|
Multiple and Default Interfaces |
|
|
117 | (1) |
|
Implementing a Secondary Interface |
|
|
118 | (2) |
|
Changing the Default Interface |
|
|
120 | (1) |
|
Inspecting a .NET Assembly from COM |
|
|
121 | (1) |
|
|
|
121 | (1) |
|
Using the TypeLib Information Component |
|
|
122 | (3) |
|
|
|
125 | (2) |
|
Calling COM Components in MTS and COM+ from .NET |
|
|
127 | (60) |
|
|
|
128 | (32) |
|
Creating a COM+ Component |
|
|
129 | (1) |
|
|
|
129 | (1) |
|
|
|
130 | (2) |
|
Taking Advantage of COM+ Transactions |
|
|
132 | (4) |
|
|
|
136 | (1) |
|
Putting the DLL into COM+ |
|
|
137 | (5) |
|
Calling COM+ Components from Visual Basic .NET |
|
|
142 | (1) |
|
|
|
143 | (5) |
|
|
|
148 | (2) |
|
|
|
150 | (1) |
|
Creating a Queued Component in VB6 |
|
|
151 | (6) |
|
Calling the Queued Component from Visual Basic .NET |
|
|
157 | (3) |
|
|
|
160 | (14) |
|
Using ADO Recordset Objects |
|
|
161 | (4) |
|
|
|
165 | (3) |
|
|
|
168 | (6) |
|
Calling .NET Components in COM+ from VB6 |
|
|
174 | (10) |
|
Creating a COM+ Component in .NET |
|
|
175 | (1) |
|
|
|
176 | (2) |
|
|
|
178 | (3) |
|
Registering the Assembly with COM+ |
|
|
181 | (1) |
|
Making the Class Available to COM Clients |
|
|
182 | (1) |
|
|
|
183 | (1) |
|
|
|
183 | (1) |
|
|
|
184 | (3) |
|
Visual Basic .NET and COM in COM+ |
|
|
187 | (28) |
|
|
|
188 | (1) |
|
Creating an ActiveX DLL for COM+ |
|
|
188 | (5) |
|
Registering the DLL in COM+ |
|
|
193 | (3) |
|
Creating a VB6 Test Application |
|
|
196 | (1) |
|
COM+ and Visual Basic .NET |
|
|
197 | (5) |
|
Registering the DLL in COM+ |
|
|
202 | (2) |
|
Creating a Visual Basic .NET Test Application |
|
|
204 | (2) |
|
Calling VB6 Components from Visual Basic .NET in COM+ |
|
|
206 | (3) |
|
Calling Visual Basic .NET Components from VB6 in COM+ |
|
|
209 | (3) |
|
|
|
212 | (3) |
|
|
|
215 | (48) |
|
The Four Different Methods of Marshaling |
|
|
216 | (6) |
|
Type I Marshaling: Using Tibimp.exe |
|
|
216 | (2) |
|
Type II Marshaling (Simple Data Type Marshaling): Adding Attributes to the Interface to Use a Standard Type |
|
|
218 | (1) |
|
Type III Marshaling: Marshaling into a Custom Data Structure to be Passed Between COM and .NET |
|
|
219 | (1) |
|
Type IV Marshaling: Implementing the ICustomMarshaler Interface |
|
|
220 | (2) |
|
|
|
222 | (1) |
|
|
|
222 | (12) |
|
|
|
222 | (1) |
|
|
|
223 | (1) |
|
Using Ildasm or Ilasm with Type II Marshaling |
|
|
224 | (1) |
|
Create the VB6 COM Component |
|
|
225 | (1) |
|
Use Tlbimp to Create the Runtime-Callable Wrapper |
|
|
226 | (1) |
|
Use Ildasm to Create the Intermediate Language Code |
|
|
226 | (1) |
|
Modify the IL to use Booleans Instead of Integers |
|
|
226 | (5) |
|
Create the New Runtime-Callable Wrapper |
|
|
231 | (1) |
|
Make a New Managed Project to Use Our Modified RCW |
|
|
231 | (2) |
|
|
|
233 | (1) |
|
|
|
234 | (13) |
|
|
|
235 | (1) |
|
|
|
236 | (1) |
|
Create the Runtime Callable Wrapper |
|
|
237 | (1) |
|
Make a New Managed Project |
|
|
237 | (2) |
|
Modify the Runtime-Callable Wrapper to Return a Usable Type |
|
|
239 | (3) |
|
Finish the Managed Interface |
|
|
242 | (5) |
|
|
|
247 | (12) |
|
|
|
247 | (1) |
|
The ICustomMarshaler Interface |
|
|
248 | (1) |
|
Create an Unmanaged COM Component |
|
|
248 | (3) |
|
Create the Managed Person Class and the Custom Marshaler |
|
|
251 | (4) |
|
Modify the Marshal Attributes on the Runtime-Callable Wrapper |
|
|
255 | (2) |
|
Create an Interface to Test the Marshaler |
|
|
257 | (2) |
|
Managed Code to Unmanaged Code |
|
|
259 | (1) |
|
|
|
260 | (3) |
|
|
|
263 | (24) |
|
|
|
264 | (5) |
|
|
|
265 | (1) |
|
Using Single versus Multi-Threading |
|
|
266 | (1) |
|
|
|
267 | (2) |
|
Threading in Visual Basic .NET |
|
|
269 | (1) |
|
|
|
269 | (14) |
|
|
|
270 | (1) |
|
Calling Multiple COM Components from .NET |
|
|
270 | (2) |
|
Calling VB6 Components from a Multi-Threaded .NET Application |
|
|
272 | (9) |
|
Calling ActiveX EXE Components from Visual Basic .NET |
|
|
281 | (1) |
|
Calling VB6 Components from ASP.NET |
|
|
282 | (1) |
|
|
|
283 | (1) |
|
|
|
283 | (4) |
|
DCOM, Remoting, and Web Services |
|
|
287 | (32) |
|
|
|
287 | (1) |
|
|
|
288 | (1) |
|
|
|
289 | (1) |
|
XML Web Services and Interop |
|
|
290 | (12) |
|
|
|
290 | (1) |
|
Creating the Web Service in VB6 |
|
|
290 | (5) |
|
|
|
295 | (2) |
|
|
|
297 | (1) |
|
Creating the XML Web Service |
|
|
298 | (2) |
|
|
|
300 | (2) |
|
.NET Remoting and Interop |
|
|
302 | (14) |
|
|
|
303 | (1) |
|
Creating the Wrapper Project |
|
|
304 | (1) |
|
Hosting the Wrapper Assembly for Remoting |
|
|
305 | (4) |
|
Creating a Remoting Client |
|
|
309 | (3) |
|
|
|
312 | (1) |
|
|
|
313 | (2) |
|
|
|
315 | (1) |
|
|
|
316 | (3) |
|
Sharing Configuration Information |
|
|
319 | (18) |
|
|
|
320 | (6) |
|
The Structure of an INI File |
|
|
320 | (1) |
|
Accessing INI Files in VB6 |
|
|
321 | (3) |
|
Accessing INI Files in Visual Basic .NET |
|
|
324 | (2) |
|
Using the Windows Registry to Store Configuration Settings |
|
|
326 | (2) |
|
XML-Based Configuration Files |
|
|
328 | (7) |
|
Accessing XML Configuration Info with the .NET Framework Classes |
|
|
329 | (1) |
|
Accessing Settings Using System.XML in Visual Basic .NET |
|
|
330 | (2) |
|
Accessing Settings Using MSXML in VB6 |
|
|
332 | (3) |
|
|
|
335 | (1) |
|
|
|
335 | (2) |
|
|
|
337 | (20) |
|
Random Access to Flat Files |
|
|
338 | (7) |
|
|
|
338 | (2) |
|
Using FreeFile to Get the File Number |
|
|
340 | (1) |
|
Random Access in Visual Basic .NET |
|
|
341 | (1) |
|
Replacements for File Access Keywords |
|
|
341 | (2) |
|
Structures Replace UDTs in Visual Basic .NET |
|
|
343 | (1) |
|
Handling Fixed Length Strings in Visual Basic .NET |
|
|
344 | (1) |
|
|
|
344 | (1) |
|
Binary Acces to Flat Files |
|
|
345 | (5) |
|
|
|
345 | (3) |
|
Binary Access in Visual Basic .NET |
|
|
348 | (2) |
|
|
|
350 | (2) |
|
|
|
350 | (1) |
|
Sequential Access in Visual Basic .NET |
|
|
351 | (1) |
|
Streams as an Alternative in Visual Basic .NET |
|
|
352 | (3) |
|
Sequential Access with Streaming Techniques |
|
|
353 | (1) |
|
Binary Access with Streaming Techniques |
|
|
354 | (1) |
|
|
|
355 | (2) |
|
|
|
357 | (12) |
|
Comparison Between ADO and ADO.NET |
|
|
357 | (4) |
|
ADO Advantages and Disadvantages |
|
|
358 | (1) |
|
When is ADO Still Needed in .NET? |
|
|
359 | (1) |
|
ADO.NET Only Has Optimistic Concurrency |
|
|
359 | (1) |
|
ADO Supports Pessimistic Concurrency |
|
|
359 | (1) |
|
ADO.NET Does Not Support Most Cursors |
|
|
360 | (1) |
|
ADO Supports a Variety of Cursors, Including Server.Side |
|
|
360 | (1) |
|
|
|
361 | (5) |
|
ADO Code in Visual Basic .NET |
|
|
362 | (1) |
|
|
|
362 | (1) |
|
Problems in Setting Some ADO Properties to Strings |
|
|
363 | (1) |
|
Converting an ADO Recordset into an ADO.NET DataSet |
|
|
364 | (2) |
|
|
|
366 | (1) |
|
|
|
367 | (2) |
|
Calling API or Static DLL Functions from .NET |
|
|
369 | (16) |
|
Reduced Need for Using DLLs with Static Entry Points in .NET |
|
|
370 | (3) |
|
Reduced Need for Access to Windows API |
|
|
370 | (3) |
|
|
|
373 | (1) |
|
Platform Invocation Services |
|
|
373 | (7) |
|
|
|
373 | (1) |
|
|
|
374 | (1) |
|
|
|
375 | (1) |
|
Passing Structures as parameters |
|
|
375 | (2) |
|
Example of an API with a Structure Parameter |
|
|
377 | (1) |
|
|
|
378 | (1) |
|
|
|
378 | (1) |
|
Using Automatic ANSI/Unicode Location |
|
|
379 | (1) |
|
|
|
380 | (1) |
|
Control Over Data Marshaling |
|
|
380 | (1) |
|
Using DLLImport Instead of Declare |
|
|
380 | (1) |
|
Performance Considerations |
|
|
381 | (1) |
|
|
|
382 | (3) |
|
Interoperability of ActiveX Controls in .NET |
|
|
385 | (10) |
|
When to Use ActiveX Controls in .NET |
|
|
386 | (1) |
|
The Differences Between Windows Forms Controls and ActiveX Controls |
|
|
387 | (1) |
|
|
|
387 | (1) |
|
Hosting an ActiveX Control in .NET |
|
|
387 | (5) |
|
Example - Windows Media Player Control |
|
|
388 | (2) |
|
|
|
390 | (1) |
|
Custom Property Moved from Properties List |
|
|
390 | (1) |
|
Creating a Wrapper with Aximp.exe |
|
|
390 | (1) |
|
Importing VB6 UserControls |
|
|
391 | (1) |
|
Controls that Cannot be Imported |
|
|
391 | (1) |
|
|
|
391 | (1) |
|
.NET Windows Forms Controls in VB6 |
|
|
392 | (1) |
|
|
|
392 | (3) |
|
How Do I Prepare VB6 Code for Migration? |
|
|
395 | (9) |
|
Stop Using Default Properties and Methods |
|
|
396 | (1) |
|
Avoid Non-Zero Lower Bounds for Arrays |
|
|
396 | (1) |
|
Make All Parameters Explicitly ByRef or ByVal |
|
|
397 | (1) |
|
Place Default Values on All Optional Parameters |
|
|
397 | (1) |
|
Declare All Variables on a Seprate Line |
|
|
398 | (1) |
|
Be Careful Where You Declare Variables |
|
|
398 | (1) |
|
Avoid Fixed Length Strings in UDTs |
|
|
399 | (1) |
|
Get Rid of Obsolete Keywords |
|
|
400 | (1) |
|
Remove Implicit Object Instantiation |
|
|
400 | (1) |
|
Stop Implicit Loading of Forms |
|
|
401 | (1) |
|
Switch Data Binding to ADO |
|
|
402 | (1) |
|
Use Intrinsic Constants Whenever Possible |
|
|
402 | (1) |
|
Stop Writing DHTML Pages and WebClasses |
|
|
403 | (1) |
|
|
|
403 | (1) |
|
Get Your Logic Out of the UI and Into Components and Classes |
|
|
404 | (1) |
|
|
|
404 | (1) |
|
|
|
404 | |