На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
Страницы: (3) 1 2 [3]  все  ( Перейти к последнему сообщению )  
> Как вызвать событие? , Есть поток из него надо вызвать событие
    Цитата arj99 @
    Handle должен передать сам компонент при запуске потока, удобнее всего параметром конструктора.

    то есть
    я должен при создании компонента должен передать ему Handle окна?
      Можно создать свое невидимое окно, как это делается в TTimer. См. AllocateHwnd, DeallocateHwnd

      Что касается RecThread, то по моему это должен быть чисто вспомогательный зависимый класс, который можно полностью упрятать в implementation, а в компоненте ссылку на него объявить просто как TThread
        Цитата leo @
        Что касается RecThread, то по моему это должен быть чисто вспомогательный зависимый класс, который можно полностью упрятать в implementation, а в компоненте ссылку на него объявить просто как TThread

        То есть? напиши по подробней
        Сообщение отредактировано: v1m -
          Как-то так:
          ExpandedWrap disabled
            type
              TReadEvent = procedure(Data:pAnsiChar;Size:integer) of object;
              vmUDPSocket = class(TComponent)
              private
                ...
                FWnd:cardinal;       //окно
                FRecvThr:TThread;    //поток
                FOnRead:TReadEvent;  //внешний обработчик события
                procedure WndMethod(var Message: TMessage); //процедура окна
                procedure StartThread;
              protected
                ...
              public
                ...
                property OnRead:TReadEvent read FOnRead write FOnRead;
              end;
             
            implementation
            var
              WM_MyRecvData:cardinal;
             
            type
              TRecvThread = class(TThread)
                Owner:vmUDPSocket; //владелец
                constructor Create(AOwner:vmUDPSocket);
                procedure Execute; override;
              end;
            constructor TRecvThread.Create(AOwner:vmUDPSocket);
            begin
              inherited Create(false);
              Owner:=AOwner;
              FreeOnTerminate:=true; //???
            end;
            procedure TRecvThread.Execute;
            var
              buf:array[0..???] of AnsiChar;
              data:pAnsiChar;
              len:integer;
            begin
              while not Terminated do
              begin
                len:=recv(Owner.Socket,buf,sizeof(buf),0);
                if len > 0 then
                begin
                  GetMem(data,len);
                  Move(buf,data^,len);
                  SendMessage(Owner.FWnd,WM_MyRecvData,Integer(data),len);  
                end
                else
                  ...
              end;
            end;
             
            //-------------------
             
            procedure vmUDPSocket.WndMethod(var Message: TMessage);
            begin
              with Message do
                if Msg = WM_MyRecvData then
                begin
                  if Assigned(FOnReadData) then
                    FOnReadData(pointer(wParam),lParam);
                  FreeMem(pointer(wParam));
                  Result:=0;
                end
                else
                  Result:=DefWindowProc(FWnd,Msg,wParam,lParam);
            end;
             
            procedure vmUDPSocket.StartThread;
            begin
              WM_MyRecvData:=RegisterWindowMessage('WM_MyRecvData');
              if FWnd = 0 then
                FWnd:=AllocateHwnd(WndMethod);
              FRecvThr:=TRecvThread.Create(Self);
            end;
          Сообщение отредактировано: leo -
            спс :thanks: сейчас код просмотрел попробую реализовать... :)
              Кстати, если передавать данные синхронно через SendMessage, то и динамическую память под данные не обязательно выделять\освобождать - можно прямо передавать указатель на локальный буфер buf
                вот так?
                SendMessage(Owner.FWnd,WM_MyRecvData,Integer(buf),len);
                  Integer(@buf)
                    спс!!!!!!! :rolleyes: :rolleyes: :rolleyes: :rolleyes: :yes: :yes: :yes: :yes: :thanks: :thanks: :yummy: :good:
                    все работает!!
                    arj99 и leo отдельное СПС!
                    и еще вопрос как добавить несколько параметров в сообщении?
                    на пример мне надо еще добавить от кого пришло сообщение..
                    Сообщение отредактировано: v1m -
                      Цитата v1m @
                      все работает!!

                      Только не забудь довести все это "сырье" до ума, в частности добавить DeallocateHwnd в деструктор ;)

                      Цитата v1m @
                      как добавить несколько параметров в сообщении?

                      Еще проще\нагляднее чем с разрощненной парой - просто cложить все необходимые данные в record и передавать указатель на нее, например:
                      ExpandedWrap disabled
                        type
                          pRecvData = ^TRecvData;
                          TRecvData = record
                            Data:pChar;
                            DataSize:integer;
                            From:pChar;
                            Reserved:integer;
                          end;
                          TReadEvent = procedure(const Data:TRecvData) of object;
                         
                          //посылка сообщения
                          with Data do
                          begin
                            Data:=buf;
                            DataSize:=len;
                            From:=...;
                          end;
                          SendMessage(Owner.FWnd,WM_MyRecvData,integer(@Data),0);
                         
                          //прием сообщения
                          if (wParam <> 0) and Assigned(FOnReadData) then
                            FOnReadData(pRecvData(wParam)^);
                      Сообщение отредактировано: leo -
                        v1m

                        Я бы рекомендовал разобраться как реализован TThread.
                        В этом случае 99% вопросов просто отпадёт за ненадобностью.
                          Цитата leo @
                          Только не забудь довести все это "сырье" до ума, в частности добавить DeallocateHwnd в деструктор

                          добавил уже))
                          Цитата Демо @
                          Я бы рекомендовал разобраться как реализован TThread.

                          я читал по TThread но видимо не то читал)
                            Цитата v1m @
                            я читал по TThread но видимо не то читал)


                            Я говорил не про статьи и справку, а про исходники TThread.
                              ааа :D
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:
                              Страницы: (3) 1 2 [3]  все


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0362 ]   [ 16 queries used ]   [ Generated: 1.05.24, 20:19 GMT ]