Microsoft KB Archive/278949

= PRB: Range::GetApplication Method Returns an Incorrect Interface Pointer =

Article ID: 278949

Article Last Modified on 1/29/2007

-

APPLIES TO


 * Microsoft Excel 2000 Service Pack 1
 * Microsoft Excel 2000 Standard Edition
 * Microsoft Excel 97 Standard Edition

-



This article was previously published under Q278949



SYMPTOMS
When a developer uses the #import functionality of Microsoft Visual C++ to generate smart pointers for Excel and then uses those smart pointers to access the pointer returned by the Range::GetApplication property, an access violation occurs.

This problem does not occur in Microsoft Visual Basic applications, but can be observed in Component Object Model (COM) code that does not use #import.



CAUSE
The type library for Excel indicates that the CoClass &quot;Application&quot; is returned by the Range::GetApplication method. COM methods return only interface pointers, not CoClass pointers. Because of this, Microsoft Visual C++ concludes that the interface pointer returned must be for the default interface of the Application CoClass, _Application.

The _Application interface is dual, meaning that it can be called either through the IDispatch interface, or directly through the vtable. However, the interface returned from Range::GetApplication does not support vtable binding. When the wrappers generated by #import attempt to make a vtable call, an access violation results.

This problem is not seen elsewhere in Excel.



RESOLUTION
To work around the problem, call IUnknown::QueryInterface on the interface pointer returned from Range::GetApplication before using it. The following code demonstrates the workaround: _ApplicationPtr appPtr2; IUnknown* pUnk = NULL; HRESULT hr = xlRange->GetApplication->QueryInterface( __uuidof(_Application), (void**)&pUnk ); if (SUCCEEDED(hr)){ appPtr2 = pUnk; appPtr2->PutVisible(0, TRUE ); }



Steps to Reproduce Behavior
 Create a new Microsoft Foundation Classes (MFC) AppWizard(exe) project. Name it ExcelDemo and make it a dialog-based application.  In the project Wizard, the project displays the dialog box when you click Finish. Double-click the default OK CommandButton to edit the click handler for the button. Replace the default code with the following: using namespace Excel; _ApplicationPtr appPtr1; _ApplicationPtr appPtr2; WorkbooksPtr xlBooks; _WorkbookPtr xlBook; _WorksheetPtr xlSheet; RangePtr xlRange; if(!AfxOleInit) {     AfxMessageBox(&quot;Failed to initialize COM&quot;); return; }  appPtr1.CreateInstance( &quot;Excel.Application&quot; ); xlBooks = appPtr1->GetWorkbooks; xlBook = xlBooks->Add; xlSheet = xlBook->GetActiveSheet;

xlRange = xlSheet->GetRange( COleVariant(&quot;A1&quot;) );

//This fails {     appPtr2 = xlRange->GetApplication; appPtr2->PutVisible( 0, TRUE ); } /*  //This works {     IUnknown* pUnk = NULL; xlRange->GetApplication->QueryInterface( __uuidof(_Application),         (void**)&pUnk ); appPtr2 = pUnk; appPtr2->PutVisible(0, TRUE ); }                     Add the following code immediately above the click handler code of the CommandButton: /* // Use #import to generate smart pointers for Excel97... rename(&quot;DocumentProperties&quot;, &quot;OfficeDocumentProperties&quot;)
 * 1) import &quot;C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\MSO97.DLL&quot; no_namespace \

no_namespace
 * 1) import &quot;C:\PROGRAM FILES\COMMON FILES\MICROSOFT SHARED\VBA\VBEEXT1.OLB&quot; \

rename(&quot;DialogBox&quot;, &quot;ExcelDialogBox&quot;) rename(&quot;RGB&quot;, &quot;ExcelRGB&quot;) \ rename(&quot;DocumentProperties&quot;, &quot;ExcelDocumentProperties&quot;) \ rename(&quot;ExitWindows&quot;, &quot;ExcelExitWindows&quot;)
 * 1) import &quot;C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\Excel8.Olb&quot; no_dual_interfaces \

// Use #import to generate smart pointers for Excel2000... rename(&quot;DocumentProperties&quot;, &quot;OfficeDocumentProperties&quot;)
 * 1) import &quot;C:\PROGRAM FILES\Microsoft Office\OFFICE\MSO9.DLL&quot; no_namespace \

no_namespace
 * 1) import &quot;C:\PROGRAM FILES\COMMON FILES\MICROSOFT SHARED\VBA\VBA6\VBE6EXT.OLB&quot; \

rename(&quot;DialogBox&quot;, &quot;ExcelDialogBox&quot;) rename(&quot;RGB&quot;, &quot;ExcelRGB&quot;) \ rename(&quot;DocumentProperties&quot;, &quot;ExcelDocumentProperties&quot;) \ rename(&quot;ExitWindows&quot;, &quot;ExcelExitWindows&quot;) NOTE: If you installed Microsoft Office to a custom location, you may need to modify the paths above to conform to your installation.
 * 1) import &quot;C:\PROGRAM FILES\Microsoft Office\OFFICE\excel9.Olb&quot; \

 Compile and run the application, click the CommandButton, and note that the application crashes with an access violation. You need to find Excel.exe in the process list of Microsoft Windows NT and end it manually. Comment out the block of code marked &quot;This fails,&quot; and uncomment the block marked &quot;This works.&quot; Recompile and run the code, and note that the application succeeds and no access violation occurs.</li></ol>

Additional query words: AppWizard AV freezes freeze stops responding crash

Keywords: kbautomation kbprb kbprogramming KB278949

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.