|
Работа с документами
|
|||
---|---|---|---|
#18+
Есть таблица, в которой храниться содержимое файлов (каждый файл в отдельной записи на SQL сервере). В гриде на форме показвается наименование файла. Можно ли организовать интерактивный показ содержимого выбраного файла, если заранее не известно, какое приложение отвечает за работу с этим типом файлов? Хотелось бы, чтобы работы с файлом (просмотр, редактирование) прооисходили в пределах моей формы (оле), но как заставить олеконтрол понять, что работать надо с файлом, который будет подсунут интерактивно? Вообще возможно ли это? PS Для отображения картинок есть контрол image, в который можно сунуть любую картинку (не обязательно физический файл на диске). Хотелось бы что-то наподобии, но с любым типом документов. Так, например, можно страницу Excel встроить в документ Word, и Word внутри себя покажет документ Excel. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2008, 17:06 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Через ShellExecute сделал. Содержимое файла можно посмотреть, изменить. lcFileName=GETENV("TEMP")+'\'+SYS(3)+JUSTFNAME(Document.Naimen) STRTOFILE(Document.Document, lcFileName) DECLARE INTEGER ShellExecute IN SHELL32.DLL ; INTEGER, STRING, STRING, STRING, STRING, INTEGER ? ShellExecute(0, "Open", lcFileName, NULL, NULL, 1) Но отслеживать, что файл был закрыт, а потом еще проверить был ли он изменен - слабо представляю как реализовать. Есть ли механизмы открыть файл "внутри своей формы"? Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2008, 17:38 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Word`овские файлы отследить, что они открыты по томы, что сам не могу открыть их на запись. Т.е. пока я не могу открыть эти файлы на запись - sleep(500). Как открыл - обрабатывай, проверяй изменения. Но чтука в том, что некороые типы файлов открываются "родными просмоторщиками" только на чтение. Т.е. в то время, когда файл еще смотрят, его можно не только открыть другим приложением, но и удалить. А это уже не знаю как отследить. Как вариант на форму повесить кнопочку "Когда закончите работать с файлом нажми на меня, чтобы сохранить изменения". Но, боюсь пользователи будут тыркать на нее когда только не лень (и зачастую раньше времени). Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2008, 18:08 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Как узнать, что в данный момент файл открыт другой программой (хоть на чтение хоть на запись)? Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.09.2008, 18:16 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
если он кем то открыт - будет ошибка вот ее обрабатывай либо fopen() ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 08:41 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
> Автор: leaf > если он кем то открыт - будет ошибка > вот ее обрабатывай > либо fopen() Не факт. :( Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 08:47 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Galyamov RinatЧерез ShellExecute сделал. Содержимое файла можно посмотреть, изменить. Попробуй GETOBJECT(). Galyamov RinatНо чтука в том, что некороые типы файлов открываются "родными просмоторщиками" только на чтение. Т.е. в то время, когда файл еще смотрят, его можно не только открыть другим приложением, но и удалить. А это уже не знаю как отследить. Некоторые проги (блокнот например) читают файл и закрывают, т.е. в процессе работы с файлом он закрыт, поэтому его можно даже удалить, но если пользователь его сохранит файл будет создан заново. Можно попробовать по принципу WinRAR`а сделать. Он при запуске распаковывает во временный файл, а потом следит за файлом если файл изменился (дата-время, размер) то спрашивает "обновить файл в архиве" Tакой вариант рассматривал: убрать файлы из базы в расшаренную папку, в базе только имя файла. Открывать файл из папки и дальше следить за ним не надо. Если пользователь его сохранит, то он сохранится сразу куда надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 08:56 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
> Можно попробовать по принципу WinRAR`а сделать. Он при запуске > распаковывает во временный файл, а потом следит за файлом если файл > изменился (дата-время, размер) то спрашивает "обновить файл в архиве" А вот по какому принципу он отслеживает файл? Не постоянно же он его опрашивает? Да и мусор за собой он сам подчищает. > Tакой вариант рассматривал: убрать файлы из базы в расшаренную папку, > в базе только имя файла. Открывать файл из папки и дальше следить за ним > не надо. Если пользователь его сохранит, то он сохранится сразу куда надо. Думал над этим, но хочется избавиться от шары, в принципе - невозможно отследить кто и когда изменения внес. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 10:01 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Galyamov Rinat > Можно попробовать по принципу WinRAR`а сделать. Он при запуске > распаковывает во временный файл, а потом следит за файлом если файл > изменился (дата-время, размер) то спрашивает "обновить файл в архиве" А вот по какому принципу он отслеживает файл? Не постоянно же он его опрашивает? Да и мусор за собой он сам подчищает. Поизучал FileMon`ом. Похоже WinRAR следит не за файлом, а за приложением его открывшим и срабатывает на закрытие приложения. За приложением следить достаточно просто. Например если открыть *.DOC из архива, поменять, сохранить, закрыть файл не закрывая ворда, то WinRAR файл даже не проверяет, но стоит закрыть Word так сразу WinRAR начинает вопросы задавать. WinRAR создает отдельный поток внутри себя для ожидания, в фоксе такое не провернуть, фокс однопоточный. Разве что в таймере ADIR() делать периодически и с исходными данными сравнивать. Или WinAPI функцию FindFirstChangeNotification() задействовать. Она примерно то же самое делает. Galyamov Rinat> Tакой вариант рассматривал: убрать файлы из базы в расшаренную папку, > в базе только имя файла. Открывать файл из папки и дальше следить за ним > не надо. Если пользователь его сохранит, то он сохранится сразу куда надо. Думал над этим, но хочется избавиться от шары, в принципе - невозможно отследить кто и когда изменения внес. Возможно отследить кто когда открывал, чтобы только через прогу открывали можешь запретить чтение содержимого папки, тогда просто руками открыть папку и найти нужный в ней файл будет невозможно. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 10:40 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
>За приложением следить достаточно просто. А вот с этого места, пожалуйста, поподробнее >Разве что в таймере ADIR() делать периодически и с исходными данными >сравнивать. Если сравнивать дату - еще туда сюда, а если сравнивать по содержимому - то засада. > Или WinAPI функцию FindFirstChangeNotification() задействовать. Она > примерно то же самое делает. В любом случае - это поможет мне определиться, что файл был изменен (но не обязательно закрыт, что тоже проблема). А вот если пользователь посмотрел, закрыл приложение, но не сохранил изменения - то я никогда не дождусь "FirstChange". А мусор за собой почистить не помешает. > Возможно отследить кто когда открывал, чтобы только через прогу > открывали можешь запретить чтение содержимого папки, тогда просто руками > открыть папку и найти нужный в ней файл будет невозможно. Если не найду приемлимых вариантов - придется копнуть в эту сторону. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 10:53 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Galyamov Rinat >За приложением следить достаточно просто. А вот с этого места, пожалуйста, поподробнее Есть WinAPI функция CreateToolhelp32Snapshot() с ее помошью можно получить список всех запущенных процессов. Следить примерно так: 1. Получить текущий список 2. Открыть файл. С помошью ShellExecute() например 3. Получить список, сравнить с п.1, новый процесс будет от проги обработчика файла. 4. Ждем завершения процесса с помошью WaitForSingleObject() Там правда структур много, писать на фоксе муторно будет. Могу исходник на MS VC 6 дать, там список запущенных процессов выводится. Есть один подвох серьезный, WinRAR тоже на нем попадается. Если запустить Ворд, затем открыть из WinRAR`а какой-нибудь *.DOC, то новый процесс не создается, файл открывается имеющимся вордом, поэтому WinRAR в этом случае изменение файла не замечает. Можешь проверить. Galyamov Rinat>Разве что в таймере ADIR() делать периодически и с исходными данными >сравнивать. Если сравнивать дату - еще туда сюда, а если сравнивать по содержимому - то засада. Содержимое зачем сравнивать? Сохранил во временный файл, запомнил дату-время, если изменилась, то значит изменили файл. Тут надо другое отслеживать, если сначала твою прогу закрыли, а потом измененный файл сохранили, так он обратно в базу никогда не попадет. Galyamov RinatА мусор за собой почистить не помешает. Как вариант: всегда кидать все временные файлы в одну папку, смотреть на дату файла и удалять все файлы старше N дней. Galyamov Rinat> Возможно отследить кто когда открывал, чтобы только через прогу > открывали можешь запретить чтение содержимого папки, тогда просто руками > открыть папку и найти нужный в ней файл будет невозможно. Если не найду приемлимых вариантов - придется копнуть в эту сторону. Тут можешь добавить хранение нескольких последних версий файла на случай если кто попортит файл. Перед открытием сравнивай последнюю копию и текущее состояние, если отличаются сначала делай копию, затем открывай на редактирование. А кто попортил можно отловить по дате файла и логу где открытие файла будет фиксироваться. По крайней мере для Word`а и Excel`я это точно сработает, т.к. двум разным пользователям один файл одновременно не открыть. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 11:47 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Dima TЕсть WinAPI функция CreateToolhelp32Snapshot() с ее помошью можно получить список всех запущенных процессов. Проблема в том, что это будет именно список процессов . А не приложений (файлов), запустивших этот процесс. Например, если на машине есть два одинаковых приложения, но расположенных в разных директориях и оба они будут запущены одновременно, то в списке процессов отличить их друг от друга будет невозможно. Несмотря на то, что в документации написано о том, что можно прочитать полный путь доступа до файла, запустившего процесс, но реально возвращается только и исключительно имя файла. Без пути доступа. По крайней мере, у меня не получилось "выцарапать" полный путь доступа к процессу. Только и исключительно собственно имя файла, запустившего процесс. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 12:02 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
ВладимирМНапример, если на машине есть два одинаковых приложения, но расположенных в разных директориях и оба они будут запущены одновременно, то в списке процессов отличить их друг от друга будет невозможно. Элементарно сравнить ProcessID, даже у одного и того же приложения запущенного в нескольких экземплярах этот параметр отличается. ВладимирМНесмотря на то, что в документации написано о том, что можно прочитать полный путь доступа до файла, запустившего процесс, но реально возвращается только и исключительно имя файла. Без пути доступа. По крайней мере, у меня не получилось "выцарапать" полный путь доступа к процессу. Только и исключительно собственно имя файла, запустившего процесс. Получить полный путь можно перебирая модули внутри процесса с помошью CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID) Только в данном случае достаточно сравнить два массива ProcessID до запуска и после. И выявить тот который добавился. Проблема только в том что он может не добавиться, как я выше писал. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 12:16 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Dima TПолучить полный путь можно перебирая модули внутри процесса с помошью CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID) Я тоже так думал. А ты сам пробовал? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 12:20 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Ясно. Решение задачи в итоге окажется очень сложным и неоправданно запутанным. Если склониться к хранению в шаре сервера, то есть еще одна проблема - когда будет много фалов будут большие тормоза. Придется, наверное, ограничивать список возможных документов для хранения. И обрабатывать каждый тип документа своим OLE сервером. Возможно, даже положить его на форму и прямо в ней открывать. Примеры такого кто-нить видел? Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 12:26 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
ВладимирМ Dima TПолучить полный путь можно перебирая модули внутри процесса с помошью CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID) Я тоже так думал. А ты сам пробовал? Пробовал, результат в архиве с исходниками на MSVC6 Выводит список всех процессов с подробностями. А пробовал чтобы написать проверку запущен ли какой-нибудь процесс из заданной папки. Там же в ListProcess.cpp функция IsWorkingPath(LPCTSTR pcszPath) ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 12:27 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Galyamov RinatЕсли склониться к хранению в шаре сервера, то есть еще одна проблема - когда будет много фалов будут большие тормоза. Наблюдал однажды автоматизацию хранения сертификатов отсканированных, в папке жило около 100 тысяч файликов с отсканированными бумажками, тормозило немного, но работало. Потом перестроили хранение в подпапках с ограничением кол-ва файлов на одну папку, тормоза прошли. Проверять надо до какого кол-ва файлов не тормозит если непосредственно по имени файла обращаться. Дерево из подпапок соорудить, и ограничить не более N файлов и подпапок в одной папке например. И хранить путь к файлу относительно шары, что-то типа такого "SUBFOLDER001\SUBFOLDER123\MyFile.doc" ... |
|||
:
Нравится:
Не нравится:
|
|||
09.09.2008, 12:42 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Т.к. других вариантов не нашел, решил ограничиться "известными" типами файлов (с последующим расширением списка). Сделал слдеующее: В клике кнопки "показать": Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
В timer1.timer: Код: plaintext 1. 2. 3. 4. 5.
Использую TYPE('ThisForm.Pageframe1.Page2.Doc.Parent'), а не VARTYPE(ThisForm.Pageframe1.Page2.Doc), т.к. VARTYPE(ThisForm.Pageframe1.Page2.Doc) возвращает "O" даже если сам объект уже разрушен. Приходится передернуть любое свойство объекта. Насколько "некривой" подход? Есть мысли? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2008, 13:49 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Что будет если прогу раньше закроют чем файл? Ни разу не пользовался, в SOLUTION увидел. Можно лист экселя (или документ ворда) прямо в форму вставить: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2008, 14:42 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Случайно попало: Код: plaintext
... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2008, 14:44 |
|
Работа с документами
|
|||
---|---|---|---|
#18+
Dima TСлучайно попало: Код: plaintext
http://forum.foxclub.ru/read.php?29,343196,343216#msg-343216 ... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2008, 16:00 |
|
|
start [/forum/topic.php?fid=41&msg=35529337&tid=1587305]: |
0ms |
get settings: |
11ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
50ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 157ms |
0 / 0 |