![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
SendMessage WM_COPYDATA
Евгений07 © (2011-02-14 13:51:00)Доброго времени!
Возникла необходимость написать обмен данными по SendMessage WM_COPYDATA двух (трех) прог типа
передача сообщений - передача ответа
procedure TSinxro.WriteTerminal; // передача сообщений
begin
Otladka(2, Buf); // Memo1.Lines.Add(Buf);
if not FlgWrite and (Length(Buf) > 0) then begin
FlgWrite := True; // занято = True
CDS.cbData := 1;
CDS.dwData := CD_CMD_SETCAPTION;
CDS.cbData := CDS.cbData + Length(Buf);
GetMem(CDS.lpData, CDS.cbData);
try
StrPCopy(CDS.lpData, Buf);
SendMessage(FindWindow(NIL, PChar (NameFormDial)),
// SendMessage(FindWindow('TForm1', PChar (NameFormDial)),
WM_COPYDATA, HandleForm, Integer(@CDS)); // посылаем сообщение в окно с заголовком "Client"
finally
FreeMem(CDS.lpData, CDS.cbData);
end;
FlgWrite := False;
end;
end;
procedure TSinxro.OnReadTerminal(var M: TWMCopyData); // прием сообщений
begin
if M.CopyDataStruct.dwData = CD_CMD_SETCAPTION then begin
if not FlgRead then begin
FlgRead := True; // занято = True
Buf := PChar(M.CopyDataStruct.lpData);
ReadTerminal; //обработка
if OnReadTerminalRead then begin
M.Result := 1;
end;
end else
M.Result := 0;
FlgRead := False; // свободно = False
end;
end;
В каждой проге есть передача сообщений и прием сообщений
Идет диалог типа
команда 1 ответ 1
команда 2 ответ 2
команда 3 и здесь диалог обрывается
???
не успевает передать/принять одно и уже не успевает передать/принять другое?
Евгений07 (2011-02-16 11:04:00) [1]Была ошибка типа: не успевает передать/принять одно и уже не успевает передать/принять другое
Исправил, заработало
Возник вопрос:
Как организовать систему полноценного диалога (позже триалога: будет Прога3) по схеме:
Прога1 команда передача
Прога2 команда прием
Прога2 данные передача
Прога1 данные прием
Прога1 команда передача
и т.д.
У меня схема была организована в каждой проге примерно так:
procedure TForm1.OnReadTerminal(var M: TWMCopyData); // прием сообщений
обработка сообщений
запрос данных
передача данных
try
SendMessage(FindWindow(NIL, PChar (NameFormDial)),
WM_COPYDATA, HandleForm, Integer(@CDS));
finally
завершение передачи данных
Была ошибка: Этап завершения передачи данных прерывался приемом нового сообщения и процесс запускался по новой
Ошибку устранил задержкой передачи данных по таймеру
К чему это может привести (обработка данных может продолжаться очень различное время)?
Как лучше? Где что почитать? Реальных 3 - 4 статьи в куче перепечаток читал
Евгений07 (2011-02-16 10:56:00) [2]Leonid Troyanovsky © (14.02.11 23:48) [10
объект Sinxro1 класса TSinxro пользовался процами класса TSinxrо1
правда с глюками
type
TSinxro = class(TObject)
. . .
end;
type
TSinxro1 = class(TSinxro)
Constructor Create(Handle: Hwnd; Name: string;
Memo1Lines0: TStrings; CheckBox1Checked0: boolean);
. . .
end;
type
TForm1 = class(TForm)
. . .
public
Sinxro1: TSinxro;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Sinxro1 := TSinxro1.Create(Form1.Handle, NameFormDial, Memo1.Lines, CheckBox1.Checked);
end;
Leonid Troyanovsky (2011-02-14 23:48:00) [3]
> Евгений07 (14.02.11 16:19) [8]
> ТСинхро? откуда у него окно окна у него нет
> Sinxro1: TSinxro; ??????
> Sinxro1: TSinxro1; !!!!!!!!!
А ты покажи ошибку в 17 строке.
С нами все делятся.
--
Regards, LVT.
Palladin (2011-02-14 16:21:00) [4]еще один неадекват... удачи, и спасибо за рыбу
Евгений07 (2011-02-14 16:19:00) [5]Palladin © (14.02.11 15:17) [5]
ТСинхро? откуда у него окноокна у него нет
Sinxro1: TSinxro;??????
Sinxro1: TSinxro1;!!!!!!!!!
clickmaker (2011-02-14 15:18:00) [6]да, и почему бы так не сделать?
LocalVariableBuf := PChar(M.CopyDataStruct.lpData);
ReadTerminal(LocalVariableBuf);
если Buf - разделяемая переменная между методами Read и Write, то они должны вызываться строго синхронно
Palladin (2011-02-14 15:18:00) [7]
> данные читаются нормально
...как я мог забыть коронное ) "по встречке тоже можно ездить"
Palladin (2011-02-14 15:17:00) [8]все страньше и страньше... а что за ТСинхро? откуда у него окно, му прочим начиличе дескриптора окна не гарантирует исполнения в основном потоке
Евгений07 (2011-02-14 15:14:00) [9]Palladin © (14.02.11 14:35) [3]
данные читаются нормально
обе проги построены примерно так
type
TSinxro1 = class(TSinxro)
public
{ Public declarations }
Constructor Create(Handle: Hwnd; Name: string;
Memo1Lines0: TStrings; CheckBox1Checked0: boolean);
procedure ReadTerminalErr(kol: integer); override; // проверка данных из Buf
function OnReadTerminalRead: boolean; override; // запрос к базе данных
end;
type
TForm1 = class(TForm)
private
{ Private declarations }
procedure OnReadTerminal(var M: TWMCopyData); message WM_COPYDATA;
// прием сообщений от терминала
public
{ Public declarations }
procedure OnReadBD; // прием сообщений базы данных
function ReadBD(k0: integer): integer; // чтение базы данных
procedure ZaprosBD; // запрос к базе данных
end;
var
Form1: TForm1;
Sinxro1: TSinxro;
Palladin (2011-02-14 14:35:00) [10]я надеюсь ты понимаешь, что данные из буфера, переданного wm_copydata, должны быть "выужены", до конца обработки события? а то ведь строчки
Buf := PChar(M.CopyDataStruct.lpData);
ReadTerminal;
навевают на мысль о передачи ссылки куда-то на глобал, и потом какой-то поток (thread) пытается читать данные из этого "куда-то", в то время как событие пометилось как "обработанное"
Евгений07 (2011-02-14 14:23:00) [11]прога 1
type
TForm1 = class(TForm)
private
procedure OnReadTerminal(var M: TWMCopyData); message WM_COPYDATA;
прога 2
type
TForm1 = class(TForm)
private
procedure OnReadTerminal(var M: TWMCopyData); message WM_COPYDATA;
команды 1, 2 и 3 с разным объемом данных
был случай, когда я ставил таймер на команду 1 = старт диалога - команда 3 проходила 1раз
clickmaker (2011-02-14 13:57:00) [12]OnReadTerminal откуда вызывается?
и строго на команде 3 обрывается?