После Attach
клиент отправляется куда-то Subscribe
в свойство, где он передает ссылку TRequestStatus
. Сервер сообщит свойству статуса запроса через ядро, когда произошло асинхронное событие (в вашем случае это свойство было изменено). Если ваш пример исходного кода реализован правильно, вы обнаружите активный объект (AO; CActive
производный класс), висящий вокруг, и iStatus
этого AO будет передано в RProperty API. В этом случае функция RunL
AO будет вызываться при изменении свойства.
В Symbian важно понимать структуру активного объекта, и на самом деле мало кто это делает. К сожалению, я не нашел по-настоящему хорошего описания в Интернете (они достаточно хорошо объяснены в книге о внутренних операциях Symbian OS), но эта страница по крайней мере дает вам быстрый пример.
Пример
В ConstructL
вашего подкласса CMyActive CActive
:
CKeyEventsClient* iClient;
RProperty iProperty;
// ...
void CMyActive::ConstructL()
{
RProcess myProcess;
TSecureId propertyCategory = myProcess.SecureId();
// avoid interference with other properties by defining the category
// as a secure ID of your process (perhaps it's the only allowed value)
TUint propertyKey = 1; // whatever you want
iClient = CKeyEventsClient::NewL(propertyCategory, propertyKey, ...);
iClient->OpenNotificationPropertyL(&iProperty);
// ...
CActiveScheduler::Add(this);
iProperty.Subscribe(iStatus);
SetActive();
}
Ваш RunL будет вызываться при изменении свойства:
void CMyActive::RunL()
{
if (iStatus.Int() != KErrCancel) User::LeaveIfError(iStatus.Int());
// forward the error to RunError
// "To ensure that the subscriber does not miss updates, it should
// re-issue a subscription request before retrieving the current value
// and acting on it." (from docs)
iProperty.Subscribe(iStatus);
TInt value; // this type is passed to RProperty::Define() in the client
TInt err = iProperty.Get(value);
if (err != KErrNotFound) User::LeaveIfError(err);
SetActive();
}