Creating, opening and printing a word file from C++ - c++

I have three related questions.
I want to create a word file with a name from C++. I want to be able to sent the printing command to this file, so that the file is being printed without the user having to open the document and do it manually and I want to be able to open the document. Opening the document should just open word which then opens the file.

You can use Office Automation for this task. You can find answers to frequently asked questions about Office Automation with C++ at http://support.microsoft.com/kb/196776 and http://support.microsoft.com/kb/238972 .
Keep in mind that to do Office Automation with C++, you need to understand how to use COM.
Here are some examples of how to perform various tasks in word usign C++:
http://support.microsoft.com/kb/220911/en-us
http://support.microsoft.com/kb/238393/en-us
http://support.microsoft.com/kb/238611/en-us
Most of these samples show how to do it using MFC, but the concepts of using COM to manipulate Word are the same, even if you use ATL or COM directly.

As posted as an answer to a similar question, I advise you to look at this page where the author explains what solution he took to generate Word documents on a server, without MsWord being available, without automation or thirdparty libraries.

When you have the file and just want to print it, then look at this entry at Raymond Chen's blog. You can use the verb "print" for printing.
See the shellexecute msdn entry for details.

You can use automation to open MS Word (in background or foreground) and then send the needed commands.
A good starting place is the knowledge base article Office Automation Using Visual C++
Some C source code is available in How To Use Visual C++ to Access DocumentProperties with Automation (the title says C++, but it is plain C)

I have no experience from integrating with Microsoft Office, but I guess there are some APIs around that you can use for this.
However, if what you want to accomplish is a rudimentary way of printing formatted output and exporting it to a file that can be handled in Word, you might want to look into the RTF format. The format is quite simple to learn, and is supported by the RtfTextBox (or is it RichTextBox?), which also has some printing capabilities. The rtf format is the same format as is used by Windows Wordpad (write.exe).
This also has the benefit of not depending on MS Office in order to work.

My solution to this is to use the following command:
start /min winword <filename> /q /n /f /mFilePrint /mFileExit
This allows the user to specify a printer, no. of copies, etc.
Replace <filename> with the filename. It must be enclosed in double-quotation marks if it contains spaces. (e.g. file.rtf, "A File.docx")
It can be placed within a system call as in:
system("start /min winword <filename> /q /n /f /mFilePrint /mFileExit");
Here is a C++ header file with functions that handle this so you don't have to remember all of the switches if you use it frequently:
/*winword.h
*Includes functions to print Word files more easily
*/
#ifndef WINWORD_H_
#define WINWORD_H_
#include <string.h>
#include <stdlib.h>
//Opens Word minimized, shows the user a dialog box to allow them to
//select the printer, number of copies, etc., and then closes Word
void wordprint(char* filename){
char* command = new char[64 + strlen(filename)];
strcpy(command, "start /min winword \"");
strcat(command, filename);
strcat(command, "\" /q /n /f /mFilePrint /mFileExit");
system(command);
delete command;
}
//Opens the document in Word
void wordopen(char* filename){
char* command = new char[64 + strlen(filename)];
strcpy(command, "start /max winword \"");
strcat(command, filename);
strcat(command, "\" /q /n");
system(command);
delete command;
}
//Opens a copy of the document in Word so the user can save a copy
//without seeing or modifying the original
void wordduplicate(char* filename){
char* command = new char[64 + strlen(filename)];
strcpy(command, "start /max winword \"");
strcat(command, filename);
strcat(command, "\" /q /n /f");
system(command);
delete command;
}
#endif

Related

Opening excel files with system( ) on mac?

I am trying to get my C++ program to open up an existing Excel spreadsheet (along with a bunch of applications), however it keeps returning an error that a file does not exist. I am using the following code:
int main(){
system("open ~/path/file");
//--open applications using same command--//
}
The file is definitely there and this command works to open all the applications, so I'm not sure what I am doing wrong.
Thanks in advance!!
Very probably, the system /bin/sh -which by definition is used by system(3)- does not expand ~.
You might try something like
char cmd[256];
snprintf(cmd, sizeof(cmd), "open %s/path/file", getenv("HOME"));
if (0 != system(cmd))
{ fprintf(stderr, "%s failed\n", cmd); exit(EXIT_FAILURE); };
since interactive shells usually expand ~ as $HOME and HOME is generally an environment variable.
(With C++, you could use std::string operations instead of snprintf)
My snprintf + system trick is not at all failproof. If $HOME contains spaces or bizarre characters like ; or ', it wont work. And snprintf itself might fail (e.g. because $HOME is huge).
Of course, you'll better test before that getenv("HOME") is not NULL. You might use getpwuid(3) with getuid(2) if getenv("HOME") fails by returning NULL.
On Linux you probably want xdg-open instead of open.

How to open Nano and get a string from it in C++?

I am creating a simple logging program. When a user enters log some_file into the console, the program currently simply receives some basic input from cin, and records it into some_file.
However, instead of implementing my own editor with cin, I'd like to open the Nano editor and let the user edit his message there.
Then, when the message is complete, I'd like my C++ logger to receive it as a string and carry on.
This is exactly what git does on commits.
How can I achieve this?
(Preferably without using tools such as expect, just raw C++ code.)
Most editors expect to work with normal files, so you'd typically create a temporary file, then pass the name of that file to the editor on its command line. When the editor returns, you copy the content from the temporary file into your log, then destroy the file.
If you want to use the Nano editor then you need to run the system() function to invoke Nano with a temporary file. Then remove the file later..
std::string filename = "/tmp/.out." + std::to_string(getpid());
std::string cmd = "/bin/nano " + filename
system(cmd.c_str());
// read from filename
unlink(filename.c_str());
Update
If using tmpnam() as suggested by DevSolar
char filename[L_tmpnam];
tmpnam(filename);
std::string cmd = "/bin/nano " + filename
system(cmd.c_str());
unlink(filename);
what about open a file(passing file name to the editor), save and then read it from your program? I've always thought git works the same way.

Saving a file to a network in Qt

I need to save a file to my company's network. This needs to be coded into my application not using a File Dialog box or anything. When I save the file without specifying a path it saves it completely fine in the directory that my application is in but when I try to do it the network nothing happens. This is what I have to save it.
QFile outfile;
outfile.setFileName("//DTPRIMARY/MyFile.htm");
outfile.open(QIODevice::WriteOnly);
QTextStream out(&outfile);
out << textEdit->toHtml();
out.flush();
outfile.close();
I actually want to save it here \\DTPRIMARY\Inetpub\wwwroot but took out the other folders thinkging that could have been part of the problem but it wasn't. And I'm using '/'s instead of '\'s because thats what a few places said to do (I've never really understood why file paths have to use '\' or '/' though so it could be wrong idk.)
Does anyone know how to do this/what's wrong with my code?
UNC paths should work perfectly normally, you can test this with a local file eg "\\?\C:\MyFile.htm" would be a file called MyFile.htm in the top of the C drive
Normally the path would be \\machine\share eg \\dtprimaray\share\MyFile.htm
The reason for using "/" is that the C language uses \ to mean the next char is special, so \t is tab, \n is newline. DOS was copied (sorry influenced by) an earlier OS that used "/" for file separators and Microsoft didn't want DOS to look too much like a copy. It's been a source of bugs ever since.
You can use \\ to say to C the next \ is really a \ - but it's easy to make mistakes when you have to write \\\\ to mean \\ and \\ to mean \ - so Windows lets you use /
Just tested it on my machine
QFile file("//machinename/downloads/MyFile.htm");
file.open(QIODevice::WriteOnly);
file.write("blah");
file.close();

Open .chm file at specific page/topic using command line arguments

I am attempting to open a .chm file(A windows help file) at a specific page/topic by using a system call in C++.
I can successfully open the .chm file to the start page through the following code, but how can I open a .chm file to a specific page/topic inside the help file?
system("start c:/help/myhelp.chm");
PS: I know system is evil/discouraged but the system part is not really relevant its the command line arguments I pass with the .chm file(that will specify what page I want to open) that I am trying to determine.
Ok the arguments are like so:
system(" /Q /E:ON /C HH.EXE ms-its:myChm.chm::myPageName.htm");
There is an API in the Windows SDK called HtmlHelp in the HtmlHelp.h file. You can call like so:
HtmlHelp(GetDesktopWindow(), L"C:\\helpfile\\::/helptopic.html", HH_DISPLAY_TOPIC, NULL);
The Microsoft Docs - HtmlHelpA function provides more information about the function. HtmlHelp() will normally resolve to HtmlHelpA() or HtmlHelpW() depending on whether Unicode compiler option is set or not.
See as well Microsoft Docs - HTML Help API Overview.
Another option - use ShellExecute. The Microsoft help is not easy to use. This approach is much easier and in line with your question. Here is a quick routine to open a help file and pass an ID number. I have just set up some simple char’s so you can see what is going on:
void DisplayHelpTopic(int Topic)
{
// The .chm file usually has the same name as the application - if you don’t want to hardcode it...
char *CmndLine = GetCommandLine(); // Gets the command the program started with.
char Dir[255];
GetCurrentDirectory (255, Dir);
char str1[75] = "\0"; // Work string
strncat(str1, CmndLine, (strstr(CmndLine, ".exe") - CmndLine)); // Pull out the first parameter in the command line (should be the executable name) w/out the .exe
char AppName[50] = "\0";
strcpy(AppName, strrchr(str1, '\\')); // Get just the name of the executable, keeping the '\' in front for later when it is appended to the directory
char parms[300];
// Build the parameter string which includes the topic number and the fully qualified .chm application name
sprintf(parms,_T("-mapid %d ms-its:%s%s.chm"), Topic, Dir, AppName);
// Shell out, using My Window handle, specifying the Microsoft help utility, hh.exe, as the 'noun' and passing the parameter string we build above
// NOTE: The full command string will look like this:
// hh.exe -mapid 0 ms-its:C:\\Programs\\Application\\HelpFile.chm
HINSTANCE retval = ShellExecute(MyHndl, _T("open"), _T("hh.exe"), parms, NULL, SW_SHOW);
}
The topics are numbered within your .chm file. I set up a #define for each topic so if I had to change the .chm file I could just change the include file to match and not have to worry about searching through the code for hardcoded values.

printing to a network printer using fstream c++ in mac

I wish to print some text directly to a network printer from my c++ code (I am coding with xcode 4). I do know that everything on unix is a file and believe that it would not be impossible to redirect the text using fstream method in c++ to the printer device file. The only problem is I don't know the device file in /dev associated with my network printer.
Is it possible to achieve printing using fstream method? Something like
std::fstream printFile;
printFile.open("//PATH/TO/PRINTER/DEV", std::ios::out);
printFile << "This must go to printer" << std::endl;
printFile.close();
And, if so
How to obtain the file in /dev corresponding to a particular printer?
Thanks in advance,
Nikhil
Opening and writing directly to a file used to be possible back in the days of serial printers; however, this is not the approach available today.
The CUPS daemon provides print queuing, scheduling, and administrative interfaces on OS X and many other Unix systems. You can use the lp(1) or lpr(1) commands to print files. (The different commands come from different versions of print spoolers available in Unix systems over the years; one was derived from the BSD-sources and the other derived from the AT&T sources. For compatibility, CUPS provides both programs.)
You can probably achieve something like you were after with popen(3). In shell, it'd be something like:
echo hello | lp -
The - says to print from standard input.
I haven't tested this, but the popen(3) equivalent would probably look like this:
FILE *f = popen("lp -", "w");
if (!f)
exit(1);
fprintf(f, "output to the printer");
I recommend testing some inputs at the shell first to make sure that CUPS is prepared to handle the formatting of the content you intend to send. You might need to terminate lines with CRLF rather than just \n, otherwise the printer may "stair-step" the output. Or, if you're sending PDF or PS or PCL data, it'd be worthwhile testing that in the cheapest possible manner to make sure the print system works as you expect.