-
2009-03-27
自定义窗口的回调函数--鼠标处理
class CParentWnd:public CWindowImpl<CParentWnd, CWindow>
{
public:
CParentWnd();
~CParentWnd();BEGIN_MSG_MAP(CParentWnd)
END_MSG_MAP()static int OnButtonPress(UINT, CMyButtion*);//相应按键消息
};class CMyButton
{
public:
CMyButton(CParentWnd*);
public:
void SetPressProc(int (*fpCallBack)(UINT, CMyButton*);int (*m_fpCallBack)(UINT, CMyButton*);//member data
void (*m_fpCallBack_HoverLeave)(UINT, CMyButton*, BOOL);
};
在一个CParentWnd的成员函数中。
CMyButton *pBT = new CMyButton(this);
pBT->Create(...);
pBT->SetPressProc(OnButtionPress);在一个合适的时候调用函数指针
if(m_fpCallBack)
{
m_fpCallBack(uId,bInTextRect,this,bButtonDown);
}
-
2009-03-27
2009-03-27
class CParentWnd:public CWindowImpl<CParentWnd, CWindow>
{
public:
CParentWnd();
~CParentWnd();BEGIN_MSG_MAP(CParentWnd)
END_MSG_MAP()static int OnButtonPress(UINT, CMyButtion*);//相应按键消息
};class CMyButton
{
public:
CMyButton(CParentWnd*);
public:
void SetPressProc(int (*fpCallBack)(UINT, CMyButton*);int (*m_fpCallBack)(UINT, CMyButton*);//member data
void (*m_fpCallBack_HoverLeave)(UINT, CMyButton*, BOOL);
};
在一个CParentWnd的成员函数中。
CMyButton *pBT = new CMyButton(this);
pBT->Create(...);
pBT->SetPressProc(OnButtionPress);在一个合适的时候调用函数指针
if(m_fpCallBack)
{
m_fpCallBack(uId,bInTextRect,this,bButtonDown);
}
-
2009-03-25
使用CMarkup类解析XML
-
2009-03-17
替代IDispatch::Invoke的SINK方法 - [ATL]
// Client.cpp : Defines the entry point for the application.
//#include "stdafx.h"
#include "Client.h"
#include <atlbase.h>
#include <atlcom.h>
#include <atlimpl.cpp>
#include "..\shm\SHM_i.h"
#include "..\shm\SHM_i.C"
//use VT_I4 with HRESULT
_ATL_FUNC_INFO AddCompParam = {CC_STDCALL, VT_I4,1,VT_I4};
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class nameCComModule _Module;
class CUserATLCom
{
public:
CUserATLCom()
{
CoInitialize(NULL);
}
~CUserATLCom()
{
CoUninitialize();
}
};
class CAddEvents:public IDispEventSimpleImpl<1, CAddEvents, &__uuidof(_IAddEvents)>
{
public:
CAddEvents(){};long __stdcall AddCompleted(long hr)
{
LONG i = hr;
return 1;
}
// IUnknown
BEGIN_SINK_MAP(CAddEvents)
SINK_ENTRY_INFO(1, __uuidof(_IAddEvents), 0x1, AddCompleted, &AddCompParam)
END_SINK_MAP()STDMETHODIMP AddOk(BSTR bstrOK)
{
CComBSTR str(bstrOK);
return S_OK;
}
};
CUserATLCom _gUserATL;// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);_Module.Init(NULL, hInstance);
//get Add com
CComPtr<IAdd> ptrAdd;
HRESULT hr;
hr = CoCreateInstance(CLSID_Add, NULL, CLSCTX_SERVER, IID_IAdd, (void**)&ptrAdd);//get Add events
CAddEvents* ptrAddEvents = new CAddEvents;
ptrAddEvents->DispEventAdvise(ptrAdd);
//fire connection point
LONG lVal;
ptrAdd->AddLongVal(1, 2, &lVal);
ptrAdd->IsOK(BSTR("a"));
//queryInter ISub interface
CComPtr<ISub> ptrSub;
hr = ptrAdd->QueryInterface(IID_ISub, (void**)&ptrSub);if(FAILED(hr))
{
ATLASSERT(FALSE);
}//call the function of ISub
ptrSub->SubFun(4,1,&lVal);return 1;
} -
2009-03-17
My first ATL COM with connection point - [ATL]
///
1.连接点 事件接口_IAddEvents包含连个方法AddCompleted 和IsOK
2.两个接口IAdd和ISub
IAdd 中的方法包括AddLongVal和IsOK在该方法中都fire一个事件。
Fire事件的过程:
Fire Event->Fire_EventHandle(CProxy_IAddEvents)->Invoke方法(客户端从IAddEvent派生)->调用客户端的方法。// SHM.idl : IDL source for SHM
//// This file will be processed by the MIDL tool to
// produce the type library (SHM.tlb) and marshalling code.import "oaidl.idl";
import "ocidl.idl";[
object,
uuid(A986F54E-A7C9-4B16-B542-450BAAAF84F5),
dual,
nonextensible,
helpstring("IAdd Interface"),
pointer_default(unique)
]
interface IAdd : IDispatch{
[id(1), helpstring("method AddLongVal")] HRESULT AddLongVal([in] LONG lVal, [in] LONG rVal, [out,retval] LONG* retVal);
[id(2), helpstring("method IsOK")] HRESULT IsOK([in] BSTR bstrOK);
};
[
object,
uuid(480C3EF7-812E-4818-9860-6729B56C62F2),
dual,
nonextensible,
helpstring("ISub Interface"),
pointer_default(unique)
]interface ISub : IDispatch{
[id(1), helpstring("method SubFun")] HRESULT SubFun([in] LONG lVal, [in] LONG rVal, [out,retval] LONG* retVal);
};
[
uuid(7002FB8A-F615-4710-81AB-716F1A3ADD06),
version(1.0),
helpstring("SHM 1.0 Type Library")
]
library SHMLib
{
importlib("stdole2.tlb");
[
uuid(5F66AE9F-1DFC-4621-B7A7-D0EFE04E0118),
helpstring("_IAddEvents Interface")
]
dispinterface _IAddEvents
{
properties:
methods:
[id(1), helpstring("method AddCompleted")] HRESULT AddCompleted([in] LONG val);
[id(2), helpstring("method AddOK")] HRESULT IsOK(BSTR* szOK);
};
[
uuid(AD7ABE60-1865-45E4-AE0B-ED16B1A9F5D1),
helpstring("Add Class")
]
coclass Add
{
[default] interface IAdd;
interface ISub;
[default, source] dispinterface _IAddEvents;
};
};///CAdd
// Add.h : Declaration of the CAdd
#pragma once
#include "resource.h" // main symbols#include "SHM_i.h"
#include "_IAddEvents_CP.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif// CAdd
class ATL_NO_VTABLE CAdd :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CAdd, &CLSID_Add>,
public IConnectionPointContainerImpl<CAdd>,
public CProxy_IAddEvents<CAdd>,
public IDispatchImpl<IAdd, &IID_IAdd, &LIBID_SHMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispatchImpl<_IAddEvents, &__uuidof(_IAddEvents), &LIBID_SHMLib, /* wMajor = */ 1, /* wMinor = */ 0>,
public IDispatchImpl<ISub, &__uuidof(ISub), &LIBID_SHMLib, /* wMajor = */ 1, /* wMinor = */ 0>
{
public:
CAdd()
{
}DECLARE_REGISTRY_RESOURCEID(IDR_ADD)
BEGIN_COM_MAP(CAdd)
COM_INTERFACE_ENTRY(IAdd)
COM_INTERFACE_ENTRY2(IDispatch, _IAddEvents)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY(_IAddEvents)
COM_INTERFACE_ENTRY(ISub)
END_COM_MAP()BEGIN_CONNECTION_POINT_MAP(CAdd)
CONNECTION_POINT_ENTRY(__uuidof(_IAddEvents))
END_CONNECTION_POINT_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()HRESULT FinalConstruct()
{
return S_OK;
}void FinalRelease()
{
}public:
STDMETHOD(AddLongVal)(LONG lVal, LONG rVal, LONG* retVal);
// _IAddEvents Methods
public:
STDMETHOD(AddCompleted)( LONG val)
{
// Add your function implementation here.
return E_NOTIMPL;
}STDMETHOD(IsOK)(BSTR bstrOK);
// ISub Methods
public:
STDMETHOD(SubFun)( LONG lVal, LONG rVal, LONG * retVal)
{
*retVal = lVal - rVal;
return S_OK;
}
};OBJECT_ENTRY_AUTO(__uuidof(Add), CAdd)
///CProxy_IAddEvents<T>
#pragma once
template<class T>
class CProxy_IAddEvents :
public IConnectionPointImpl<T, &__uuidof(_IAddEvents)>
{
public:
HRESULT Fire_AddCompleted( LONG val)
{
HRESULT hr = S_OK;
T * pThis = static_cast<T *>(this);
int cConnections = m_vec.GetSize();for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
pThis->Lock();
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
pThis->Unlock();IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
if (pConnection)
{
CComVariant avarParams[1];
avarParams[0] = val;
avarParams[0].vt = VT_I4;
CComVariant varResult;DISPPARAMS params = { avarParams, NULL, 1, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}HRESULT Fire_IsOK( BSTR bstrOK)
{
HRESULT hr = S_OK;
T * pThis = static_cast<T *>(this);
int cConnections = m_vec.GetSize();for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
pThis->Lock();
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
pThis->Unlock();IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
if (pConnection)
{
CComVariant avarParams[1];
avarParams[0] = bstrOK;
avarParams[0].vt = VT_BSTR;
CComVariant varResult;DISPPARAMS params = { avarParams, NULL, 1, 0 };
hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
};///client
// Client.cpp : Defines the entry point for the application.
//#include "stdafx.h"
#include "Client.h"
#include <atlbase.h>
#include <atlcom.h>
#include <atlimpl.cpp>
#include "..\shm\SHM_i.h"
#include "..\shm\SHM_i.C"
#define MAX_LOADSTRING 100// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class nameCComModule _Module;
class CUserATLCom
{
public:
CUserATLCom()
{
CoInitialize(NULL);
}
~CUserATLCom()
{
CoUninitialize();
}
};
class CAddEvents:public CComObjectRoot
, public _IAddEvents
{
public:
CAddEvents(){};BEGIN_COM_MAP(CAddEvents)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(_IAddEvents)
END_COM_MAP()// IUnknown
//IAddEvents
public:
STDMETHODIMP GetTypeInfoCount(UINT *)
{
return E_NOTIMPL;
}STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo)
{
return E_NOTIMPL;
}STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID *rgDisID)
{
return E_NOTIMPL;
}STDMETHODIMP Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDisParams,
VARIANT* pVarResult,
EXCEPINFO* pExcepInfo,
UINT* pnArgErr)
{
switch(dispIdMember)
{
case 0x1:
{ if (pDisParams->cArgs != 1)
{
return DISP_E_BADPARAMCOUNT;
}
if (pDisParams->cNamedArgs)
{
return DISP_E_NONAMEDARGS;
}//Coerce the argument into a long
HRESULT hr;
VARIANTARG var;
VariantInit(&var);
hr = VariantChangeType(&var, &(pDisParams->rgvarg[0]), 0, VT_I4);
if FAILED(hr)
{
return DISP_E_BADVARTYPE;
}AddCompleted(var.lVal);
break;
}
case 0x2:
{
if (pDisParams->cArgs != 1)
{
return DISP_E_BADPARAMCOUNT;
}
if (pDisParams->cNamedArgs)
{
return DISP_E_NONAMEDARGS;
}//Coerce the argument into a long
HRESULT hr;
VARIANTARG var;
VariantInit(&var);
hr = VariantChangeType(&var, &(pDisParams->rgvarg[0]), 0, VT_BSTR);
if FAILED(hr)
{
return DISP_E_BADVARTYPE;
}AddOk(var.bstrVal);
}break;
default:
{
ATLASSERT(FALSE);
}
break;
}
}STDMETHODIMP AddCompleted( LONG val)
{
LONG i = val;
return S_OK;
}
STDMETHODIMP AddOk(BSTR bstrOK)
{
CComBSTR str(bstrOK);
return S_OK;
}
};
CUserATLCom _gUserATL;// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);_Module.Init(NULL, hInstance);
//get Add com
CComPtr<IAdd> ptrAdd;
HRESULT hr;
hr = CoCreateInstance(CLSID_Add, NULL, CLSCTX_SERVER, IID_IAdd, (void**)&ptrAdd);//get Add events
CComObject<CAddEvents>* ptrAddEvents;
CComObject<CAddEvents>::CreateInstance(&ptrAddEvents);
//get pointer to the IUNKNOWN interface
CComPtr<IUnknown>ptrEventsUnk = ptrAddEvents;
DWORD dwCookie;
hr = AtlAdvise(ptrAdd,ptrEventsUnk, DIID__IAddEvents, &dwCookie);
if (FAILED(hr))
{
ATLASSERT(FALSE);
}
//fire connection point
LONG lVal;
ptrAdd->AddLongVal(1, 2, &lVal);
ptrAdd->IsOK(BSTR("a"));
//unadvise
AtlUnadvise(ptrAdd, DIID__IAddEvents, dwCookie);
//queryInter ISub interface
CComPtr<ISub> ptrSub;
hr = ptrAdd->QueryInterface(IID_ISub, (void**)&ptrSub);if(FAILED(hr))
{
ATLASSERT(FALSE);
}//call the function of ISub
ptrSub->SubFun(4,1,&lVal);
return 1;
}







