пятница, декабря 07, 2012
понедельник, декабря 03, 2012
Что, мальчики, не получается?
Несчастные вы бедолажки в Эпле... Ну, кое-как портировали уродца своего на Windows, ладно. Он, правда, почти год после этого не понимал русский язык, ну, тоже спишем на вашу экстраординарную нетрадиционность. Но вы же всё-таки инженеры, нет? Я там не говорю, что все как один состоите в IETF, но хотя бы общие представления о платформе, на которую делает порт, надо иметь!
Safari это поганое: DDE не поддерживает, с COM не знакомо, требованиям Windows по проектированию оконных интерфейсов не удовлетворяет.
Что же так слабо? Не умеете? Не получается? Ай-яй-яй. Да... это вам не подсветочку вокруг кнопки рисовать. Срамота!
Safari это поганое: DDE не поддерживает, с COM не знакомо, требованиям Windows по проектированию оконных интерфейсов не удовлетворяет.
Что же так слабо? Не умеете? Не получается? Ай-яй-яй. Да... это вам не подсветочку вокруг кнопки рисовать. Срамота!
Отправил
Das Ich
в
6:53 PM
0
раз прокомментировано
Метки: бананотехнологии, всякое, любители
Простой пример DDE и C
Потребовалось получить URL из Firefox. FF вообще написан чудным образом, весьма далёким от того, как надо писать программы для Windows. Поэтому пройти по иерархии окон и получить текст окна - невозможно. Зато возможно получить нужное через DDE. О командах, которые можно использовать в DDE для получения информации из браузера, примерно можно почитать тут: http://support.microsoft.com/kb/160957 Не знаю, какие именно из них поддерживает FF, но получить URL таким образом можно. Для этого нужно использовать команду WWW_GetWindowInfo.
Несмотря на то, что DDE уже старенькая технология (в этом году ей исполнилось 22 года), она по-прежнему работает и неплохо. Её суть примерно в следующем.
Подключаемся к FF (никакой обработки ошибок и дурацкие имена для понятности)
Несмотря на то, что DDE уже старенькая технология (в этом году ей исполнилось 22 года), она по-прежнему работает и неплохо. Её суть примерно в следующем.
- Клиент-серверная архитектура DDE подразумевает, что одна сторона (клиент) будет слать запросы, а другая (сервер) - их выполнять. Используется парадигма "разговора", а именно: вопрос-ответ.
- Клиент может задавать темы "разговора" (не знаю, для чего это нужно). Выглядит, в переводе на человеческий язык это так. Клиент говорит: "Эй, ты, сервер по имени Firefox, хочу с тобой потолковать насчёт WWW_GetWindowInfo. Ты как, в настроении?". Сервер отвечает: "Ну, давай. Дескриптор этого разговора равен 1232134. Если дальше будешь спрашивать про своё - не забывай мне напоминать, о чём толкуем, подставляя это число как идентификатор. А то много вас тут лезет поговорить, не уследишь по-другому"
- Если сервер согласился поддержать "разговор" (выдав HCONV не равный NULL), дальше можно задавать ему вопросы. Для каждой темы, на которую можно клиент может потолковать с сервером есть допустимый "список вопросов". В нашем случае для темы WWW_GetWindowInfo браузер предполагает, что дальше его будут спрашивать про URL и WindowText. Задать вопросы про прогресс закачки файла в разговоре, посвящённом WWW_GetWindowInfo, не выйдет.
- Задавание вопроса заключается в последовательном вызове 3х функций:
- DdeCreateStringHandle - создаёт DDE-описатель для "вопроса", такого как "URL"
- DdeClientTransaction - начинает транзакцию передачи данных. Можно это себе представлять как фразу "Эй, сервер, хочу тебя спросить... Ну, вот мы говорим, про WWW_GetWindowInfo. Так что там с URL?"
- DdeGetData - это вызывается для получения ответа на свой вопрос. В ответ на этот вызов DDE скопирует данные в переданный вами буфер и в нём будет искомый ответ.
- Инициализировать DDE, чтобы можно было дальше вызывать его функции
- Установить соединение с сервером DDE, каковым является FF. При установке соединения задать тему разговора WWW_GetWindowInfo
- Спросить FF про URL
TCHAR ddeServer[] = L"Firefox";
TCHAR conversationTopic[] = L"WWW_GetWindowInfo";
TCHAR topicSpecificCommand[] = L"URL";
DWORD idInst=0;
DdeInitialize(&idInst, (PFNCALLBACK)DdeCallback, APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0 );
HSZ appStringHandle, topicStringHandle;
HCONV conversationHandle;
appStringHandle = DdeCreateStringHandle(idInst, ddeServer, 0);
topicStringHandle = DdeCreateStringHandle(idInst, conversationTopic, 0);
conversationHandle = DdeConnect(idInst, appStringHandle, topicStringHandle, NULL);
DdeFreeStringHandle(idInst, appStringHandle);
DdeFreeStringHandle(idInst, topicStringHandle);
Спрашиваем у FF, какой URL у его активной закладки активного экземпляра
HSZ commandStringHandle = DdeCreateStringHandle(idInst, topicSpecificCommand, 0);
HDDEDATA hData = DdeClientTransaction(NULL,0,conversationHandle,commandStringHandle, CF_TEXT, XTYP_REQUEST, 5000, NULL); // CF_TEXT для получения однобайтовой строки
// CF_UNICODETEXT - для юникодной
char res[255] = {0};
DdeGetData(hData, (unsigned char*)res, 255, 0);
printf("%s\n", szResult);
Всё. В res лежит URL закладки, с которой пользователь работал последней в экземпляре FF с которым пользователь работал последним. P.S. Само собой, не забывайте проверять ошибки после вызовов. А то всякое может быть. Например, нету у вас запущенного экземляра FireFox, вы не знаете и стремитесь с ним поговорить. Не выйдет! :)
P.P.S. Удаляйте всё, что создаёте: DdeCreateStringHandle -> DdeFreeStringHandle, DdeCreateDataHandle -> DdeFreeDataHandle
P.P.P.S. То же самое работает и для Opera, только содержимое ddeServer должно быть "Opera"
Отправил
Das Ich
в
2:13 PM
0
раз прокомментировано