Поиск и замена в автоматизации OLE Word - как закрыть верхний и нижний колонтитулы?

У меня есть отлично работающая функция для поиска и замены переменной текстом в текстовых документах.

HRESULT CMSWord::FindReplace( CString szVar, CString szText, bool bOnlyOnce/*=false*/ )
{
    if(m_pWApp==NULL || m_pActiveDocument==NULL) return E_FAIL;
    IDispatch *pDocApp;
    {  
        VARIANT result;
        VariantInit(&result);
        OLEMethod(DISPATCH_PROPERTYGET, &result, m_pActiveDocument, L"Application", 0);
        pDocApp= result.pdispVal;
    }
    IDispatch *pSelection;
    {
        VARIANT result;
        VariantInit(&result);
        OLEMethod(DISPATCH_PROPERTYGET, &result, pDocApp, L"Selection", 0);
        pSelection=result.pdispVal;
    }
    IDispatch *pFind;
    {
        VARIANT result;
        VariantInit(&result);
        OLEMethod(DISPATCH_PROPERTYGET, &result, pSelection, L"Find", 0);
        pFind=result.pdispVal;
    }
    OLEMethod(DISPATCH_METHOD, NULL, pFind, L"ClearFormatting",0);

    szText.Replace(_T("\r\n"), _T("\v")); 
    COleVariant sVariable(szVar);
    COleVariant sReplaceText(szText);
    COleVariant replace((long)2);
    COleVariant varBoolTrue;
    varBoolTrue.boolVal = true;
    COleVariant varBoolFalse;
    varBoolFalse.boolVal = false;
    COleVariant wdContinue((long)1);
    bool bFound=false;
    IDispatch *pExecute = NULL;
    {
        for(;;) {
            VARIANT result;
            VariantInit(&result);

            if(OLEMethod(DISPATCH_METHOD, &result, pFind, L"Execute", 8, wdContinue, varBoolTrue, varBoolFalse, varBoolFalse, varBoolFalse, varBoolTrue, varBoolFalse, sVariable)==S_OK) {
                pExecute=result.pdispVal;
                if(!pExecute) break;
                bFound = true;
                if(szText.IsEmpty()) DeleteChar(false);         else SetSelectionText(szText);
            }
            else break;
            if(bOnlyOnce) break;
        }
    }
    pDocApp->Release();
    pSelection->Release();
    pFind->Release();
    if(!bFound) return E_FAIL;
    else return S_OK;
}

Проблема заключается в том, что этот код не будет касаться текста в заголовке или нижнем колонтитуле.

Может быть, есть параметр для метода выполнения pFind?

Честно говоря, я искал эту проблему с понедельника. Большинство моих результатов поиска - документы VB, С#,.NET и VBA, но документации по VС++ OLE немного, несколько строк кода, но ничего полезного. Я даже начал создавать и переводить некоторые макросы Word, ничего не работает.

Здесь, при переполнении стека, я нашел много вопросов, связанных с этой темой. Некоторые из них выглядели многообещающими, но, похоже, они используют некоторые рамки, которые я не знаю, и люди не оставили ответа, если я попросил пример кода или ссылки.

Если кто-то может мне помочь в этом вопросе, это было бы потрясающе, и я бы очень благодарен за ссылки на документацию и код на общую тему автоматизации OLE Word (помимо этой статьи кодепроекта).

Спасибо заранее!

Ответ 1

Вот функция Delphi, которая выполняет поиск и заменяет заголовок. Я знаю, что это вопрос на С++, но вы можете видеть из функций, что вам нужно делать.

Я всегда считаю, что самый простой способ сделать что-то в работе - использовать MacroRecorder и посмотреть, как это делается, а затем вызвать этот код из вашего приложения.

Мне жаль, что вы программируете COM на С++

Procedure Find_ReplaceText(find, ReplaceWith: String; Header : Boolean = false);
var
    tmpText: String;
    spos , epos : Integer;
begin
    {Start on first page.}
    fWordApp.Selection.Goto(wdGoToPage,wdGotoFirst);
    {Extra code is needed if I'm trying to replace text in the header}
    if Header then
    begin
        fWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekCurrentPageHeader;



        If fWordApp.Selection.HeaderFooter.IsHeader = False Then
        begin
            fWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekCurrentPageHeader;
        end;

        tmpText := fWordApp.ActiveDocument.sections.item(1).Headers.item(wdHeaderFooterPrimary).Range.text;
        spos := pos('[' ,tmptext);
        epos := pos(']' , tmpText);

        tmptext := copy(tmptext,1, spos);
        tmptext := tmptext + ReplaceWith + ']';
        fWordApp.ActiveDocument.sections.item(1).Headers.item(wdHeaderFooterPrimary).Range.text := tmptext;
        fWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekMainDocument;
    end
    else
    begin
        fWordApp.Selection.Find.Text := find;
        fWordApp.Selection.Find.Execute;
        fWordApp.Selection.typeText(' ');
        fWordApp.Selection.InsertAfter(ReplaceWith);
    end;

end;