Solved

How to make a  .doc file out of a report made from VC++ to be able to email it.

Posted on 2003-11-07
27
463 Views
Last Modified: 2013-11-20
Hi!
I have an app made with VC++ 6.0 that prints out a multipage report...quite a job!!!! The way I print it is to take the desired CString data from the data base (Access), stuff it into a CStringArray(). I have my print preview and everything working fine. Now, I want to be able to email the report. So I guess I have to create a text file, and put the data into the say .doc extension to be able to be read by MS Word for the user on the recieving end to be able to print it out. How to go about this ?? Here is an example of part of my code that prints out one part of the report just so you can understand where I'mm coming from. There may be more than one way to make an emailable file. I'm open to all suggestions. Thanks very much.

CODE***************************
void CINSPECView::OnPrint(CDC *pDC, CPrintInfo *pInfo)
{

            CINSPECDoc *pDoc =GetDocument();
            m_nPage=pInfo->m_nCurPage;//for PrintPageFooter's benefit
            //*********************************
            //detailed report printout code
            if(m_nPage<=detailPages)
            {
                  CString str = "";
                  pDC->SetMapMode(MM_TWIPS);

                  CPoint            point(0,0);

                  TEXTMETRIC tm;

                  if(m_nPage==1)
                  {
                        nLinesPerPage=24;
                  }      
                  if(m_nPage==2)
                  {
                        pDC->SetMapMode(MM_TWIPS);//reset if desired for pages after page 1
                        nLinesPerPage=52;
                  }
                  if(m_nPage>=3)      
                  {
                        pDC->SetMapMode(MM_TWIPS);//reset if desired for pages after page 1
                        nLinesPerPage=50;
                  }
            //**************************************************************************************
                  //nStart is first line number of current page
                  //nEnd is last line number of current page
            //******************************************                  
                  if(m_nPage==1)
                  {
                        i=1;//reset index valuevfor CStringArray
                        nStart = (m_nPage-1) * nLinesPerPage;
                        nEnd = nStart + nLinesPerPage;
                  }
                  if(m_nPage==2)
                  {
                        nStart = 25;
                        nEnd = nStart + nLinesPerPage;
                  }
                  if(m_nPage>2)
                  {
                        nStart = nEnd+1;
                        nEnd = nStart + nLinesPerPage;
                  }
            //******************************************
                  //decide which PageHeader to use. Use PrintPageHeader(pDC) if page 1
                  //else, use PrintPageHeader2(pDC).
                  if(m_nPage>=2)
                  {
                        PrintPageHeader2(pDC);//header for second page and on
                  }
                  else
                  {
                        PrintPageHeader(pDC);//header for first page only
                  }
                  pDC->GetTextMetrics(&tm);      
                  nHeight = tm.tmHeight + tm.tmExternalLeading;                  
                  if(m_nPage==1)
                  {
                        j=0;
                        point.Offset(0,-6000);
                  }
                  if(m_nPage==2)
                  {
                        point.Offset(0,0);
                        point.Offset(0,-600);
                        j=48;
                  }
                  if(m_nPage>=3)//page 3 ok
                  {
                        point.Offset(0,0);
                        point.Offset(0,-600);
                        j=((m_nPage-1)*100)-48;
                  }
                  for(i=nStart;i<nEnd;i++)      //count for line numbers
                  {
                        CFont font;
                        CFont fontTitle;
                        str=strArray[j];
                        if(str.Find('=')==0)
                        {
                              fontTitle.CreateFont(-225,0,0,0,600,FALSE,FALSE,
                                    0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
                                    CLIP_DEFAULT_PRECIS,PROOF_QUALITY,
                                    DEFAULT_PITCH|FF_MODERN,"Bookman Old Style Bold");
                              CFont *pOldFont = (CFont*)(pDC->SelectObject(&fontTitle));
                        str.Format("%-30s %-80s",
                              strArray[j],
                              strArray[j+1]);
                              point.y-=nHeight;      //space between printed lines
                              str.Remove('=');
                                    pDC->TextOut(point.x,point.y,str);
                                    pDC->SelectObject(pOldFont);

                        }
                        str=strArray[j];
                        if(str.Find('#')==0)
                        {
                              fontTitle.CreateFont(-225,0,0,0,600,FALSE,FALSE,
                                    0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
                                    CLIP_DEFAULT_PRECIS,PROOF_QUALITY,
                                    DEFAULT_PITCH|FF_MODERN,"Bookman Old Style Bold");
                              CFont *pOldFont = (CFont*)(pDC->SelectObject(&fontTitle));
                        str.Format("%-30s %-80s",
                              strArray[j],
                              strArray[j+1]);
                              point.y-=nHeight;      //space between printed lines
                              str.Remove('#');
                                    pDC->TextOut(point.x,point.y,str);
                                    pDC->SelectObject(pOldFont);
                        }
                        str=strArray[j];
                        if(!((str.Find('=')==0)||(str.Find('#')==0)))
                        {
                              font.CreateFont(-175,0,0,0,500,FALSE,FALSE,
                                    0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
                                    CLIP_DEFAULT_PRECIS,PROOF_QUALITY,
                                    DEFAULT_PITCH|FF_MODERN,"Courier New");
                              CFont *pOldFont = (CFont*)(pDC->SelectObject(&font));

                              str.Format("%-40s %-40s",
                                    strArray[j],
                                    strArray[j+1]);
                                    point.y-=nHeight;      //space between printed lines
                                          pDC->TextOut(point.x,point.y,str);
                                          pDC->SelectObject(pOldFont);

                        }
                        j+=2;

                        if(j>=actualarraySize)
                        break;
                  }
                  PrintPageFooter(pDC);
            }
      //*****************************************
0
Comment
Question by:pigeonbr
  • 15
  • 7
  • 5
27 Comments
 
LVL 8

Accepted Solution

by:
martynjpearson earned 500 total points
Comment Utility
You can use MS Word automation to create a document. Basically, your application creates an invisible instance of Word, and by using the automation interfaces that Word exposes, you can add the content of your report and save the file as a Word document. The only warning is that because you are using MS Word, it has to be installed on the computer you are doing the report generation on.

To use Word automation, follow these steps :
 
1) Open ClassWizard and press "Add Class". Select "from a type library" from the drop down list
2) Locate the Word type library - MSWordx.olb, where x is a number that avaries according to the version you have installed
3) ClassWizard will present you with a list of classes which can be created. Select them all, and press OK
4) Tbe result of this is a cpp file and a header file, called MSWordx.cpp and MSWordx.h, again with x varying on the version you have
5) Include "MSWordx.h" in the source file that is to generate the report
6) Use the following code to create a new word document, add some content and save it.

COleVariant varEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
COleVariant varTrue((short)VARIANT_TRUE, VT_BOOL), varFalse((short)VARIANT_FALSE, VT_BOOL);

    _Application application;
    bool bPublished = false;
   CString strFilename = "C:\\Output.doc"; // Change this as necessary

    // Start up Word
    if (application.CreateDispatch("Word.Application"))
    {
        try
        {
            // Get the documents collection and add a new document
            Documents documents(application.GetDocuments());
            _Document document;
           
            document = documents.Add(&varEmpty, &varEmpty);

            // Get the selection - this is the bit that we actually do the writing to
            Selection selection(application.GetSelection());

            selection.SetText("This is my content");

            // Save the document
            COleVariant varFilename(strFilename); // strFilename should be set to the filename
            document.SaveAs(&varFilename, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty);

            // Quit the application
            application.Quit(&varEmpty, &varEmpty, &varEmpty);
        }
        catch (COleDispatchException * e)
        {
            CString strErrorMessage;
            e->GetErrorMessage(strErrorMessage.GetBuffer(1024), 1024);
            strErrorMessage.ReleaseBuffer();
            AfxMessageBox("Failed :\n\n" + strErrorMessage);
            e->Delete();
        }
        catch (COleException * e)
        {
            CString strErrorMessage;
            e->GetErrorMessage(strErrorMessage.GetBuffer(1024), 1024);
            strErrorMessage.ReleaseBuffer();
            AfxMessageBox("Failed :\n\n" + strErrorMessage);
            e->Delete();
        }
        catch (CFileException * e)
        {
            CString strErrorMessage;
            e->GetErrorMessage(strErrorMessage.GetBuffer(1024), 1024);
            strErrorMessage.ReleaseBuffer();
            AfxMessageBox("Failed :\n\n" + strErrorMessage);
            e->Delete();
        }
        catch (CString strException)
        {
            AfxMessageBox(CString("Failed :\n\n") + strException);
        }
        catch (...)
        {
            AfxMessageBox("Failed :\n\nUnknown internal error");
        }

    }
    else
    {
        AfxMessageBox("Failed to start Microsoft Word.");
    }

This is obviously very basic in terms of the content that is inserted, but should get you started. You might want to put content in a bit at a time, format it as necessary, move the selection (effectively the insertion point) and add more content etc.

Hope this helps
Martyn
0
 
LVL 8

Expert Comment

by:martynjpearson
Comment Utility
Oops, forgot to add that you need to call CoInitialize() before using automation - best place to do this is in your app's InitInstance(). You'll also need to call CoUninitialize(), maybe in your apps ExitInstance().

Martyn
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
Just stuufing the text into a winword doc file will give you a 'list' of the text.  You could with further work add formatting.
If all you want is a plain text file then save it as a .txt file (no formatting possibilities) and then e-mail that.  Any recipient would then be able to read it.  You could even have that as the body of the message (no attachment).

An alternative would be to generate a text file containing html statements.  That you could format and again any recipient could read it (using their browser).

(Did you know Winword silently saves various bits of info about your PC/user into the doc).
0
 

Author Comment

by:pigeonbr
Comment Utility
martynjpearson,
Hi Martyn..thanks for your response. Im looking at your example...if I understand correctly, the SetText is used to write the phrase "This is my content" to the file. As you say, very basic. The SetText() outputs a block of text at a time...if I want to output 2 columns of text on my report,one line at a time,  like I do in my sample code supplied, how would I go about that ?

Ok...As you saw my partial code I supplied, I'm taking text from a CStringArray() and formating it with different fonts, depending on what is being printed. Can I still use this format with your example ? Since my output is going to a DC using TextOut command, could I just write to the .doc with another command instead of SetText, ain the line after I output text with the TextOut command, then in my OnEndPrinting() just save the .doc and quit the application as in your code ? I would appreciate just a little more help in the details...then I will be ok I think...Thanks Martyn.
0
 

Author Comment

by:pigeonbr
Comment Utility
I must also say what I'm looking for is to have the report look the same in the .doc file as in my VC++ print preview...I have a .jpg logo at top of first page, page headers and footers. I want the same result or setup to be in my .doc file. Would it be easier to create a CRichEditView, dump the data retrieved from my Access database using pretty much the same code as in my OnPrint() as spplied in my original question? I want the .doc file to be WYSIWYG in .doc file as well. But I would need a function like the TextOut where I can specify the position and the string to be output. My .jpg logo is in my header for the first page only. I use different headers depending on where I am in the print process, as I am printing 3 different reports, one after the other...not an easy task directly in VC++, but I got it working fine. I await any ideas..thanks all!
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
You want the e-mail (eg. Winword doc) to look like your report you coded.
Method 1)
Use Winword as your reporting viewer.  Just one set of code to display it then you can e-mail it...  [Requires user and recipient to have Winword installed]
Method 2)
Use HTML and use your browser to display the report.
Method 3)
Purchase a reporting engine (I use Crystal Reports on Access databases, it can be redistributed as a runtime for other users - no extra licence fees.)  WYSIWG editor for making the report.  e-mail support already coded.
0
 

Author Comment

by:pigeonbr
Comment Utility
AndyAinscow;
Hi...thanks for your help on this question also...the customer wants the format to be .doc as to be opened in MSWord...which is I guess on more computers than Winword...can it work with MSWord also as in your Method 1 ? The idea is not to have to start to distribute a new program to everyone that the report is sent to...I wnat to keep it simple:)

So how do I make MSWord my "reporting viewer" ?? :)
0
 

Author Comment

by:pigeonbr
Comment Utility
Is there any means of using SetText() with a carriage return to write one line, do a return, then on the next pass write another line under the first ?
0
 

Author Comment

by:pigeonbr
Comment Utility
Hi Guys;
While doing some research, I found this on the Selection object in Word:


The CreateObject function starts a Word session that Automation won't close when the object variable that references the Application object expires. Setting the object reference to the Nothing keyword won't close Word either. Instead, use the Quit method to close Word. The following Microsoft Excel example inserts data from cells A1:B10 on Sheet1 into a new Word document and then arranges the data in a table. The example uses the Quit method to close the new instance of Word if the CreateObject function was used. If the GetObject function returns error 429, the example uses the CreateObject function to start a new session of Word.

Dim appWD As Word.Application
Err.Number = 0
On Error GoTo notloaded
Set appWD = GetObject(, "Word.Application.8")
notloaded:
If Err.Number = 429 Then
    Set appWD = CreateObject("Word.Application.8")
    theError = Err.Number
End If
appWD.Visible = True

With appWD
    Set myDoc = .Documents.Add
    With .Selection
        For Each c In Worksheets("Sheet1").Range("A1:B10")
            .InsertAfter Text:=c.Value
            Count = Count + 1
            If Count Mod 2 = 0 Then
                .InsertAfter Text:=vbCr
            Else
                .InsertAfter Text:=vbTab
            End If
        Next c
        .Range.ConvertToTable Separator:=wdSeparateByTabs
        .Tables(1).AutoFormat Format:=wdTableFormatClassic1
    End With
    myDoc.SaveAs FileName:="C:\Temp.doc"
End With
If theError = 429 Then appWD.Quit
Set appWD = Nothing
//***************************************

This seems not so bad...looks like in VB (which I know next to nothing about) that here is a way to do a carriage return (.InsertAfter Text:=vbCr) and a tab ( .InsertAfter Text:=vbTab)....so, I figure there has got to be a way in VC++..If there is and you can help me find it, then possible I could stick my routine that reads the CStringArray and puts one line at a time into the Word.doc file. Am I all wet or on the right track ??


0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
From your original question
'There may be more than one way to make an emailable file. I'm open to all suggestions'
Hence my suggesting alternatives to WinWord.
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
You are filling a Winword document for e-mailing.
That involves launching Word, putting text/formatting into it. E-mailing it, closing word.
If you used word as your reporting engine the following logic applies.
That involves launching Word, putting text/formatting into it. DISPLAYING it, closing word.

Not a very big change.
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
"\r\n" is a typical carriage return / line feed to make page breaks.  Give that a try.
0
 
LVL 8

Expert Comment

by:martynjpearson
Comment Utility
Sorry about the delay getting back to you - my wife decided that decorating was the priority this weekend, not computing!!

Anyway, you can do pretty much everything with Word that you can do as an editor (there are a few bits you can't do). The best bet is to do what you want to do in Word, whilst recording a macro. Then, examine the code in the macro. It will be in VBA (like VB) - I appreciate you said you didn't know that much about VB, but the code should give you an idea of the objects, methods, parameters etc that you need to use.

In terms of getting columns into your document, you could use a table - you can set the table format so that the lines aren't shown if needs be. So, you'd create the table, then get the selection for each of the cells and insert the appropriate text. You can apply different formatting as necessary to the text you put in the cells. Here's some code which I hope will help...

            // Now insert a table of the issue history - this should overwrite the selection!
            Tables tables(selection.GetTables());
            Table table(tables.Add(selection.GetRange(), nRows, nColumns)); // nRows and nColumns need to be set!
            COleVariant varFormat((long)wdTableFormatGrid1); // Change this as necessary
            table.AutoFormat(&varFormat, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty, &varEmpty);

Then, you can set the text of the cells like this :

            SetCellText(table, nRow, nColumn, strText);

void SetCellText(Table & table, int nRow, int nColumn, const CString & strText)
{
    Cell cell(table.Cell(nRow, nColumn));
    Range range(cell.GetRange());
    range.InsertAfter(strText);
 }

All the best
Martyn
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:pigeonbr
Comment Utility
Looks like using a table is the best way to go. The \r\n doesnt work with SetText because the command is a block command. Iy is made to write a bolck of text. Using more that one SetText juste replaces the text written by the first by the text written by the second. I will do some experimenting and get back in a day or two.Thanks very much.
0
 
LVL 8

Expert Comment

by:martynjpearson
Comment Utility
With regards to the overwriting, I believe you need to collapse the selection (to the right) and then you can add more content after your previous content. To add a carriage return, try Selection::InsertBreak(wdLineBreak)

All the best
Martyn
0
 

Author Comment

by:pigeonbr
Comment Utility
Any ideas how I could get the .jpg logo in my header to the first page anyone ???
0
 

Author Comment

by:pigeonbr
Comment Utility
When I try this:
            selection.SetText("This is line one");
            selection.InsertBreak(wdLineBreak);
I get this compiler error :
error C2065: 'wdLineBreak' : undeclared identifier
0
 

Author Comment

by:pigeonbr
Comment Utility
martynjpearson;
Found some help you gave to someone else in a similar question...you had includes the Word constants..I dit as you said and made a header file containing them , and added the line to my CView .cpp file....but I still get a compile error:
error C2664: 'InsertBreak' : cannot convert parameter 1 from 'const int' to 'struct tagVARIANT *'

0
 
LVL 8

Expert Comment

by:martynjpearson
Comment Utility
Sorry - my fault. You need to do this :

COleVariant varLineBreak((long)wdLineBreak);
selection.InsertBreak(&varLineBreak);

To get an image into the header, you can do something like this :

Sections sections(document.GetSections()); // document is your instance of _Document
Section section(sections.Item(1));

HeadersFooters  headers(section.GetHeaders());
HeaderFooter header(headers.Item(1));
header.SetLinkToPrevious(FALSE);

Range rangeHeader(header.GetRange());

InlineShapes shapes(rangeHeader.GetInlineShapes());
shapes.AddPicture("C:\\MyPicture.jpg", &varEmpty, &varEmpty, &varEmpty);


Hope this helps
Martyn
0
 

Author Comment

by:pigeonbr
Comment Utility
martynjpearson;
 I have had some time to work on the problem...I now have my .doc file being created, the table is setup  and I am able to fill the table with my data from my array. Only a couple more little questions:

1. How do I go about formatting data in a particular cell for a certain font and bold ?
2. How do I make the lines of the table invisible ?

Thanks :)
0
 
LVL 8

Expert Comment

by:martynjpearson
Comment Utility
1) If you get the range of the cell, you can call Range::SetBold() etc, or you can call Range::GetFont() to get the font and tweak that, like this :

        Range rangeCell(cell.GetRange()); // cell is a Cell object
        _Font font(rangeCell.GetFont());

        font.SetName("Arial");
        font.SetSize(20.0);
        font.SetBold(VARIANT_TRUE); // Bold is on
        font.SetItalic(VARIANT_FALSE); // Italic is off
        font.SetUnderline(VARIANT_TRUE); // Underlined is on


2) When you call Table::AutoFormat(), instead of passing the variant with value wdTableFormatGrid1, set the variant to wdTableFormatNone.

All the best
Martyn
0
 

Author Comment

by:pigeonbr
Comment Utility
martynjpearson,
Hi..still working on the project..got alot done so far... I will now award you the points since you gave the best help for what I needed...I really appreciate it and I learned something new:)

I have been looking for somewhere to find info on all the functions relating to Automating Word, to quit asking you so many questions...but here is another:
My table starts at the top of page 1. I know how to do page breaks, but how do I get, say, the table on the first page to start further down on the page so I will have place for my logo ? Thanks.
 
0
 

Author Comment

by:pigeonbr
Comment Utility
Martynjpearson;

Could you help me sort out how to put the logo in the header on the first page only, and not on ther pages ? I have found some info on this but having problems...thanks for your help...really appreciate it.

I know about wdHeaderFooterFirstPage,wdHeaderFooterPrimary, but cant figure out how to use them. Thanks!
0
 

Author Comment

by:pigeonbr
Comment Utility
Martynjpearson;

1. Also, about dividing the document into sections...My table is created at the start with a fairly large number of rows, depending on the amount of data in my CStringArray...To divide the array into sections, do I have to create each of my 3 sections of the report int 3 different tables, or is the way I'm doing it alright ?

2. Also, I'm doing alot of research on the net trying to find info on using these Word objects like HeadersFooters, etc, but cant find much....if you have any links or books which talk about these in detail, and how to set headers etc up,it would be appreciated.

I can create what I want with ease in Word, and then check out the VB it generates, but as I said, not familiar enough with VB, nor the VC functions ...I know all the functions are in the classes created in the project, but it's exactly how to use them. I would really appreciate your help when you get a chance...If need be I will create another question for you specifically so you can collect more points. Thanks!
0
 
LVL 8

Expert Comment

by:martynjpearson
Comment Utility
Sorry about the delay in getting back to you - I've been out of the office!

OK, getting the image into the header is possible, although I had some issues when getting it aligned in the centre and getting text wrapped around it nicely. Anyway, the basic principle is to get the header or footer, then get the text range, and add to the pictures collection of the range. Like this :

    Sections sections(document.GetSections()); // Assumes "document" is your document object

    Section section(sections.Item(1));

    HeadersFooters  headers(section.GetHeaders());
    HeaderFooter header(headers.Item(1));
    header.SetLinkToPrevious(FALSE);

    Range rangeHeader(header.GetRange());
    InlineShapes shapes(rangeHeader.GetInlineShapes());
    shapes.AddPicture(strPicFilename, &varEmpty, &varEmpty, &varEmpty);

How you divide your data up I guess comes down to how you want to present it. One thing that might be useful is Row::SetHeadingFormat() - if you pass True to this, it means that the row is set to be a header, and will appear at the top of every page.

With regards to links for documentation, I got most of my knowledge through the MSDN, browsing the files that ClassWizard generates, and most importantly, the macro recorder in Word. The macro recorder is the best way of working out how to do something - simply start the macro recording, perform your operation(s), stop recording and view the code of the macro. Although it is in VBA and not C++, you can easily see the objects and their methods that are used, along with the parameters that are passed to them.

All the best
Martyn
0
 

Author Comment

by:pigeonbr
Comment Utility
martynjpearson:
Yes, you already gave me this code above...but my question is getting more specific...this code gets the logo and puts it at the top of every page as I stated in my last comment...my problem is understanding how to get it just on the first page. That's why I was asking if I had to divide the table int sections...the documetation I've found talks about dividing the report into sections, but the actual way to do it is not clear to me...I know about wdSectionBreakNewPage (I think it is) and several other functions and parameters that seem to have to do with it, but can't get it right.

Also as I stated in my last comment, I can get the VB code recorded from a macro in word after doing what I want, but the transitoin from VB to VC is not obvious.

Can you give me any example code of how I would load a logo.jpg to the header of first page only ?? The code above as I said, makes the logo appear on eader of all pages. Tis would really help...I will give you 250 more points, no problem if you can be a little more specific, and help me get started in understanding this a little depper than I do right now... I really need help.Thanks Martyn...really appreciate your help:)
Bruce
0
 

Author Comment

by:pigeonbr
Comment Utility
martynjpearson; Hi !

Doing some reading and testing... how come if I use Item(2) it compiles, but does not pt the logo anywhere ??
I modified your code and instead of Item(1) put Item(2), which  I take as meaning 2=wdHeaderFooterFirstPage, if I refer to the MSWord Constants.h file I have:

// WdHeaderFooterIndex

#define wdHeaderFooterPrimary  1
#define wdHeaderFooterFirstPage  2
#define wdHeaderFooterEvenPages  3


I modified your code like this:

                  Sections sections(document.GetSections()); // document is your instance of _Document
                  Section section1(sections.Item(1));

                  HeadersFooters headers(section1.GetHeaders());
                  HeaderFooter header(headers.Item(2));   //<---------- 2 instead of 1
                  
                  header.SetLinkToPrevious(FALSE);
                  
                  Range rangeHeader(header.GetRange());
                  InlineShapes shapes(rangeHeader.GetInlineShapes());
                  shapes.AddPicture("C:\\Inspec\\LogoInspec.jpg", &varEmpty, &varEmpty, &varEmpty);
//*********************

Am I wrong in thinking the two should mean wdHeaderFooterFirstPage?? If i write it like this:

                  Sections sections(document.GetSections()); // document is your instance of _Document
                  Section section1(sections.Item(1));

                  HeadersFooters headers(section1.GetHeaders());
                  HeaderFooter header(headers.Item(wdHeaderFooterFirstPage));//<-------------
                  
                  header.SetLinkToPrevious(FALSE);
                  
                  Range rangeHeader(header.GetRange());
                  InlineShapes shapes(rangeHeader.GetInlineShapes());
                  shapes.AddPicture("C:\\Inspec\\LogoInspec.jpg", &varEmpty, &varEmpty, &varEmpty);
///********


...I get the same result...no logo displaying. But if I use Item(1) OR Item(wdHeaderFooterPrimary), it puts the logo on top of each page...

Why is the 2 or wdHeaderFooterFirstPage not working ?? Am I on the wrong track ?
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now