Andreas Kosch COM/DCOM/COM+ mit Delphi Software & Support Verlag GmbH Frankfurt, 2000
Inhaltsverzeichnis VORWORT 15 1 STANDORTBESTIMMUNG 17 1.1 DER URSPRUNG 17 1.2 WAS HABE ICH ALS ENTWICKLER VON COM? 21 1.3 WO WIRD COM EINGESETZT? 22 1.4 EIGENE COM-SERVER ENTWICKELN... 24 1.4.1 Delphi-3/4-Beispiel: In-process Server Step by Step 25 1.4.2 Delphi-3/4-Beispiel: Local Server Step by Step 39 1.4.3 Delphi-5-Beispiel: Automation-Server mit Events 39 1.5 BEISPIEL: WINDOWS SCRIPTING HOST 45 1.5.1 Beispiel: Windows Scripting Host und COM+ 46 1.5.2 Beispiel: Windows Scripting Host undadsi 46 1.6 DELPHI-TOOLS 47 1.6.1 Delphi's Typbibliothekseditor 47 1.6.2 Welche Darstellung verwenden? 53 1.6.3 TLIBIMP.EXE 55 1.6.4 TREGSRV.EXE - Borland Turbo-Registrierungs-Server 56 1.7 DAS DOKUMENTATIONS-PROBLEM 56 1.8 WIE GEHT'S WEITER? 59 2 COMPONENT OBJECT MODEL 61 2.1 WAS IST EIN OBJEKT? 61 2.2 WARUM COM? 62 2.3 SERVER UND CLIENT 65 2.3.1 In-process Server 66 2.3.2 Local Server 68 2.3.3 Remote Server 69 2.3.4 COM-Handler 71 2.3.5 Der technische Unterschied 71 2.4 COM-lNTERFACE 72 2.4.1 Interface als binärer Standard 72 2.4.2 Interface- Vorläufer - Objekt aus einer DLL exportieren 74 2.4.3 IUnknown 80 2.4.4 Dispinterface IDispatch 98 2.4.5 Sonderfall Dispinterface mit feststehenden DispIDs 706 2.4.6 Dual Interface 108 2.4.7 Vergleich IDispatch und Dual Interface 111 2.4.8 VTABLE-Interface 113 2.4.9 Mehrere Interface-Versionenl 113
2.4.10 Mehrfachvererbung in Object Pascal durch Interfaces? 116 2.5 COM IDENTIFIER 121 2.6 COM CLASS 124 2.6.1 Die COM-Class-Alternativen von Delphi 725 2.6.2 Kein Server von der Stange! 727 2.6.3 Object Interface am Beispiel TInterfacedObject 133 2.7 CLASS OBJECT UND CLASS FACTORY 135 2.7.7 Delphi erzeugt eine Server-Instanz 137 2.7.2 Class Factory 139 2.7.3 Die vordefinierten Class Factories 742 2.8 COL - COMPONENT OBJECT LIBRARY 142 2.8.1 Eine Instanz einer COM Class wird angefordert 143 2.8.2 COM und die Registry 144 2.9 TYPE LIBRARY - DIE TYPBIBLIOTHEK DES COM-OBJEKTS 146 2.9.7 Beispiel für das Beschreiben von DLL-Funktionen 146 2.9.2 Typbibliothekßr COM-Server. 750 2.9.3 Elemente der Typbibliothek 752 2.9.4 Enumerated Types in der Typbibliothek 755 2.9.5 Zweite Typbibliothek für das Callback-Interface 758 2.9.6 Registrieren oder nicht registrieren? 767 2.9.7 Server-Registrierung unter Delphi 762 2.9.8 Die Registry und die Typbibliotheken 766 2.10 COM OBJECT ALS INSTANZ DER COM CLASS 167 2.11 MARSHALER UND APARTMENTS 168 3 COM OBJECT - INSTANZ DER COM CLASS 169 3.1 EINFACHE VS. MEHRFACHE INSTANZ 170 3.2 WAS BEIM DELPHI-EXPERTEN FEHLT 172 3.3 SINGLETON SERVER 175 3.4 RUNNING OBJECT TABLE (ROT) 177 3.4.1 Moniker 777 3.4.2 Beispiel für einen ROT-Server 779 3.4.3 Inhalt der ROT auslesen 787 3.5 TOLESERVER.CONNECTKIND 184 3.6 STARTMODE SMSTANDALONE 185 3.7 FORMULARLOSE COM-SERVER 186 3.8 CLIENTS ALS KONSOLENANWENDUNG 187 4 MARSHALER UND APARTMENTS 191 4.1 PROZESSE UND THREADS - EINE KURZEINFÜHRUNG 191 4.2 MARSHALER 192 4.2.7 Praktische Auswirkungen 193 4.2.2 COM als Programmiermodell 797 4.2.3 Standard- vs. Custom-Marshaling 799 4.2.4 Standard-Marshaler 200
4.3 APARTMENT UND THREADING MODEL 203 4.3.1 COM und Threads 206 4.3.2 Warum sind Threading-Modelle notwendig? 207 4.4 SlNGLE-THREADED APARTMENT (STA) 207 4.4.7 Single-threading Model 270 4.4.2 Regeln für Single-threaded Apartments (STA) 277 4.5 MULTI-THREADED APARTMENT (MTA) 217 4.6 WER DIE WAHL HAT, HAT DIE QUAL 218 4.7 MARSHALING AUS SICHT DER API-FUNKTIONEN 219 4.7.7 IStream 220 4.7.2 CoMarshallnterface und CoUnmarshallnterface 227 4.7.3 In-process-Helfer für den Marshaler 222 4.7.4 Global Interface Table (GIT) 224 4.8 PRAKTISCHE VERSUCHE 226 4.8.1 STA - Zugriff auf einen Local Server 226 4.8.2 STA - Zugriff auf einen In-process Server 230 4.8.3 STA: Server muss seine globalen Daten schützen 232 4.8.4 STA: Thread muss Windows-Botschaften verteilen 235 4.8.5 MTA - Zugriff auf einen In-process Server 239 4.8.6 Unterschiede der Threading-Beispiele 242 4.9 PRAXISBEISPIEL STA-MULTITHREAD-SERVER FSOBJ 246 4.9.7 Server-Implementierung 247 4.9.2 Client-Implementierung 257 4.9.3 Testergebnisse 254 4.9.4 Sink-Objekt des Clients in einem eigenen Thread 255 4.10 ZUSAMMENFASSUNG 259 4.11 FEHLT DA WAS? 260 5 HRESULT UND SAFECALL 261 5.1 HRESULT 261 5.7.7 Exceptions in einer Interface-Methode? 262 5.1.2 HRESULT-Außau 263 5.1.3 HRESULT-Wert auswerten und erzeugen 265 5.1.4 OleCheck 266 5.2 SAFECALL 267 5.2.7 Das Problem 269 5.2.2 Ein praktisches Beispiel 270 5.2.3 Der Haken an der Sache mit SafeCall 274 5.2.4 SafeCall - ein Blick hinter die Kulissen 275 5.2.5 ServerExceptionHandler 276 5.3 SAFECALL FÜR NICHT-COM-ANWENDUNGEN? 279 5.4 EOLESYSERROR 282 6 AGGREGATION UND CONTAINMENT 285 6.1 NATIVE AGGREGATION 286
6.2 INTERFACE-METHODEN-MAPPING 291 6.3 IMPLEMENTS 292 6.3.1 Einfaches Aggregations-Beispiel 293 6.3.2 Komplexes Aggregations-Beispiel 298 DATENAUSTAUSCH 309 7.1 ISTREAM 309 7.2 ISTRINGS 312 7.2.7 Ein Beispiel 572 7.2.2 IStrings intern 316 7.2.3 Fehlt da nicht etwas? 322 7.3 IFONT UND IFONTDlSP 323 7.4 IPICTUREDISP 326 7.5 VARIANT-ARRAY 328 Z5.7 Variant 328 7.5.2 Was ist ein Variant-Array? 331 7.5.3 TMemo-Inhalt als Variant-Array 335 7.5.4 TStrings als Variant-Array 338 7.5.5 Beispielprojekt Records als Variant-Array 342 7.5.6 TStream als VariantArray verpackt 344 7.6 PSAFEARRAY 346 7.6.7 VarArrayRef. 348 7.6.2 Einsatzbeispiel: Interne Verwendung 350 7.6.3 Einsatzbeispiel: Local Server fordert Speicher an 352 7.7 JPG-GRAFIK ALS WIDESTRING ÜBERTRAGEN 355 7.8 USER DEFINED TYPES (UDT) UND DELPHI 359 7.9 USER DEFINED TYPES (UDT) VIA IRECORDINFO 362 7.10 IMALLOC 371 7.10.1 Das erste Beispielprogramm 373 7.10.2 Das zweite Beispielprogramm 374 7.11 COTASKMEMALLOC 376 7.12 IENUMSTRING 379 7.13 IENUMVARIANT 383 7.14 OPTIONALE PARAMETER 388 7.15 IDATAOBJECT 389 7.75.7 IDataObject-Grundlagen 390 7.15.2 Das Beispielprojekt 392 7.16 ADO-RECORDSET 396 7.76.7 Warum ADO? 397 7.16.2 OLE DB 399 7.16.3 ADO 2.1 - die Bestandteile 407 7.16.4 ADO-Programmiermodell 407 7.16.5 Das Recordset-Beispielprojekt 406 7.16.6 Das Stream-Objekt von ADO 2.5 470 7.76.7 RDS - das Borland-Beispiel wird erweitert. 413
8 CALLBACK VS. CONNECTION POINT 417 9 OBJEKTMODELLE 419 9.1 EINFACHES BEISPIEL MIT FESTER OBJEKTANZAHL 419 9.2 KOMPLEXES BEISPIEL MIT VARIABLER OBJEKTANZAHL 426 9.3 FEINTUNING - AUS TAUTOOBJECT WIRD TAUTOINTFOBJECT 435 9.4 UMBAU ZUM DCOM-SERVER 437 10 COM UND DAS BETRIEBSSYSTEM 445 11 OLE - DER URSPRUNG VON COM 447 12 AUTOMATION 449 12.1 WAS IST zu TUN? 450 12.2 EIGENEN AUTOMATION-SERVER ENTWICKELN 452 12.2.1 Schritt 1: Anwendungsprogramm 452 12.2.2 Schritt 2: Automatisierungsobjekt. 453 12.2.3 Schritt 3: Client 455 12.2.4 Schritt 4: Running Object Table (ROT) 457 12.2.5 Schritt 5: Client nutzt die ROT aus 458 12.3 DAS OBJEKTMODELL VON MICROSOFT WORD 459 72.5.7 Was ist ein Objektmodell? 459 12.3.2 Wie finde ich das richtige Objekt? 462 12.3.3 Delphi als Automation-Controller 466 12.3.4 Global-Objekt 476 12.3.5 Application-Objekt 476 12.3.6 Document-Objekt 478 12.3.7 Range-Objekt 480 12.3.8 Selection-Objekt '. 482 12.3.9 Word als Report-Engine 483 12.3.10 Delphi und die Datentypen von VBA 485 12.3.11 Stolperstellen 485 12.4 TOLESERVER - NEUES IN DELPHI 5 487 72.4.7 TWordApplication und TWordDocument 488 12.4.2 TWordApplication und Threads 497 12.5 NEUES IN MICROSOFT WORD 2000 493 12.5.1 Komponenten für Office 2000 installieren 494 12.5.2 Überladene Interface-Methoden 496 12.5.3 COM Add-Inför Word 2000 497 12.6 DELPHI 5 UND MICROSOFT OFFICE 2000 505 12.6.1 Text über Bookmarks einfügen 505 12.6.2 Der Serienbrief in Word 2000 506 12.6.3 Word 2000 und das Internet v 508 12.6.4 Das FileSearch-Objekt 570 72.6.5 Office Assistant 572
12.6.6 Makro, Menü und Toolbar konfigurieren 576 12.7 CONTROLLER FÜR WORD 95 UND WORD 97/2000? 521 12.8 BEISPIELE MIT MICROSOFT EXCEL 2000 527 72.8.7 Das Objektmodell von Excel 2000 528 12.8.2 Zellen auslesen und mit den Daten füllen 529 12.8.3 Excel 2000 und ADO 535 12.9 BEISPIELE MIT MICROSOFT OUTLOOK 536 72.9.7 Das Objektmodell von Outlook 536 12.9.2 Delphi 4/5 ohne Outlook-Komponenten 538 12.9.3 Delphi 5 mit den Outlook-Komponenten 544 12.10 ANWENDUNGSBEISPIEL MICROSOFT AGENT 547 72.70.7 Die Installation 548 12.10.2 Der Import in Delphi 4 548 12.10.3 Das Beispielprogramm 557 12.10.4 Connection-Points-Unterstützung 553 12.11 INTERNET EXPLORER 557 13 DCOM 561 14 MIDAS 563 14.1 DELPHI 4 UND MIDAS 2 563 74.7.7 Client ruft Server - die Verbindungsalternativen 563 14.1.2 MIDAS-2-Server. : 564 14.1.3 Briefcase-Modell 565 14.1.4 Singlelnstance-Server 577 74.7.5 Multilnstance-Server. 573 14.1.6 Multilnstance-Multithread-Server 574 14.1.7 Poolmanager-Server 579 14.1.8 ActiveForm als MIDAS-Client 584 14.2 DELPHI 5 UND"MIDAS 3 584 14.3 TCOMPONENTFACTORY 585 14.3.1 Das Standardverhalten von TAutoObjectFactory 586 14.3.2 Das Standardverhalten von TComponentFactory 587 14.3.3 Das Geheimnis von TComponentFactory 587 15 MTS 589 15.1 STANDORTBESTIMMUNG 589 75.7.7 Was ist der MTS? 590 15.1.2 Einsatzfälle 597 75.7.5 MTS-Steckbrief. 592 15.2 INSTALLATION DES MTS 593 15.3 DAS MINIMAL-BEISPIEL MIT DELPHI 599 15.4 DAS PRINZIP DES MTS 602 75.4.7 MTS-Begriffe '. 602 15.4.2 Beispiel für das Zusammenspiel 608 10
15.5 MIDDLE-TIER-OBJEKTE FÜR DEN MTS 609 75.5.7 Objekt-Anforderungen 670 75.5.2 Objekt-Aktivierung 677 75.5.5 Zustandslose Objekte 675 15.6 MTS-TRANSAKTIONEN 616 15.6.1 Ein kurzer Ausflug in die Theorie 676 75.6.2 Das 2-Phasen-Commit des MTS 627 15.6.3 Deklarative Transaktionen 622 15.6.4 Transaktionsregeln des MTS 625 15.7 ZUSTANDSLOSE VS. ZUSTANDSBEHAFTETE OBJEKTE 628 75.7.7 Zustandsbehaftetes Objekt 628 15.7.2 Zustandsloses Objekt 636 15.7.3 Shared Property Manager 647 75.7.4 MTS-Objekte debuggen 644 15.8 MTS-OBJEKTE MIT DATENBANKZUGRIFF 645 75.8.7 BDE als Resource Dispenser 646 15.8.2 Die Beispiel-Datenbank 650 15.8.3 Der konventionelle Client/Server-Ansatz 652 15.8.4 Das zustandslose Datenbankobjekt. 667 15.8.5 Self-made Session-Manager 670 15.8.6 MIDAS für Arme 673 15.9 DESIGN VON MULTI-TIER-ANWENDUNGEN 677 75.9.7 CRUD-Aktionen 678 15.9.2 Beispielprojekt MTSKdnManager 680 15.10 MTS UND ADO 683 15.10.1 Microsoft-Empfehlungen 683 15.10.2 ACCESS-Datenbank ohne Transaktion 685 15.10.3 Kurzeinführung in die MSDE 688 15.10.4 MSDE-Datenbank ohne Transaktion 698 15.10.5 MSDE-Datenbank mit Transaktion 699 15.10.6 Recordset-Objekt übertragen 704 15.11 MICROSOFT-REGELN ZUM MTS 707 15.12 TROUBLESHOOTING 708 16 COM+ 711 16.1 STANDORTBESTIMMUNG 711 76.7.7 Von COM zu COM+ 777 16.1.2 Configured vs. Nonconfigured 775 16.2 WAS GIBT'S NEUES IN COM+? 714 76.2.7 COM+Services 775 76.2.2 COM+Runtime 776 76.2.5 COM+ Administration 778 16.2.4 Process, Apartment, Activity und Context 723 16.2.5 Type Libraries und ProgIDsßr COM+ 727 16.2.6 Das neue COM+-Programmier-Modell 728 rr
16.3 VERTEILTE ANWENDUNGEN 737 16.3.1 Warum eine verteilte Anwendung? 738 16.3.2 Warum nicht CORBA, Java oder XML? 743 16.3.3 Nebenwirkungen 744 16.3.4 Performance von verteilten Anwendungen 747 16.4 COM+UND DELPHI 5 750 16.4.1 Borlands Eigentor 757 76.4.2 Non-blocking Calls 755 16.4.3 COM+-Komponenten debuggen 756 16.5 VERWENDETE ENTWICKLUNGSUMGEBUNG 757 16.6 COM+ EVENT SERVICE 758 16.6.1 Das Minimalbeispiel 762 16.6.2 Transiente Subscription 774 16.6.3 Die Bibliotheksanwendung 776 16.6.4 Event-Filter 778 16.6.5 Queued Subscribers 779 16.7 CONSTRUCTOR STRINGS 779 16.8 TRANSACTION SERVICES 782 76.8.7 Beispiel für den Microsoft SQL-Server 7 784 16.8.2 Der C/S-Client (Two-tier) 788 16.8.3 Fehlerbehandlung von ADO 797 76.8.4 Aus C/S wird Three-tier 795 16.8.5 Verzicht auf TADOConnection und TADOStoredProc 807 16.8.6 SetAbort-Bug von Windows 2000 820 16.9 MICROSOFT MESSAGE QUEUE SERVICES 823 16.10 QUEUED COMPONENTS 824 16.11 COM+SECURITY 831 76.77.7 Standard-Sicherheit 832 16.11.2 Identität 833 16.11.3 Rollen 834 16.11.4 CallContext 842 16.11.5 ColnitializeSecurity 845 16.12 LOAD BALANCING 846 16.13 OBJECT POOLING 848 76.75.7 Objekt-Pool trotz CanBePooled := False 849 16.13.2 Der echte Objekt-Pool 850 16.14 COM+-SYNCHRONISATION 852 16.14.1 Gemeinsame Testbedingungen 852 16.14.2 Verhalten des STA-Objekts 855 16.14.3 Verhalten des MTA-Objekts 856 16.14.4 Verhalten des TNA-Objekts 867 16.15 MIGRATION VOM MTS zu COM+ 863 17 INTERNET INFORMATION SERVICES 867 17.1 INTRANET WEBSITE EINRICHTEN 867 12
17.1.1 Neue IP-Adresse vergeben 868 17.1.2 Neue Website konfigurieren 869 17.1.3 Index Service konfigurieren 873 17.2 DIE IIS-ARCHITEKTUR 879 77.2.7 Web Application Manager (WAM) 880 17.2.2 IIS-Anwendung 882 17.2.3 Anwendungsschutz 883 17.2.4 IUSR_Rechnername 885 17.3 INTERNET SERVER API (ISAPI) 887 77.5.7 Was ist eine ISAPI-DLL? 887 17.3.2 ISAPI-DLL für eine Datenbankabfrage 892 77.5.5 ISAPI-DLL für das Einßgen und Löschen von Daten 899 17.3.4 ISAPI-DLL mit TPageProducer 907 17.3.5 ISAPI-DLLßr das Uploaden von Dateien 908 17.4 ACTIVE SERVER PAGES (ASP) 910 77.4.7 Was ist eine ASP? 970 77.4.2 Neue ASP-Funktionen in IIS 5.0 977 77.4.5 ASP startet COM-Objekt 974 77.4.4 ASP ruft direkt die ADO-Objekte auf. 920 17.4.5 ASP mit Objektkontext-Unterstützung 925 17.4.6 ASPundIBX. 928 17.4.7 ASP-Objekt mit Delphi Professional 929 17.5 ACTIVEFORM 934 77.5.7 Das erste Beispiel 934 17.5.2 ActiveForm-Methoden aus der HTML-Seite aufrufen 939 17.6 TWEBCONNECTION 941 INDEX 945 13