Russian Qt Forum
Ноябрь 24, 2024, 01:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QFileOpenEvent ? [решено]  (Прочитано 8587 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Сентябрь 13, 2014, 08:03 »

Добрый день

Пользователь сделал  double-click на файл моего приложения. Прописал куда положено что умею открывать файлы с таким extension (на Вындоуз в реестр). Приложение запускается, в командной строке пусто.

Цитировать
The QFileOpenEvent class provides an event that will be sent when there is a request to open a file or a URL.
Думаю вот хорошо! Читаю дальше
Цитировать
Note: This class is currently supported for Mac OS X and Symbian only.
А что же на Вындоуз? Прорываться в нативняке ? Плачущий Плачущий

Спасибо
« Последнее редактирование: Сентябрь 14, 2014, 12:31 от Igors » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Сентябрь 13, 2014, 08:28 »

Нас сколько я помню имя файла передается в командной строке при запуске приложения связанного с файлом.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Сентябрь 13, 2014, 08:32 »

Нас сколько я помню имя файла передается в командной строке при запуске приложения связанного с файлом.
Пусто (Win 7). И непринципиально - юзер может открывать когда приложение уже запущено.
Ищу какая это месяга  Плачущий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Сентябрь 13, 2014, 10:37 »

Нет, не пусто, в командной строке приходит (то я в реестре насвистел). Но это не помогает если приложение уже стартовало. Вроде надо действовать через WM_DDE_INITIATE?

[off]
Где тот молодой-интересный называющий себя виндоузятником? Как до дела доходит - ветром сдувает  Улыбающийся
[/off]
« Последнее редактирование: Сентябрь 13, 2014, 10:42 от Igors » Записан
Bepec
Гость
« Ответ #4 : Сентябрь 13, 2014, 10:44 »

Я вас особо не люблю, потому и не отписываюсь без призыва.
Очевидно:  на деле это должно поддерживаться приложением.
Варианты:
1) одно приложение за раз - запуск второго передаёт параметры в первый.
2) COM длл, которая будет передавать параметры приложению.

А если вы хотите, чтобы ОС правило код вашего приложения, то вы будете разочарованы. Именно вы должны добавить поддержку. 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Сентябрь 13, 2014, 11:36 »

Варианты:
1) одно приложение за раз - запуск второго передаёт параметры в первый.
2) COM длл, которая будет передавать параметры приложению.
Такие рекомендации недоступны моему пониманию  Улыбающийся

Ладно, начнем от печки. Есть расширение напр .da1 (мое). Прописываю в HKEY_CLASSES_ROOT

Ключ  Значение
.da1    MyApp_da1

Теперь создаю там же,  в HKEY_CLASSES_ROOT

MyApp_da1
     DefaultIcon       C:\Test\MyApp.exe,3
     shell
             open
                     command  C:\Test\MyApp.exe %1
                     ddeexec                              Open(%1)
                               application                 MyApp
                               topic                         system
 
Это работает, Если приложение уже запущено, то по крайней мере WM_DDE_INITIATE приходит. Если нет - запускается, и я получаю имя файла в командной строке. но при этом появляется неприятный варнинг в Explorer'e 
Цитировать
Тhere was a problem sending the command to the program

Если убрать секцию ddeexec, варнинг исчезает, но и WM_DDE_INITIATE не приходит

ЧЯДНТ ?


Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #6 : Сентябрь 13, 2014, 12:43 »

с QtSingleApplication все работает идеально, и даже QFileOpenEvent приходит на маке

кстати по-хорошему надо оба параметра command брать в кавычки: command  "C:\Test\MyApp.exe" "%1"
« Последнее редактирование: Сентябрь 13, 2014, 12:47 от kambala » Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Bepec
Гость
« Ответ #7 : Сентябрь 13, 2014, 12:47 »

Беглый просмотр сообщения показывает, что оно должно использоваться клиентами для соединения с сервером. Подразумевается что сервер в момент посыла сообщения УЖЕ запущен и ожидает команду.

Так же на некоторых форумах рекомендуют не использовать этот механизм, т.к. он устаревший.

Собственно именно из-за  "устаревания" этот метод прошёл мимо моих глаз Улыбающийся

PS а на сей день работают без сомнений способы, указанные в предыдущем моём сообщении.


PPS если не понятно то
1) приложение при запуске проверяет, запущен ли ещё 1 его экземпляр и если запущен, то передаёт туда данные и закрывается.
2) COM dll, которая в принципе будет делать то же, что и в п.1. Правда 100% гарантии не даю - этим способом не пользовался.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Сентябрь 13, 2014, 13:23 »

с QtSingleApplication все работает идеально, и даже QFileOpenEvent приходит на маке
На маке я и так сделал  Улыбающийся

кстати по-хорошему надо оба параметра command брать в кавычки: command  "C:\Test\MyApp.exe" "%1"
Только что получил за отсутствие кавычек, исправил. Но тут др беда - на Вындоуз когда юзер выбрал 2 или более файлов и правой кнопкой Open - в командной строке только первый. Пробовал %* (вместо %1) - не помогло

Беглый просмотр сообщения показывает,
Наверное речь идет о сообщении WM_DDE_INITIATE. Хорошо, устарело, что вместо него?

PS а на сей день работают без сомнений способы, указанные в предыдущем моём сообщении.

PPS если не понятно то
1) приложение при запуске проверяет, запущен ли ещё 1 его экземпляр и если запущен, то передаёт туда данные и закрывается.
2) COM dll, которая в принципе будет делать то же, что и в п.1. Правда 100% гарантии не даю - этим способом не пользовался.
В любом случае приложение должно что-то получить (напр сигнал, месягу, event), иначе как оно узнает что нужно открыть файл? Причем тут 2-я instance - хз. И вообще неясно о чем Вы  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Сентябрь 13, 2014, 13:38 »

В любом случае приложение должно что-то получить (напр сигнал, месягу, event), иначе как оно узнает что нужно открыть файл? Причем тут 2-я instance - хз. И вообще неясно о чем Вы  Улыбающийся
Ну так вам и предлагают отправлять сигнал, месягу, event от одной instance программы другой.
Запущенных программ нет. Пользователь кликнул на файле с данными - запустилась первая instance вашей программы. Теперь пользователь кликнут на другом файл с данными - стартует вторая instance вашей программы - она определяет, что запущенна первая instance - она отправляет сигнал, месягу, event с именами файлов этой первой instance - вторая instance завершается.
Поэтому и про QtSingleApplication упомянули.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Сентябрь 14, 2014, 10:35 »

Ну так вам и предлагают отправлять сигнал, месягу, event от одной instance программы другой.
Запущенных программ нет. Пользователь кликнул на файле с данными - запустилась первая instance вашей программы. Теперь пользователь кликнут на другом файл с данными - стартует вторая instance вашей программы - она определяет, что запущенна первая instance - она отправляет сигнал, месягу, event с именами файлов этой первой instance - вторая instance завершается.
Поэтому и про QtSingleApplication упомянули.
Спасибо, теперь понял. Решил что проще использовать этот механизм чем возиться с DDE, делаю.
Проблема: запуск происходит только "по одному". Напр юзер выбрал 8 файлов Open - запускается 8 instances, причем асинхронно. Как бы сделать чтобы в командной строке приходили все?

Спасибо
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Сентябрь 14, 2014, 12:31 »

Как бы сделать чтобы в командной строке приходили все?
Погуглил, тоже люди спрашивают, но видимо в этой чудесной ОС такого нету. Ну ладно, сделал через QSharedMemory, там тривиально. Работает

Спасибо
Записан
Bepec
Гость
« Ответ #12 : Сентябрь 14, 2014, 12:45 »

Групповая обработка только через COM дллку. Что скажем так не прельщает. Но механизм "передачи в 1 инстанс" и в этом случае работает нормально.
Записан
OKTA
Гость
« Ответ #13 : Сентябрь 15, 2014, 09:25 »

Я делал так, что запускается маленькое приложенице, основанное на QtSingleApplication и оно ждет какое-то количество миллисекунд, когда придут данные обо всех остальных запущенных копиях и уже после этого запускаю основное приложение, куда кидаю все данные накопленные.

А чтобы все приходило за один раз - по простому не сделать  В замешательстве
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Сентябрь 15, 2014, 10:54 »

Я делал так, что запускается маленькое приложенице, основанное на QtSingleApplication и оно ждет какое-то количество миллисекунд, когда придут данные обо всех остальных запущенных копиях и уже после этого запускаю основное приложение, куда кидаю все данные накопленные.

А чтобы все приходило за один раз - по простому не сделать  В замешательстве
Хз как можно такое придумать "запуск копии на КАЖДЫЙ" - но это факт Улыбающийся У меня примерно так (псевдокод)

Код
C++ (Qt)
QSharedMemory theSharedMem;
 
struct CSharedData {
int mType. mVers;
HWND mWnd;
char mDummy[4];
};
UINT theMsgID = 0;
------------
theMsgID = ::RegisterWindowMessage(GetAppFullName());
 
theSharedMem.setName(GetAppFullName());
if (theSharedMem.create(SHARED_SIZE)) {    // рабочая копия
theSharedMem.lock();
CSharedData * sd =  (CSharedData *) theSharedMem.data();
memset(sd, 0, SHARED_SIZE);
sd.mType = DATA_TYPE;  // инициализация
sd.mVers = DATA_VERS;
theSharedMem.unlock();
}
 
else  
if (theSharedMem.attach()) {      // копия для передачи командной строки
bool stop = false;
while (!stop) {
 theSharedMem.lock();
 CSharedData * sd =  (CSharedData *) theSharedMem.data();
  if (sd->mWnd) {
    // добавляем командную строку
   ...
   stop = true;
   ::PostMessage(sd->mWnd, theMsgID, 0, 0):
  }
 theSharedMem.unlock();
 if (!stop) ::Sleep(10);   // ждем когда появится mWnd
}
exit(0);
}
 
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.087 секунд. Запросов: 22.