Страница 2 из 2

Открыть окно командой из внешнего приложения

Добавлено: 11 Ноябрь 2015, 13:06
Admin
Дед Пахом писал(а): Что-то я не пойму, если приложение чужое, то с какой радости оно будет реагировать на твои сообщения?
Почитай про AutoHotKey. Удивишься, что только ни делают с чужими приложениями :)

Открыть окно командой из внешнего приложения

Добавлено: 11 Ноябрь 2015, 13:14
Дед Пахом
Admin писал(а): Почитай про AutoHotKey. Удивишься, что только ни делают с чужими приложениями
Ну я не совсем это имел в виду... Например, сколько не бейся, всё равно не получится послать в блокнот такое сообщение, чтобы он (блокнот) вдруг начал картинки рисовать.

Открыть окно командой из внешнего приложения

Добавлено: 11 Ноябрь 2015, 13:18
Admin
Я так до конца и не понял хотелку автора поста!

Открыть окно командой из внешнего приложения

Добавлено: 11 Ноябрь 2015, 13:40
RaFaeL
Admin писал(а): Я так до конца и не понял хотелку автора поста!
Нужно выполнить внешнюю команду так, чтобы в уже запущенном приложении выполнился некий код. Пример:
- внешняя команда: program.exe -firm 123
- код: updatefirm(123)

program.exe может быть либо то же самое приложение, либо можно написать отдельное, не принципиально
ОК, находим хэндл приложения как-либо, делаем SendMessage(handle,,,)
Здесь нужны примеры: а) какого типа сообщение послать; б) как описать передаваемый параметр; в) как принять передаваемые данные. Далее если я правильно понял где-то внутри приложения на каком то евенте я уже пропишу вызов нужной мне процедуры

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 7:15
Admin
Что то стал с вопросом разбираться и попал в затруднения. Не могу строку передать между программами.
Т.е. число просто через sendmessage передается без проблем, а вот строку не получается.
Пробовал WM_COPYDATA и нифига. Только размер строки указываешь - не передает.
Странности. Есть конечно еще варианты но хотелось попроще.

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 7:42
PavelNK
Нужно передавать не строку, а указатель на строку

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 8:16
Admin
PavelNK писал(а):Нужно передавать не строку, а указатель на строку
Да вроде не первый день "замужем" :)
Просто там какие то заморочки с памятью. Я то передаю ссылку на строку из первой программы. А потом эту строку пытается читать вторая программа. Что как бы не положено. Я думаю.
Не спец. Методом тыка все делаю.

Вот по этой причине хотел заюзать WM_COPYDATA, вроде для этого и служит. Но там когда указываю размер буфера перестает работать.

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 8:19
Admin
На дельфи когда писал хуки на клаву/мышку приходилось делать такое через отображение файла в память. Может и тут нужно.

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 8:23
Admin
Еще вариант сокеты :)

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 8:28
Admin
Когда в клиенте задаешь размер

Код: Выделить всё

SendData.DataSize = SIZE(SendCString)
Следующий код не отправляет сообщение...

Код: Выделить всё

ClaSendMessage(loc:hFind, WM_COPYDATA, loc:hFind, ADDRESS(SendData))
т.е. кажется Windows не может скопировать структуру при указании размера переменной из SendData.Data

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 9:18
Ал
Admin писал(а):Вот на этом тестировал
SendMessage.zip
Когда в клиенте задаешь размер

Код: Выделить всё

SendData.DataSize = SIZE(SendCString)
Следующий код не отправляет сообщение...

Код: Выделить всё

ClaSendMessage(loc:hFind, WM_COPYDATA, loc:hFind, ADDRESS(SendData))
т.е. кажется Windows не может скопировать структуру при указании размера переменной из SendData.Data
пишут что все хорошо? - http://delphiru.ru/other/14--.html

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 9:32
Ал
ps ещё тут весело обучали http://www.sql.ru/forum/1081804/otpravk ... m-copydata

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 9:51
Admin
Все заработало. Строка уходит!

Спасибо за последний пост. Сам протупил. Группу неверно описал. :)
Клиент/отправитель события:

Код: Выделить всё

    PROGRAM

    INCLUDE('CFCWndProc.inc')

    MAP
      MODULE('WinApi')
         ClaRegisterWindowMessage(LONG lpString),ULONG,PASCAL,RAW,NAME('RegisterWindowMessageA')
         ClaSendMessageTimeout(LONG hWnd,ULONG wMsg,ULONG wParam,LONG lParam,ULONG fuFlags,ULONG uTimeout,LONG lpdwResult),PROC,LONG,PASCAL,NAME('SendMessageTimeoutA')
         ClaSendMessage(LONG hWnd,ULONG wMsg,ULONG wParam,LONG lParam),PROC,LONG,PASCAL,NAME('SendMessageA')
         ClaEnumWindows(LONG lpEnumFunc,LONG lParam),BOOL,PASCAL,RAW,NAME('EnumWindows')
         GetLastError(),LONG,PASCAL,RAW,NAME('GetLastError')
      END
      Searcher(ULONG hWnd, LONG lParam),BOOL,PASCAL
    END

LOC:hFind           LONG
GLO:RegMsgID        LONG
GLO:SearchMsgID     LONG
GLO:RegMsgStr       CSTRING('MY_CLA_EVENT1')
GLO:SearchMsgStr    CSTRING('MY_CLA_EVENT2')

CopyStruct          GROUP,TYPE
PacketNum             LONG
DataSize              LONG
Data                  LONG
                    END

SendData            LIKE(CopyStruct)
SendCString         CSTRING(200)
WM_COPYDATA         EQUATE(74)

 CODE
 GLO:RegMsgID    = ClaRegisterWindowMessage(ADDRESS(GLO:RegMsgStr))
 GLO:SearchMsgID = ClaRegisterWindowMessage(ADDRESS(GLO:SearchMsgStr))
 Err# = ClaEnumWindows(ADDRESS(Searcher), ADDRESS(LOC:hFind))
 IF LOC:hFind
   SendCString = 'Тестовые данные для отправки в другое приложение'
   SendData.PacketNum = 32768 ! используем как ID
   SendData.Data = ADDRESS(SendCString)
   SendData.DataSize = SIZE(SendCString)
   ClaSendMessageTimeout(loc:hFind, WM_COPYDATA, loc:hFind, ADDRESS(SendData), 3, 200, 0)
   !ClaSendMessage(loc:hFind, WM_COPYDATA, loc:hFind, ADDRESS(SendData))
 END

Searcher            PROCEDURE(ULONG hWnd, LONG lParam)!,BOOL,PASCAL
loc:Result          LONG
loc:ok              LONG
loc:pFind           &LONG
 CODE
 loc:ok = ClaSendMessageTimeout(hWnd, GLO:SearchMsgID, 0, 0, 3, 200, ADDRESS(loc:Result))
 IF loc:ok
   IF loc:Result = 887799
     loc:pFind &= (lParam)
     IF NOT loc:pFind &= NULL
       loc:pFind = hWnd
     END
     RETURN FALSE
   ELSE
     RETURN TRUE
   END
 END
 RETURN TRUE
Сервер/получатель события:

Код: Выделить всё

    PROGRAM

    INCLUDE('CFCWndProc.inc')

    MAP
      MODULE('WinApi')
         ClaRegisterWindowMessage(LONG lpString),ULONG,PASCAL,RAW,NAME('RegisterWindowMessageA')
         MemCpy( long dest, long src, signed n ),long,proc,name('_memcpy')
      END
    END

WP                  CLASS(CFCWndProc) ! сабклассинг окна
CallBackProc          PROCEDURE(ULONG hWnd,ULONG wMsg,ULONG wParam,LONG lParam),LONG,DERIVED
                    END

Window              WINDOW('Server'),AT(,,222,151),SYSTEM,GRAY,DOUBLE
                    END

GLO:RegMsgID        LONG
GLO:SearchMsgID     LONG
GLO:RegMsgStr       CSTRING('MY_CLA_EVENT1')
GLO:SearchMsgStr    CSTRING('MY_CLA_EVENT2')

CopyStruct          GROUP,TYPE
PacketNum             LONG
DataSize              LONG
Data                  LONG
                    END

ReceivedStruct      &CopyStruct
ReceivedCString     &CSTRING

WM_COPYDATA         EQUATE(74)

 CODE
 OPEN(Window)
 GLO:RegMsgID    = ClaRegisterWindowMessage(ADDRESS(GLO:RegMsgStr))
 GLO:SearchMsgID = ClaRegisterWindowMessage(ADDRESS(GLO:SearchMsgStr))
 WP.SetCallBack(Window{PROP:Handle})
 ACCEPT
   CASE ACCEPTED()
   END
 END
 WP.RemoveCallback()
 CLOSE(Window)

WP.CallBackProc     PROCEDURE(ULONG hWnd,ULONG wMsg,ULONG wParam,LONG lParam)!,LONG,DERIVED
loc:RetValue        LONG
  CODE
  CASE wMsg
  OF WM_COPYDATA
    ReceivedStruct &= (lParam)
    ReceivedCString &= (ReceivedStruct.Data)
    MESSAGE(ReceivedCString)
  OF GLO:RegMsgID
    !
  OF GLO:SearchMsgID
    RETURN 887799
  END
  RETURN PARENT.CallBackProc(hWnd,wMsg,wParam,lParam)

SendMessage1.zip
(20.95 КБ) 148 скачиваний

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 12:12
RaFaeL
Вот спасибо, буду пробовать
Правда меня и число устроило бы

Открыть окно командой из внешнего приложения

Добавлено: 12 Ноябрь 2015, 12:53
Admin
RaFaeL писал(а): Правда меня и число устроило бы
В таком случае все чуть чуть проще. Через wParam и lParam можно два числа передать.