WebBrowser2封装的容器收藏

  WebBrowser2封装的容器收藏

新一篇: C++和JavaScript脚本的相互调用 | 旧一篇: 关于greta正则表达式的使用

<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

最近一直都在研究关于有界面的组件如何做为主框架的子view显示出来, 终于有一些心得,在此把它贴出来供高人指点.并分享成果,难免有错误之处,因为我的水平只有这么多.

任何组件都会存在唯一的CLSID,此组件也一样存在这个ID,在工程目录下面找到和类名相同的HTM文件,运行它就是发现就是组件的界面,功能也 是组件里写的功能.HTML文件里是可以写脚本的,所以也可以把组件的事件同时抛出来,就可以使用WebBrowser2封装的容器显示此页面.由于组件 在系统里也会以HTML页面的形式呈现出来,并在WebBrowser2里显示,其实也就没有必要使用ATL做界面了,只需要使用HTML+脚本写出一个 界面,使用此容器就可以在VC的框架里正确的运行,从而实现VC和脚本的相互调用.(有关脚本和VC的相互调用参考其它文档)

容器的代码如下:

IDL

import  " oaidl.idl " ;
import 
" ocidl.idl " ;
import 
" atliface.idl " ;
#include 
" olectl.h "
    

    [
        
object ,
        uuid(0BB8B6DB
- 52F9 - 4C2A - BB04 - 5150B8FE5841),
        dual,
        helpstring(
" IATLOpener Interface " ),
        pointer_default(unique)
    ]
    
interface  IATLOpener : IDispatch  //  对外的接口
     {
        [id(
1), helpstring("method OpenURL")] HRESULT OpenURL(BSTR bstrURL);
        [id(
2), helpstring("method OpenHTML")] HRESULT OpenHTML(BSTR bstrURL);
    }
;
    

    
    [
        
object , dual,
        uuid(8F1C3679
- 9EED - 419A - 9D42 - C1B7C60E2F5B),
        helpstring(
" IATLOpenerUI Interface " ),
        pointer_default(unique)
    ]
    
interface  IATLOpenerUI : IDocHostUIHandlerDispatch         //  容器有滚动条,对脚本的接口
     {
        
// Example method that will be called by the HTML
        [id(1), helpstring("method OnClick")] HRESULT OnClick([in]IDispatch* pdispBody, [in]VARIANT varColor);
        [id(
2), helpstring("method fireEvent")] HRESULT fireEvent(BSTR bstrID, BSTR bstrValue);
    }
;

[
    uuid(370F70AC
- 6AAA - 41E9 - 980F - 14431FECBDB1),
    version(
1.0 ),
    helpstring(
" ATLMaskWrapper 1.0 Type Library " )
]
library ATLMASKWRAPPERLib
{
    importlib(
"stdole32.tlb");
    importlib(
"stdole2.tlb");

    [
        uuid(0E0D5320
-125B-4078-B002-544CC536CEF5),
        helpstring(
"_IATLOpenerEvents Interface")
    ]
    dispinterface _IATLOpenerEvents
    
{
        properties:
        methods:
        [id(
1), helpstring("method OnEvent")] HRESULT OnEvent(BSTR bstrID,BSTR bstrValue);
        [id(
2), helpstring("method OnEvent2")] HRESULT OnEvent2(BSTR bstrID,BSTR bstrValue1,BSTR bstrValue2);
        [id(
3), helpstring("method OnEvent3")] HRESULT OnEvent3(BSTR bstrID,BSTR bstrValue1,BSTR bstrValue2,BSTR bstrValue3);
        [id(
4), helpstring("method OnSetFrameTitle")] HRESULT OnSetFrameTitle(BSTR bstrFrameTitle);
    }
;

    [
        uuid(4B9529DA
-1FE1-49AC-AD51-9EAA66C97351),
        helpstring(
"ATLOpener Class")
    ]
    coclass ATLOpener
    
{
        [
defaultinterface IATLOpener;
        [
default, source] dispinterface _IATLOpenerEvents;
        
interface IATLOpenerUI;
    }
;
}
;

头文件

 

#ifndef __ATLOPENER_H_
#define  __ATLOPENER_H_

#include 
" resource.h "         //  main symbols
#include  < atlctl.h >
#include 
< MSHTMCID.H >
#include 
< MSHTMHST.h >
#include 
" ATLMaskWrapperCP.h "


/////
//  CATLOpener
class  ATL_NO_VTABLE CATLOpener : 
    
public  CComObjectRootEx < CComSingleThreadModel > ,
    
public  IDispatchImpl < IATLOpener,  & IID_IATLOpener,  & LIBID_ATLMASKWRAPPERLib > ,
    
public  IDispatchImpl < IATLOpenerUI,  & IID_IATLOpenerUI,  & LIBID_ATLMASKWRAPPERLib > ,
    
public  CComControl < CATLOpener > ,
    
public  IPersistStreamInitImpl < CATLOpener > ,
    
public  IOleControlImpl < CATLOpener > ,
    
public  IOleObjectImpl < CATLOpener > ,
    
public  IOleInPlaceActiveObjectImpl < CATLOpener > ,
    
public  IViewObjectExImpl < CATLOpener > ,
    
public  IOleInPlaceObjectWindowlessImpl < CATLOpener > ,
    
public  ISupportErrorInfo,
    
public  IConnectionPointContainerImpl < CATLOpener > ,
    
public  CComCoClass < CATLOpener,  & CLSID_ATLOpener > ,
    
public  IProvideClassInfo2Impl <& CLSID_ATLOpener,  & DIID__IATLOpenerEvents,  & LIBID_ATLMASKWRAPPERLib > ,
    
public  CProxy_IATLOpenerEvents <  CATLOpener  > ,
    
public  IObjectSafetyImpl < CATLOpener, INTERFACESAFE_FOR_UNTRUSTED_CALLER >
{
public:
    CATLOpener()
    
{
        m_bWindowOnly 
= TRUE;
        HRESULT hr 
=CoInitialize(NULL);
    }

    
~CATLOpener()
    
{
        CoUninitialize();
    }


BEGIN_CATEGORY_MAP(CATLOpener)
    IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
    IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
END_CATEGORY_MAP()

DECLARE_REGISTRY_RESOURCEID(IDR_ATLOPENER)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CATLOpener)
    COM_INTERFACE_ENTRY(IATLOpener)
    COM_INTERFACE_ENTRY(IATLOpenerUI)
    COM_INTERFACE_ENTRY2(IDispatch, IATLOpener)
    COM_INTERFACE_ENTRY(IViewObjectEx)
    COM_INTERFACE_ENTRY(IViewObject2)
    COM_INTERFACE_ENTRY(IViewObject)
    COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
    COM_INTERFACE_ENTRY(IOleInPlaceObject)
    COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
    COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
    COM_INTERFACE_ENTRY(IOleControl)
    COM_INTERFACE_ENTRY(IOleObject)
    COM_INTERFACE_ENTRY(IPersistStreamInit)
    COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
    COM_INTERFACE_ENTRY(ISupportErrorInfo)
    COM_INTERFACE_ENTRY(IConnectionPointContainer)
    COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
    COM_INTERFACE_ENTRY(IProvideClassInfo)
    COM_INTERFACE_ENTRY(IProvideClassInfo2)
    COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()

BEGIN_PROP_MAP(CATLOpener)
    PROP_DATA_ENTRY(
"_cx", m_sizeExtent.cx, VT_UI4)
    PROP_DATA_ENTRY(
"_cy", m_sizeExtent.cy, VT_UI4)
    
// Example entries
    
// PROP_ENTRY("Property Description", dispid, clsid)
    
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()

BEGIN_CONNECTION_POINT_MAP(CATLOpener)
CONNECTION_POINT_ENTRY(DIID__IATLOpenerEvents)
END_CONNECTION_POINT_MAP()

BEGIN_MSG_MAP(CATLOpener)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    CHAIN_MSG_MAP(CComControl
<CATLOpener>)
END_MSG_MAP()
// Handler prototypes:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);



// ISupportsErrorInfo
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
    
{
        
static const IID* arr[] = 
        
{
            
&IID_IATLOpener,
        }
;
        
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
        
{
            
if (InlineIsEqualGUID(*arr[i], riid))
                
return S_OK;
        }

        
return S_FALSE;
    }


// IViewObjectEx
    DECLARE_VIEW_STATUS(0)

// IDispatch 一定要重载,否则脚本找不到接口
public:
    STDMETHOD (GetIDsOfNames) (REFIID riid,
        LPOLESTR
* rgszNames,
        UINT cNames,
        LCID lcid,
        DISPID
* rgdispid);
    
    STDMETHOD (Invoke) (DISPID dispidMember,
        REFIID riid,
        LCID lcid,
        WORD wFlags,
        DISPPARAMS
* pdispparams,
        VARIANT
* pvarResult,
        EXCEPINFO
* pexcepinfo,
        UINT
* puArgErr);

    
// IATLOpener
public:
    STDMETHOD(OpenURL)(BSTR bstrURL);

// IATLOpenerUI
public:
    
// Example method called by the HTML to change the <BODY> background color
    STDMETHOD(OnClick)(IDispatch* pdispBody, VARIANT varColor);

public:
    LRESULT OnCreate(UINT 
/*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);

public:
    STDMETHOD(fireEvent)(BSTR bstrID, BSTR bstrValue);
    CComPtr
<IWebBrowser2> m_spBrowser;

// IDocHostUIHandlerDispatch
public:
    STDMETHOD(OpenHTML)(BSTR bstrURL);
    STDMETHOD (ShowContextMenu) (
        
/* [in] */ DWORD dwID,
        
/* [in] */ DWORD x,
        
/* [in] */ DWORD y,
        
/* [in] */ IUnknown  *pcmdTarget,
        
/* [in] */ IDispatch *pdispReserved,
        
/* [retval][out] */ HRESULT  *dwRetVal)
    
{
        
#define IDR_BROWSE_CONTEXT_MENU  24641
                
        
#define IDM_REFRESH2    6042
        
#define IDM_SAVEASDESKTOPITEM 2278
        
#define IDM_SEPARATOR      0
        
#define IDM_SEPARATOR2     6047
        
        HRESULT hr;
        HINSTANCE hinstSHDOCLC;
        HWND hwnd;
        HMENU hMenuParent, hMenu;
        CComPtr
<IOleCommandTarget> spCT;
        CComPtr
<IOleWindow> spWnd;
        MENUITEMINFO mii 
= {0};
        CComVariant var, var1, var2;
        
        hr 
= pcmdTarget->QueryInterface(IID_IOleCommandTarget, reinterpret_cast< void ** > (&spCT));
        hr 
= spCT->QueryInterface(IID_IOleWindow, reinterpret_cast< void ** > (&spWnd));
        hr 
= spWnd->GetWindow(&hwnd);
        
        hinstSHDOCLC 
= LoadLibrary(TEXT("SHDOCLC.DLL"));
        
        
if (hinstSHDOCLC == NULL)
        
{
            
// Error loading module -- fail as securely as possible
            return S_FALSE;
        }

        
        hMenuParent 
= LoadMenu(hinstSHDOCLC,
            MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU));
        
        
if (dwID == 5//anchor
            hMenu = GetSubMenu(hMenuParent, static_cast< int > (0));
        
else
            hMenu 
= GetSubMenu(hMenuParent, static_cast< int > (dwID));
        
        
// Remove View Source
        DeleteMenu(hMenu, IDM_REGISTRYREFRESH, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_REFRESH, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_REFRESH2, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_PROPERTIES, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_ADDFAVORITES, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_CREATESHORTCUT, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_VIEWSOURCE, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_LANGUAGE, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_GOBACKWARD, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_GOFORWARD, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_SAVEBACKGROUND, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_SETWALLPAPER, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_COPYBACKGROUND, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_SAVEASDESKTOPITEM, MF_BYCOMMAND);
        DeleteMenu(hMenu, IDM_PRINT, MF_BYCOMMAND);
        
        
        
int iItemCount = GetMenuItemCount(hMenu)-1;
        
for(int i=iItemCount; i>=0; i--)
        
{
            
if(GetMenuItemID(hMenu,i) == IDM_SEPARATOR || GetMenuItemID(hMenu,i) == IDM_SEPARATOR2)
            
{
                
if(i==0)
                    DeleteMenu(hMenu, i, MF_BYPOSITION);
                
else if(GetMenuItemID(hMenu,i-1== IDM_SEPARATOR || GetMenuItemID(hMenu,i-1== IDM_SEPARATOR2)
                    DeleteMenu(hMenu, i, MF_BYPOSITION);
            }

            
        }

        iItemCount 
= GetMenuItemCount(hMenu)-1;
        
if(GetMenuItemID(hMenu,iItemCount) == IDM_SEPARATOR || GetMenuItemID(hMenu,iItemCount) == IDM_SEPARATOR2)
            DeleteMenu(hMenu, iItemCount, MF_BYPOSITION);
        
        
        
// Show shortcut menu
        int iSelection = ::TrackPopupMenu(hMenu,
            TPM_LEFTALIGN 
| TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
            x,
            y,
            
0,
            hwnd,
            (RECT
*)NULL);
        
        
// Send selected shortcut menu item command to shell
        LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(LOWORD(iSelection), 0x0), 0);
        
        ::DestroyMenu( hMenuParent );
        
        FreeLibrary(hinstSHDOCLC);
        
        
if (iSelection != 31//if not select all
        {
            SetFocus();
        }

        
//--------
        
        
*dwRetVal = S_OK;
        
return S_OK;
    }


    STDMETHOD (GetHostInfo) (
        
/* [out][in] */ DWORD  *pdwFlags,
        
/* [out][in] */ DWORD  *pdwDoubleClick)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (ShowUI) (
        
/* [in] */ DWORD dwID,
        
/* [in] */ IUnknown  *pActiveObject,
        
/* [in] */ IUnknown  *pCommandTarget,
        
/* [in] */ IUnknown  *pFrame,
        
/* [in] */ IUnknown  *pDoc,
        
/* [retval][out] */ HRESULT  *dwRetVal)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (HideUI) (
void)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (UpdateUI) (
void)
    
{
        
return E_NOTIMPL;
    }


    STDMETHOD (EnableModeless) (
        
/* [in] */ VARIANT_BOOL fEnable)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (OnDocWindowActivate) (
        
/* [in] */ VARIANT_BOOL fActivate)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (OnFrameWindowActivate) (
        
/* [in] */ VARIANT_BOOL fActivate)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (ResizeBorder) (
        
/* [in] */ long left,
        
/* [in] */ long top,
        
/* [in] */ long right,
        
/* [in] */ long bottom,
        
/* [in] */ IUnknown  *pUIWindow,
        
/* [in] */ VARIANT_BOOL fFrameWindow)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (TranslateAccelerator) (
        
/* [in] */ DWORD hWnd,
        
/* [in] */ DWORD nMessage,
        
/* [in] */ DWORD wParam,
        
/* [in] */ DWORD lParam,
        
/* [in] */ BSTR bstrGuidCmdGroup,
        
/* [in] */ DWORD nCmdID,
        
/* [retval][out] */ HRESULT  *dwRetVal)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (GetOptionKeyPath) (
        
/* [out] */ BSTR  *pbstrKey,
        
/* [in] */ DWORD dw)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (GetDropTarget) (
        
/* [in] */ IUnknown  *pDropTarget,
        
/* [out] */ IUnknown  **ppDropTarget)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (GetExternal) (
        
/* [out] */ IDispatch  **ppDispatch)
    
{
        
//return E_NOTIMPL;
        return QueryInterface(IID_IATLOpenerUI,(void**)ppDispatch);
    }



    STDMETHOD (TranslateUrl) (
        
/* [in] */ DWORD dwTranslate,
        
/* [in] */ BSTR bstrURLIn,
        
/* [out] */ BSTR  *pbstrURLOut)
    
{
        
return E_NOTIMPL;
    }



    STDMETHOD (FilterDataObject) (
        
/* [in] */ IUnknown  *pDO,
        
/* [out] */ IUnknown  **ppDORet)
    
{
        
return E_NOTIMPL;
    }

}
;

#endif   // __ATLOPENER_H_

CPP文件

 

#include  " stdafx.h "
#include 
" ATLMaskWrapper.h "
#include 
" ATLOpener.h "
#include 
" PrepareHtml.h "

typedef IDispatchImpl
< IATLOpener,  & IID_IATLOpener,  & LIBID_ATLMASKWRAPPERLib >  ATLOpenerType;
typedef IDispatchImpl
< IATLOpenerUI,  & IID_IATLOpenerUI,  & LIBID_ATLMASKWRAPPERLib >  ATLOpenerUIType;
const  DISPID INTERFACEMASK  =   0xFFFF0000 ;
const  DISPID DISPIDMASK   =   0x0000FFFF ;
const  DISPID IDISPATLOPENER  =   0x00010000 ;
const  DISPID IDISPATLOPENERUI  =   0x00020000 ;

/////
//  CATLOpener
STDMETHODIMP CATLOpener::GetIDsOfNames(REFIID riid,
                                    LPOLESTR
*  rgszNames,
                                    UINT cNames,
                                    LCID lcid,
                                    DISPID
*  rgdispid)
{
    HRESULT hr 
= DISP_E_UNKNOWNNAME;

    hr 
= ATLOpenerType::GetIDsOfNames(riid,
        rgszNames, cNames, lcid, rgdispid);
    
if (SUCCEEDED(hr))
    
{
        rgdispid[
0|= IDISPATLOPENER;
        
return hr;
    }


    hr 
= ATLOpenerUIType::GetIDsOfNames(riid,
        rgszNames,
        cNames,
        lcid,
        rgdispid);
    
if (SUCCEEDED(hr))
    
{
        rgdispid[
0|= IDISPATLOPENERUI;
        
return hr;
    }


    
return hr;
}


STDMETHODIMP CATLOpener::Invoke(DISPID dispidMember,
                             REFIID riid,
                             LCID lcid,
                             WORD wFlags,
                             DISPPARAMS
*  pdispparams,
                             VARIANT
*  pvarResult,
                             EXCEPINFO
*  pexcepinfo,
                             UINT
*  puArgErr)
{
    DWORD dwInterface 
= (dispidMember & INTERFACEMASK);
    dispidMember 
&= DISPIDMASK;

    
switch(dwInterface)
    
{

    
case IDISPATLOPENERUI:
        
return ATLOpenerUIType::Invoke(dispidMember,
            riid,
            lcid,
            wFlags,
            pdispparams,
            pvarResult,
            pexcepinfo,
            puArgErr);

    
case IDISPATLOPENER:
    
default:
        
//return DISP_E_MEMBERNOTFOUND;
        return ATLOpenerType::Invoke(dispidMember,
            riid,
            lcid,
            wFlags,
            pdispparams,
            pvarResult,
            pexcepinfo,
            puArgErr);
    }


}


STDMETHODIMP CATLOpener::OnClick(IDispatch
*  pdispBody, VARIANT varColor)
{
    CComQIPtr
<IHTMLBodyElement> spBody(pdispBody);
    
if (spBody != NULL)
        spBody
->put_bgColor(varColor);
    
return S_OK;
}


LRESULT CATLOpener::OnCreate(UINT 
/*uMsg*/ , WPARAM  /*wParam*/ , LPARAM  /*lParam*/ , BOOL &   /*bHandled*/ )
{
    CAxWindow wnd(m_hWnd);
    HRESULT hr 
= wnd.CreateControl(IDH_ATLOPENER);
    
if (SUCCEEDED(hr))
    
{
        
// 有滚动条
        CComQIPtr<IDocHostUIHandlerDispatch> pIUI(static_cast<IDocHostUIHandlerDispatch*>(this));
        hr 
= wnd.SetExternalUIHandler(pIUI);
        
// 无滚动条
//        hr = wnd.SetExternalDispatch(static_cast<IATLOpenerUI*>(this));
    }


    
if (SUCCEEDED(hr))
    
{
        hr 
= wnd.QueryControl(IID_IWebBrowser2, (void**)&m_spBrowser);
    }

    
return SUCCEEDED(hr) ? 0 : -1;
}


STDMETHODIMP CATLOpener::OpenURL(BSTR bstrURL) 
//  显示组件界面
{
    
// TODO: Add your implementation code here
    HRESULT hr = NULL;

    hr 
= m_spBrowser->Navigate(bstrURL, NULL, NULL, NULL, NULL);

    
if (hr != S_OK)
    
{
        MessageBox(
"Navigate failed!");
    }


    
return S_OK;
}


STDMETHODIMP CATLOpener::fireEvent(BSTR bstrID, BSTR bstrValue) 
//  脚本抛事件
{
    
// TODO: Add your implementation code here
    Fire_OnEvent(bstrID,bstrValue);
    
return S_OK;
}


STDMETHODIMP CATLOpener::OpenHTML(BSTR bstrURL) 
//  显示HTML页面
{
    
// TODO: Add your implementation code here
    CPrepareHtml Prepare;
    Prepare.Prepare(bstrURL);

    
return S_OK;
}

发表于 @ 2008年02月18日 10:30:00|评论(3<script type="text/javascript">AddFeedbackCountStack("2102339")</script>)|编辑

新一篇: C++和JavaScript脚本的相互调用 | 旧一篇: 关于greta正则表达式的使用

评论

# kevenquwei 发表于2008-03-06 10:03:34  IP: 218.249.36.*
收益了!谢谢
# chenge1980 发表于2008-05-26 09:16:33  IP: 218.108.51.*
对ATL不大了解,源码好像少了几个头文件,可否将联系方式告知 chenge@miacisoft.com

Thanks
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值