Конференция "WinAPI" » Проблема получением сообщения WM_COPYDATA, Проблема с аглоритмом
 
  • Жэня (12.03.10 22:24) [0]
    Собственно задача
    Нужно отправить определённой программе команду с помощью SendMessage(WM_CopyData), дождаться пока прийдёт ответ от нее (тоже она отправляет с помощью WMCopyData и SendMessage) и возвращитить его как резалт функции. Это конечно можно сделать асинхронно всё. Т.е. отправил команду. Потом получил ответ в оконную функцию и запустил нужную функцию или присвоил его переменной какой-то. Но хотелось бы как. Из любого места в программе вызвал функцию
    MYSENDCOMMAN('тут команда') и она возвратила результат который ей пришел от другой программы. Реально ли этол вообще сделать?

    Пытался сделать так. в MYSENDCOMMAN отправляю сообщение, потом делаю бесконечный цыкл где происходит application.processmessage который обрываеться когда приходит WM_CopyData в оконную функцию. Только вот проблема что в оконную функцию это сообщение уже не приходит так капк подозреваю что цыкл который бесконечный с application.processmessage недает этому свершиться. Может знает кто-то как вообще можно это реализовать?...
  • DVM © (12.03.10 23:07) [1]

    > Жэня   (12.03.10 22:24) 

    для обмена данными между процессами есть множество методов:
    1) Сообщения
    2) Сокеты
    3) Именованные каналы
    4) Файлы отображенные в память
    5) Майлслоты всякие
    6) DCOM

    Сообщения не лучший способ в твоем случае
  • DVM © (12.03.10 23:09) [2]

    > MYSENDCOMMAN('тут команда') и она возвратила результат который
    > ей пришел от другой программы. Реально ли этол вообще сделать?
    >

    что из себя представляет результат? Если целое число, то SendMessage как раз это и позволит сделать.
  • Жэня (12.03.10 23:54) [3]
    ну тут спецификация такая что нужно именно сообщениями
    поэтому других вариантов нету

    да, я вкурсе что sendmessage возвращает результат, тольво вот он не integer и нужно именно получить резалт что шлёт программа через wm_copydata
  • DVM © (13.03.10 00:04) [4]

    > Жэня

    Две посылки WM_COPYDATA всегда будут асинхронны. Одной WM_COPYDATA тоже не обойдешься, т.к принимающая сторона не может менять данные в сообщении.
    Если уж приспичило именно сообщениями, то может их использовать в паре с MMF
  • Жэня (13.03.10 00:09) [5]
    ну тут нето чтобы приспичило, вторая прога это третья разработка и она так работает.//
  • DVM © (13.03.10 00:11) [6]

    > Жэня   (13.03.10 00:09) [5]

    Сделать из асинхронного синхронное конечно всегда можно, но надо ли? Это как корове седло.
  • Rouse_ © (13.03.10 00:30) [7]
    Если нельзя, но все-же очень хочется, то можно. Пусть принимающая сторона на SendMessage возвращает хэндл выданный GlobalAlloc, откуда можно будет прочитать результирующие данные.
  • Игорь Шевченко © (13.03.10 00:39) [8]

    > Пусть принимающая сторона на SendMessage возвращает хэндл
    > выданный GlobalAlloc, откуда можно будет прочитать результирующие
    > данные.


    Из другого процесса ?
  • Rouse_ © (13.03.10 00:40) [9]
    Ну и вот это конечно очень сильно удивило:

    > вкурсе что sendmessage возвращает результат, тольво вот
    > он не integer
  • Rouse_ © (13.03.10 00:47) [10]

    > Игорь Шевченко ©   (13.03.10 00:39) [8]
    >
    >
    > > Пусть принимающая сторона на SendMessage возвращает хэндл
    > > выданный GlobalAlloc, откуда можно будет прочитать результирующие
    > > данные.
    >
    >
    > Из другого процесса ?

    А это проблемма?
  • Жэня (13.03.10 00:51) [11]
    я всмысле что sendmessage возвращает целое только программа та возвращает не целое... поэтому определять успешность команды сендмеседж неподходит.

    В любом случае решил уже проблему.
    ReplyMessage(1); спасла, просто вызывался цыкл в оконной функции и небыло ответа на сообщение, поэтому не слались другие. Всем спасибо
  • Игорь Шевченко © (13.03.10 01:11) [12]
    Rouse_ ©   (13.03.10 00:47) [10]

    Возвратить Handle, полученный по GloballAlloc в другом процессе - не проблема.

    Прочитать данные оттуда представляется проблемой, нет ? Как-то до сих пор не приходилось слышать об обмене между процессами по Handle GlobalAlloc, все больше через MMF.

    У меня такой пробел в образовании ?
  • Rouse_ © (13.03.10 01:26) [13]

    > Игорь Шевченко ©   (13.03.10 01:11) [12]
    > У меня такой пробел в образовании ?

    Стесняюсь спросить, CreateStreamOnHGlobal работает только в рамках твоего процесса?
  • Игорь Шевченко © (13.03.10 01:32) [14]
    Rouse_ ©   (13.03.10 01:26) [13]

    Ты не стесняйся, ты лучше код приведи, когда один процесс выделяет память по GlobalAlloc, передает этот HGlobal в другой процесс, а другой эту память использует. Хотя бы через CreateStreamOnHGlobal, или через GlobalLock + чтение/запись
  • Германн © (13.03.10 01:39) [15]

    > Rouse_ ©   (13.03.10 01:26) [13]


    > Игорь Шевченко ©   (13.03.10 01:32) [14]

    Бедн(ый)ая Жэня.
    Он(а) совсем о другом спрашивал(а).
    (((
  • Rouse_ © (13.03.10 12:18) [16]

    > Игорь Шевченко ©   (13.03.10 01:32) [14]
    >
    > Rouse_ ©   (13.03.10 01:26) [13]
    >
    > Ты не стесняйся, ты лучше код приведи

    Хм, мдя, что-то я зарапортовался, глядя на код своего снапина :)
    Ну тогда вот так:

    Отправляющая сторона:
    procedure TForm2.Button1Click(Sender: TObject);
    var
     P: PDWORD;
     CDS: TCopyDataStruct;
    begin
     CDS.dwData := GetCurrentProcessId;
     CDS.cbData := 0;
     CDS.lpData := nil;
     P := PDWORD(SendMessage(StrToInt(Edit1.Text),
       WM_COPYDATA, Handle, Integer(@CDS)));
     if P <> nil then
     begin
       ShowMessage(IntToHex(P^, 8));
       VirtualFree(P, 4, MEM_RELEASE);
     end;
    end;



    Принимающая сторона:
    type
     TForm1 = class(TForm)
       procedure FormCreate(Sender: TObject);
     private
       procedure Foo(var Message: TWMCopyData); message WM_COPYDATA;
     end;

    var
     Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.Foo(var Message: TWMCopyData);
    var
     P: Pointer;
     Data: DWORD;
     hProc: THandle;
     lpNumberOfBytesWritten: DWORD;
    begin
     Data := $DEADBEEF;
     Message.Result := 0;
     hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_WRITE, False,
       Message.CopyDataStruct^.dwData);
     if hProc <> 0 then
     try
       P := VirtualAllocEx(hProc, nil, 4, MEM_COMMIT, PAGE_READWRITE);
       WriteProcessMemory(hProc, P, @Data, 4, lpNumberOfBytesWritten);
       if lpNumberOfBytesWritten = 4 then    
         Message.Result := Integer(P);
     finally
       CloseHandle(hProc);
     end;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
     Caption := IntToStr(Handle);
    end;

 
Конференция "WinAPI" » Проблема получением сообщения WM_COPYDATA, Проблема с аглоритмом
Есть новые Нет новых   [134432   +18][b:0][p:0.001]