|
Did you try to pass it as a reference instead?
va.vt = VT_ARRAY | VT_BYREF | VT_R4;
va.pparray= &psa;
Your code seems to work fine other than that!
What API are you using? the way it expects to
receive your data is also important.
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ernest Laurentin wrote:
Did you try to pass it as a reference instead?
Yup, didn't work too.
The API is a Avid SoftImage XSI v2 SDK. It has virtually ZERO documentation so I'm guessing how to call it by looking at headers and vbscript examples.
The vbscript version works like this
<br />
Blah( array(5,6,7) )<br />
The C++ version is defined as
<br />
virtual HRESULT STDMETHODCALLTYPE Blah( <br />
VARIANT in_pNewEffPos );<br />
The worst part is the API runs successfully (HR succeeded) but the results are wrong.
I'm not well experienced enough with COM or I would have condemn it as a bug with their API straight away.
|
|
|
|
|
Sorry it took me long to write you!
Did you try to send "long" or "short" array?
You example here both integer value not float. Maybe
the API accepts integer value not float!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ernest Laurentin wrote:
Maybe
the API accepts integer value not float!
Thanks for the reply.
Quite impossible. It should be taking either float or double because in the UI, one can enter decimal places for the values. They can't be using fixed point maths.
But I will try again just to make doubly sure.
|
|
|
|
|
I see... but I still think if you can make it work with
VBScript, you can implement the same in C++. Did you try
to reproduce simple code in VB? For example:
dim vbArray(3)
dim nloop
for nloop = 0 to 3
vbArray(nloop) = nloop+4 ' or other value
next
Blah( vbArray )
The reason I will do it like this instead to do just call:
Blah( array(5,6,7) ) is that I am not really sure
how VB interprets that line. But you should be able to reproduce
the same type of array (dim vbArray as "type").
Good luck!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
That's a very good idea you have there. Unfortunately (fortunately?), it's weekend party and I have to wait till next week to try it out.
Thanks for your time. Very appreciated.
|
|
|
|
|
Fortunately for you, I guess! Keep in touch! Have great time!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ah, I spotted an mistake
It should be
<br />
Dim vbArray(2)<br />
instead of
<br />
Dim vbArray(3)<br />
because for reasons I cannot fathom, vbArray(2) means a 3 element array.
Anyway, the vbscript in the form above works. I am unable to explicitly declare the dim type though. Dim vbArray(2) As Double generates an "Expected end of statement" error. This seems to be more of the scripting environment problem rather than mine.
|
|
|
|
|
Yes, the reason is VBScript is only a subset of visual basic. You can't
really use that form Dim vbArray(2) as Double . In fact, I was
suggesting you to try it in Visual Basic or VBA (I use Excel sometimes to do that!
As far as the syntax, Dim vbArray(3) is the one that I used with another
API and it works fine. BTW, VBScript will pass your data as an array of variant.
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Basicly, I want to do this in vc++:
open Excel application
open Excel worksheet
add some cells
save & quit the application
all this without MFC, want to use it inside a dll.
I've searched the msdn for some while, but the only thing I've found was some examples using the vb libraries.
Can anyone show me a page where I can start from?
Is it true that there are no header files for office (examples use vbeext1.olb)?
Is it true that every office-version needs other libraries? (Some of our clients have o97, others have o2000 or oXP)
btw. I've already worked with com, direct-x is no problem for me.
tnx.
[VISUAL STUDIO 6.0] [MFC] [WIN98/2]
Bluute tette!
|
|
|
|
|
Look at MSDN
HOWTO: Embed and Automate a Microsoft Excel Worksheet with MFC (Q184663)
--------------------------------------------------------------------------------
The information in this article applies to:
Microsoft Visual C++, 32-bit Professional Edition, versions 5.0 , 5.0sp3 , 6.0
The Microsoft Foundation Classes (MFC)
Microsoft Office XP Developer
Microsoft Office 2000 Developer
Microsoft Excel 2002
Microsoft Excel 2000
Microsoft Excel 97 for Windows
--------------------------------------------------------------------------------
SUMMARY
This article describes how to embed a Microsoft Excel Worksheet into a View object in an SDI MFC application.
This article includes step-by-step instructions for embedding the worksheet and adding some text to cell A1, as well as comments explaining each step.
Although the sample code in this article can be taken and put into your application, the real benefit comes from reading and understanding the sample.
MORE INFORMATION
Here are the steps for creating the MFC application:
Use the AppWizard to create a new MFC AppWizard (EXE) project named "Embed_Excel."
Select Single Document as the type of application to create, and select Container as the type of compound document support to include. Accept all other default settings.
The following classes are generated:
Application : CEmbed_ExcelApp in Embed_Excel.h and Embed_Excel.cpp
Frame : CMainFrame in MainFrm.h and MainFrm.cpp
Document : CEmbed_ExcelDoc in Embed_ExcelDoc.h and Embed_ExcelDoc.cpp
View : CEmbed_ExcelView in Embed_ExcelView.h and Embed_ExcelView.cpp
Container Item : CEmbed_ExcelCntrItem in CntrItem.h and CntrItem.cpp
On the View menu, click ClassWizard . Click the Automation tab, click Add Class , and choose From a Type Library . Locate the Microsoft Excel type library , and add all the classes in the type library to your project. For Excel 97, the type library is located in Excel8.olb. For Excel 2000 the type library is located in Excel9.olb, and for Excel 2002, the type library it located in Excel.exe.
Add the following line to CntrItem.h:
LPDISPATCH GetIDispatch();
Then add the GetIDispatch method to CntrItem.cpp:
Sample Code
-----------
/*******************************************************************
* This method returns the IDispatch* for the application linked to
* this container.
********************************************************************/
LPDISPATCH CEmbed_ExcelCntrItem::GetIDispatch()
{
//The this and m_lpObject pointers must be valid for this function
//to work correctly. The m_lpObject is the IUnknown pointer to
// this object.
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
LPUNKNOWN lpUnk = m_lpObject;
//The embedded application must be running in order for the rest
//of the function to work.
Run();
//QI for the IOleLink interface of m_lpObject.
LPOLELINK lpOleLink = NULL;
if (m_lpObject->QueryInterface(IID_IOleLink,
(LPVOID FAR*)&lpOleLink) == NOERROR)
{
ASSERT(lpOleLink != NULL);
lpUnk = NULL;
//Retrieve the IUnknown interface to the linked application.
if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
{
TRACE0("Warning: Link is not connected!\n");
lpOleLink->Release();
return NULL;
}
ASSERT(lpUnk != NULL);
}
//QI for the IDispatch interface of the linked application.
LPDISPATCH lpDispatch = NULL;
if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch)
!=NOERROR)
{
TRACE0("Warning: does not support IDispatch!\n");
return NULL;
}
//After assuring ourselves it is valid, return the IDispatch
//interface to the caller.
ASSERT(lpDispatch != NULL);
return lpDispatch;
}
Add the following line to Embed_ExcelView.h:
void EmbedAutomateExcel();
Then add the EmbedAutomateExcel method to Embed_ExcelView.cpp:
Sample Code
-----------
/********************************************************************
* This method encapsulates the process of embedding an Excel
* Worksheet in a View object and automating that worksheet to add
* some text to cell A1.
********************************************************************/
void CEmbed_ExcelView::EmbedAutomateExcel()
{
//Change the cursor so the user knows something exciting is going
//on.
BeginWaitCursor();
CEmbed_ExcelCntrItem* pItem = NULL;
TRY
{
//Get the document associated with this view, and be sure it's
//valid.
CEmbed_ExcelDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//Create a new item associated with this document, and be sure
//it's valid.
pItem = new CEmbed_ExcelCntrItem(pDoc);
ASSERT_VALID(pItem);
// Get Class ID for Excel sheet.
// This is used in creation.
CLSID clsid;
if(FAILED(::CLSIDFromProgID(L"Excel.sheet",&clsid)))
//Any exception will do. We just need to break out of the
//TRY statement.
AfxThrowMemoryException();
// Create the Excel embedded item.
if(!pItem->CreateNewItem(clsid))
//Any exception will do. We just need to break out of the
//TRY statement.
AfxThrowMemoryException();
//Make sure the new CContainerItem is valid.
ASSERT_VALID(pItem);
// Launch the server to edit the item.
pItem->DoVerb(OLEIVERB_SHOW, this);
// As an arbitrary user interface design, this sets the
// selection to the last item inserted.
m_pSelection = pItem; // set selection to last inserted item
pDoc->UpdateAllViews(NULL);
//Query for the dispatch pointer for the embedded object. In
//this case, this is the Excel worksheet.
LPDISPATCH lpDisp;
lpDisp = pItem->GetIDispatch();
//Add text in cell A1 of the embedded Excel sheet
_Workbook wb;
Worksheets wsSet;
_Worksheet ws;
Range range;
_Application app;
//set _Workbook wb to use lpDisp, the IDispatch* of the
//actual workbook.
wb.AttachDispatch(lpDisp);
//Then get the worksheet's application.
app = wb.GetApplication();
//Then get the first worksheet in the workbook
wsSet = wb.GetWorksheets();
ws = wsSet.GetItem(COleVariant((short)1));
//From there, get a Range object corresponding to cell A1.
range = ws.GetRange(COleVariant("A1"), COleVariant("A1"));
//Fill A1 with the string "Hello, World!"
range.SetValue(COleVariant("Hello, World!"));
//NOTE: If you are automating Excel 2002, the Range.SetValue method has an
//additional optional parameter specifying the data type. Because the
//parameter is optional, existing code will still work correctly, but new
//code should use the new convention. The call for Excel2002 should look
//like the following:
//range.SetValue( ColeVariant( (long)DISP_E_PARAMNOTFOUND, VT_ERROR ),
// COleVariant("Hello, World!"));
}
//Here, we need to do clean up if something went wrong.
CATCH(CException, e)
{
if (pItem != NULL)
{
ASSERT_VALID(pItem);
pItem->Delete();
}
AfxMessageBox(IDP_FAILED_TO_CREATE);
}
END_CATCH
//Set the cursor back to normal so the user knows exciting stuff
//is no longer happening.
EndWaitCursor();
}
Add the following line to Embed_ExcelView.h:
#include "excel8.h"
NOTE: If you are automating Excel 2000, the header file is "excel9.h." If you are automating Excel 2002, the header file is "excel.h."
Look at the OnInsertObject() method of the View class. It is interesting to note that this method, and the method we've just written, are strikingly similar. In fact, the code we've written is merely a special case of OnInsertObject(), which allows the user to select from a list of available OLE objects to insert into the application. Because we only want to automate the Excel Worksheet, we override this behavior. For our application, remove all the code from the interior of InsertObject() and replace it with a call to EmbedAutomateExcel().
Compile and run the application.
On the Edit menu, click Insert New Object .
RESULTS: A Microsoft Excel worksheet is embedded into the View; additionally, through automation, the contents of cell A1 is populated with "Hello, World!"
|
|
|
|
|
I am trying to create a visualization for the Windows Media Player. The SDK comes with a wizard that creates an ATL class for a COM DLL with the appropriate interfaces etc. One of the functions is Render which is passed a HDC. Using the HDC one can draw whatever visualization. All this works fine.
Now I want to display some bitmaps. So in the DLL I added a Bitmap into the resource by importing a picture. Then I am trying to use LoadBitmap or LoadImage. Both fail. I get the following error when I call GetLastError:
1814: The specified resource name cannot be found in the image file.
I am assuming I am getting this because I do not have the propoer HINSTANCE for the call to LoadImage or LoadBitmap. I am using a NULL not knowing how to get the HINSTANCE for the media player. Or should it be one for the DLL? Now I am all confused..... help........
Thanks...
|
|
|
|
|
Finally got it. I needed to use _Module.GetResourceInstance()
|
|
|
|
|
in your DLLMain
myBitmap = LoadBitmap( hInstance , MAKEINTRESOURCE( IDB_MY_BITMAP);
and in your control class, or wherever you need it, do an
extern HBITMAP myBitmap;
There may be other ways.
|
|
|
|
|
Hello,
I've just read an article here saying how to use the IPStorage COM class to enumerate the data in windows' protected storage.
http://www.codeproject.com/w2k/pseenuma.asp
First of all, (please corret me if I'm wrong) must a Coclass be created before used? plus, must it be first declared in a header file? If yes, how about the method suggested in the example - create a class using a DLL function and then access its members directly without being declared?
I've done too much Delphi programming before moving to VC++ so please excuse me if I'm talking nonsense here...
I would be glad if anyone can give me an example for doing the enumeration.
|
|
|
|
|
Hi,
I'm getting scrolling problem in WTL Scrollview window. I've derived a class from CScrollWindowImpl class and did some drawing. If I want to scroll the window, here the problem comes. In MFC OnInitialUpdate function there, is it any equivalent function available in WTL. Please can any one help me out?
If I want to scroll dynamically by calculating the view size and set the scroll ranges, what are all the steps I've to follow?
Advance thanx
Regards,
Ramesh.
|
|
|
|
|
Should an MFC ActiveX control be designed to retun SCODES or HRESULTS to indicate status of a method? I'm not talking about critical problems, just to indicate failure.
From my understanding they should fire an error (in a custom method, throw in a property setting method) if it's a critical problem, but what about those little day to day things like an invalid parameter or to indicate the status of a procedure such as updating a database record?
I tried returning a VARIANT_BOOL, but it always evaluates to TRUE at the container end, in both an mfc dialog app and a vb test app, even when explictly set to VARIANT_FALSE and comparing the return agains VARIANT_FALSE (making no assumptions about its actual value).
I've pored over approximately 200 documents/web pages mostly on the net and in the MSDN documentation and they are completely conflicting on this issue. Generally they have completely different standpoints depending upon what era they come from.
Some say SCODES are a holdout from the times of the proverbial ancients (1995?), but VC7 Add method wizard only lists SCODE as a return type, not HRESULT.
Some docs say they are the same and interchangeable, others say SCODES are 16 bits and HRESULTS 32, other docs say SCODES are 64 bit and HRESULT 32!!!!
Some docments say that all ActiveX objects should return only HRESULTS and some say SCODES only.
If they are the same why are there functions to convert and SCODE into an HRESULT in the platform sdk etc etc. It goes on, but does anyone know the definitive answer?
|
|
|
|
|
SCODE and HRESULT are different on 16(bit) platforms,
and they are the same on 32(bit) platforms
soptest
|
|
|
|
|
Like others said, SCODE is for 16/32 legacy systems.
New code should use HRESULT.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Hmmm...so why does the VC7 Add method wizard not supply HRESULT on the list of possible return types but rather SCODE?
|
|
|
|
|
for 16(bit) compatibility
soptest
|
|
|
|
|
When I call IGlobalInterfaceTable::RevokeInterfaceFromGlobal from a FTM object created in the main STA for an sub-object that was created from a MTA thread, a deadlock seems to occurs while I am revoking the interface (from the STA).
Here are the steps:
1) Create an object (that aggregate the FTM) in the main STA
2) Call a function on that object from a MTA thread and from that function create an sub-object (that does uses the FTM) in the STA but register it in the GIT from the MTA.
3) Destroy the object from the STA. When revoking the cookie for the sub-object a deadlock seems to occurs.
Any idea for a solution?
Should an object always be registered from it own apartment?
Does there is some restrictions when using the GIT for FTM objects?
Is my problem caused by the MTA not responding at that time?
In fact, if I force the creation of the sub-object from the STA instead of waiting when I need it (which will occurs from a call made from a MTA in my case), no deadlock will occurs...
I haven't found much "advanced" informations on the GIT and the MSDN documentation is not clear enough about potential problems, limitations and restrictions. Any suggestions?
Philippe Mori
|
|
|
|
|
May be this will help you to resolve this problem:
The apartment that calls RegisterInterfaceInGlobal method must remain alive until the corresponding call to RevokeInterfaceFromGlobal.
soptest
|
|
|
|
|
I have change how objects are destroyed and it seems to works fine...
Now I start by destroying sub-object in FinalRelease and then releasing the FTM for that object. In my initial implementation (which was not working in some cases), the FTM was destroyed first (in FinalRelease) but sub-objects were destroyed only by the destructor (automatic objects are used).
Also I now aggregate the FTM on demand for each of those object.
Philippe Mori
|
|
|
|
|
[earlier posted in the VC++ forum with zero answers ]
Is it S_OK to use W2A to convert from a BSTR to a const char * ?
Means, can I do this?
const char * p = W2A(bstrBlah);
Nish
p.s. I am doing this now and without any problem. But I just wanna know if it is safe!
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|