Как я могу закрыть приложение без отображения модального диалогового окна?

У меня есть приложение, которое может открывать PDF-файлы после их создания. Если последовательно генерируются два отчета с одним и тем же именем, вторая попытка завершится неудачей, если в первой копии acrobat все еще открыт PDF-файл, поэтому перед записью PDF-файла я проверяю (с помощью FindWindow) окно с именем документа. Если он найден, я выдаю SendMessage WM_Close.

Это работает нормально, но я проводил некоторые другие тесты и использовал Word для «редактирования» PDF, чтобы держать его открытым, чтобы я мог проверить поведение приложения, когда оно не может записать файл PDF. Теперь, когда мое приложение пытается закрыть окно, Word выводит диалоговое окно «Вы хотите сохранить?». Если я нажму «Отмена», Word останется открытым, мое приложение продолжит работу, и я смогу проверить, ведет ли оно себя разумно, когда встречает файл, в который не может записать.

Все хорошо, но это предупредило меня о том, что использование SendMessage WM_CLOSE для закрытия другого приложения заблокирует мое приложение, если другое приложение откроет модальное диалоговое окно. Есть ли способ обойти это, то есть более сильный (но не слишком сильный) способ закрыть другое приложение? Или «Закрыть и нажать «Отмена», если необходимо». Или я должен использовать асинхронные сообщения?


person rossmcm    schedule 24.11.2011    source источник


Ответы (3)


Не принудительно закрывайте какое-либо приложение, могут быть открыты другие документы, которые просматривает пользователь и т. д. Вы можете использовать SendMessageTimeout, чтобы дождаться возврата WM_CLOSE разумное количество времени, а затем продолжить либо с ошибкой, либо с успехом.

var
  Word: HWND;
  msgResult: DWORD;
begin
  ...

  SendMessageTimeout(Word, WM_CLOSE, 0, 0, SMTO_NORMAL, 5000, msgResult);
  if IsWindow(Word) then begin
    // bummer! Application is open...
 
person Sertac Akyuz    schedule 25.11.2011

Я бы вообще не закрывал другое приложение. Я думаю, что лучше удалить текущий файл перед созданием отчета. В случае неудачи (DeleteFile) показать пользователю сообщение о том, что файл не может быть перезаписан (поскольку он открыт другой программой) и вообще не формировать отчет. Это гораздо безопаснее, потому что вы оставляете право выбора пользователю. Кроме того, это избавит вас от головной боли: что, если программа будет открыта другой программой, которая не отображает заголовок в заголовке окна?

person The_Fox    schedule 25.11.2011

Если вы хотите сделать еще один шаг, чем WM_CLOSE, вы можете только завершить приложение. Все остальное будет похоже на лотерею.

Тем не менее, я против обоих. Что делать, если ваш PDF-файл открывается в приложении MDI, в котором уже отображаются другие документы? При принудительном закрытии приложения пользователь потеряет все изменения в других открытых документах. И отправка сообщения о закрытии этому приложению будет раздражать, поскольку пользователю все еще нужно открыть другие документы.

Вы не можете предсказать поведение каждого приложения. И вы, конечно, не знаете каждое приложение. Если отчет имеет то же имя, вы можете попросить пользователя закрыть другой отчет с тем же именем. В противном случае он не получит новый отчет. Подумайте, что произойдет, если Windows начнет закрывать ваши приложения, как только вы попытаетесь перезаписать файл, который в данный момент используется.

person Heinrich Ulbricht    schedule 25.11.2011
comment
Согласованный. Я думаю, что ответ @Sertac имеет смысл, и логика сообщения об истечении времени ожидания хорошо работает в моем приложении. - person rossmcm; 25.11.2011