ActiveX控件窗口的产生---源码分析

来源:互联网 发布:熊族刀路软件英文原版 编辑:程序博客网 时间:2024/05/16 14:30
<span style="font-family: Arial, Helvetica, sans-serif;">控件窗口的建立过程(只取了函数中的关键代码):</span>
STDMETHODIMP COleControl::XOleObject::DoVerb(LONG iVerb, LPMSG lpmsg,LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent,LPCRECT lprcPosRect){//OLEIVERB_INPLACEACTIVATE:pThis->OnActivateInPlace((iVerb != OLEIVERB_INPLACEACTIVATE), lpmsg);}HRESULT COleControl::OnActivateInPlace(BOOL bUIActivate, LPMSG pMsg){m_bInPlaceSiteEx = FALSE;m_pInPlaceSite->OnInPlaceActivate();  //告诉容器要进行原地激活m_pInPlaceSite->GetWindow(&hwndParent);//获得容器窗口m_pInPlaceSite->GetWindowContext(&m_pInPlaceFrame, &m_pInPlaceDoc,&m_rcPos, &rcClip, &m_frameInfo);//获取容器实现IOleInPlaceFrame接口的对象
m_bInPlaceActive = CreateControlWindow(hwndParent, m_rcPos,rectClip);  //(1)以容器窗口为父窗口,创建控件窗口SendAdvise(OBJECTCODE_SHOWOBJECT); //(2)}(1):BOOL COleControl::CreateControlWindow(HWND hWndParent, const CRect& rcPos,LPCRECT prcClip){dwStyle = WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;dwExStyle = WS_EX_NOPARENTNOTIFY;
if ((!IsSubclassedControl() || m_bMsgReflect) && m_bAutoClip)
{ AfxDeferRegisterClass(AFX_WNDOLECONTROL_REG); //注册窗口类,见注CreateEx(dwExStyle, AFX_WNDOLECONTROL, m_strText, dwStyle,rcPos.left, rcPos.top, rcPos.Width(), rcPos.Height(),hWndParent, 0); //(1.1)
}
else
{
if (m_pReflect == NULL)
{
m_pReflect = new CReflectorWnd;
m_pReflect->Create(prcClip, hWndParent);  //创建反射通知消息的窗口
}
else if (m_pReflect->m_hWnd != NULL)//如果该窗口已经存在,则为其指定父窗口{::SetParent(m_pReflect->m_hWnd, hWndParent);::SetWindowPos(m_pReflect->m_hWnd, NULL, 0, 0, 0, 0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_SHOWWINDOW);}
if (m_pReflect != NULL && m_pReflect->m_hWnd != NULL)//成功创建反射窗口后{CreateEx(dwExStyle, NULL, m_strText, dwStyle,m_ptOffset.x, m_ptOffset.y, rcPos.Width(), rcPos.Height(),m_pReflect->m_hWnd, 0);//创建控件窗口}
}OnFontChanged(); // 设置新窗口字体(1.2)}(1.1):BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,int x, int y, int nWidth, int nHeight,HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam){PreCreateWindow(cs);//(1.1.1)AfxHookWindowCreate(this);//(1.1.2)HWND hWnd = ::AfxCtxCreateWindowEx(cs.dwExStyle, cs.lpszClass,cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);}(1.1.1):BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs){// AfxDeferRegisterClass(AFX_WND_REG);return TURE;}(1.1.2):void AFXAPI AfxHookWindowCreate(CWnd* pWnd){pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT, _AfxCbtFilterHook, NULL, ::GetCurrentThreadId());//设置窗口钩子}LRESULT CALLBACK  _AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam){ASSERT(code == HCBT_CREATEWND);CWnd* pWndInit = pThreadState->m_pWndInit;//值为 {CTZWpsSignCtrl hWnd=0x00000000}HWND hWnd = (HWND)wParam;pWndInit->Attach(hWnd);WNDPROC *pOldWndProc = pWndInit->GetSuperWndProcAddr();//返回 &m_pfnSuper;WNDPROC afxWndProc = AfxGetAfxWndProc();oldWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (DWORD_PTR)afxWndProc);//再次设置窗口钩子if (oldWndProc != afxWndProc)*pOldWndProc = oldWndProc;::UnhookWindowsHookEx(pThreadState->m_hHookOldCbtFilter);}WNDPROC AFXAPI AfxGetAfxWndProc(){return &AfxWndProc;}LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam){CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);if (pWnd == NULL || pWnd->m_hWnd != hWnd)return ::DefWindowProc(hWnd, nMsg, wParam, lParam);return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);}LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg, WPARAM wParam = 0, LPARAM lParam = 0){if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL))pWnd->m_pCtrlCont->OnUIActivate(NULL);dwStyle=0;if (nMsg == WM_INITDIALOG)_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);lResult = pWnd->WindowProc(nMsg, wParam, lParam);//该函数中负责处理映射表中的消息if (nMsg == WM_INITDIALOG)_AfxPostInitDialog(pWnd, rectOld, dwStyle);return lResult;}(1.2):void COleControl::OnFontChanged(){InvalidateControl();}void COleControl::InvalidateControl(LPCRECT lpRect, BOOL bErase){SendAdvise(OBJECTCODE_VIEWCHANGED);(1.2.1)SendAdvise(OBJECTCODE_DATACHANGED);   (1.2.2)}(1.2.1):void COleControl::SendAdvise(UINT uCode){//COleControl类内嵌的实现IViewObjectEx接口的对象m_xViewObject.GetAdvise(&aspects, &advf, &pAdvSink);  pAdvSink->OnViewChange(DVASPECT_CONTENT, -1);}STDMETHODIMP COleControl::XViewObject::GetAdvise(DWORD* pAspects, DWORD* pAdvf,LPADVISESINK* ppAdvSink){_AFXCTL_ADVISE_INFO* pAdviseInfo = pThis->m_pAdviseInfo;*pAspects = pAdviseInfo->m_dwAspects;    //DWORD类型*pAdvf = pAdviseInfo->m_dwAdvf;//DWORD类型*ppAdvSink = pAdviseInfo->m_pAdvSink;//IAdviseSink*类型}(1.2.2):void COleControl::SendAdvise(UINT uCode){//m_pDataAdviseHolder为IDataAdviseHolder * 类型m_pDataAdviseHolder->SendOnDataChange(&m_xDataObject, 0, 0);}(2):void COleControl::SendAdvise(UINT uCode){m_pClientSite->ShowObject();}注:#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister){wndcls.lpfnWndProc = DefWindowProc; //(b)wndcls.hInstance = AfxGetInstanceHandle();wndcls.hCursor = afxData.hcurArrow;if (fToRegister & AFX_WNDOLECONTROL_REG){// OLE Control windows - use parent DC for speedwndcls.style |= CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;wndcls.lpszClassName = _afxWndOleControl;//变量值为 "AfxOleControl80sd"if (AfxRegisterClass(&wndcls))//(a)fRegisteredClasses |= AFX_WNDOLECONTROL_REG;}}(a):BOOL AFXAPI AfxRegisterClass(WNDCLASS* lpWndClass){AfxCtxGetClassInfo(lpWndClass->hInstance, lpWndClass->lpszClassName, &wndcls);::AfxCtxRegisterClass(lpWndClass);}(b):LRESULT COleControl::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam){if (m_hWnd != NULL)return CWnd::DefWindowProc(nMsg, wParam, lParam);}LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam){if (m_pfnSuper != NULL)return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam);WNDPROC pfnWndProc;if ((pfnWndProc = *GetSuperWndProcAddr()) == NULL)return ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);elsereturn ::CallWindowProc(pfnWndProc, m_hWnd, nMsg, wParam, lParam);}

0 0
原创粉丝点击