c++ - ¿No se puede obtener el control de una clase Cwnd en Activex sin ventana de MFC?
atl (1)
Como mencionó, necesita un identificador de ventana para poder recibir mensajes de usuario a través de él, siempre tiene la opción de crear una ventana de ayuda, como la ventana de solo mensaje, vea Usar CreateWindowEx para crear una ventana de solo mensaje.
Para su control sin ventana, está bien que no tenga ningún identificador de ventana, por lo que no puede confiar realmente en la disponibilidad del manejador a menos que sea propietario de una ventana.
He hecho dos preguntas antes sobre esto y para cada publicación hay algunas soluciones que probé, pero el problema aún existe.
Mi primera pregunta fue: por qué un Activex sin ventana no devuelve el Handle. la sugerencia fue "cambiar la configuración de creación de una activación sin m_hWnd
, lo he intentado pero aún la propiedad m_hWnd
ha regresado a cero como lo GetSafeHwnd()
método GetSafeHwnd()
.
la segunda fue la misma pregunta que esta se centró en la clase COleControl y su antecesor CWnd. la solución fue la siguiente: "Cree una ventana invisible en algún lugar de su código de inicialización de control. Maneje los mensajes enviados a esta ventana y llame directamente a los métodos de control" . así que lo hice, pero la clase creada aún devuelve cero asa.
aquí está mi nueva fuente de clase invisible:
// moWind.cpp : implementation file
//
#include "stdafx.h"
#include "PINActive.h"
#include "moWind.h"
#include "include/xfspin.h"
#include <math.h>
// moWind
IMPLEMENT_DYNAMIC(moWind, CWnd)
moWind::moWind(){}
moWind::~moWind(){}
//=============================================================
LRESULT moWind::OnExecuteEvent (WPARAM wParam, LPARAM lParam)
{
WFSRESULT *pResult = (WFSRESULT *)lParam;
CString EK=_T("");
CString str;
int reskey=0;
if (pResult->u.dwEventID=WFS_EXEE_PIN_KEY)
{
LPWFSPINKEY pressedkey;
pressedkey=(LPWFSPINKEY)pResult->lpBuffer;
reskey = log10((double)pressedkey->ulDigit) / log10((double)2);
EK.Format("%d",reskey);
xfsOnKeyEvent->OnKeyRecieved(reskey);
}
else
{
str.Format("ExecuteEvent: ID = %d/r/n", pResult->u.dwEventID);
}
MessageBox("a Execute message Recieved");
return 0;
}
BEGIN_MESSAGE_MAP(moWind, CWnd)
ON_MESSAGE(WFS_EXECUTE_EVENT,OnExecuteEvent)
END_MESSAGE_MAP()
y este es .h archivo de la clase:
// moWind.h
class IXFSEvents
{
protected:
IXFSEvents(){};
virtual ~IXFSEvents(){};
public:
virtual void OnKeyRecieved(int key)=0;
};
class moWind : public CWnd
{
DECLARE_DYNAMIC(moWind)
public:
moWind();
virtual ~moWind();
void Register(IXFSEvents* obj)
{
xfsOnKeyEvent= obj;
}
protected:
IXFSEvents* xfsOnKeyEvent;
LRESULT OnExecuteEvent (WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
y al final aquí esta es la forma en que he usado esta clase en mi Activex: en el archivo myActivex.h:
incluye "moWind.h"
class CmyActivexCtrl : public COleControl, public IXFSEvents
{
...
Class definition
...
protected:
moWind tmpWind;
.
.
};
finalmente, en el método de creación de myActivex, he inicializado el método de devolución de llamada del componente y quería obtener su Handle como este:
CmyActivexCtrl::CmyActivexCtrl()
{
InitializeIIDs(&IID_DmyActivex, &IID_DmyActivexEvents);
tmpWind.Register(this);
myOtherComponent.WindowsHandle=tmpWind.GetSafeHwnd(); //here my Cwnd derived class returns zero
//my other component gets the handle and call an API with it to register
//the given handle and force the API to send the messages to that handle.
}