|
yep u got my point.....but how can we make it....
Suman
|
|
|
|
|
Yes that can be done by using OLE AUTOMATION. Just search on net for key word "Office Automation" VC++. You'll get lots of articles.
|
|
|
|
|
thanks Sujan..,
I will look over thru some of those articles and if I am not able to figure it out... then i will let u know...i hope u understood my problem clearly...
though i am able to open an excel sheet in my vc++ program... i must be able to write the values tht my program generates into it from whereever i want to in tht sheet (i.e in some way i must be able to switch between rows and columns of the excel sheet).
cheers,
Suman
|
|
|
|
|
Hi
the better way to start is to use the macro option in office products. Record a macro, open it in visual basic editor, convert it to a VC++ structure, and use it. But converting the visual basic code to VC++ code will take some time.
I haven't worked with excel, but with ms word and outlook.
Hope this helps you
Sujan
|
|
|
|
|
|
Hi Azam,
thanks for ur advice, I have gone through the link tht u have given and created an example project based upon those tutorial. Actually its an MFC application and it creates a dialog box on which we have to click on 'run' which then activates the excel.
but wht i am trying to do is .. my program is a pire c++ source file. it generates certain values in the time of its execution and at present i am writing them into an text file. But i want to open an excel sheet (just like i opened a text file) and then i have to write the values tht i generate..into the excel sheet (just like i write the values whenever generated into a text file). and then i have at the end of the execution i have show up the excel sheet.
one more thing is I'm willing to write the data in the sheet from a particular row and column. My data is a 2D data (256x256).
hope i am clear to u...if u r having any ideas lemme know i'll work on it.
thanks in advance,
Pavan.
Suman
|
|
|
|
|
ya i got it but wud you plz confirm me one thing, what kind of application you are developing, i mean is it a MFC based application (using CFile or some derivative of it for opening and writing text file) or a WIN32 application (using HFILE for opening and writing text file) or core C++ (using FILE structure for opening and writing text file).
As far as i know in either case you can use COM (or specifically Automation) for your application.
Also the link that i sent to you shows how you can write data in cells of excel sheet. were you able to run that program since if you are using excel 2002 or above then i suppose you have to change the line range.SetValue(COleVariant(saRet)); to range.SetValue2(COleVariant(saRet)); in your run method
any ways will try to figure out some thing for you
regards
Azam
|
|
|
|
|
Hi Azam,
I am writing just a common cpp source file and it is not any MFC or win32 application.I am using 'ofstream' to create text file and writing the values into it. My program goes like this....
#include <fstream.h>
#include <iostream.h>
#include <math.h>
#include <conio.h>
#define phi 3.1412
void main()
{.....
ofstream out_file("data.txt");
for(...)
{
for(...)
{.....
out_file<<",,,,";
}
}
....
}
yep i have ran tht tutorial program and it is indeed writing the values into excel..... but the only thing is completely dialog based and we have to enter values into the dialog box and then it writes it into excel sheet. But, here i have to write them directly into the excel sheet as and when i generate a value in my program..
hope i answered ur question in a right way...
thanks for ur help,
Suman
|
|
|
|
|
Hi Suman
Create a Win32 Console application project and paste the following code in the file containing main function donot forget to remove all things from that file b4 pasting
hope you will be able to customize this code according to your need what i suggest try to find the nested for loop that is writing in cells of excell file and in that nested for loop generate you data and assign it to the variable that is being written to the file;
One more suggestion try to encapsulate this procedureal code into some class for elegent look. and expose method like FIllCell(row,col,data) ..any ways its upto you further investigation of this code will also enable you to save the excel file on disk;
#include "stdafx.h"
#include <ole2.h>
// AutoWrap() - Automation helper function...
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010);
_exit(0);
}
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
if(FAILED(hr)) {
sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
VARIANT *pArgs = new VARIANT[cArgs+1];
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(marker, VARIANT);
}
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
va_end(marker);
delete [] pArgs;
return hr;
}
int main(int argc, char* argv[])
{
CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);
if(FAILED(hr)) {
::MessageBox(NULL, "CLSIDFromProgID() failed", "Error", 0x10010);
return -1;
}
IDispatch *pXlApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pXlApp);
if(FAILED(hr)) {
::MessageBox(NULL, "Excel not registered properly", "Error", 0x10010);
return -2;
}
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible", 1, x);
}
IDispatch *pXlBooks;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Workbooks", 0);
pXlBooks = result.pdispVal;
}
IDispatch *pXlBook;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"Add", 0);
pXlBook = result.pdispVal;
}
VARIANT arr;
arr.vt = VT_ARRAY | VT_VARIANT;
{
SAFEARRAYBOUND sab[2];
sab[0].lLbound = 1; sab[0].cElements = 15;
sab[1].lLbound = 1; sab[1].cElements = 15;
arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
}
for(int i=1; i<=15; i++) {
for(int j=1; j<=15; j++) {
VARIANT tmp;
tmp.vt = VT_I4;
tmp.lVal = i*j;
long indices[] = {i,j};
SafeArrayPutElement(arr.parray, indices, (void *)&tmp);
}
}
IDispatch *pXlSheet;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"ActiveSheet", 0);
pXlSheet = result.pdispVal;
}
IDispatch *pXlRange;
{
VARIANT parm;
parm.vt = VT_BSTR;
parm.bstrVal = ::SysAllocString(L"A1:O15");
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);
VariantClear(&parm);
pXlRange = result.pdispVal;
}
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L"Value", 1, arr);
::MessageBox(NULL, "All done.", "Notice", 0x10000);
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlBook, L"Saved", 1, x);
}
AutoWrap(DISPATCH_METHOD, NULL, pXlApp, L"Quit", 0);
pXlRange->Release();
pXlSheet->Release();
pXlBook->Release();
pXlBooks->Release();
pXlApp->Release();
VariantClear(&arr);
CoUninitialize();
return 0;
}
hope this time i am on right direction
regards
Azam
|
|
|
|
|
oh there was a typo mistake
in HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...)
// Extract arguments...
for(int i=0; i pArgs[i] = va_arg(marker, VARIANT);
}
replace these lines with these
for(int i=0; i < cArgs; i++) {
pArgs[i] = va_arg(marker, VARIANT);
}
|
|
|
|
|
Hi Azam,
thank you very much... it seems u have spent some of ur valuable time for my program.... at sometime today, i will try to include it in my program and make necessary changes and let you know the consequences.
once again thanking you,
Pavan.
Suman
|
|
|
|
|
Hi Azam,
thanks for ur concern and I am not able to understand ur code and include it into my program. Actually I have tried it doin till today and as I am feeling some guilty to tell you that I am unable to understand it. The actual thing is it was a long time for me doin programming (my undergrad is CSE) and at present i am in Biomedical Engineering doing a project on programming related BME project.
Actually instead of doin all these, if u don't mind i got an idea... why can't we draw a graph (3D graph) in c++ only with tht data. i did some 2D graphs, but no idea on 3D graphs, if I am goin in right direction, can u gimme any suggestions on this.
thanks for ur help,
Suman
|
|
|
|
|
Hi Suman
i really appreciate your effort, beleive me there is nothing to feel guilty about if you are unable to understand some code (it also happens to me as well, so no prob ). Atleast you haven't given it up and this should be the spirit, since not failure but low AIM is a crime.
any ways in C++, there are a number of graphics libraries that can be used to render 3D graphs. OpenGl (for example) is a very simple,powerful and easy to use 3d library and inparticular if you use one of its utility called "glut" then just with few lines of code you can draw 3D object in you program. (ya in console program as well )
so if you need any paarticular help about it then i can also do something in it for you since i worked on OpenGL in 2001 ( ya long ago).
wish you best of luck in your BME project
regards
Azam
|
|
|
|
|
Hi Azam,
thanks for ur inspiration. Anyway i am not an easy goin one, so i always feel guilty if i am not getting something which I have to.
I have seen some articles on OpenGL for 3D plots and I am goin thru them and let u know if i need any help in tht.
Meanwhile if u can i am having another task to complete, i.e changing my medical images into BMP format so that I can read them directly. My image files are in *.LL1 and *.LT1 formats. I am having their header info, but i haven't done regarding to header of images reviously, nor i did any format manipulations of images. The interesting thing is i have approached someone at fCoder group of developers, and they r able to convert, but for the source code or exe file they want me to pay $1000... . I have asked them to gimme some step by step procedure how to convert it. I hope they are even not willin to tell tht.
anyway thanks for ur time,
Suman
|
|
|
|
|
Hi Azam,
sorry to bother u again. Here is an article from our code project tht seems interesting to me on 3D plots.
http://www.thecodeproject.com/opengl/ntgraph3d_atl.asp
i am surprised whether it is so easy to implement it. But u know mine is a normal c++ source file, but he says tht inorder to use it we have to have an ActiveX control and then he has given the c++ snippet. Can u tell me how can i change my program to ActiveX control and embed this code into mine. Also i am generating my data in a for loop and i am having x,y,z values (one z value for each iteration) and how can i plot with my values. I will mail him too. But if got some ideas lemme know.
thanks in advance,
Suman
|
|
|
|
|
Hi Suman
There is no need to convert your program into an ActiveX control to use this code. Basically the author has given An ActiveX control, that can be used in our applications, to do this first we have to register the control using following command regsvr32 "C:\NTGraph3D_bin\NTGraph3D.dll" then we can use it in our ( vb,vc) applications (as demostrated by author in NTGraph3D_demo project ).
As far as your senario is concerned you have a plain C++ application, you have two options,
1. either search web for "using activeX control in console based applications".
2. or since the author has given the source of this ActiveX control use the classes created by him in your code.
if you are determined to use this control then do tell me lets see if i can figure out further on the above mentioned options, or if you have some other idea then also share it with me.
ActiveX Controls basically expose some methods and properties that we use to communicate with the control.
regards
Azam
|
|
|
|
|
Hi Azam,
Thanks for ur reply. I finally decidedd to use this control given in our forum. But i am not getting how to use it in my application. Prefer not to say, the demo progams are all greek and latin for me (sorry as a programmer i shouldn't say tht, but actually i am not able to understand). If I can sit for 1 to 2 days on it, i hope i may understand. But, this week i am busy with my midterm exams in other courses and i have to complete this by this friday. So, if u don't mind can u help me out in using this control in my program.
I want just an ActiveX control window showin my 3DSurface plot on it (i mean i don't need all those extra controls tht he has implemented in his demos, just a window with my plot). I hope I am clear. Just tell me how I can use it in my program if I am having 3 coordinates (x,y,z).
sorry, If i am bothering you. But, its urgent for me and I am not having time to go thru those demos in detail.
once again thanks for ur concern,
Suman
|
|
|
|
|
Suman, the problem here is that ActiveX control requires a container to run ( and container should be a CWnd derived class ). I have got an idea, if you donot mind give, give me you code ( i will embed this control in it thruogh some way and will mail it back to you ).
my email address is
muhammadazam_cis08@hotmail.com
regards
Azam
|
|
|
|
|
I opened a Word document using CreateProcess but how do I close or exit the process? I know I need to use ExitProcess(UINT exitcode) but how to I obtain the exitcode. Below is a sample of my code. Thanks!
----------------------------------------------------------------
void OpenFile()
{
char str[300];
DWORD dwExitCode;
STARTUPINFO stStartUpInfo;
PROCESS_INFORMATION pProcessInfo;
memset(&stStartUpInfo, 0, sizeof(STARTUPINFO));
stStartUpInfo.cb = sizeof(STARTUPINFO);
stStartUpInfo.dwFlags = STARTF_USESHOWWINDOW;
stStartUpInfo.wShowWindow = SW_SHOWDEFAULT;
stStartUpInfo.dwXSize = STARTF_USESIZE;
stStartUpInfo.dwYSize = STARTF_USESIZE;
CreateProcess(NULL, str, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS, NULL,
NULL, &stStartUpInfo, &pProcessInfo);
GetExitCodeProcess(pProcessInfo.hProcess, &dwExitCode);
}
void CloseFile()
{
....code...
ExitProcess(dwExitCode);
}
|
|
|
|
|
After the process is created, you can use pProcessInfo and OpenProcess to obtain a handle to the running process (pProcessInfo.hProcess ). Giving this handle to TerminateProcess will instantly kill the running application. Note that this is the same thing as using CTRL+ALT+DEL on a Windows XP machine: the target process is not notified that it is closing, but is terminated instantly. If you're operating on a Word document to which the user can read, write and save, then using TerminateProcess is a sure way to lose all unsaved work. It will not ask questions or confirmations: it will just kill the process, straight through.
After the process is terminated, GetExitCodeProcess will return the exit code with which the primary thread of the application exited.
Is this what you asked for ?
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Yes, TerminateProcess is what I need to exit the process unconditionally. What I'm really trying to do is parse a word document and pass the values to another child MDI Window for display. The word document gets parsed and opened for viewing via CreateProcess.
Now if the child window was closed and needs to be viewed once again, the user must select that same word document to be re-parsed. It can't parse it when it's already open so I need to close that document and then reopen it for the parsing to work. How can I keep track of all of the word documents that are currently open so that I can close them for re-parsing?
|
|
|
|
|
Hey all, I am having a problem when given a CTempWnd pointer to a deleted window.
I have developed CButton derived class that is supposed to, when clicked, return the input focus to the window that had it before it was clicked. I do this by saving the HWND of the window that is passed into the OnSetFocus() function, and set the focus back to it in the BN_CLICKED message handler.
void COneClickButton::OnSetFocus(CWnd *pOldWnd)
{
CButton::OnSetFocus(pOldWnd);
COneClickButton *pOCB = dynamic_cast<COneClickButton *>(pOldWnd);
m_hFocusFromWnd = *pOCB ? pOCB->m_hFocusFromWnd : *pOldWnd;
}
BOOL COneClickButton::OnClicked()
{
if (IsWindow(m_hFocusFromWnd))
::SetFocus(m_hFocusFromWnd);
else
GetParent()->SetFocus();
return FALSE;
} Ok, that was the easy part. Now comes the fun part that I am having a problem with.
I am using Chris's MFCGrid on a CPropertyPage, with several COneClickButton buttons on the property sheet. The problem comes when the user is editing a cell on the grid and then clicks one of the buttons while the edit window is still open. The CInPlaceEdit class that the grid uses for editing has a feature where by it closes and deletes itself as soon as it loses the input focus, which is all fine and well. But now, when the COneClickButton gets the focus, the pOldWnd pointer points to a now invalid window and the button has no idea where to return the focus. Currently I just set the focus to the property sheet, which passes the focus to the first control on the page. I want the focus to go back to the MFCGrid.
Anybody have any ideas on how to accomplish this, short of handling WM_SETFOCUS messages for every control in my app?
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it!
|
|
|
|
|
The answer is inside the CPropertyPage . This class is derived from CDialog and onwards from CWnd . This inheritance chain will allow access to the GetDlgItem function. Using this function can return a pointer to the requested dialog control's CWnd parent class.
As you are coding the property page, you also have access to the ID specified to the MFCGrid. Thus, you can use GetDlgItem to obtain the CWnd -pointer and call CWnd::SetFocus to set the input focus to the grid. All this should be done only if the handle to the old window is no longer valid (in place of GetParent()->SetFocus() ).
Does this solve it ?
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Antti Keskinen wrote:
Does this solve it ?
Yes and no. It sounds like it will work, I will give it try. But it is not very OOP. It will require the COneClickButton knowing all about the property sheet it is on, the pages that are on the sheet, and the grids that are on the pages. I was hoping to there was a way that it could be done without the COneClickButton knowing all that stuff.
Thanks for the pointer, I am now further along then I was before.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it!
|
|
|
|
|
If you had a normal Windows control, it would always have the HWND of the parent window. Thus, getting this HWND and enumerating the child windows would return the control itself at some point.
The COneClickButton is a similar case: it is an MFC control (I presume), thus it needs to be derived from CWnd. In this case, it has the GetParent function, which allows it to get a pointer to the parent's CWnd class.
The most object-oriented way (I think) would be to first use GetParent to get the parent window (property page) and then use EnumChildWindows to query through all children of this page, looking for one which has the same class name as the grid control.
I don't think there is a more object oriented way than that without breaking the way Windows works.. Or at least, I'm not aware of one if there is..
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|