Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
Давным-давно, почти шесть лет назад, уже создавал тему наподобие, но тогда речь шла о собственноручно созданном диалоговом окне Showmessage. Предложенная метода для него отрабатывает нормально. Суть теперешней проблемы похожа, но непонятно, как ее решить. Объясняю суть проблематики: допустим, программе подсовывают на вход файл с расширением .rtf, .doc или .docx, но на самом деле он таковым не является (банально переименован) или является дефектным. Запущенный компонент WordApplication, пытаясь его открыть, как-то определяет его чужеродность (вот бы знать, как!) и предлагает переконвертировать. Если отказаться от конвертирования, т.е. просто закрыть этот диалог, блок try... except, в котором открывается псевдо-документ, формирует нужное исключение и тогда ясно, что казачок засланный. Однако хотелось бы автоматизировать это закрытие, т.е. не самому кликать, а осуществить это программно. А вот как - непонятно, ведь это окно не отдельный процесс, а просто диалог запущенного Word-приложения, а его (приложение) мне закрывать совсем не нужно. Старая метода с поиском окна успеха не принесла, по заголовку "Конвертировать файл" ничего не ищется, в списке процессов, открываемом специальной программой, приложение класса OpusApp c четырьмя подклассами (_WwF,MsoWorkPane,NUIPane,NetUIHWND) с одним и тем же ProcessID, ничего не меняется после появления указанного диалога. Можно ли что-то сделать в этом случае? Да, сразу скажу - такую возможность как отмена конвертирования с помощью WordApplication1.Options.ConfirmConversions:=false просьба не предлагать, я было сначала обрадовался, а потом оказалось, что открытый таким образом псевдо-документ намертво вешает программу.
30 июл 12, 11:30    [12933444]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
S.PR
Member

Откуда: Минск
Сообщений: 1274
Надо смотреть что опубликовано в WordApplication и что возвращает.
В макросах можешь потестировать.
30 июл 12, 20:51    [12937097]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
Как тестировать с помощью макросов, я в курсе. Не совсем понял Ваше первое предложение - кто что возвращает, можно поподробнее?
31 июл 12, 11:14    [12939090]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
user89
Member

Откуда: аватар в профиле
Сообщений: 1291
Полуламер
Старая метода с поиском окна успеха не принесла, по заголовку "Конвертировать файл" ничего не ищется

У нас в офисе стоит Word 2010. Окно "Преобразование файла"
Картинка с другого сайта.

нашел через GetNextWindow
Картинка с другого сайта.

procedure TForm1.Button1Click(Sender: TObject);
var
  wnd: HWND;
  caption: string;
begin
  memo1.Clear;
  wnd := GetTopWindow(0);
  repeat
    SetLength(caption, GetWindowtextLength(wnd));
    GetWindowText(wnd, @caption[1], length(caption) + 1);
    memo1.Lines.Add(caption);
    wnd := GetNextWindow(wnd, GW_HWNDNEXT);
  until wnd = 0;
end;
31 июл 12, 11:45    [12939351]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
qwerty112
Guest
Полуламер
Запущенный компонент WordApplication, пытаясь его открыть, как-то определяет его чужеродность (вот бы знать, как!) и предлагает переконвертировать. Если отказаться от конвертирования, т.е. просто закрыть этот диалог, блок try... except, в котором открывается псевдо-документ, формирует нужное исключение и тогда ясно, что казачок засланный. Однако хотелось бы автоматизировать это закрытие, т.е. не самому кликать, а осуществить это программно.

а просто, запретить его (диалога переконверт.) открытие - не вариант ?
у Application.Documents.Open есть параметр, который за это отвечает ..
NoEncodingDialog Optional Variant. True to skip displaying the Encoding dialog box that Word displays if the text encoding cannot be recognized. The default value is False.
31 июл 12, 11:56    [12939448]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
qwerty112
а просто, запретить его (диалога переконверт.) открытие - не вариант ?

qwerty112, увы, не вариант - все не так просто, попытка открыть документ делается не просто в приложении, а в TOLEContainer, если я запрещаю конвертирование, то все безнаджено повисает. Поэтому нужно именно закрытие окна и метод user89 с простым перебором прекрасно работает. Но совсем не устраивает выполнение поиска по нажатию кнопки, я ведь не знаю, когда выскочит окно диалога, его надо отловить, однако по методе TTimer + Findwindow оно по-прежнему не ловится
31 июл 12, 13:53    [12940604]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 5838
Полуламер
однако по методе TTimer + Findwindow оно по-прежнему не ловится
FindWindowEx()?
31 июл 12, 14:03    [12940710]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
Короче, в результате мучительных экспериментов пришел к следующему не слишком утешительному результату. Использую такую конструкцию:

procedure TForm1.Timer1Timer(Sender: TObject);
var h:HWND;
begin
   h := FindWindow('bosa_sdm_Microsoft Office Word 12.0',nil); // ужас в кавычках - это название класса диалоговых окон MS Word 2007
   if h <> 0 then 
 SendMessage(h, WM_SYSCOMMAND, SC_Close, 0);
 end;

Так вот, окно "Преобразование файла" успешно ловится и закрывается, если псевдо-документ (дефектный документ) открывается двойным щелчком из Windows Explorer. Но если попробовать открыть его программно (из WordApplication или OLEContainer, без разницы) и опция ConfirmConversions=true, то диалог выскакивает и FindWindow его в этом случае не находит; если закрыть прогу, оставив диалог висеть, то при новом старте она найдет это окно и закроет его. Такие невеселые дела. Не представляю, куда девается окно в этом случае. Может быть, есть лучший метод отлавливания, без использования TTimer?
31 июл 12, 18:03    [12942756]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
Не придумал ничего лучше, как загнать всю эту лабуду с таймером в отдельное приложение - сделал его "невидимым", запускаю с помощью ShellExecute при старте программы, при выходе убиваю в списке процессов... Вроде работает исправно, ловит и закрывает зловредное окошко. Ну а по-другому разве можно сделать?
1 авг 12, 10:53    [12944741]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Anton R.
Member

Откуда:
Сообщений: 103
Полуламер,
1. Диалог отлавливать не надо. Либо оставить диалог конвертирования для выбора варианта конвертации конечным пользователем, либо отключить диалог и оставить конвертацию на совести Word`а. Описанный Вами костыль потенциально грозит проблемами с развертыванием, сопровождением и сменой версий MS Office.
2. Для защиты от чужеродных файлов можно перед открытием проверять соответствует ли расширение файла его фактической сигнатуре (заголовочной информации внутри файла).

Кстати, если файл поврежден (или, например, это .zip файл переименованный в .doc), то Documents.Open(AFileName, False{ConfirmConversions}) вызовет Exception, который легко обработать. Да, этот метод может на некоторое время задуматься, но пользователь сам виноват, что кормит программу всяким мусором.
1 авг 12, 13:38    [12946119]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
Anton R.
Описанный Вами костыль потенциально грозит проблемами с развертыванием, сопровождением и сменой версий MS Office
Очень может быть, спорить не буду.

автор
Для защиты от чужеродных файлов можно перед открытием проверять соответствует ли расширение файла его фактической сигнатуре (заголовочной информации внутри файла).
А вот отсюда поподробнее, пожалуйста - искал везде какую-нибудь статью с контекстом "сигнатура файлов MS Office", нашел шиш да маленько, только то, что сигнатуры документов Word и Excel 2007 совпадают, поскольку оба являются zip-архивами. Если знаете, как это сделать, я весь внимание.

Кстати, если файл поврежден (или, например, это .zip файл переименованный в .doc), то Documents.Open(AFileName, False{ConfirmConversions}) вызовет Exception
А если я открываю документ в OLEContainer (собственно, из-за этого весь сыр-бор), то как в таком случае ловить это Exception?
1 авг 12, 14:14    [12946455]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Anton R.
Member

Откуда:
Сообщений: 103
Полуламер
искал везде какую-нибудь статью с контекстом "сигнатура файлов MS Office", нашел шиш да маленько, только то, что сигнатуры документов Word и Excel 2007 совпадают, поскольку оба являются zip-архивами. Если знаете, как это сделать, я весь внимание.

Например:
http://www.microsoft.com/openspecifications/en/us/programs/osp/office-file-formats/default.aspx
+
http://msdn.microsoft.com/en-us/library/cc313105.aspx

Полуламер
А если я открываю документ в OLEContainer

Метод Application.Documents.Open там точно так же доступен.
1 авг 12, 14:36    [12946619]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
Anton R.
Например:
http://www.microsoft.com/openspecifications/en/us/programs/osp/office-file-formats/default.aspx
+
http://msdn.microsoft.com/en-us/library/cc313105.aspx
Спасибо за линки, но я, к сожалению, не настолько крут, чтобы играючи запрограммировать обработку всех форматов Microsoft Это вообще весьма трудная задача, которую каждый для себя решает как может.

Метод Application.Documents.Open там точно так же доступен.
Вероятно, имееется в виду типа такая строчка:

Olecontainer1.OleObject.Application.Documents.Open(FileName, false, true);


Приведите хоть один работающий пример, нашел что-то похожее только у китайцев:

Doc_ole.CreateObject( 'Word.Application ',False);
Doc_ole.Run;
Doc_ole.DoVerb(1);
Doc_ole.OleObject.Application.Documents.open( 'c:\testfile.doc ',false,true);


но это не функционирует - выдает ошибку на Run
1 авг 12, 15:09    [12946863]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Anton R.
Member

Откуда:
Сообщений: 103
не настолько крут, чтобы играючи запрограммировать обработку всех форматов Microsoft

А и не надо. Только заголовки посмотреть.
но это не функционирует - выдает ошибку на Run

Я не спец по контейнерам.
Можно попробовать обойти баг:
OleContainer1.CreateObjectFromFile('c:\Dummy.doc', false); //'Dummy.doc' - пустой вспомогательный файл, например, в папке с программой
OleContainer1.OleObject.Application.Documents.Item(1).Close;
OleContainer1.OleObject.Application.Documents.open( 'c:\testfile.doc ',false,true);
1 авг 12, 15:53    [12947276]     Ответить | Цитировать Сообщить модератору
 Re: Диалоговое окно MS Word - как бы закрыть его?  [new]
Полуламер
Member

Откуда: Забугорье
Сообщений: 493
Интересная идея, но на строчке
OleContainer1.OleObject.Application.Documents.Item(1).Close;
как и следовало ожидать, спотыкается - "Интерфейс не поддерживается".
1 авг 12, 17:23    [12947991]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить