Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Использование Win API / 18 сообщений из 18, страница 1 из 1
22.06.2018, 13:10
    #39664183
patrick1968
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
Добрый день. Возникла необходимость применить WinAPI, раньше мало сталкивался, надо сообщение передать из одного приложения в другое, рассматриваю примеры из тематических форумов, пробую реализовать. Так вот сделал приложение - приемник, там организовал присвоение кода приложению, так

Код: pascal
1.
2.
3.
4.
5.
6.
procedure TForm7.FormShow(Sender: TObject);
 var p : pointer;
begin
   p := Pointer($12345);
   SetWindowLong( Application.Handle, GWL_UserData, Integer(p));
end;



затем в другом приложении по кнопке выдаю инфу по всем окнам
коряво, но как-то так

Код: pascal
1.
2.
3.
4.
5.
  GetWindowText(wd, buf, sizeof(buf));
  s := StrPas(buf);
  if (s <> '')
    then begin
          lst.Add(s + ' ' + IntToStr(GetWindowLong(Wd, GWL_USERDATA)) + ' ');



так вот получается что напротив моего приложения приемника выводит 0, почему-то видимо SetWindowLong я не верно применяю

Модератор: Пользуйтесь тегом (кнопкой) SRC для оформления кода, пожалуйста.
...
Рейтинг: 0 / 0
22.06.2018, 13:16
    #39664192
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
Х.з. Странная какое то желание, так передавать "сообщения" (в кавычках). Почему не работает - точно не знаю, так никогда не делал. Но в описание ф-ции черным по белому (на моем мониторе) написано:

MSDN Remarks
Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly.
...
Рейтинг: 0 / 0
22.06.2018, 13:30
    #39664202
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
patrick1968так вот получается что напротив моего приложения приемника выводит 0

Во-первых, у приложения много окон.
Во-вторых, GWL_USERDATA может использоваться VCL, поэтому лезть в него не стоит.
В-третьих, передача сообщения из одного приложения в другое делается гораздо проще через
SendMessage, причём в обе стороны сразу, ибо это функция.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
22.06.2018, 13:44
    #39664212
patrick1968
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
В реалиях у приложения приемника (написанного на vfp) как раз разработчиком сделано так что приложению (окну) через SetWindowLong присваивается код по которому следует это приложение однозначно определить, в принципе передать сообщение удалось, но на том конце структура TCopyDataStruct не воспринимается
...
Рейтинг: 0 / 0
22.06.2018, 13:56
    #39664222
stells2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
patrick1968Возникла необходимость применить WinAPI
Это хорошо, давно пора
patrick1968
Код: pascal
1.
   SetWindowLong( Application.Handle, GWL_UserData, Integer(p));



Зачем? Для какой цели?
можно почитать тут
...
Рейтинг: 0 / 0
22.06.2018, 13:57
    #39664225
patrick1968
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
lcStringToSend=Strconv(lcstr + Chr(0), 5)
lnPtrStringToSend = WinAPI_HeapAlloc(WinAPI_GetProcessHeap(), 0, Lenc(lcStringToSend))
Sys(2600, lnPtrStringToSend,Lenc(lcStringToSend), lcStringToSend) && Copy value to memory
Local lcCOPYDATASTRUCT As String
lcCOPYDATASTRUCT = ;
BINTOC(ID_DATA, "4RS") ; && ULONG_PTR dwData
+ BinToC(Lenc(lcStringToSend), "4RS") ; && DWORD cbData
+ BinToC(lnPtrStringToSend, "4RS") && PVOID lpData
SendMessage(hwnd1,WM_COPYDATA,_vfp.HWnd,@lcCOPYDATASTRUCT)

вот так организовано формирования структуры сообщения в vfp, как это можно переложить на структуру COPYDATA
...
Рейтинг: 0 / 0
22.06.2018, 14:03
    #39664230
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
patrick1968....
вот так организовано формирования структуры сообщения в vfp, как это можно переложить на структуру COPYDATA
"простите, кто на ком стоял" ( C ) Собачье сердце
кого на кого положить?

В чем вообще проблема? В коде все в комментариях подписано

https://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs.85).aspx
http://www.foxclub.ru/rhproject/project/html/c3b28578-7b4f-487f-9192-fb619ff83ad6.htm

Что в результате появляется после "BINTOC(ID_DATA, "4RS")", мне сказать сложно. Проще foxPro запустить и посмотреть. IMHO
...
Рейтинг: 0 / 0
22.06.2018, 14:16
    #39664249
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
patrick1968,

"Приемник":
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure TMainForm.WMCopyData(var Msg: TWMCopyData);
var S:String;
    AData:TCopyDataStruct;
begin
  case Msg.CopyDataStruct.dwData of
    WM_MYCOMMAND: begin
                                    Msg.Result:=1;
                                    S:=String(PChar(Msg.CopyDataStruct.lpData));
                                    // в s - "сообщение"
                                 end;
   end;
end;


"Передатчик":
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
var WTargetWindow:HWND;

function EnumWindowsProc(WHandle: HWND; lParam: LPARAM): BOOL; export; stdcall;
var WindowName:array[0..MAX_PATH] of char;
    AClassName:array[0..1024] of char;
    S1:string;
begin
  Result:=True;
  GetWindowText(WHandle,WindowName,MAX_PATH);
  S1:=String(WindowName);
  GetClassName(WHandle,AClassName,1024);
  if String(AClassName)='TMyTargetMainForm') then
     begin
      WTargetWindow:=WHandle;   // find target form
      Result:=False;       
     end;
end;

function FindTargetWindow:HWND;
begin
  WFadWindow:=0;
  EnumWindows(@EnumWindowsProc,LPARAM(PChar('TApplication_Class_Name')));
  Result:=WFadWindow;
end;

procedure SendDataStrToTarget(ACommand,Flags:integer; S:String);
var TargetHWND:HWND;
    AData:TCopyDataStruct;
begin
 TagretHWND:=FindTargetWindow;
 if TargetHWND<>0 then
    begin
      AData.dwData:=ACommand;
      if Trim(S)='' then
         begin
           AData.cbData:=0;
           AData.lpData:=nil;
         end
      else begin
             AData.cbData:=StrLen(PChar(S))+1;
             AData.lpData:=PChar(S+#0);
           end;
      SendMessage(TargetHWND,WM_COPYDATA,wParam(Flags),lParam(@AData));
    end;
end;

// использование
SendDataStrToTarget(WM_MYCOMMAND,'My message to target');



Примерно так.
...
Рейтинг: 0 / 0
22.06.2018, 14:18
    #39664251
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
DarkMaster,

Поправка. Не все переименовал :)

Код: pascal
1.
2.
3.
4.
5.
6.
function FindTargetWindow:HWND;
begin
  WTargetWindow:=0;
  EnumWindows(@EnumWindowsProc,LPARAM(PChar('TApplication_Class_Name')));
  Result:=WTargetWindow;
end;
...
Рейтинг: 0 / 0
22.06.2018, 14:52
    #39664272
patrick1968
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
procedure SendDataStrToTarget(ACommand,Flags:integer; S:String); 3 параметра



// использование
SendDataStrToTarget(WM_MYCOMMAND,'My message to target'); а здесь 2, что-то пропустили
...
Рейтинг: 0 / 0
22.06.2018, 15:27
    #39664309
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
patrick1968,

Выкинь Flags из параметров - там дополнительные всякие специфичные вещи с их помощью делались. Тебе это не нужно.
...
Рейтинг: 0 / 0
22.06.2018, 16:01
    #39664330
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
patrick1968,

Кстати, забыл сказать. Тут есть тонкое место при передаче данных. Если у тебя Дельфя поддерживает unicode, то строку нужно запихивать более акуратно, чем в примере (он на AnsiString заточен). Для Unicode лучше сделать вот так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure SendDataStrToTarget(ACommand,Flags:integer; S:String);

// -----------
      else begin
               AData.cbData:=Length(S)*SizeOf(Char)+1*SizeOf(Char);
               AData.lpData:=PChar(S+#0);
           end;
// -----------


Иначе у тебя придет или обрезанная строка или вообще непонятно что. Так что учитывай, какую строку ты передаешь - Ansi или Unicode и примет ли твой приемник такую строку.
...
Рейтинг: 0 / 0
22.06.2018, 16:09
    #39664335
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
DarkMasterВыкинь Flags из параметров - там дополнительные всякие специфичные вещи с их помощью делались. Тебе это не нужно.
Как я понял, Flags автору нужен
21513065
у него там должно быть
BINTOC( ID_DATA, "4RS" )

IMHO
...
Рейтинг: 0 / 0
22.06.2018, 16:30
    #39664345
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
Leonid Kudryavtsev,

Ну пример вообще выкушен из какого-то старого проекта, Flags я использовал тогда для другого. ТС может помедитировать над структурой COPYDATA и напихать в нее все, что ему нужно - основное я показал. У меня в dwData передавалась команда (одна из) приемнику. ТС может использовать dwData для чего-то другого - в общем простор для творчества.
...
Рейтинг: 0 / 0
22.06.2018, 17:32
    #39664376
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
DarkMaster,

для передачи строк может лучше такую конструкцию использовать:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
var
  CDS: TCopyDataStruct;
  Buffer: UTF8String;
  s: string;
begin

      Buffer := UTF8Encode(s);

      CDS.dwData := MyMessageCommand;

      CDS.cbData := Length(Buffer) + 1;
      CDS.lpData := Pointer(Buffer);

      SendMessage(FTargetFormHandle, WM_COPYDATA, wparam(Flags), Lparam(@CDS));
end;
...
Рейтинг: 0 / 0
22.06.2018, 17:40
    #39664380
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
Kast2K,

Length(Buffer) тебя не смущает?
...
Рейтинг: 0 / 0
22.06.2018, 17:54
    #39664385
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
DarkMasterKast2K,
Length(Buffer) тебя не смущает?
А должна? UTF8String = type AnsiString, не?
...
Рейтинг: 0 / 0
22.06.2018, 18:01
    #39664391
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование Win API
alekcvp,

Точно, я посмотрел. Тогда да, нормально. Можно вообще TBytes() и прочие вариации на тему array of ... использовать - не в этом дело в принципе.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Использование Win API / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]