nektar Napisano Maj 18, 2008 Zgłoś Share Napisano Maj 18, 2008 Witam. Mam problem przy tworzeniu nowej zakładki PageControl w kliencie irc która ma być tworzona przy próbie wejścia na nowy kanał. Ma ją wywoływać procedura OnJoin komponentu TidIRC ale za każdym razem kończy się to zawieszeniem się programu. Przed zawieszeniem się zostają wykonane jeszcze kolejne polecenia takie jak wypisanie tekstu na nowoutworzonym memo. Próbowałem już filtrować komunikaty serwera i reagować na IdIRC1Raw ale sytuacja się powtarza. Nie pojawiają się żadne błędy ani komunikaty. Komplikacja też przechodzi bez problemu. Co dziwne wywołanie funkcji tworzenia nowej zakładki przez przycisk działa bez zarzutu i nie powoduje zawieszenia się. Fragment programu: Wywołanie funkcji: procedure TForm1.IdIRC1Join(ASender: TIdContext; const ANickname, AHost, AChannel: string); begin if ANickname = idirc1.nickname then begin CreateChannelTab(AChannel); GetMsg(AChannel,' *** Witaj na kanale ' + AChannel + ' ***'); end; end; [ui' function Tform1.CreateChannelTab(NewTabName : String) : Boolean; var NewTab: TTabSheet; NewListBox: TListBox; Newedit: TEdit; NewMsgWindow: TMemo; begin channels[chaninxtmp] := NewTabName; NewTab := TTabSheet.Create(self); try with NewTab do begin Caption := NewTabName; PageControl := PageControl1; end; except on E: Exception do ShowMessage(E.Message+' '+IntToStr(E.HelpContext)); end; NewListBox := TListBox.Create(self); try with NewListBox do begin Left := 616; Top := 0; Width := 121; Height := 428; TabOrder := 0; Parent := NewTab; Name := 'ListBox' + inttostr(chaninxtmp); end; except on E: Exception do ShowMessage(E.Message+' '+IntToStr(E.HelpContext)); end; NewMsgWindow := Tmemo.Create(self); try with NewMsgWindow do begin ReadOnly := true; Left := 0; Top := 0; Width := 617; Height := 428; Align := alCustom; Parent := NewTab; ReadOnly := True; OnClick := FormActivate; OnMouseUp := MsgWindowMouseUp; Name := 'MsgWindow' + inttostr(chaninxtmp); clear; end; except on E: Exception do ShowMessage(E.Message+' '+IntToStr(E.HelpContext)); end; Newedit := TEdit.Create(self); try with NewEdit do begin Left := 0; Top := 405; Width := 732; Height := 20; Align := alBottom; TabOrder := 1; OnKeyPress := ServerEditKeyPress; Parent := NewTab; Name := 'chanedit' + inttostr(chaninxtmp); OnKeyPress := EditEnter; clear; end; except on E: Exception do ShowMessage(E.Message+' '+IntToStr(E.HelpContext)); end; inc(chaninxtmp); Result := true; end; Z góry dziękuję za pomoc P.S. Delphi 2007(RAD Studio) + Indy 10.1.5 Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Maj 18, 2008 Zgłoś Share Napisano Maj 18, 2008 Nie wiem czy ten komponent dziala na watkach, ale zakladam ze tak. Jesli tak to wszystkie odwolania do VCL musza byc zsynchronizowane. zrob w OnJoin (czy w jakiesj to sie wiesza) wywolanie takie Synchronized(myProc). A w myProc zrob wlasciwa obsluge zdarzenia. Od tego bym zaczal. Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
nektar Napisano Maj 18, 2008 Autor Zgłoś Share Napisano Maj 18, 2008 Nie wiem czy ten komponent dziala na watkach, ale zakladam ze tak. Jesli tak to wszystkie odwolania do VCL musza byc zsynchronizowane. zrob w OnJoin (czy w jakiesj to sie wiesza) wywolanie takie Synchronized(myProc). A w myProc zrob wlasciwa obsluge zdarzenia. Od tego bym zaczal. próbowałem synchronizować przez synchronize; ale nie mam możliwośći podania tej funkcji parametru. Gdy zrobiłem synchronize(TmpProcCreate); kompilator pluje 'E2066 Missing operator or semicolon'. Zauważyłem też, że program wiesza się dopiero w momencie gdy nowa zakładka staje sie aktywna. Mogę pisać w innych zakładkach bez problemu aż kliknę na tą nową. Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Maj 19, 2008 Zgłoś Share Napisano Maj 19, 2008 przez synchronize mozesz przekazac funkcje bez parametrow czyli robisz takie obejscie: 1) ustawiasz w swoim obiekcie parametry ktore ma uzyc metoda zsynchronizowana (najlepiej obuduj to sekcja krytyczna) 2) wywolujesz metode przez Synchronize, ta metoda siegnie do ustawionych w punkcie 1 parametrow. Co do bledu znaczy ze zapomniales dodac srednika lub przecinka Bez kodu nie mam pojecia o co chodzi Co do zawieszania, ustaw breakpointa tuz przed zawieszeniem sie. Skapiluj program z ustawieniem na zakladce kompilatora (use debug dcu) i zacznij uzywac F8. Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
nektar Napisano Maj 20, 2008 Autor Zgłoś Share Napisano Maj 20, 2008 przez synchronize mozesz przekazac funkcje bez parametrow czyli robisz takie obejscie: 1) ustawiasz w swoim obiekcie parametry ktore ma uzyc metoda zsynchronizowana (najlepiej obuduj to sekcja krytyczna) "Wydaje" mi się, że prawidłowo obudowałem funkcje: function Tform1.CreateChannelTab(NewTabName : String) : Boolean; var NewTab: TTabSheet; NewListBox: TListBox; Newedit: TEdit; NewMsgWindow: TMemo; CriticalSection: TRTLCriticalSection; begin InitializeCriticalSection(CriticalSection); EnterCriticalSection(CriticalSection); channels[chaninxtmp] := NewTabName; NewTab := TTabSheet.Create(self); try with NewTab do begin Caption := NewTabName; PageControl := PageControl1; end; except on E: Exception do ShowMessage(E.Message+' '+IntToStr(E.HelpContext)); end; ......ciach...... Newedit := TEdit.Create(self); try with NewEdit do begin Left := 0; Top := 405; Width := 732; Height := 20; Align := alBottom; TabOrder := 1; Parent := NewTab; Name := 'chanedit' + inttostr(chaninxtmp); OnKeyPress := EditEnter; clear; end; except on E: Exception do ShowMessage(E.Message+' '+IntToStr(E.HelpContext)); end; LeaveCriticalSection(CriticalSection); inc(chaninxtmp); Result := true; end; przy procedure TIdThread.Execute; w IdTread.pas Nie wiem jak dokładniej to opisać, mam nadzieje, że jest zrozumiałe. Na życzenie mogę dołączyć źródło programu. Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Maj 20, 2008 Zgłoś Share Napisano Maj 20, 2008 1) wywoluje sie Synchronize(twojaProcedura), przy czym synchronize moze byc wywolane TYLKO z zakresu watku. Wywolanie synchronize na glownym watku moze prowadzic do deadlocka (o czym pisze w helpie) czyli twoja procka powinna wygladac tak procedure TForm1.IdIRC1Join(ASender: TIdContext; const ANickname, AHost, AChannel: string); begin fChanel := AChanel; synchronize( createchanneltab ); end; vhćyZwŚ,ł<ćz7zZhr7Ź)0^dŁ-hśh)Ąźui' procedure TForm1.IdIRC1Join(ASender: TIdContext; const ANickname, AHost, AChannel: string); begin critSection.enter; fChanel := AChanel; synchronize( createchanneltab ); critSection.leave; end; gdzie critSection jest typu TCriticalSection (wiecej w helpie i googlu). To co pisze tyczy sie pracy wielowatkowej. Objaw ktory piszesz swiadczy o tym ze masz cos zrabane w obsludze tego taktu, nie wiem czy sam go tworzysz czy tworzy go cos innego. Przeanalizuj jak pokolei ida eventy i czy masz to wywolanie z watku pobocznego czy z glownego watku programu. Niewiele wiecej moge ci pomoc. Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
nektar Napisano Maj 20, 2008 Autor Zgłoś Share Napisano Maj 20, 2008 .....ciach.... synchronize( createchanneltab ); .... ciach... Ćzh7 %jxł)'7jśŚz+\"y^uzIZ#jŁŚyZui'procedure Synchronize(Method: TThreadMethod); overload; znajduje się w IdTread.pas i pochodzi z samego Indy. Wywołuję ją sam komponent TidIrc a nie ja. Próbowałem znów bezskutecznie zastosować Twoje porady. Nic nie pomaga. Mam tez wrażenie, że ten problem moze występować tylko u mnie. Może coś pogrzebalem przy aktualizacji pakietu indy. Dlatego jeżeli ktoś mógłby skompilować program u siebie i sprawdzić czy zachowuje się tak samo byłbym wdzięczny. Żródło programu Link do komentarza Udostępnij na innych stronach More sharing options...
Polecane posty
Zarchiwizowany
Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.