Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Не клеится событиями


Автор: Guest 10.11.2003, 12:19
Что-то у меня с событиями не клеится.
Код

namespace CTest
{
//Есть интерфейс
public delegate void DelegateLogIpAddr(uint dwIpAddr);

[Guid("A7B88840-A812-11cf-8011-00A0C90A8F78")]
public interface IDCCManTest
{
   event DelegateLogIpAddr EventLogIpAddr;
   void OnLogIpAddr(uint dwIpAddr);
                  ...
}
//Есть компонент, который должен перехватывать событие OnLogIpAddr интерфейса
public class CTestComp : System.ComponentModel.Component, IDCCManTest
{
  ...
  public event DelegateLogIpAddr EventLogIpAddr;
  public virtual void OnLogIpAddr(uint dwIpAddr)
  {
      if (EventLogIpAddr != null)
             EventLogIpAddr(dwIpAddr); // Так confused.gif
}
}


Почему то в приложение это событие не приходит.
Спасибо.

Автор: stab 10.11.2003, 12:42
может просто обработчик не назначен?

Автор: AntonSaburov 10.11.2003, 12:43
Цитата
public virtual void OnLogIpAddr(uint dwIpAddr)


А ту уверен, что надо именно virtual ?
Может правильнее override ?

Хотя я в такую область не залезал, так что попытка чисто интуитивная.
Если найдешь решение - большая просьба опубликовать.

Автор: Guest 10.11.2003, 12:57
По моему я дошел до корней проблемы, но решения не знаю.
При создании компонента делается следующее:
Код

private uint FContext;
...
public CTestComp()
{
   InitializeComponent();

   Guid CLSID_IDCCMan = new Guid("{499C0C20-A766-11cf-8011-00A0C90A8F78}");
   Type tmpIDCCManTestType = Type.GetTypeFromCLSID(CLSID_IDCCMan);
    if (tmpIDCCManTestType == null) throw new Exception("IUnknown not assigned.");
    object tmpIDCCManTestObj = Activator.CreateInstance(tmpIDCCManTestType);
    if (tmpIDCCManTestObj == null) throw new Exception("IDCCMan not found.");

   fixed (uint *ptr = &FContext)
   {    
       FIDCCMan.Advise(this, ptr); // Вот здесь то Advise не проходит - почему не понятно
       // соот-но и далле компонент не работает
   }  
}

Кто-нибудь знает в чем тут дело. На Delphi код следующий и работает:
Код

protected
   FContext:DWord;
...
constructor TTestComp.Create(AOwner: TComponent);
 var tmpIUnknown:IUnknown;
begin
 tmpIUnknown:=CreateComObject(CLSID_IDCCMan);
 if not assigned(tmpIUnknown) then raise ESyncError.Create('InternalNewInit.IUnknown not assigned.');
 if (tmpIUnknown.QueryInterface(IDCCMan, FIDCCMan)<>S_OK)or(not assigned(FIDCCMan)) then
    raise  ESyncError.Create('InternalNewInit.IDCCMan not found.');
 FIDCCMan.Advise(self, @FContext);
end;


Автор: stab 10.11.2003, 13:30
Код
FIDCCMan.Advise(this, ptr);


на сколько я понимаю:

1. метод Advise требует что бы первый параметр поддерживал интерфейс IAdviseSink, точнее это указатель на этот интерфейс.
2. this в данном случае класса CTestComp, следовательно CTestComp должен реализовывать интерфейс IAdviseSink, может как раз он и нереализован?

з.ы может я ваще не в ту степь полез? smile.gif

Автор: Unregistered 10.11.2003, 13:38
Да, ты все верно говоришь
класс CTestComp объявлен как
public class CTestComp : System.ComponentModel.Component, IDCCManSink{}
IDCCManSink - это и есть тот самый интерфейс.

Автор: stab 10.11.2003, 13:57
Покажи как описан IDCCManSink.

Автор: Unregistered 10.11.2003, 14:01
using System;
using System.Runtime.InteropServices;

namespace CTestCompLib
{
public delegate void DelegateLogIpAddr(uint dwIpAddr);
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("09994751-A5A2-4306-899C-A47E6C4525B7")]
//[Guid("A7B88840-A812-11cf-8011-00A0C90A8F78")]
public interface IDCCManSink
{
event DelegateLogIpAddr EventLogIpAddr;
void OnLogIpAddr(uint dwIpAddr);
void OnLogTerminated();
void OnLogActive();
void OnLogInactive();
void OnLogAnswered();
void OnLogListen();
void OnLogDisconnection();
void OnLogError();
}

Автор: stab 10.11.2003, 14:08
хз, вроде все ок.

Автор: stab 10.11.2003, 14:09
Цитата
FIDCCMan.Advise(this, ptr); // Вот здесь то Advise не проходит - почему не понятно


а что происходит?

Автор: Unregistered 10.11.2003, 14:14
Когда кидаю компонент на форму вылетает ошибка:
An exception occurred while trying to create an instance of CTestCompLib.CTestComp. The exception was "Object reference not set to an instance of an object.".

Автор: stab 10.11.2003, 14:20
т.е. FIDCCMan получается равен null ?

Автор: Guest 10.11.2003, 14:22
Навернное. bored.gif

Автор: stab 10.11.2003, 14:22
фигурируют два объекта tmpIDCCManTestObj и FIDCCMan, может это должен быть один и тот же объект и одна переменная?

Автор: Guest 10.11.2003, 14:32
В коде на Delphi так и есть
Код

protected
  FContext:DWord;
...
constructor TTestComp.Create(AOwner: TComponent);
var tmpIUnknown:IUnknown;
begin
tmpIUnknown:=CreateComObject(CLSID_IDCCMan);
if not assigned(tmpIUnknown) then raise ESyncError.Create('InternalNewInit.IUnknown not assigned.');
if (tmpIUnknown.QueryInterface(IDCCMan, FIDCCMan)<>S_OK)or(not assigned(FIDCCMan)) then
   raise  ESyncError.Create('InternalNewInit.IDCCMan not found.');
FIDCCMan.Advise(self, @FContext);
end;

но на C# у меня не получилось так сделать.
Если ты знаешь как, пожалуйста подскажи.

Автор: stab 10.11.2003, 14:52
я просто не вижу места в коде, где бы FIDCCMan присваивалось значение.

Автор: Unregistered 10.11.2003, 14:58
Да ты прав, но если
Код

Guid CLSID_IDCCMan = new Guid("499C0C20-A766-11cf-8011-00A0C90A8F78");
Type tmpIDCCManType = Type.GetTypeFromCLSID(CLSID_IDCCMan);
if (tmpIDCCManType == null) throw new Exception("InternalNewInit.IUnknown not assigned.");
[B]FIDCCMan = Activator.CreateInstance(tmpIDCCManType);[/B]
if (FIDCCMan == null) throw new Exception("InternalNewInit.IDCCMan not found.");

то компилятор ругается
(877): Cannot implicitly convert type 'object' to 'CTestCompLib.IDCCMan'
Как тут быть?

Автор: Unregistered 10.11.2003, 15:08
Вообще, что является аналогом функции QueryInterface(IDCCMan, FIDCCMan) из Delphi в C#confused.gif
Как правильно работать в таких ситуацияхconfused.gif

Автор: stab 10.11.2003, 15:19
сделай так:
Код
FIDCCMan = (IDCCMan) Activator.CreateInstance(tmpIDCCManType);


smile.gif должно помочь

Автор: stab 10.11.2003, 15:22
а нет-нет smile.gif IDCCMan это ж интерфейс? тогда так:

Код
FIDCCMan = Activator.CreateInstance(tmpIDCCManType) as IDCCMan;

Автор: Guest 10.11.2003, 15:27
При помещении компонента на форму вываливается
IDCCMan not found.
??
Что тут не так notify.gif Блин. У меня уже нервы на пределе. mad.gif

Автор: stab 10.11.2003, 15:36
может так:

Код
FIDCCMan = Activator.CreateInstance(tmpIDCCManType) as CTestCompLib.IDCCMan;

Автор: Unregistered 10.11.2003, 15:43
Не помогло - такая же ошибка.

Автор: stab 10.11.2003, 15:47
а если в хелпе почитать описание ошибки? там же ведь наверняка есть кнопка Help или что-то вроде.

Автор: Unregistered 10.11.2003, 15:51
Нет, это же мое сообщение
if (FIDCCMan == null) throw new Exception("IDCCMan not found.");

Автор: stab 10.11.2003, 15:55
тьфу, блин smile.gif

Автор: Guest 10.11.2003, 15:58
Мне тоже смешно. На Delphi все работает, а здесь... hehe.gif

Автор: stab 10.11.2003, 16:05
у меня пишет:

Цитата
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll

Additional information: COM object with CLSID {499C0C20-A766-11CF-8011-00A0C90A8F78} is either not valid or not registered.


на Activator.CreateInstance(tmpIDCCManTestType)

что это за объект c CLSID {499C0C20-A766-11CF-8011-00A0C90A8F78}? у меня такого в системе вроде нет.

Автор: Unregistered 10.11.2003, 16:11
IDCCMan ставится ActiveSync для синхронизации с Pocket. Если у тебя нет ActiveSync, то наверное и IDCCMan нет

Автор: stab 10.11.2003, 16:20
где бы взять ActiveSync? ;)

Автор: Guest 10.11.2003, 16:30
Короче победилась ента ошибка withstupid.gif
Заменил
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("A7B88841-A812-11cf-8011-00A0C90A8F78")]
на
[Guid("A7B88841-A812-11cf-8011-00A0C90A8F78")]
public interface IDCCMan {}
и использовал
FIDCCMan = Activator.CreateInstance(tmpIDCCManType) as CSyncPocketLib.IDCCMan;
Спасибо.
Но надо еще проверить работу событий.

Автор: Unregistered 10.11.2003, 16:42
Скажи, мне что на каждое событие IDCCManSink писать делегат?
[CODE]
public delegate void DelegateLogIpAddr(uint dwIpAddr);
public delegate void DelegateLogTerminated();
public delegate void DelegateLogActive();
public delegate void DelegateLogInactive();
public delegate void DelegateLogAnswered();
public delegate void DelegateLogListen();
public delegate void DelegateLogDisconnection();
public delegate void DelegateLogError();

[Guid("A7B88840-A812-11cf-8011-00A0C90A8F78")]
public interface IDCCManSink
{
event DelegateLogIpAddr EventLogIpAddr;
void OnLogIpAddr(uint dwIpAddr);
event DelegateLogTerminated EventLogTerminated;
void OnLogTerminated();
event DelegateLogActive EventLogActive;
void OnLogActive();
event DelegateLogInactive EventLogInactive;
void OnLogInactive();
event DelegateLogAnswered EventLogAnswered;
void OnLogAnswered();
event DelegateLogListen EventLogListen;
void OnLogListen();
event DelegateLogDisconnection EventLogDisconnection;
void OnLogDisconnection();
event DelegateLogError EventLogDisconnection;
void OnLogError();
}

Автор: stab 10.11.2003, 17:14
Цитата
Скажи, мне что на каждое событие IDCCManSink писать делегат?


нет, я бы так сделал:

public delegate void DelegateLogIpAddr(uint dwIpAddr);
public delegate void DelegateGenericLog();

[Guid("A7B88840-A812-11cf-8011-00A0C90A8F78")]
public interface IDCCManSink
{
event DelegateLogIpAddr EventLogIpAddr;
void OnLogIpAddr(uint dwIpAddr);
event DelegateGenericLog EventLogTerminated;
void OnLogTerminated();
event DelegateGenericLog EventLogActive;
void OnLogActive();
event DelegateGenericLog EventLogInactive;
void OnLogInactive();

.
.
.

}

Автор: Unregistered 10.11.2003, 17:22
Так, а в классе как описать ??
Извини за такие вопросы, но не врубаюсь в MSDN-ое описание.

Автор: stab 10.11.2003, 17:48
Объясни какую роль этот интерфейс выполняет или ссылку дай где почитать, а то так ни че не могу точно сказать.

Автор: Unregistered 10.11.2003, 18:01
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/html/_wcesdk_IDccMan_IUnknown.asp

Автор: stab 11.11.2003, 04:11
вроде так:

Код

public interface IDCCManSink
{
void OnLogIpAddr(uint dwIpAddr);
void OnLogTerminated();
void OnLogActive();
void OnLogInactive();
void OnLogAnswered();
void OnLogListen();
void OnLogDisconnection();
void OnLogError();
}

public delegate void DelegateLogIpAddr(uint dwIpAddr);
public delegate void DelegateGenericLog();

public class CDCCManSink: IDCCManSink
{

public event DelegateLogIpAddr OnLogIpAddrEvent;
void OnLogIpAddr(uint dwIpAddr)
{
 if (OnLogIpAddrEvent != null) OnLogIpAddrEvent(dwIpAddr);
}

public event DelegateGenericLog OnLogTerminatedEvent;
void OnLogTerminated()
{
 if (OnLogTerminatedEvent != null) OnLogTerminatedEvent();
}
.
.
.
}



и перед передачей в Advise

CDCCManSink DCCManSink = new CDCCManSink();
.... настройка событий
FDCCMan.Advise(DCCManSink, ptr)

или если у тебя сам компонент будет реализовывать IDCCManSink способом описанным выше, тогда просто FDCCMan.Advise(this, ptr)

Автор: Unregistered 11.11.2003, 10:25
Advise у меня проходит. Мне не понятно следующее:
когда я кладу компонент на форму, то в инспекторе объектов появляются события OnLogIpAddrEvent, OnLogTerminatedEvent... а при 2-ом клике в редакторе кода
Код

private void cTestComp1_OnLogAnsweredEvent()
{
this.Text = "Status: " + cTestComp1.NewStatusConnection; // мой код
}

Так вот упоминания OnLogIpAddr или OnLogTerminated нет. Может этого не хватает?

Автор: Guest 12.11.2003, 11:25
Все в общем-то получилось после следующего объявлении интерфейса
Код

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("A7B88840-A812-11cf-8011-00A0C90A8F78")]
public interface IDCCManSink
{
void OnLogIpAddr(uint dwIpAddr);
void OnLogTerminated();  
void OnLogActive();  
void OnLogInactive();  
void OnLogAnswered();  
void OnLogListen();  
void OnLogDisconnection();  
void OnLogError();
}

Дело в том, что IDCCManSink - это CОМ интерфейс.
Всем спасибо, особенно cully exclamation.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)