Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.147.43.190] |
|
Сообщ.
#1
,
|
|
|
Передать строку в другое приложение посредством сообщений WINDOWS
Добрый день(или утро, или вечер). Недавно я столкнулся с проблемой передачи строки в другое приложение. Задача состояла вот в чем: 1. Проанализировать есть ли уже запущенные экземпляры программы. 2. Если есть то передать управление уже запущенной программе. 3. Если пользователь пытается открыть файл то передать запущенной программе строку с именем файла. 4. Закрыть текущий экземпляр в случае успешных предидущих действий. Я решил сразу использовать метод передачи сообщений от окна к окну. И тут случилось... Посредством SendMessage очень легко передавать САМУ МЕССАГУ и два целых числа (WPARAM)+(LPARAM). А чтобы передать строчку.... Пришлось "повозиться". Предложенные варианты решения меня не очень устроили в связи со своей громоздкостью. Подумав решил использовать ГЛОБАЛЬНУЮ ТАБЛИЦУ АТОМОВ. Привожу пример кода. с краткими пояснениями. //Приложение запускающее мессагу //Регестрируем сообщение extern UINT MY_FILES_MSG1 = ::RegisterWindowMessage("MY_FILES_MSG"); ....... //Код описанный в процедуре CMyApp::InitInstance CString cap ; cap.LoadString(IDR_MAINFRAME); //Ищем уже запущенное приложение по окошку CWnd *pwnd = CWnd::FindWindow(NULL,cap); if (pwnd !=NULL) { //Если нашли то вперед запускать нашу мессагу pwnd->ShowWindow(SW_RESTORE); pwnd->SetForegroundWindow(); // CString cs = AfxGetApp()->m_lpCmdLine; //ЧИТАЕМ преданный файл //вы вместо файла можете отправить все что угодно CCommandLineInfo cl; ParseCommandLine(cl); if(strlen(cl.m_strFileName)>1) { UINT _len = GlobalAddAtom(cl.m_strFileName); ::SendMessage(pwnd->m_hWnd,MY_FILES_MSG,strlen(cl.m_strFileName)+1,_len); } return false; } //Код приложения принимающей сообщение //Регестрируем сообщение extern UINT MY_FILES_MSG2 = ::RegisterWindowMessage("MY_FILES_MSG"); // В описании класса окна обязательно надо указать нашу //процедуру для обработки сообщения protected: //{{AFX_MSG(CMainFrame) ... afx_msg LRESULT OnFileMessage(WPARAM wParam, LPARAM lParam); .... //}}AFX_MSG DECLARE_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ...... //Макрос МФС ON_REGISTERED_MESSAGE предназначен для сопряжения //Нашей мессаги с процедурой обработки (Крутая штука) ON_REGISTERED_MESSAGE(MY_FILES_MSG2, OnFileMessage) ....... //}}AFX_MSG_MAP END_MESSAGE_MAP() //Обработчик нашей процедуры. LRESULT CMainFrame::OnFileMessage(WPARAM wParam, LPARAM lParam) { LPCTSTR ls; if(wParam>0) //Если нашлась "длина" { LPSTR b =new TCHAR[wParam]; //Создаем буфер int _len = wParam; GlobalGetAtomName(lParam,b,_len); //Исчем строчку по ИНДЕКСУ АТОМА ls = (LPCTSTR)b; //Переводим в выгодный и простой (для нас) формат GlobalDeleteAtom(lParam); //Удаляем АТОМ, если конечно он уже не нужен CreatCld(ls);//Процедура обрабатывающея строчку // Вы можете вписать сюда все что угодно delete b;//Чистим память. } return 0; } Вся суть заключается в следующем. Одна прога ложит в ГТА строку и передает уникальный идентификатор АТОМА(WPARAM) + (Длину заложенной Строки)(LPARAM) Другой проге. Посредством сообщения другая прога "разжовует" сообщение и принимает некоторые действия. Статья предназначена пояснить лишь принцип передачи. А ШЕДЕВРЫ - ТВОРИТЬ ПРИЙДЕТСЯ ВАМ. Все вопросы на aster_x@inbox.ru |
Сообщ.
#2
,
|
|
|
Красивый велосипед. А не пробовал просто через WPARAM передать свой HINSTANCE, через LPARAM - указатель на строку, потом открыл процесс и ReadProcessMemory? Или еще проще, заюзать WM_COPYDATA? К тому же вроде бы в МФЦ прозрачно то, что ты описал, делается через DDE...
|
Сообщ.
#3
,
|
|
|
barazuk
А HINSTANCE-то зачем? |
Сообщ.
#4
,
|
|
|
Тьфу, блин, о другом задумался... Конечно, ID процесса...
|
Сообщ.
#5
,
|
|
|
А если надо в разное время выполнения программ юзать одну и туже строку на разных приложениях.
На разных уровнях и к примеру с зарытым реестром а файловую систему юзать нельзя. WM_COPYDATA Мне предлагали и что... Вот кульно отрпавлять КОНСОЛЬНЫМ приложениям виндовые мессаги... ReadProcessMemory А если прога полчаса назад закрыта.... Тем более повторюсь Предложенные варианты решения меня не очень устроили в связи со своей громоздкостью. И тем более я не борюсь за получение права на новый ВЕЛОСИПЕД я просто предложил один из методов. |
Сообщ.
#6
,
|
|
|
Да метод как метод, ничем не лучше и не хуже чем другие. Единственное, ты забыл указать очень важное ограничение на твой метод:
Цитата ...The string can have a maximum size of 255 bytes.... И, не путай людей. GlobalAddAtom возвращает не длину, а идентификатор вставленного (либо уже находящегося) атома. |
Сообщ.
#7
,
|
|
|
Ace я понял Спасибо
просто идентификатор АТОМА(WPARAM) + (Длину заложенной Строки) в (LPARAM) И для остальных.... Немного теории... Data Exchange - Обмен данными(В переводе с английского). Dynamic Data Exchange - Динамический Обмен данными. Если быть уже совсем точным то... К протоколу Data Excange относятся следующие компонентные методики операционной системы MS Windows. 1) Атомы 2)Буфер обмена 3)Копирование данных посредством COPYDATA & WM_COPYDATA 4)Как вы уже упянули ... это DDE к которыму якобы относятся GAT Глобальная таблица атомов. Извините но мне кажется что вы немного ошиблись, и метод COPYDATA может быть и приемлем но он также я вляется "дочерним подклассом" Системы обмена данными WINDOWS. Так что ТАБЛИЦА АТОМОВ не является подситемой DDE. А может я ошибаюсь вместе с MICROSOFT??????????????? P.S. А вполне может быть, что мы немного ошибаемся (вместе MICROSOFT). |
Сообщ.
#8
,
|
|
|
Цитата aster_x @ ReadProcessMemory А если прога полчаса назад закрыта.... Цитата aster_x @ ::SendMessage(pwnd->m_hWnd,MY_FILES_MSG,strlen(cl.m_strFileName)+1,_len); Т.е. твоя полчаса назад закрытая программа посылает другой программе, которая еще не открылась, это сообщение? Или как правильно понять твою логику? WM_COPYDATA кстати, по-моему, можно обработать и после "смерти" пославшей проги, там данные копируются (Гуру! Поправьте, если гоню...) |
Сообщ.
#9
,
|
|
|
Цитата aster_x @ Немного теории... Data Exchange - Обмен данными(В переводе с английского). Dynamic Data Exchange - Динамический Обмен данными. Если быть уже совсем точным то... К протоколу Data Excange относятся следующие компонентные методики операционной системы MS Windows. Не совсем понял, к чему это все... Я просто обратил внимание, что в примере была использована связка MSVS+MFC. И мне показалось достаточно странным не использовать встроенный механизм поддержки ДДЕ через комстроку для открытия всех документов в одном экземпляре приложения. См. тупейший (сразу прошу прощения у эстетов - потратил на креатив целых пять минут, так что не взыщите...) пример в аттаче. Прикреплённый файлTestDDE.rar (88.24 Кбайт, скачиваний: 238) |
Сообщ.
#10
,
|
|
|
Цитата barazuk @ WM_COPYDATA кстати, по-моему, можно обработать и после "смерти" пославшей проги, там данные копируются Смотря когда смерть произошла. Цитата While this message is being sent, the referenced data must not be changed by another thread of the sending process. |
Сообщ.
#11
,
|
|
|
Цитата barazuk @ механизм поддержки ДДЕ через комстроку для открытия всех документов Скорее всего подразумевается коммандная строка. В том то и дело что пришлось не открывыать новое приложнение а из старого забирать комстроку. И отправлять уже запущенной копии. |
Сообщ.
#12
,
|
|
|
Цитата aster_x @ Скорее всего подразумевается коммандная строка. В том то и дело что пришлось не открывыать новое приложнение а из старого забирать комстроку. И отправлять уже запущенной копии. Блин, дак никто ничего и не открывает, если уже есть запущенное приложение! Просто твоя вторая копия при наличии первой ничего не делает, а только посылает через DDE сообщение открыть файл (или что ты захочешь) первой. ВСЕ! Встроено в MFC уже лет пятнадцать как. Покрути приложенный пример, и все станет ясно. |
Сообщ.
#13
,
|
|
|
Цитата aster_x @ 2. Если есть то передать управление уже запущенной программе. 3. Если пользователь пытается открыть файл то передать запущенной программе строку с именем файла. 4. Закрыть текущий экземпляр в случае успешных предидущих действий. Цитата aster_x @ В том то и дело что пришлось не открывыать новое приложнение а из старого забирать комстроку. И отправлять уже запущенной копии. Что ты сказать то хотел? Сам не запутался? |
Сообщ.
#14
,
|
|
|
Нет не запутался. И еще я не претендую на монопольное содержание метода
кто как хочет тот так и делает. ОСНОВНЫЕ ПРИНЦИПЫ Демократии и MICROSOFT. А может быть я ошибаюсь(Вместе с MICROSOFT) |