Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.08.2010, 10:41   #1
mig_ira
 
Регистрация: 10.06.2010
Сообщений: 6
Вопрос Потоки. Сообщения между потоками

Здравствуйте, уважаемые!
Нужна подсказка...
Есть поток главной формы и поток для чтения из порта, если за определенное время нужных данных в порт не поступало, то второстепенный поток отправляет сообщение главному и тот уже выдает сообщение пользователю с запросом - "перезапросить ли данные?" Если ответ отрицательный, то главный поток должен сообщить об этом второстепенному, чтобы тот больше не ждал информацию, а просто считывал все что приходит...

В чем загвоздка: Второстепенный поток без проблем отправляет сообщение главному потоку, но от главного потока второстепенному сообщение так и не доходит :'(

Заранее очень признательна за помощь!

Код:
// >>Второстепенный поток<<


type // Структура для отправки сообщений
   PMyMsg=^TMyMsg;
   TMyMsg=record
      s:TCommand_inf;
      h:THandle;
   end;

...
TNewThread = class(TThread) // Второстепенный поток
  private
    { Private declarations }
  protected
...
 public
    procedure OnDeleteCommand(var aMessage: TMessage); message WM_Del_comm;// Обработчик сообщения о том, чтобы перестать ждать 
                    // данные
  end;
...

const
  WM_Del_comm = WM_USER + 1010; // Сообщение от главного потока 
                                                   //   о том, что ожидание следует 
                                                   //  прекратить
....
var m: PMyMsg;// Сообщение для главного потока
....
New(m);
m.s := Current.Value; //Данные о команде, на которую нужен был ответ
m.h:=  Handle;          // Запоминаю Handle второстепенного потока
//Отправляю сообщение о том, что нужных данных нет:
SendMessage(Form1.handle,WM_err_read,Integer(m),0);

...
procedure TNewThread.OnDeleteCommand(var aMessage: TMessage);
var
m: PMyMsg;
cmd:TCommand_Inf;
begin
   m := Pointer(aMessage.WParam);
   cmd:=m.s;
   Dispose(m);
  remove(find_by_sysnum_cmd(cmd.Sysnum,cmd.comm1));
end;

// >>Главный поток<<

type
  TForm1 = class(TForm)
....
  private
    { Private declarations }
  public
    { Public declarations }
    procedure OnErrReadInTread(var aMessage: TMessage); message WM_err_read; // Обработчик сообщения о том, что нужные данные не были получены

  end;

const
  WM_err_read = WM_USER + 1000; // Сообщение о том, что нужные 
                                                // данные не получены
...

procedure TForm1.OnErrReadInTread(var aMessage: TMessage);
var
m: PMyMsg;
cmd:TCommand_Inf;
btn:integer;
begin
  m := Pointer(aMessage.WParam);
  cmd:=m.s;
  btn:=mrOk;
  btn:=messagedlg('Значение не прочитано! Повторить чтение?',mtWarning,[mbOk,mbCancel],0);
  if   btn=mrCancel then
 // Сообщаем второстепенному потоку, что данные больше не нужны и информацию о них надо удалить
  SendMessage(m.h, WM_Del_comm,Integer(m) ,0); // Сообщение 
                           //второстепенному потоку, которое не доходит
end;

Последний раз редактировалось mig_ira; 09.08.2010 в 11:01.
mig_ira вне форума Ответить с цитированием
Старый 09.08.2010, 11:09   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Насколько я знаю, чтоб кидаться сообщениями нужно в потоке описать их обработчик, но и этого пожалуй будет маловато - сообщения могут приходить только окну. Я бы на твоем месте вместо посылок сообщений описал и вызывал методы потока, которые бы выполняли аналогичные твоим сообщения действия
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.08.2010, 11:25   #3
mig_ira
 
Регистрация: 10.06.2010
Сообщений: 6
По умолчанию

В принципе про окна я что-то такое уже начала сама подозревать, но, честно говоря, надеялась, что без окна обойтись можно, просто я не нашла как..)
Насчет методов - тоже пробовала... Выплывает страшный глюк в момент отображения пользователю запроса - окошко запроса непредсказуемо растягивается и сужается самыми немыслимыми способами х_х, Поэтому чтобы этого не происходило, я и решила, что главный поток будет выдавать этот запрос правильно, это, как раз, сработало, но вот тут меня и настиг вопрос, с которым я обратилась)
Может быть вам встречался этот мой "страшный глюк" с окошком? Про запрос ответа у пользователя из второстепенных потоков, как в моем случае, я ничего не нашла
mig_ira вне форума Ответить с цитированием
Старый 09.08.2010, 12:07   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Может быть вам встречался этот мой "страшный глюк" с окошком?
Ану покаж скриншот...
Никогда не нарывался в потоках на такой глюк.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.08.2010, 12:23   #5
mig_ira
 
Регистрация: 10.06.2010
Сообщений: 6
По умолчанию

Конечно =) В приложенном файле только три варианта...
Изображения
Тип файла: jpg Глюк.JPG (32.2 Кб, 203 просмотров)
mig_ira вне форума Ответить с цитированием
Старый 09.08.2010, 12:39   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Ага. Попробуй триммировать сообщения функцией Trim(). Ато бывает что сообщение дополняется пробелами до посинения.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.08.2010, 12:57   #7
mig_ira
 
Регистрация: 10.06.2010
Сообщений: 6
По умолчанию

Спасибо за совет, в моем случае, правда, он это не очень помогло - срезать пыталась по всякому, и напрямую, и в переменной, пробовала текст константой задать в надежде, что не посмеет пробелов дописать... Во всяком случае, стоило попробовать)
mig_ira вне форума Ответить с цитированием
Старый 09.08.2010, 13:26   #8
Ins
Форумчанин
 
Регистрация: 29.12.2007
Сообщений: 137
По умолчанию

Отправлять сообщение непосредственно в очередь потока можно с помощью PostThreadMessage, нельзя в SendMessage указывать хэндл потока, это совсем не то же самое, что хэндл окна. Но даже посылая с помощью PostThreadMessage сообщения, нужно в потоке создать петлю обработки сообщений (см. Get(Peek)Message, TranslateMessage, DispatchMessage), иначе сообщения просто будут скапливаться в очереди, а их извлечением и диспетчеризацией окну никто не будет заниматься
Ins вне форума Ответить с цитированием
Старый 09.08.2010, 13:26   #9
mig_ira
 
Регистрация: 10.06.2010
Сообщений: 6
По умолчанию

Не знаю в чем прикол... Заменила MessageDlg на MessageBox, этот, может, и не такой симпатичный, но ведет себя вполне предсказуемо,а главное, вполне подходит для моей задачи)
Спасибо за проявленное внимание =)
mig_ira вне форума Ответить с цитированием
Старый 09.08.2010, 13:27   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А чем ты выводишь сообщение? какой функой?
Цитата:
Заменила MessageDlg на MessageBox
Упс. Вопрос снят )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с потоками Нюська Общие вопросы Delphi 3 27.05.2009 00:52
Работа с потоками Neymexa Общие вопросы .NET 16 23.04.2009 17:42
Как грамотно разделить данные между потоками? bagulma Общие вопросы Delphi 5 28.05.2008 22:41
C++, работа с потоками mat90x Помощь студентам 20 15.05.2008 22:20
Проблема с потоками vitalik007 Общие вопросы Delphi 1 11.03.2008 22:35