2014-01-13 1 views
0

Мне нужно, чтобы второй поток выполнял некоторые проверки ошибок, которые работают нормально. Основной поток - без окон ActiveX OCX.Передача сообщения от рабочего потока к основному потоку в элементе управления ActiveX без окон

Что бы я хотел сделать, так это то, что 2-я нить отправила сообщение обратно в основной поток. Я создал карту сообщений и обработчик сообщений. Изнутри второго потока я использую PostMessage, чтобы поместить сообщение вверх. Я знаю, что добрался туда, и я знаю, что сообщение отправлено, поскольку возвращаемое значение в вызове PostMessage приводит к одному (ИСТИНА). Я никогда не вижу ответа от обработчика сообщений. Кажется, что это не вызвано.

фрагменты кода из моего Visual Studio 2012 проект ActiveX:

//Message handler definition from the .h file: 
protected: 

    afx_msg LRESULT OnHSAmessage(WPARAM wParam, LPARAM lParam); 



//From the .cpp file: 

BEGIN_MESSAGE_MAP(CHSAObserver_ActiveXControlCtrl, COleControl) 
     ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) 
     ON_MESSAGE(WM_HSAMESSAGE, &CHSAObserver_ActiveXControlCtrl::OnHSAmessage) 
END_MESSAGE_MAP() 


// thread creation (this works) 
HSAWnd *pWnd = new HSAWnd(this); 
hwndTarget = pWnd->Create(); 
HANDLE threadHandle = CreateThread(NULL,NULL, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)  hwndTarget, NULL, &dwID); 

//thread implementation 
LONG ThreadProc(LPVOID pParam) 
{ 
      BOOL status; 
     //I know I get here the Postmessage call does not result 
     //in the message handler being invoked 
     MessageBox(_T("inside threadproc")); 
     CHSAObserver_ActiveXControlCtrl *pCtrl = (CHSAObserver_ActiveXControlCtrl*)pParam; 

     //post message using global HSAWnd 
     status = PostMessage(hwndTarget, WM_HSAMESSAGE,(WPARAM)NULL,(LPARAM)NULL); 

     //post message using Class window (here for testing only) 
     //status = PostMessage (pCtrl->m_hWnd, WM_HSAMESSAGE,(WPARAM)NULL,(LPARAM)NULL); 

    return TRUE; 
} 


afx_msg LRESULT CHSAObserver_ActiveXControlCtrl::OnHSAmessage(WPARAM wParam, LPARAM lParam) 
{ 
     //this never happens 
     MessageBox(_T("message posted")); 

    return 0; 
} 
+0

ИМО, ваш вопрос запутан, как есть, подумайте об улучшении. * «Основной поток - без окон ActiveX OCX» *, и вдруг появляется окно «hwndTarget» (или нет? И что такое «HSAWnd'?). В любом случае, элемент управления ActiveX без окон может получать только сообщение Windows через 'IOleInPlaceSiteWindowless :: OnDefWindowMessage' и только в том случае, если контейнер фактически пересылает ему сообщение. – Noseratio

+0

@Noseratio HSAWnd - класс, который я создал из Cwnd. Я пытался попытаться создать скрытое окно, в которое я мог бы отправлять сообщения. HSAWnd - это экземпляр этого класса. Я хотел бы, чтобы мой обработчик сообщений отвечал на сообщения, отправленные в HSAWnd. По вашему предложению я посмотрю OnDefWindowMessage. Спасибо. – PhilsterNH

+0

Только что заметил, что у меня было два опечатка: HSAWnd - класс, который я создал из Cwnd. Я пытался создать скрытое окно, в которое я мог бы отправлять сообщения. hwndTarget - это экземпляр этого класса. Я хочу, чтобы мой обработчик сообщения отвечал на сообщения, отправленные на hwndTarget. – PhilsterNH

ответ

0

Вы не показал код HSAWnd, но я думаю, что проблема, ваша карта сообщение объявляется внутри CHSAObserver_ActiveXControlCtrl класса, а вот где у вас есть запись для WM_HSAMESSAGE. В то же время вы отправляете сообщение в окно, созданное экземпляром класса HSAWnd, который отделен от CHSAObserver_ActiveXControlCtrl и не имеет ничего общего с его картой сообщений.

Таким образом, HSAWnd должен иметь запись на карте для WM_HSAMESSAGE вместо CHSAObserver_ActiveXControlCtrl. Я ожидаю, что это сработает.

На боковой ноте PostMessage является асинхронным API. Вы должны учитывать учет в случае, когда события рабочего потока будут выполняться быстрее, чем HSAWnd, могут обрабатывать сообщения WM_HSAMESSAGE.

Если вы хотите опубликовать сообщения от рабочего потока до , пользовательский интерфейс асинхронно, скрытое окно и PostMessage - это в значительной степени единственный выбор.

Если у вас все в порядке, сделав это синхронно, вместо этого вы можете использовать SendMessage. В качестве альтернативы вы можете использовать маршалинг COM межпотока, и в этом случае вам не нужно явно создавать скрытое окно. Определите частные интерфейсы в вашем элементе управления ActiveX (например, IPrivate, убедитесь, что он входит в библиотеку типов), затем переместите его в рабочий поток с помощью CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream и вызовите любые методы из IPrivate внутри рабочего потока на возвращаемом объекте прокси по CoGetInterfaceAndReleaseStream. В Интернете есть несколько хороших примеров такого подхода, как this one.

+0

Вы правы. У меня нет записи карты сообщений для WM_HSAMESSAGE в моем классе HSAWnd. Я сделаю эту модификацию и сообщю о моих результатах. – PhilsterNH

+0

@PhilsterNH, так что это не помогло, не так ли? – Noseratio

+0

Нет, это не помогло. Я до сих пор не вижу ответа от обработчика сообщений. По вашему предложению я создал карту сообщений и обработчик сообщений в классе HSAWnd, и это не помогло. Я удалил его из своего основного класса CHSAObserver_ActiveXControlCtrl. – PhilsterNH

Смежные вопросы