分类: C/C++
2009-06-04 10:40:55
该方法就是在窗体上添加控件MapControl,采用Microsoft Visual Studio开发环境添加消息影射。比如:
BEGIN_EVENTSINK_MAP(CDialogMapControl, CDialog)
ON_EVENT(CDialogMapControl, MapControlID, 1, CDialogMapControl::OnMouseDownMapcontrol, VTS_I4 VTS_I4 VTS_I4 VTS_I4 VTS_R8 VTS_R8)
ON_EVENT(CDialogMapControl, MapControlID, 3, CDialogMapControl::OnMouseMoveMapcontrol, VTS_I4 VTS_I4 VTS_I4 VTS_I4 VTS_R8 VTS_R8)
ON_EVENT(CDialogMapControl, MapControlID, 2, CDialogMapControl::OnMouseUpMapcontrol, VTS_I4 VTS_I4 VTS_I4 VTS_I4 VTS_R8 VTS_R8)
ON_EVENT(CDialogMapControl, MapControlID, 4, CDialogMapControl::OnDoubleClickMapControl, VTS_I4 VTS_I4 VTS_I4 VTS_I4 VTS_R8 VTS_R8)
ON_EVENT(CDialogMapControl, MapControlID, 13, CDialogMapControl::OnKeyDownMapcontrol, VTS_I4 VTS_I4)
ON_EVENT(CDialogMapControl, MapControlID, 14, CDialogMapControl::OnKeyUpMapcontrol, VTS_I4 VTS_I4)
END_EVENTSINK_MAP()
该方法是继承IMapControlEvents2接口,比如下面代码:
class CMapControlEditor : public CComObjectRoot,
public IMapControlEvents2
{
public:
CMapControlEditor();
virtual ~CMapControlEditor();
BEGIN_COM_MAP(CMapControlEditor)
COM_INTERFACE_ENTRY(IMapControlEvents2)
END_COM_MAP()
STDMETHODIMP GetTypeInfoCount(UINT *) {
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) {
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames(REFIID riid,
LPOLESTR __RPC_FAR *rgszNames,
UINT cNames,
LCID lcid,
DISPID __RPC_FAR *rgDispId) {
return E_NOTIMPL;
}
STDMETHODIMP Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS __RPC_FAR *pDispParams,
VARIANT __RPC_FAR *pVarResult,
EXCEPINFO __RPC_FAR *pExcepInfo,
UINT __RPC_FAR *puArgErr)
{
HRESULT hr;
switch(dispIdMember) {
case 0x1: // OnMouseDown
if (pDispParams->cArgs != 6) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG button, shift, x, y, mapX, mapY;
VariantInit(&button);
VariantInit(&shift);
VariantInit(&x);
VariantInit(&y);
VariantInit(&mapX);
VariantInit(&mapY);
hr = VariantChangeTypeEx(&mapY, &(pDispParams->rgvarg[0]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&mapX, &(pDispParams->rgvarg[1]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&y, &(pDispParams->rgvarg[2]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&x, &(pDispParams->rgvarg[3]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&shift, &(pDispParams->rgvarg[4]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&button, &(pDispParams->rgvarg[5]), lcid, 0, VT_I4);
OnMouseDown(button.lVal, shift.lVal, x.lVal, y.lVal, mapX.dblVal, mapY.dblVal);
}
break;
case 0x2: // OnMouseUp
if (pDispParams->cArgs != 6) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG button, shift, x, y, mapX, mapY;
VariantInit(&button);
VariantInit(&shift);
VariantInit(&x);
VariantInit(&y);
VariantInit(&mapX);
VariantInit(&mapY);
hr = VariantChangeTypeEx(&mapY, &(pDispParams->rgvarg[0]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&mapX, &(pDispParams->rgvarg[1]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&y, &(pDispParams->rgvarg[2]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&x, &(pDispParams->rgvarg[3]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&shift, &(pDispParams->rgvarg[4]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&button, &(pDispParams->rgvarg[5]), lcid, 0, VT_I4);
OnMouseUp(button.lVal, shift.lVal, x.lVal, y.lVal, mapX.dblVal, mapY.dblVal);
}
break;
case 0x3: // OnMouseMove
if (pDispParams->cArgs != 6) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG button, shift, x, y, mapX, mapY;
VariantInit(&button);
VariantInit(&shift);
VariantInit(&x);
VariantInit(&y);
VariantInit(&mapX);
VariantInit(&mapY);
hr = VariantChangeTypeEx(&mapY, &(pDispParams->rgvarg[0]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&mapX, &(pDispParams->rgvarg[1]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&y, &(pDispParams->rgvarg[2]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&x, &(pDispParams->rgvarg[3]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&shift, &(pDispParams->rgvarg[4]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&button, &(pDispParams->rgvarg[5]), lcid, 0, VT_I4);
OnMouseMove(button.lVal, shift.lVal, x.lVal, y.lVal, mapX.dblVal, mapY.dblVal);
}
break;
case 0x4: // OnDoubleClick
if (pDispParams->cArgs != 6) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG button, shift, x, y, mapX, mapY;
VariantInit(&button);
VariantInit(&shift);
VariantInit(&x);
VariantInit(&y);
VariantInit(&mapX);
VariantInit(&mapY);
hr = VariantChangeTypeEx(&mapY, &(pDispParams->rgvarg[0]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&mapX, &(pDispParams->rgvarg[1]), lcid, 0, VT_R8);
hr = VariantChangeTypeEx(&y, &(pDispParams->rgvarg[2]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&x, &(pDispParams->rgvarg[3]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&shift, &(pDispParams->rgvarg[4]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&button, &(pDispParams->rgvarg[5]), lcid, 0, VT_I4);
OnDoubleClick(button.lVal, shift.lVal, x.lVal, y.lVal, mapX.dblVal, mapY.dblVal);
}
break;
case 0x5: // OnSelectionChanged
OnSelectionChanged();
break;
case 0x6: // OnViewRefreshed
if (pDispParams->cArgs != 1) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG viewDrawPhase;
VariantInit(&viewDrawPhase);
hr = VariantChangeTypeEx(&viewDrawPhase, &(pDispParams->rgvarg[2]), lcid, 0, VT_I4);
OnViewRefreshed(pDispParams->rgvarg[3], viewDrawPhase.lVal, pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
}
break;
case 0x7: // OnBeforeScreenDraw
if (pDispParams->cArgs != 1) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG hdc;
VariantInit(&hdc);
hr = VariantChangeTypeEx(&hdc, &(pDispParams->rgvarg[0]), lcid, 0, VT_I4);
OnBeforeScreenDraw(hdc.lVal);
}
break;
case 0x8: // OnAfterScreenDraw
if (pDispParams->cArgs != 1) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG hdc;
VariantInit(&hdc);
hr = VariantChangeTypeEx(&hdc, &(pDispParams->rgvarg[0]), lcid, 0, VT_I4);
OnAfterScreenDraw(hdc.lVal);
}
break;
case 0x9: // OnAfterDraw
if (pDispParams->cArgs != 2) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG viewDrawPhase;
VariantInit(&viewDrawPhase);
hr = VariantChangeTypeEx(&viewDrawPhase, &(pDispParams->rgvarg[0]), lcid, 0, VT_I4);
OnAfterDraw(pDispParams->rgvarg[0], viewDrawPhase.lVal);
}
case 0xa: // OnExtentUpdated
if (pDispParams->cArgs != 3) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG sizeChanged;
VariantInit(&sizeChanged);
hr = VariantChangeTypeEx(&sizeChanged, &(pDispParams->rgvarg[1]), lcid, 0, VT_BOOL);
OnExtentUpdated(pDispParams->rgvarg[2], sizeChanged.boolVal, pDispParams->rgvarg[0]);
}
break;
case 0xb: // OnFullExtentUpdated
if (pDispParams->cArgs != 2) {
return DISP_E_BADPARAMCOUNT;
}
else {
OnFullExtentUpdated(pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
}
break;
case 0xc: // OnOleDrop
// 不处理该消息。
break;
case 0xd: // OnKeyDown
if (pDispParams->cArgs != 2) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG keyCode, shift;
VariantInit(&keyCode);
VariantInit(&shift);
hr = VariantChangeTypeEx(&keyCode, &(pDispParams->rgvarg[1]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&shift, &(pDispParams->rgvarg[0]), lcid, 0, VT_I4);
OnKeyDown(keyCode.lVal, shift.lVal);
}
break;
case 0xe: // OnKeyUp
if (pDispParams->cArgs != 2) {
return DISP_E_BADPARAMCOUNT;
}
else {
VARIANTARG keyCode, shift;
VariantInit(&keyCode);
VariantInit(&shift);
hr = VariantChangeTypeEx(&keyCode, &(pDispParams->rgvarg[1]), lcid, 0, VT_I4);
hr = VariantChangeTypeEx(&shift, &(pDispParams->rgvarg[0]), lcid, 0, VT_I4);
OnKeyUp(keyCode.lVal, shift.lVal);
}
break;
case 0xf: // OnMapReplaced
if (pDispParams->cArgs != 1) {
return DISP_E_BADPARAMCOUNT;
}
else {
OnMapReplaced(pDispParams->rgvarg[0]);
}
break;
default:
break;
}
return S_OK;
}
VOID OnMouseDown(LONG button, LONG shift, LONG x, LONG y, DOUBLE mapX, DOUBLE mapY);
VOID OnMouseUp(LONG button, LONG shift, LONG x, LONG y, DOUBLE mapX, DOUBLE mapY);
VOID OnMouseMove(LONG button, LONG shift, LONG x, LONG y, DOUBLE mapX, DOUBLE mapY);
VOID OnDoubleClick(LONG button, LONG shift, LONG x, LONG y, DOUBLE mapX, DOUBLE mapY);
VOID OnSelectionChanged();
VOID OnViewRefreshed(VARIANT ActiveView, LONG viewDrawPhase, VARIANT layerOrElement, VARIANT envelope);
VOID OnBeforeScreenDraw(LONG hdc);
VOID OnAfterScreenDraw(LONG hdc);
VOID OnAfterDraw(VARIANT display, LONG viewDrawPhase);
VOID OnExtentUpdated(VARIANT displayTransformation, VARIANT_BOOL sizeChanged, VARIANT newEnvelope);
VOID OnFullExtentUpdated(VARIANT displayTransformation, VARIANT newEnvelope);
/*VOID OnOleDrop(esriControlsDropAction dropAction, VARIANT dataObjectHelper, LONG * effect, LONG button, LONG shift, LONG x, LONG y); //*/
VOID OnKeyDown(LONG keyCode, LONG shift);
VOID OnKeyUp(LONG keyCode, LONG shift);
VOID OnMapReplaced(VARIANT newMap);
};
该方法是实现接口IMapControlEvents2Helper,代码如下(参见):
class MapControlEvents : public IMapControlEvents2Helper
{
public:
// IUnknown
IUNKNOWN_METHOD_DEFS
MapControlEvents();
// IMapControlEvents2
void OnAfterDraw(VARIANT display, long viewDrawPhase);
void OnAfterScreenDraw(long hdc);
void OnBeforeScreenDraw(long hdc);
void OnDoubleClick(long button, long shift, long x, long y,
double mapX, double mapY);
void OnExtentUpdated(VARIANT displayTransformation,
VARIANT_BOOL sizeChanged, VARIANT newEnvelope);
void OnFullExtentUpdated(VARIANT displayTransformation,
VARIANT newEnvelope);
void OnKeyDown(long keyCode, long shift);
void OnKeyUp(long keyCode, long shift);
void OnMapReplaced(VARIANT newMap);
void OnMouseDown(long button, long shift, long x, long y,
double mapX, double mapY);
void OnMouseMove(long button, long shift, long x, long y,
double mapX, double mapY);
void OnMouseUp(long button, long shift, long x, long y,
double mapX, double mapY);
void OnOleDrop(esriControlsDropAction dropAction, VARIANT dataObjectHelper,
long* effect, long button, long shift, long x, long y);
void OnSelectionChanged();
void OnViewRefreshed(VARIANT ActiveView, long viewDrawPhase,
VARIANT layerOrElement, VARIANT envelope);
};
Create a global variable of your class type, along with an IEventListenerHelperPtr one. They will need to be deleted when the application is closed; making them globals will make that easier to do.
MapControlEvents* g_mapControlEvents;
IEventListenerHelperPtr g_ipMapControlEvent2Helper;
main
. This needs to be done before the top-level widget is realized. // Listen for MapControlEvents
g_mapControlEvents = new MapControlEvents();
g_ipMapControlEvent2Helper.CreateInstance(CLSID_MapControlEvents2Listener);
g_ipMapControlEvent2Helper->Startup(static_cast (g_mapControlEvents));
g_ipMapControlEvent2Helper->AdviseEvents(g_ipMapControl, NULL);
// Start the application running
XtRealizeWidget(g_topLevel);
// Function called when WM_DELETE_WINDOW protocol is passed
void CloseAppCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
g_ipMapControlEvent2Helper->UnadviseEvents();
g_ipMapControlEvent2Helper->Shutdown();
g_ipMapControlEvent2Helper = 0;
delete g_mapControlEvents;
...
}