最近在学习怎么用wxwidgets来操纵word,寻找之中发现MedeoSoftware,里面有很多wxwidgets的用法,不过我最关心的还是其中的dmxMSWordDocument,操作word的方法比较全,很值得学习。代码如下(并附上全部源码):
dmxMSWordDocument.h
#ifndef _DMX_MSWORD_DOCUMENT_H_ #define _DMX_MSWORD_DOCUMENT_H_ #include "wxCommon.h" //////////////////////////////////////////////////////////////////////////////// // dmxMSWordFont //////////////////////////////////////////////////////////////////////////////// struct dmxMSWordFont { long pointsize; bool bold; bool italic; wxString font_name; wxColour color; dmxMSWordFont(long a_pointsize = 12, bool a_bold = false, bool a_italic = false, const wxString &ar_font_name = "Times New Roman", const wxColour &ar_color = wxColour(0, 0, 0)) : pointsize(a_pointsize), bold(a_bold), italic(a_italic), font_name(ar_font_name), color(ar_color) {} dmxMSWordFont(const dmxMSWordFont &ar_font) : pointsize(ar_font.pointsize), bold(ar_font.bold), italic(ar_font.italic), font_name(ar_font.font_name), color(ar_font.color) {} dmxMSWordFont& operator=(const dmxMSWordFont &ar_font) { if (&ar_font != this) { pointsize = ar_font.pointsize; bold = ar_font.bold; italic = ar_font.italic; font_name = ar_font.font_name; color = ar_font.color; } return *this; } bool operator==(const dmxMSWordFont &ar_font) const { if (pointsize != ar_font.pointsize || bold != ar_font.bold || italic != ar_font.italic || font_name != ar_font.font_name || color != ar_font.color) return false; else return true; } bool operator!=(const dmxMSWordFont &ar_font) const { return !operator==(ar_font); } }; extern dmxMSWordFont gc_DefaultMSWordFont; //////////////////////////////////////////////////////////////////////////////// // dmxMSWordDocument //////////////////////////////////////////////////////////////////////////////// class dmxMSWordDocument { public: enum Alignment { c_ALIGN_LEFT = 0, c_ALIGN_CENTER = 1, c_ALIGN_RIGHT = 2, c_ALIGN_JUSTIFY = 3 }; enum PageOrientation { c_PORTRAIT, c_LANDSCAPE }; private: bool m_ok; wxAutomationObject m_word; wxAutomationObject m_document; wxAutomationObject *mp_table; struct TableBufferElement { wxString Text; Alignment TextAlignment; dmxMSWordFont Font; }; typedef std::vector<TableBufferElement> TableLineBuffer; std::vector<TableLineBuffer> m_table_buffer; public: dmxMSWordDocument(const wxString &ar_name = wxEmptyString, bool a_visible = true); ~dmxMSWordDocument(); bool IsOk(void) const { return m_ok; } void Show(bool a_show = true); void Close(void); bool SaveAs(const wxString &ar_file_name); static bool IsAccessible(void); void AddParagraph(Alignment a_alignment = c_ALIGN_JUSTIFY, const dmxMSWordFont &ar_font = gc_DefaultMSWordFont); void AddTextParagraph(const wxString &ar_text, Alignment a_alignment = c_ALIGN_JUSTIFY, const dmxMSWordFont &ar_font = gc_DefaultMSWordFont); void AddBitmap(const wxBitmap &ar_image, Alignment a_alignment = c_ALIGN_JUSTIFY); void AddPictureFromFile(const wxString &ar_file_name, Alignment a_alignment = c_ALIGN_JUSTIFY); bool CreateTableFromString(const wxString &ar_text, long a_cols, long a_rows, const wxChar *ap_separator = "|", long a_table_format1 = 22, // 耱桦?纛痨囹桊钼囗? 22 = "彦蜿?蜞犭桷?7" long a_table_format2 = 16); // 羼腓 礤 镱塍麒腩顸, 蝾 稃蜞屐? 耱桦?纛痨囹桊钼囗? 16 = "彦蜿?蜞犭桷?1" void InitTableBuffer(long a_cols, long a_rows); void SetTableBufferCellText(long a_col, long a_row, const wxString &ar_text, Alignment a_alignment = c_ALIGN_JUSTIFY, const dmxMSWordFont &ar_font = gc_DefaultMSWordFont); bool CreateTableFromBuffer(void); void AddTable(long a_cols, long a_rows); void AddTableCellText(long a_col, long a_row, const wxString &ar_text, Alignment a_alignment = c_ALIGN_JUSTIFY, const dmxMSWordFont &ar_font = gc_DefaultMSWordFont); void AddPictureToTableCell ( long a_col, long a_row, const wxString &ar_file_name, Alignment a_alignment ); void AddBitmapToTableCell ( long a_col, long a_row, const wxBitmap &ar_bitmap, Alignment a_alignment ); void PasteFromClipboardToTableCell ( long a_col, long a_row, Alignment a_alignment ); void Paste(Alignment a_alignment); void SetPageOrientation(PageOrientation a_orientation); void SetPageLeftMargin(double a_margin_sm); void SetPageRightMargin(double a_margin_sm); void SetPageTopMargin(double a_margin_sm); void SetPageBottomMargin(double a_margin_sm); void SetPageHeaderDistance(double a_margin_sm); void SetPageFooterDistance(double a_margin_sm); private: void mf_SetPageMargin(const wxString &ar_margin_name, double a_margin); }; #endif
dmxMSWordDocument.cpp
#include "wxCommon.h" #include "dmxMSWordDocument.h" #include "Useful.h" #include "message_dialog.h" #include "wxTranslation.h" #include "wxstringutil.h" //////////////////////////////////////////////////////////////////////////////// // dmxMSWordFont //////////////////////////////////////////////////////////////////////////////// dmxMSWordFont gc_DefaultMSWordFont = dmxMSWordFont(); //////////////////////////////////////////////////////////////////////////////// // dmxMSWordDocument //////////////////////////////////////////////////////////////////////////////// dmxMSWordDocument::dmxMSWordDocument(const wxString &ar_name, bool a_visible) : m_ok(false), mp_table(NULL) { // 青矬耜噱?MSWord if (!m_word.CreateInstance("Word.Application")) return; m_ok = true; m_word.PutProperty("Visible", a_visible); m_word.CallMethod("Documents.Add"); m_word.GetObject(m_document, "ActiveDocument"); wxAutomationObject footer(m_document.CallMethod("Sections.Last.Footers.Item", 3L).GetVoidPtr()); footer.CallMethod("PageNumbers.Add"); if (!ar_name.IsEmpty()) m_document.PutProperty("Name", ar_name); m_document.PutProperty("Content.Font.Name", gc_DefaultMSWordFont.font_name); m_document.PutProperty("Content.Font.Size", gc_DefaultMSWordFont.pointsize); m_document.PutProperty("Content.Font.Bold", gc_DefaultMSWordFont.bold); m_document.PutProperty("Content.Font.Italic", gc_DefaultMSWordFont.italic); m_document.PutProperty("Content.Font.Color", (long)RGB(gc_DefaultMSWordFont.color.Red(), gc_DefaultMSWordFont.color.Green(), gc_DefaultMSWordFont.color.Blue())); } //------------------------------------------------------------------------------ void dmxMSWordDocument::Show(bool a_show) { m_word.PutProperty("Visible", a_show); m_word.CallMethod("Word.ActiveWindow.Activate"); } //------------------------------------------------------------------------------ void dmxMSWordDocument::Close(void) { m_word.CallMethod("Quit", false); } //------------------------------------------------------------------------------ bool dmxMSWordDocument::SaveAs(const wxString &ar_file_name) { m_document.CallMethod("SaveAs", ar_file_name); return true; } //------------------------------------------------------------------------------ dmxMSWordDocument::~dmxMSWordDocument() { if (mp_table) { delete mp_table; mp_table = NULL; } } //------------------------------------------------------------------------------ bool dmxMSWordDocument::IsAccessible(void) { wxAutomationObject word; bool accessible = word.CreateInstance("Word.Application"); if (accessible) word.CallMethod("Word.Close"); return accessible; } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddParagraph(Alignment a_alignment, const dmxMSWordFont &ar_font) { m_document.CallMethod("Content.InsertParagraphAfter"); wxAutomationObject paragraph; m_document.GetObject(paragraph, "Paragraphs.Last"); paragraph.PutProperty("Alignment", long(a_alignment)); paragraph.PutProperty("SpaceAfter", long(0)); paragraph.PutProperty("SpaceBefore", long(0)); paragraph.PutProperty("Range.Font.Name", ar_font.font_name); paragraph.PutProperty("Range.Font.Size", ar_font.pointsize); paragraph.PutProperty("Range.Font.Bold", ar_font.bold); paragraph.PutProperty("Range.Font.Italic", ar_font.italic); paragraph.PutProperty("Range.Font.Color", (long)RGB(ar_font.color.Red(), ar_font.color.Green(), ar_font.color.Blue())); } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddTextParagraph(const wxString &ar_text, Alignment a_alignment, const dmxMSWordFont &ar_font) { m_document.CallMethod("Content.InsertAfter", ar_text); wxAutomationObject paragraph; m_document.GetObject(paragraph, "Paragraphs.Last"); paragraph.PutProperty("Alignment", long(a_alignment)); paragraph.PutProperty("SpaceAfter", long(0)); paragraph.PutProperty("SpaceBefore", long(0)); paragraph.PutProperty("Range.Font.Name", ar_font.font_name); paragraph.PutProperty("Range.Font.Size", ar_font.pointsize); paragraph.PutProperty("Range.Font.Bold", ar_font.bold); paragraph.PutProperty("Range.Font.Italic", ar_font.italic); paragraph.PutProperty("Range.Font.Color", (long)RGB(ar_font.color.Red(), ar_font.color.Green(), ar_font.color.Blue())); AddParagraph(); } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddBitmap(const wxBitmap &ar_bitmap, Alignment a_alignment) { wxOpenClipboard(); wxEmptyClipboard(); wxSetClipboardData(wxDF_BITMAP, &ar_bitmap, ar_bitmap.GetWidth(), ar_bitmap.GetHeight()); wxCloseClipboard(); Paste(a_alignment); } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddPictureFromFile(const wxString &ar_file_name, Alignment a_alignment) { m_document.CallMethod("Content.InsertAfter", wxEmptyString); wxAutomationObject paragraph; if (!m_document.GetObject(paragraph, "Paragraphs.Last")) return; paragraph.PutProperty("Alignment", long(a_alignment)); paragraph.PutProperty("SpaceAfter", long(0)); paragraph.PutProperty("SpaceBefore", long(0)); wxVariant range = paragraph.GetProperty("Range"); wxAutomationObject shapes; m_document.GetObject(shapes, "InlineShapes"); wxVariant no_link_to_file(false); wxVariant save_with_document(true); shapes.CallMethod("AddPicture", ar_file_name, no_link_to_file, save_with_document, range); } //------------------------------------------------------------------------------ bool dmxMSWordDocument::CreateTableFromString(const wxString &ar_text, long a_cols, long a_rows, const wxChar *ap_separator, long a_table_format1, long a_table_format2) { wxAutomationObject paragraph; m_document.GetObject(paragraph, "Paragraphs.Last"); paragraph.CallMethod("Range.InsertAfter", ar_text); std::vector<wxVariant> args; args.push_back(wxVariant(dmxT("|"), dmxT("Separator"))); args.push_back(wxVariant(a_rows, dmxT("NumRows"))); args.push_back(wxVariant(a_cols, dmxT("NumColumns"))); args.push_back(wxVariant(true, dmxT("AutoFit"))); args.push_back(wxVariant(0L, dmxT("AutoFitBehavior"))); args.push_back(wxVariant(1L, dmxT("DefaultTableBehavior"))); wxVariant result; if (a_table_format1 < 0) { // 杨玟噱?蜞犭桷??纛痨囹铎 镱 箪铍鬣龛? paragraph.CallMethod("Range.ConvertToTable", args.size(), &(args[0])); } else { // 消蜞屐? 耦玟囹?蜞犭桷?镥疴 玎溧眄 纛痨囹铎 args.push_back(wxVariant(a_table_format1, dmxT("Format"))); result = paragraph.CallMethod("Range.ConvertToTable", args.size(), &(args[0])); if (result.IsNull()) { // 羼腓 礤 镱塍麒腩顸, 蝾 稃蜞屐? 耦玟囹?怛铕 玎溧眄 纛痨囹铎 args.back() = wxVariant(a_table_format2, dmxT("Format")); if (a_table_format2 > 0) result = paragraph.CallMethod("Range.ConvertToTable", args.size(), &(args[0])); if (result.IsNull()) // 眢, 珥圜栩, 耦怦屐 礤 镱塍麒腩顸 return false; } } AddParagraph(); return true; } //------------------------------------------------------------------------------ void dmxMSWordDocument::InitTableBuffer(long a_cols, long a_rows) { m_table_buffer.resize(a_rows, TableLineBuffer(a_cols, TableBufferElement())); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetTableBufferCellText(long a_col, long a_row, const wxString &ar_text, Alignment a_alignment, const dmxMSWordFont &ar_font) { TableBufferElement element; element.Text = ar_text; element.Font = ar_font; element.TextAlignment = a_alignment; m_table_buffer[a_row][a_col] = element; } //------------------------------------------------------------------------------ bool dmxMSWordDocument::CreateTableFromBuffer(void) { dmxUInt32 rows = m_table_buffer.size(); if (rows == 0) return true; dmxUInt32 cols = m_table_buffer[0].size(); if (cols == 0) return true; // 灶痨桊箦?耱痤牦 ?耦玟噱?蜞犭桷? wxString table_string; for (dmxUInt32 j = 0; j < rows; j++) for (dmxUInt32 i = 0; i < cols; i++) { table_string << m_table_buffer[j][i].Text; if (j < rows - 1 || i < cols - 1) table_string << '|'; } if (!CreateTableFromString(table_string, cols, rows, "|")) { dmxMessageBox(NULL, wxTR("tr_WordDocument", "MsgCreateTableError"), dmxMessageDialog::c_ICON_ERROR); return false; } // 灶痨囹桊箦?麇殛?蜞犭桷? wxVariant index = m_document.GetProperty("Tables.Count"); wxAutomationObject table(m_document.CallMethod("Tables.Item", index).GetVoidPtr()); for (dmxUInt32 j = 0; j < rows; j++) for (dmxUInt32 i = 0; i < cols; i++) { if (m_table_buffer[j][i].TextAlignment == c_ALIGN_JUSTIFY && m_table_buffer[j][i].Font == gc_DefaultMSWordFont) continue; wxAutomationObject cell(table.CallMethod("Cell", long(j + 1), long(i + 1)).GetVoidPtr()); if (m_table_buffer[j][i].TextAlignment != c_ALIGN_JUSTIFY) cell.PutProperty("Range.Paragraphs.Alignment", long(m_table_buffer[j][i].TextAlignment)); cell.PutProperty("Range.Paragraphs.SpaceAfter", long(0)); cell.PutProperty("Range.Paragraphs.SpaceBefore", long(0)); dmxMSWordFont font = m_table_buffer[j][i].Font; if (font.font_name != gc_DefaultMSWordFont.font_name) cell.PutProperty("Range.Font.Name", font.font_name); if (font.pointsize != gc_DefaultMSWordFont.pointsize) cell.PutProperty("Range.Font.Size", font.pointsize); if (font.bold != gc_DefaultMSWordFont.bold) cell.PutProperty("Range.Bold", font.bold); if (font.italic != gc_DefaultMSWordFont.italic) cell.PutProperty("Range.Font.Italic", font.italic); if (font.color!= gc_DefaultMSWordFont.color) cell.PutProperty("Range.Font.Color", (long)RGB(font.color.Red(), font.color.Green(), font.color.Blue())); } return true; } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddTable(long a_cols, long a_rows) { if (mp_table) { delete mp_table; mp_table = NULL; } dmxMSWordFont dummy_font(6, false, false, "Arial"); AddParagraph(dmxMSWordDocument::c_ALIGN_CENTER, dummy_font); wxAutomationObject paragraph; if (m_document.GetObject(paragraph, "Paragraphs.Last")) { paragraph.PutProperty("PointSize", long(6)); } wxVariant args[3]; args[0] = m_document.GetProperty("Paragraphs.Last.Range"); args[1] = a_rows; args[2] = a_cols; m_document.CallMethod("Tables.Add", 3, args); wxVariant index = m_document.GetProperty("Tables.Count"); mp_table = new wxAutomationObject(m_document.CallMethod("Tables.Item", index).GetVoidPtr()); mp_table->PutProperty("Borders.InsideLineStyle", 1L);// = wdLineStyleSingle mp_table->PutProperty("Borders.OutsideLineStyle", 1L); } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddTableCellText(long a_col, long a_row, const wxString &ar_text, Alignment a_alignment, const dmxMSWordFont &ar_font) { if (!mp_table) return; wxAutomationObject cell(mp_table->CallMethod("Cell", a_row, a_col).GetVoidPtr()); cell.PutProperty("Range.Paragraphs.Alignment", long(a_alignment)); cell.PutProperty("Range.Paragraphs.SpaceAfter", long(0)); cell.PutProperty("Range.Paragraphs.SpaceBefore", long(0)); if (ar_font != gc_DefaultMSWordFont) { cell.PutProperty("Range.Font.Name", ar_font.font_name); cell.PutProperty("Range.Font.Size", ar_font.pointsize); cell.PutProperty("Range.Bold", ar_font.bold); cell.PutProperty("Range.Font.Italic", ar_font.italic); cell.PutProperty("Range.Font.Color", (long)RGB(ar_font.color.Red(), ar_font.color.Green(), ar_font.color.Blue())); } cell.CallMethod("Range.InsertAfter", ar_text); } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddPictureToTableCell ( long a_col, long a_row, const wxString &ar_file_name, Alignment a_alignment ) { if (!mp_table) return; wxAutomationObject cell(mp_table->CallMethod("Cell", a_row, a_col).GetVoidPtr()); cell.CallMethod("Range.InsertAfter", wxEmptyString); wxAutomationObject paragraph; if (!cell.GetObject(paragraph, "Range.Paragraphs.Last")) return; paragraph.PutProperty("Alignment", long(a_alignment)); paragraph.PutProperty("SpaceAfter", long(0)); paragraph.PutProperty("SpaceBefore", long(0)); wxVariant range = paragraph.GetProperty("Range"); wxAutomationObject shapes; m_document.GetObject(shapes, "InlineShapes"); wxVariant no_link_to_file(false); wxVariant save_with_document(true); shapes.CallMethod("AddPicture", ar_file_name, no_link_to_file, save_with_document, range); } //------------------------------------------------------------------------------ void dmxMSWordDocument::AddBitmapToTableCell ( long a_col, long a_row, const wxBitmap &ar_bitmap, Alignment a_alignment ) { if (!mp_table) return; wxAutomationObject cell(mp_table->CallMethod("Cell", a_row, a_col).GetVoidPtr()); wxAutomationObject range; if (!cell.GetObject(range, "Range")) return; wxOpenClipboard(); wxEmptyClipboard(); wxSetClipboardData(wxDF_BITMAP, &ar_bitmap, ar_bitmap.GetWidth(), ar_bitmap.GetHeight()); wxCloseClipboard(); range.CallMethod("Paste"); range.PutProperty("Alignment", long(a_alignment)); range.PutProperty("SpaceAfter", long(0)); range.PutProperty("SpaceBefore", long(0)); } //------------------------------------------------------------------------------ void dmxMSWordDocument::PasteFromClipboardToTableCell ( long a_col, long a_row, Alignment a_alignment ) { if (!mp_table) return; wxAutomationObject cell(mp_table->CallMethod("Cell", a_row, a_col).GetVoidPtr()); wxAutomationObject range; if (!cell.GetObject(range, "Range")) return; range.CallMethod("Paste"); range.PutProperty("Alignment", long(a_alignment)); range.PutProperty("SpaceAfter", long(0)); range.PutProperty("SpaceBefore", long(0)); } //------------------------------------------------------------------------------ void dmxMSWordDocument::Paste(Alignment a_alignment) { wxAutomationObject paragraph; if (m_document.GetObject(paragraph, "Paragraphs.Last")) { paragraph.PutProperty("Alignment", long(a_alignment)); paragraph.PutProperty("SpaceAfter", long(0)); paragraph.PutProperty("SpaceBefore", long(0)); } m_document.CallMethod("Paragraphs.Last.Range.Paste"); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetPageOrientation(PageOrientation a_orientation) { wxAutomationObject page_setup; if (!m_document.GetObject(page_setup, "PageSetup")) return; page_setup.PutProperty("Orientation", long(a_orientation)); } //------------------------------------------------------------------------------ void dmxMSWordDocument::mf_SetPageMargin(const wxString &ar_margin_name, double a_margin_sm) { wxAutomationObject page_setup; if (!m_document.GetObject(page_setup, "PageSetup")) return; // 1 濑殪 = 2,54 耢 = 72 蝾麝? double margin_points = (a_margin_sm*72.0)/2.54; page_setup.PutProperty(ar_margin_name, margin_points); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetPageLeftMargin(double a_margin_sm) { mf_SetPageMargin("LeftMargin", a_margin_sm); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetPageRightMargin(double a_margin_sm) { mf_SetPageMargin("RightMargin", a_margin_sm); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetPageTopMargin(double a_margin_sm) { mf_SetPageMargin("TopMargin", a_margin_sm); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetPageBottomMargin(double a_margin_sm) { mf_SetPageMargin("BottomMargin", a_margin_sm); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetPageHeaderDistance(double a_margin_sm) { mf_SetPageMargin("HeaderDistance", a_margin_sm); } //------------------------------------------------------------------------------ void dmxMSWordDocument::SetPageFooterDistance(double a_margin_sm) { mf_SetPageMargin("FooterDistance", a_margin_sm); } ////////////////////////////////////////////////////////////////////////////////
注:在使用ole时不要忘记包含头文件#include <wx/msw/ole/automtn.h>