0
# COM Automation (Windows)
1
2
Complete Component Object Model (COM) support for Windows automation, including base interfaces, utility classes, type library importing, and comprehensive annotation-based programming model. COM enables interaction with Windows applications, system services, and automation objects.
3
4
## Capabilities
5
6
### Base COM Interfaces
7
8
Core COM interfaces that form the foundation of all COM objects and automation.
9
10
```java { .api }
11
/**
12
* Base COM interface - all COM objects implement IUnknown
13
*/
14
public interface IUnknown {
15
/**
16
* Query for a different interface on the object
17
* @param riid Interface identifier to query for
18
* @param ppvObject Output pointer to interface
19
* @return HRESULT status code
20
*/
21
HRESULT QueryInterface(REFIID riid, PointerByReference ppvObject);
22
23
/**
24
* Increment object reference count
25
* @return New reference count
26
*/
27
int AddRef();
28
29
/**
30
* Decrement object reference count, destroy when reaches zero
31
* @return New reference count (0 means object was destroyed)
32
*/
33
int Release();
34
}
35
36
/**
37
* Automation interface extending IUnknown for scripting and late binding
38
*/
39
public interface IDispatch extends IUnknown {
40
/**
41
* Get number of type info interfaces
42
* @param pctinfo Output count of type info interfaces
43
* @return HRESULT status code
44
*/
45
HRESULT GetTypeInfoCount(IntByReference pctinfo);
46
47
/**
48
* Get type information for object
49
* @param iTInfo Type info index (usually 0)
50
* @param lcid Locale identifier
51
* @param ppTInfo Output type information
52
* @return HRESULT status code
53
*/
54
HRESULT GetTypeInfo(int iTInfo, LCID lcid, PointerByReference ppTInfo);
55
56
/**
57
* Get dispatch IDs for names
58
* @param riid Reserved (should be IID_NULL)
59
* @param rgszNames Array of names to get IDs for
60
* @param cNames Number of names
61
* @param lcid Locale identifier
62
* @param rgDispId Output array of dispatch IDs
63
* @return HRESULT status code
64
*/
65
HRESULT GetIDsOfNames(REFIID riid, String[] rgszNames, int cNames,
66
LCID lcid, DISPIDByReference rgDispId);
67
68
/**
69
* Invoke method or access property
70
* @param dispIdMember Dispatch ID of member
71
* @param riid Reserved (should be IID_NULL)
72
* @param lcid Locale identifier
73
* @param wFlags Invoke flags (method, property get/put)
74
* @param pDispParams Parameters for invocation
75
* @param pVarResult Return value
76
* @param pExcepInfo Exception information
77
* @param puArgErr Argument error index
78
* @return HRESULT status code
79
*/
80
HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
81
DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult,
82
EXCEPINFO.ByReference pExcepInfo, IntByReference puArgErr);
83
}
84
```
85
86
### Connection Points and Events
87
88
COM interfaces for event handling and callback mechanisms.
89
90
```java { .api }
91
/**
92
* Connection point interface for COM events
93
*/
94
public interface IConnectionPoint extends IUnknown {
95
/**
96
* Get interface ID for this connection point
97
* @param pIID Output interface identifier
98
* @return HRESULT status code
99
*/
100
HRESULT GetConnectionInterface(Pointer pIID);
101
102
/**
103
* Get connection point container
104
* @param ppCPC Output connection point container
105
* @return HRESULT status code
106
*/
107
HRESULT GetConnectionPointContainer(PointerByReference ppCPC);
108
109
/**
110
* Establish connection to event sink
111
* @param pUnkSink Event sink interface
112
* @param pdwCookie Output connection cookie
113
* @return HRESULT status code
114
*/
115
HRESULT Advise(IUnknown pUnkSink, DWORDByReference pdwCookie);
116
117
/**
118
* Terminate connection
119
* @param dwCookie Connection cookie from Advise
120
* @return HRESULT status code
121
*/
122
HRESULT Unadvise(DWORD dwCookie);
123
124
/**
125
* Enumerate existing connections
126
* @param ppEnum Output enumerator for connections
127
* @return HRESULT status code
128
*/
129
HRESULT EnumConnections(PointerByReference ppEnum);
130
}
131
132
/**
133
* Connection point container interface
134
*/
135
public interface IConnectionPointContainer extends IUnknown {
136
/**
137
* Enumerate all connection points
138
* @param ppEnum Output enumerator for connection points
139
* @return HRESULT status code
140
*/
141
HRESULT EnumConnectionPoints(PointerByReference ppEnum);
142
143
/**
144
* Find connection point for specific interface
145
* @param riid Interface identifier to find
146
* @param ppCP Output connection point
147
* @return HRESULT status code
148
*/
149
HRESULT FindConnectionPoint(REFIID riid, PointerByReference ppCP);
150
}
151
```
152
153
### Object Persistence
154
155
COM interfaces for object serialization and persistence.
156
157
```java { .api }
158
/**
159
* Base persistence interface
160
*/
161
public interface IPersist extends IUnknown {
162
/**
163
* Get class identifier for persistent object
164
* @param pClassID Output class identifier
165
* @return HRESULT status code
166
*/
167
HRESULT GetClassID(Pointer pClassID);
168
}
169
170
/**
171
* Stream-based persistence
172
*/
173
public interface IPersistStream extends IPersist {
174
/**
175
* Check if object is dirty (needs saving)
176
* @return S_OK if dirty, S_FALSE if clean
177
*/
178
HRESULT IsDirty();
179
180
/**
181
* Load object from stream
182
* @param pStm Input stream
183
* @return HRESULT status code
184
*/
185
HRESULT Load(Pointer pStm);
186
187
/**
188
* Save object to stream
189
* @param pStm Output stream
190
* @param fClearDirty Whether to clear dirty flag
191
* @return HRESULT status code
192
*/
193
HRESULT Save(Pointer pStm, boolean fClearDirty);
194
195
/**
196
* Get size needed to save object
197
* @param pcbSize Output size in bytes
198
* @return HRESULT status code
199
*/
200
HRESULT GetSizeMax(Pointer pcbSize);
201
}
202
```
203
204
### COM Object Creation and Management
205
206
High-level utilities for creating and managing COM objects with automatic lifecycle management.
207
208
```java { .api }
209
/**
210
* COM object factory for creating and managing COM instances
211
*/
212
public class Factory {
213
/**
214
* Create COM object from program ID
215
* @param progid Program identifier (e.g., "Excel.Application")
216
* @return COM object wrapper
217
* @throws COMException if creation fails
218
*/
219
public static IDispatch createObject(String progid) throws COMException;
220
221
/**
222
* Get active COM object by program ID
223
* @param progid Program identifier
224
* @return Existing COM object wrapper
225
* @throws COMException if object not found or retrieval fails
226
*/
227
public static IDispatch getActiveObject(String progid) throws COMException;
228
229
/**
230
* Create COM object from class ID
231
* @param clsid Class identifier
232
* @return COM object wrapper
233
* @throws COMException if creation fails
234
*/
235
public static IUnknown createObject(CLSID clsid) throws COMException;
236
}
237
238
/**
239
* Enhanced object factory with additional features
240
*/
241
public class ObjectFactory {
242
/**
243
* Create COM object with specific interface
244
* @param progid Program identifier
245
* @param interfaceClass Interface class to return
246
* @return Typed COM object wrapper
247
* @throws COMException if creation fails
248
*/
249
public static <T> T createObject(String progid, Class<T> interfaceClass) throws COMException;
250
251
/**
252
* Create COM object with connection point support
253
* @param progid Program identifier
254
* @param eventSink Event handler implementation
255
* @return COM object wrapper with event connection
256
* @throws COMException if creation fails
257
*/
258
public static IDispatch createObjectWithEvents(String progid, Object eventSink) throws COMException;
259
260
/**
261
* Release COM object and clean up resources
262
* @param comObject COM object to release
263
*/
264
public static void releaseObject(Object comObject);
265
}
266
```
267
268
### Dynamic Proxy Support
269
270
Dynamic proxy implementation for type-safe COM automation without type libraries.
271
272
```java { .api }
273
/**
274
* Dynamic proxy for COM objects providing type-safe access
275
*/
276
public class ProxyObject implements InvocationHandler {
277
/**
278
* Create proxy for COM object
279
* @param comObject Underlying COM object
280
* @param interfaceClass Interface to implement
281
* @return Proxy implementing the interface
282
*/
283
public static <T> T createProxy(IDispatch comObject, Class<T> interfaceClass);
284
285
/**
286
* Get underlying COM object from proxy
287
* @param proxy Proxy object
288
* @return Underlying IDispatch interface
289
*/
290
public static IDispatch getComObject(Object proxy);
291
292
/**
293
* Handle method invocation on proxy
294
* @param proxy Proxy instance
295
* @param method Method being invoked
296
* @param args Method arguments
297
* @return Method result
298
*/
299
@Override
300
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
301
}
302
```
303
304
### COM Threading Support
305
306
Utilities for managing COM objects across different threading models.
307
308
```java { .api }
309
/**
310
* COM threading utilities for apartment and free threading
311
*/
312
public class ComThread {
313
/**
314
* Initialize COM on current thread
315
* @param threadingModel Threading model (COINIT_APARTMENTTHREADED, etc.)
316
* @throws COMException if initialization fails
317
*/
318
public static void initMTA(int threadingModel) throws COMException;
319
320
/**
321
* Initialize COM with Single Threaded Apartment
322
* @throws COMException if initialization fails
323
*/
324
public static void initSTA() throws COMException;
325
326
/**
327
* Initialize COM with Multi Threaded Apartment
328
* @throws COMException if initialization fails
329
*/
330
public static void initMTA() throws COMException;
331
332
/**
333
* Uninitialize COM on current thread
334
*/
335
public static void uninitialize();
336
337
/**
338
* Execute operation in COM apartment thread
339
* @param operation Operation to execute
340
* @return Operation result
341
* @throws Exception if operation fails
342
*/
343
public static <T> T executeInComThread(Callable<T> operation) throws Exception;
344
}
345
```
346
347
### Event Handling Support
348
349
Simplified event handling for COM automation objects.
350
351
```java { .api }
352
/**
353
* Callback proxy for COM event handling
354
*/
355
public class CallbackProxy implements InvocationHandler {
356
/**
357
* Create event sink proxy
358
* @param eventHandler Event handler object
359
* @param sinkInterface Event sink interface
360
* @return Proxy implementing sink interface
361
*/
362
public static Object createProxy(Object eventHandler, Class<?> sinkInterface);
363
364
/**
365
* Connect event handler to COM object
366
* @param comObject COM object that fires events
367
* @param eventHandler Handler object with event methods
368
* @param sinkInterface Event sink interface
369
* @return Connection cookie for later disconnection
370
* @throws COMException if connection fails
371
*/
372
public static int connectEvents(IDispatch comObject, Object eventHandler,
373
Class<?> sinkInterface) throws COMException;
374
375
/**
376
* Disconnect event handler from COM object
377
* @param comObject COM object
378
* @param connectionCookie Cookie from connectEvents
379
* @throws COMException if disconnection fails
380
*/
381
public static void disconnectEvents(IDispatch comObject, int connectionCookie) throws COMException;
382
}
383
```
384
385
### Type Library Import
386
387
Tools for importing COM type libraries and generating Java bindings.
388
389
```java { .api }
390
/**
391
* Type library importer for generating Java bindings from COM type libraries
392
*/
393
public class TlbImp {
394
/**
395
* Generate Java bindings from type library file
396
* @param tlbFile Type library file path
397
* @param outputPackage Output Java package name
398
* @param outputDir Output directory for generated files
399
* @throws Exception if import fails
400
*/
401
public static void generateBindings(String tlbFile, String outputPackage,
402
String outputDir) throws Exception;
403
404
/**
405
* Generate bindings from program ID
406
* @param progid Program identifier to import
407
* @param outputPackage Output Java package name
408
* @param outputDir Output directory
409
* @throws Exception if import fails
410
*/
411
public static void generateBindingsFromProgId(String progid, String outputPackage,
412
String outputDir) throws Exception;
413
414
/**
415
* List available type libraries on system
416
* @return Array of type library information
417
*/
418
public static TypeLibInfo[] getInstalledTypeLibraries();
419
}
420
421
/**
422
* Type library information
423
*/
424
public class TypeLibInfo {
425
public String getName();
426
public String getVersion();
427
public String getPath();
428
public GUID getGuid();
429
}
430
```
431
432
### COM Annotations
433
434
Annotations for declarative COM programming and automatic proxy generation.
435
436
```java { .api }
437
/**
438
* Mark interface as COM interface
439
*/
440
@Retention(RetentionPolicy.RUNTIME)
441
@Target(ElementType.TYPE)
442
public @interface ComInterface {
443
/**
444
* Interface identifier (optional)
445
*/
446
String iid() default "";
447
}
448
449
/**
450
* Mark class as COM object
451
*/
452
@Retention(RetentionPolicy.RUNTIME)
453
@Target(ElementType.TYPE)
454
public @interface ComObject {
455
/**
456
* Program identifier
457
*/
458
String progid();
459
460
/**
461
* Class identifier (optional)
462
*/
463
String clsid() default "";
464
}
465
466
/**
467
* Mark method as COM method
468
*/
469
@Retention(RetentionPolicy.RUNTIME)
470
@Target(ElementType.METHOD)
471
public @interface ComMethod {
472
/**
473
* Dispatch ID (optional for late binding)
474
*/
475
int dispId() default -1;
476
477
/**
478
* Method name (defaults to Java method name)
479
*/
480
String name() default "";
481
}
482
483
/**
484
* Mark method as COM property
485
*/
486
@Retention(RetentionPolicy.RUNTIME)
487
@Target(ElementType.METHOD)
488
public @interface ComProperty {
489
/**
490
* Dispatch ID
491
*/
492
int dispId();
493
494
/**
495
* Property access type
496
*/
497
PropertyAccess access() default PropertyAccess.GET;
498
}
499
500
/**
501
* Mark method as COM event callback
502
*/
503
@Retention(RetentionPolicy.RUNTIME)
504
@Target(ElementType.METHOD)
505
public @interface ComEventCallback {
506
/**
507
* Dispatch ID for event
508
*/
509
int dispId();
510
}
511
512
/**
513
* Property access enumeration
514
*/
515
public enum PropertyAccess {
516
GET, PUT, PUT_REF
517
}
518
```
519
520
### COM Utility Classes
521
522
Essential utility classes that simplify COM programming and handle complex operations like error checking, type library access, and object management.
523
524
#### COMUtils - Core Utilities
525
526
Helper functions for COM operations, error handling, and system COM registry access.
527
528
```java { .api }
529
/**
530
* Core COM utility functions for error handling and system information
531
*/
532
public class COMUtils {
533
/**
534
* Check if HRESULT indicates success
535
* @param hr HRESULT value to check
536
* @return true if successful
537
*/
538
public static boolean SUCCEEDED(HRESULT hr);
539
540
/**
541
* Check if HRESULT indicates failure
542
* @param hr HRESULT value to check
543
* @return true if failed
544
*/
545
public static boolean FAILED(HRESULT hr);
546
547
/**
548
* Check HRESULT and throw exception if failed
549
* @param hr HRESULT value to check
550
* @throws COMException if hr indicates failure
551
*/
552
public static void checkRC(HRESULT hr);
553
554
/**
555
* Check HRESULT with detailed error information
556
* @param hr HRESULT value to check
557
* @param pExcepInfo Exception information structure
558
* @param puArgErr Argument error reference
559
* @throws COMException if hr indicates failure with detailed error info
560
*/
561
public static void checkRC(HRESULT hr, EXCEPINFO pExcepInfo, IntByReference puArgErr);
562
563
/**
564
* Check if COM is initialized on current thread
565
* @return true if COM is initialized
566
*/
567
public static boolean comIsInitialized();
568
569
/**
570
* Get information about all registered COM objects on the system
571
* @return List of COMInfo objects describing registered COM classes
572
*/
573
public static ArrayList<COMInfo> getAllCOMInfoOnSystem();
574
}
575
576
/**
577
* Information about a registered COM object
578
*/
579
public static class COMInfo {
580
public String clsid; // Class ID
581
public String progid; // Programmatic ID
582
public String typelib; // Type library ID
583
public String inprocServer32; // In-process server path
584
public String localServer32; // Local server path
585
}
586
```
587
588
#### TypeLibUtil - Type Library Access
589
590
High-level wrapper for accessing COM type library information and metadata.
591
592
```java { .api }
593
/**
594
* Type library access and manipulation utilities
595
*/
596
public class TypeLibUtil {
597
/**
598
* Load type library by CLSID and version
599
* @param clsidStr Type library CLSID as string
600
* @param wVerMajor Major version number
601
* @param wVerMinor Minor version number
602
*/
603
public TypeLibUtil(String clsidStr, int wVerMajor, int wVerMinor);
604
605
/**
606
* Load type library from file
607
* @param file Path to type library file (.tlb, .dll, .exe)
608
*/
609
public TypeLibUtil(String file);
610
611
/**
612
* Get number of type definitions in library
613
* @return Count of type definitions
614
*/
615
public int getTypeInfoCount();
616
617
/**
618
* Get type kind for type info at index
619
* @param index Index of type info
620
* @return TYPEKIND indicating type (interface, coclass, enum, etc.)
621
*/
622
public TYPEKIND getTypeInfoType(int index);
623
624
/**
625
* Get type information object at index
626
* @param index Index of type info
627
* @return ITypeInfo interface for type
628
*/
629
public ITypeInfo getTypeInfo(int index);
630
631
/**
632
* Get type info utility wrapper at index
633
* @param index Index of type info
634
* @return TypeInfoUtil wrapper for convenient access
635
*/
636
public TypeInfoUtil getTypeInfoUtil(int index);
637
638
/**
639
* Get type library attributes
640
* @return TLIBATTR structure with library metadata
641
*/
642
public TLIBATTR getLibAttr();
643
644
/**
645
* Get documentation for type at index
646
* @param index Index of type (-1 for library documentation)
647
* @return TypeLibDoc with name, help text, and help context
648
*/
649
public TypeLibDoc getDocumentation(int index);
650
}
651
```
652
653
#### TypeInfoUtil - Type Information Access
654
655
Wrapper for ITypeInfo providing convenient access to type metadata, function descriptors, and member information.
656
657
```java { .api }
658
/**
659
* Type information access and manipulation utilities
660
*/
661
public class TypeInfoUtil {
662
/**
663
* Get type attributes
664
* @return TYPEATTR structure with type metadata
665
*/
666
public TYPEATTR getTypeAttr();
667
668
/**
669
* Get function descriptor for method at index
670
* @param index Function index
671
* @return FUNCDESC structure with function metadata
672
*/
673
public FUNCDESC getFuncDesc(int index);
674
675
/**
676
* Get variable descriptor for property/field at index
677
* @param index Variable index
678
* @return VARDESC structure with variable metadata
679
*/
680
public VARDESC getVarDesc(int index);
681
682
/**
683
* Get names for member ID
684
* @param memid Member ID
685
* @param maxNames Maximum number of names to retrieve
686
* @return Array of names (first is member name, rest are parameter names)
687
*/
688
public String[] getNames(MEMBERID memid, int maxNames);
689
690
/**
691
* Get reference type for implemented interface at index
692
* @param index Implementation index
693
* @return HREFTYPE for referenced interface
694
*/
695
public HREFTYPE getRefTypeOfImplType(int index);
696
697
/**
698
* Get implementation flags for interface at index
699
* @param index Implementation index
700
* @return Implementation flags (default, source, etc.)
701
*/
702
public int getImplTypeFlags(int index);
703
704
/**
705
* Invoke method or property on instance
706
* @param pvInstance Object instance
707
* @param memid Member ID to invoke
708
* @param wFlags Invocation flags (method, property get/put)
709
* @param pDispParams Parameters for invocation
710
* @return Invoke result with return value and parameter results
711
*/
712
public Invoke Invoke(PVOID pvInstance, MEMBERID memid, WORD wFlags,
713
DISPPARAMS.ByReference pDispParams);
714
}
715
```
716
717
#### COM Object Base Classes
718
719
Foundation classes for building COM object wrappers with lifecycle management.
720
721
```java { .api }
722
/**
723
* Base class for COM object wrappers
724
*/
725
public abstract class COMBindingBaseObject {
726
/**
727
* Create COM object wrapper by CLSID
728
* @param clsid Class ID of COM object
729
* @param useActiveInstance true to connect to existing instance
730
*/
731
protected COMBindingBaseObject(CLSID clsid, boolean useActiveInstance);
732
733
/**
734
* Create COM object wrapper by Program ID
735
* @param progId Programmatic ID of COM object
736
* @param useActiveInstance true to connect to existing instance
737
*/
738
protected COMBindingBaseObject(String progId, boolean useActiveInstance);
739
740
/**
741
* Get IDispatch interface for automation
742
* @return IDispatch interface
743
*/
744
public IDispatch getIDispatch();
745
746
/**
747
* Get IUnknown interface
748
* @return IUnknown interface
749
*/
750
public IUnknown getIUnknown();
751
752
/**
753
* Invoke OLE automation method
754
* @param nType Invocation type (method, property get/put)
755
* @param pvResult Reference for return value
756
* @param name Method or property name
757
* @param pArgs Method arguments
758
* @return HRESULT from invocation
759
*/
760
protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult,
761
String name, VARIANT[] pArgs);
762
}
763
764
/**
765
* Late binding COM object wrapper with convenience methods
766
*/
767
public abstract class COMLateBindingObject extends COMBindingBaseObject {
768
/**
769
* Get property value as IDispatch
770
* @param propertyName Property name
771
* @return Property value as IDispatch
772
*/
773
protected IDispatch getAutomationProperty(String propertyName);
774
775
/**
776
* Get boolean property value
777
* @param propertyName Property name
778
* @return Property value as boolean
779
*/
780
protected boolean getBooleanProperty(String propertyName);
781
782
/**
783
* Get date property value
784
* @param propertyName Property name
785
* @return Property value as Date
786
*/
787
protected Date getDateProperty(String propertyName);
788
789
/**
790
* Get integer property value
791
* @param propertyName Property name
792
* @return Property value as int
793
*/
794
protected int getIntProperty(String propertyName);
795
796
/**
797
* Get string property value
798
* @param propertyName Property name
799
* @return Property value as String
800
*/
801
protected String getStringProperty(String propertyName);
802
803
/**
804
* Invoke method with no parameters
805
* @param methodName Method name
806
* @return Method result as VARIANT
807
*/
808
protected VARIANT invoke(String methodName);
809
810
/**
811
* Invoke method with parameters
812
* @param methodName Method name
813
* @param args Method arguments
814
* @return Method result as VARIANT
815
*/
816
protected VARIANT invoke(String methodName, VARIANT[] args);
817
818
/**
819
* Set property value (multiple overloads for different types)
820
* @param propertyName Property name
821
* @param value Property value (boolean, Date, int, String)
822
*/
823
protected void setProperty(String propertyName, boolean value);
824
protected void setProperty(String propertyName, Date value);
825
protected void setProperty(String propertyName, int value);
826
protected void setProperty(String propertyName, String value);
827
}
828
```
829
830
#### COM Threading Management
831
832
Thread-safe COM object creation and execution with automatic apartment management.
833
834
```java { .api }
835
/**
836
* COM thread management for apartment threading
837
*/
838
public class ComThread {
839
/**
840
* Create COM thread with timeout and error handling
841
* @param threadName Thread name for debugging
842
* @param timeoutMilliseconds Operation timeout
843
* @param uncaughtExceptionHandler Exception handler
844
*/
845
public ComThread(String threadName, long timeoutMilliseconds,
846
UncaughtExceptionHandler uncaughtExceptionHandler);
847
848
/**
849
* Execute callable task in COM apartment thread
850
* @param task Task to execute
851
* @return Task result
852
*/
853
public <T> T execute(Callable<T> task);
854
855
/**
856
* Terminate COM thread and clean up resources
857
* @param timeoutMilliseconds Termination timeout
858
*/
859
public void terminate(long timeoutMilliseconds);
860
}
861
862
/**
863
* Enhanced object factory with COM threading support
864
*/
865
public class Factory extends ObjectFactory {
866
/**
867
* Get associated COM thread for this factory
868
* @return ComThread instance managing COM operations
869
*/
870
public ComThread getComThread();
871
872
// All ObjectFactory methods are automatically executed in proper COM thread context
873
}
874
```
875
876
### Complete COM Usage Examples
877
878
**Basic COM Automation:**
879
880
```java
881
import com.sun.jna.platform.win32.COM.util.*;
882
883
// Create Excel application
884
IDispatch excel = Factory.createObject("Excel.Application");
885
886
// Make Excel visible
887
excel.setProperty("Visible", true);
888
889
// Create new workbook
890
IDispatch workbooks = (IDispatch) excel.getProperty("Workbooks");
891
IDispatch workbook = (IDispatch) workbooks.invoke("Add");
892
893
// Get first worksheet
894
IDispatch worksheets = (IDispatch) workbook.getProperty("Worksheets");
895
IDispatch worksheet = (IDispatch) worksheets.invoke("Item", 1);
896
897
// Set cell value
898
IDispatch range = (IDispatch) worksheet.invoke("Range", "A1");
899
range.setProperty("Value", "Hello from JNA!");
900
901
// Save and close
902
workbook.invoke("SaveAs", "C:\\temp\\test.xlsx");
903
workbook.invoke("Close");
904
excel.invoke("Quit");
905
906
// Clean up
907
ObjectFactory.releaseObject(excel);
908
```
909
910
**Event Handling:**
911
912
```java
913
// Event handler class
914
public class ExcelEventHandler {
915
@ComEventCallback(dispId = 1565) // WorkbookOpen event
916
public void onWorkbookOpen(IDispatch workbook) {
917
System.out.println("Workbook opened: " + workbook.getProperty("Name"));
918
}
919
920
@ComEventCallback(dispId = 1558) // WorkbookBeforeClose event
921
public void onWorkbookBeforeClose(IDispatch workbook, BooleanByReference cancel) {
922
System.out.println("Workbook closing: " + workbook.getProperty("Name"));
923
// Set cancel.setValue(true) to prevent closing
924
}
925
}
926
927
// Connect events
928
ExcelEventHandler handler = new ExcelEventHandler();
929
IDispatch excel = Factory.createObject("Excel.Application");
930
931
int connectionCookie = CallbackProxy.connectEvents(excel, handler,
932
ExcelEventHandler.class);
933
934
// Use Excel with event handling...
935
936
// Disconnect events when done
937
CallbackProxy.disconnectEvents(excel, connectionCookie);
938
ObjectFactory.releaseObject(excel);
939
```
940
941
**Annotation-Based COM Programming:**
942
943
```java
944
@ComInterface(iid = "{00020970-0000-0000-C000-000000000046}")
945
public interface IApplication {
946
@ComProperty(dispId = 558)
947
boolean getVisible();
948
949
@ComProperty(dispId = 558, access = PropertyAccess.PUT)
950
void setVisible(boolean visible);
951
952
@ComMethod(dispId = 302)
953
IWorkbooks getWorkbooks();
954
955
@ComMethod(dispId = 1105)
956
void quit();
957
}
958
959
// Use with proxy
960
IDispatch excelDispatch = Factory.createObject("Excel.Application");
961
IApplication excel = ProxyObject.createProxy(excelDispatch, IApplication.class);
962
963
excel.setVisible(true);
964
IWorkbooks workbooks = excel.getWorkbooks();
965
// ... use type-safe interface
966
excel.quit();
967
```