|
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.
|
|
|
|
|
Well,
I have been using the same for some time now with
out any probs.
Anyway, Just be careful that the BSTRs can contain
null('\0') characters in between and this macro will
not take that into account.
|
|
|
|
|
Prem Kumar wrote:
I have been using the same for some time now with
out any probs
Whew! Good to hear that!
Prem Kumar wrote:
Anyway, Just be careful that the BSTRs can contain
null('\0') characters in between and this macro will
not take that into account.
Thanks for that.
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
W2A uses stack, so size of BSTR is limited.
Use this code:
inline char* ConvertBSTRToString(BSTR pSrc)
{
if(!pSrc) return NULL;
DWORD cb,cwch = ::SysStringLen(pSrc);
char *szOut = NULL;
if(cb = ::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, NULL, 0, 0, 0))
{
szOut = new char[cb];
if(szOut)
{
szOut[cb - 1] = '\0';
if(!::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, szOut, cb, 0, 0))
{
delete []szOut;
szOut = NULL;
}
}
}
return szOut;
};
soptest
|
|
|
|
|
Wow! Thanks. That's a lot of code for a conversion.
Nish
p.s. Right now I won't have to use this, as I know the size of the BSTRs and they are rather small
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
I created an ATL DLL server project and inserted a new ATL object as a simple one, named Inter. Next, i added a new BSTR-type property named Str.
I wrote:
STDMETHODIMP CInter::get_Str(BSTR *pVal)
{
_bstr_t x(*pVal, FALSE);
m_str=x.copy();
return S_OK;
}
This code links perfectly on debug versions but generates this error:
LIBCMT.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
on release versions.
Do you know how to handle it?
rechi
|
|
|
|
|
Taken from "INFO: Active Template Library (ATL) 2.0 Readme File" in MSDN, hope it helps...
<br />
_ATL_MIN_CRT and Link Error "unresolved external symbol _main"<br />
--------------------------------------------------------------<br />
<br />
When you build a Release version of an ATL project, you can get the<br />
following link error:<br />
<br />
LIBCMT.LIB(crt0.obj) : error LNK2001: unresolved external symbol _main<br />
<br />
This error occurs if you are using CRT functions that require CRT startup<br />
code. The Release configurations define _ATL_MIN_CRT, which excludes CRT<br />
startup code from your EXE or DLL. To avoid this error, do one of the<br />
following:<br />
<br />
- Remove _ATL_MIN_CRT from the list of preprocessor defines to allow CRT<br />
startup code to be included. On the Build menu, click Settings. Hold<br />
the ctrl key while selecting all Release configurations. On the C/C++<br />
tab, choose the General category, then remove _ATL_MIN_CRT from the<br />
preprocessor definitions edit box.<br />
<br />
- If possible, remove calls to CRT functions that require CRT startup<br />
code. Instead, use their Win32 equivalents. For example, use lstrcmp()<br />
instead of strcmp(). Known functions that require CRT startup code are<br />
some of the string and floating point functions.<br />
Dylan Kenneally
London, UK
|
|
|
|
|
I've an OLE automated project to convert MS Excel document to PDf file. I use the
void _Workbook::PrintOut(const VARIANT& From,
const VARIANT& To,
const VARIANT& Copies,
const VARIANT& Preview,
const VARIANT& ActivePrinter,
const VARIANT& PrintToFile,
const VARIANT& Collate,
const VARIANT& PrToFileName)
for printing into Acrobat PDFWriter. It runs, but the problem is that Acrobat appears. How can i do to avoid this, please ?
Thanks.
Aziz Rajim.
|
|
|
|
|
I think if you use Adobe PDFWriter, then Acrobat is gonna popup. Alternatively you could consider using LibPDF or other pdf writing libraries to write your pdf file?
sonork: 100:18407
|
|
|
|
|
I want to get HTML code from MSHTML Document.But I can't.
public Samples
//pDoc,IHTMLDocument2
IHTMLElement *elem;
BSTR* bstrVal;
pDoc->get_body(&elem);
elem->get_innerHTML(&bstrVal);
.....
But This Code can't get or ,etc.
For Example,
....
...
....
Please tell me how to get ALL HTML code.
|
|
|
|
|