网页调用ActiveX,在同一页面中切换时会死掉,cpu占50%。 在新窗口中调用没有问题。应该是共享变量的问题下面是引用网上一个人的话“如果在两个IE中运行,每一个IE就会把控件当作一个进程来执行,两个IE中的控件就是两个独立的进程,相互之间没有任何关系,但同一个IE的不同TAB时,IE则开一个进程,把打开的多个控件分别当作一个线程,那么此时问题就来了,多个线程之间会共享资源的,在我的控件中,引起问题的就是全局变量问题。”    我之前曾经删除过一个全局对象,然后给同事在网页上用这个控件,他说没问题了。我当时挺高兴。后来那又告诉我又有问题了。    我又检查了一下我的代码 。发现还有两处共享数据。分别是: 
  typedef struct _value{
double dValue;
CTime ValueTime;
}value;typedef struct{
void (*GetData)(CTime beginTime,CTime endTime,unsigned long param);
unsigned long param;
}GETDATA_T;
一个是全局结构体,一个是回调函数。  全局结构体 不方便 定义成局部的, 要改的太多了。 这个回调函数我也不知道能不能写成局部了,不太用回调函数。    大家帮我分析分析, IE卡死的原因会是上面的全局结构体和 回调函数引起的吗?

解决方案 »

  1.   


    rendao0563高手你终于出现了,我都想死你了。
    回调函数我已经成员化了。 之前有很多全局结构体, 我都成员化了。就差上面的一个了。我正努力呢。要改的地方比较多。
      

  2.   

    网页调用ActiveX,在同一窗口中切换时会死掉,cpu占50% 这个还记得吗。 你说加分回答我。我又加了20分。等你几天。你也没有回答我
      

  3.   

    //*******************************************************************************************************/
    //* FileName        : clPlot.h
    //*
    //* Description     : Real Time Plot for MFC
    //*
    //* Contents: : axis y (x) axis info.
    //*   timeaxis time axis info
    //*   legend legend info.
    //*   serie data serie info & array
    //*   clPlot The plot itself.
    //*
    //* Author          : Jan Vidar Berger
    //*******************************************************************************************************/
    #if !defined(AFX_DQPLOT_H__0D536D37_5CF1_11D1_AED1_0060973A08A4__INCLUDED_)
    #define AFX_DQPLOT_H__0D536D37_5CF1_11D1_AED1_0060973A08A4__INCLUDED_
    #pragma warning(disable:4786)
    #if _MSC_VER >= 1000
    #pragma once
    #endif // _MSC_VER >= 1000
    // clPlot.h : header file
    //
    #include <vector>
    #include <set>
    #include <math.h>
    using namespace std;
    //#define MAXSERIES 5
    #define MAXSERIES 10//add//*******************************************************************************************************/
    //* simple data value struct. used in dynamic array
    //*******************************************************************************************************/
    typedef struct _value{
    double dValue;
    CTime ValueTime;
    }value;class axis  
    {
    public:
    CString szTitle;
    double minrange[MAXSERIES];
    double maxrange[MAXSERIES];
    double m_dValuePrPixel[MAXSERIES];
    double min_range;
    double max_range;
    double m_dValPrPixel;
    axis()
    {
    szTitle  = "Title";

    min_range = 0.0;
    max_range = 0.0;
    m_dValPrPixel = 0.0; for ( int i = 0 ;i<MAXSERIES; i++ )//shixi
    {
    minrange[i] = 0.0;
    maxrange[i] = 6.0;
    m_dValuePrPixel[i] = 1;
    }
    };
    };//*******************************************************************************************************/
    //* time axis
    //*******************************************************************************************************/
    class  timeaxis
    {
    public:
    CString m_szTitle; // time axis title;
    CTime m_mintime; // min time
    CTime m_maxtime; // max time
    int m_iTimeMode; // axis grid and legend interval index double m_dSecondsPrPixel;
    timeaxis()
    {
    m_szTitle = "Time";
    m_mintime = 0;
    m_maxtime = 600;
    m_iTimeMode=0;
    m_dSecondsPrPixel=1;
    }
    };//*******************************************************************************************************/
    //* data serie
    //*******************************************************************************************************/
    //定义一个时间索引
    typedef set<value> TIMEINDEX;
    inline bool operator <( value v1, value v2)
    {
    if(v1.ValueTime < v2.ValueTime)
    return true;
    else
    return false;
    };class  serie
    {
    public:

    value * GetValueByTime(CTime valuetime,CTimeSpan ts);
    int Min();
    int Max();
    int CurrentRange(int &nMinVar,int &nMaxVar,CTime &MinTime,CTime &MaxTime);
    int Average();
    BOOL        m_bShow24Data;
    BOOL m_bDisplay; //is serie dispaly
    BOOL m_bIAmInUse; //is serie use
    COLORREF m_color;    // serie line color
    int m_iLineStyle;    // line style
    BOOL m_bRightAxisAlign; // align to right axis
    long m_lSize;     // 数组大小,实际数组大小减一
    void    SetTitle(CString title) { m_Title = title; };
    CString GetTitle() { return m_Title; };
    //显示时间也当前时间的时间差
    CTimeSpan m_TimeSpan;
    TIMEINDEX m_TimeIndexValue;
    serie();
    ~serie();
    value *GetValue(CTime mintime,unsigned nLeftX,double SecondsPrPixel,unsigned int nSecsInterval,CPoint point);
    void AddPoint(CTime &valuetime, double &y);
    void Reset();
    private:
    CString m_Title;
    _int64 m_minval;
    _int64 m_maxval;
    double m_averageval;
    };//*******************************************************************************************************/
    //* Class           : clPlot
    //*
    //* Base Class      : public CWnd
    //*
    //* Description     : Plot Component.
    //*
    //*   This is a standard plot and can be used for any application.
    //*
    //* 1. A special 'autoscroll'mode exist for real time plots.
    //* 2. Only a minimum of features are implemented.
    //* 3. Series and legends are separated and must be set up individually.
    //* 4. A set of defines (see top of file) are used to set the max array sizes.
    //* 5. Only time are supported as x-axis.
    //* 6. A large range of pre-calculated values are used for maximum speed.
    //*
    //* Author          : Jan Vidar Berger
    //*******************************************************************************************************/
    //typedef struct{
    // int nSub;
    // CString strTitle;
    // COLORREF color;
    // int nMin;
    // int nMax;
    // double nAverage;
    //}BOTTOMTIP;typedef struct{
    CString strMsg;
    COLORREF color;
    }TIPMSG_T;typedef struct{
    void (*GetData)(CTime beginTime,CTime endTime,unsigned long param);
    unsigned long param;
    }GETDATA_T;//typedef vector<BOTTOMTIP> BOTTOMMSG;
    class CKeyboardHook;
    class  clPlot : public CWnd
    {
    // Construction
    public:
    clPlot();
    virtual ~clPlot();
    // Attributes
    private:
    int  m_xPosition;
    bool m_bDiffTime;
    int m_iSecsInterval; // 读取数据的时间间隔
    int         m_iSecsInterval2;   //用于缩放时用的标度
    CTime m_plotMinTime; //所有线中最小时间
    CPoint      m_CurrentPosition;  //十字架的位置
    CPoint m_CursorPosition;   //移动鼠标前的光标位置 int         m_serie;            //shixi
    bool        m_bRButtonUp;
    bool m_bMouseWheel; int         m_curveType;public:
    GETDATA_T m_pGetData;
    CRect m_ctlRect; // control rect
    CRect m_clientRect; // ctlRect - borderspace
    CRect m_plotRect; // clientRect - margins
    CRect m_axisLYRect; // Left axisi rect
    CRect m_axisRYRect; // right y axis
    CRect m_axisBXRect; // bottom x axis int m_iMleft; // left margin
    int m_iMright; // right margin
    int m_iMtop; // top margin
    int m_iMbottom; // bottom margin COLORREF m_ctlBkColor; // control background color
    COLORREF m_plotBkColor; // plot bacground color
    COLORREF m_gridColor; // grid line color BOOL m_bctlBorder; // control border
    BOOL m_bplotBorder; // plot border
    BOOL m_bAxisLY; // left axis
    BOOL m_bAxisRY; // right axis
    BOOL m_bAxisBX; // bottom axis
    BOOL m_bAutoScrollX; // automatic x range scrolling
    BOOL m_bSimMode; // simulate data input
    int m_iViewflag; //0显示提示信息,其它为不显示 static long m_lMaxDataPrSerie; // max allowed data pr. serie.
    static long m_lMaxDataTotal; // max allowed data total.

    serie m_series[MAXSERIES];
    axis m_leftaxis; // left axis
    axis m_rightaxis; // right axis
    timeaxis m_timeaxis; // bottom axis CFont m_font;
    LOGFONT m_logFont;
    LOGFONT m_zoomFont;
    double m_dzoom;
    int m_TextHeight; //BOTTOMMSG m_vecBottomMsg;
    CString m_strTitle; //曲线图上面显示的文字
    HCURSOR m_hCursor;
    HCURSOR m_hCursorHand;
    HCURSOR m_hCursorLast;
    BOOL m_bTracking;
    //测试
    int m_testType;public:
    typedef struct{
    int nSub;
    CString strTitle;
    COLORREF color;
    int nMin;
    int nMax;
    double nAverage;
    }BOTTOMTIP;
    typedef vector<BOTTOMTIP> BOTTOMMSG;
    BOTTOMMSG m_vecBottomMsg;// Operations
    public:
    BOOL Create(DWORD dwstyle, CRect &rect, CWnd *pParent, UINT id);
    void MoveWindow(CRect &Rect);
    CTime GetTime(CPoint point);
    virtual void Draw(CDC * dc); // Draw the entire plot
    virtual void DrawBasic(CDC * hdc); // Draw plot basics
    virtual void DrawPlot(CDC * dc); // Draw the plot series
    virtual void DrawSerie(CDC *dc, int serie);
    virtual void DrawGrid(CDC * dc); // Draw grids
    void SetPlotTitle(CString strTitle);
    virtual void DrawYAxisGrid(CDC * dc);
    virtual void DrawXAxisGrid(CDC * dc);
    void DrawTipMsg(CDC *dc);
    void ShowRectTip(CDC *dc,CPoint point );
     
    vector<TIPMSG_T> DrawTipRect(CDC *dc,CTime m_tipTime  );

    void DrawTopTitle(CDC * dc);
    void DrawBottomTip(CDC * dc);
    bool Zoom(bool direct,CPoint pt,int times = 1);
    void MoveTimeLine(int key); virtual void ComputeRects(BOOL bInitialize); virtual BOOL AddPoint(int serie, CTime &valuetime, double &y, int tag );
    virtual void SetBXRange(CTime &fromtime, CTime &totime,BOOL bMove=TRUE);
    virtual void SetLYRange();
    virtual void SetRYRange();
    virtual void SetSerie(int s, int style, COLORREF color, double minrange, double maxrange, const char *szTitle, BOOL Rightalign = FALSE, BOOL bOnlyDay = TRUE,CTimeSpan timeSpan=0); void ChartClean();//shixi at 2009.07.28
    bool m_bTag;
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(clPlot)
    //}}AFX_VIRTUAL// Implementation
    public:
    void SetViewFlag(int iViewFlag); //iViewFlag=0显示提示信息,其它为不显示
    void SetInterval(int nInterval);
    int GetInterval(){return m_iSecsInterval;};
    BOOL SetSerieDispaly(int s,BOOL bDispaly);
    void SetDataCallBack(GETDATA_T DataCallBack);
    COLORREF GetBKColor();
    void SetBKColor(COLORREF BGColor);
    int GetCurrentRange(int &nMinVar,int &nMaxVar);
    // Generated message map functions
    protected:
    //{{AFX_MSG(clPlot)
    afx_msg void OnPaint();
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnRButtonDown( UINT nFlags, CPoint point );
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnRButtonUp( UINT nFlags, CPoint point );
    //}}AFX_MSG
    BOOL clPlot::OnEraseBkgnd(CDC* pDC) ;
    DECLARE_MESSAGE_MAP()

    public:
    afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    LRESULT OnMouseLeave(WPARAM wparam, LPARAM lparam);
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Developer Studio will insert additional declarations immediately before the previous line.#endif // !defined(AFX_DQPLOT_H__0D536D37_5CF1_11D1_AED1_0060973A08A4__INCLUDED_)
      

  4.   


    #pragma once#ifdef L_IMPL_OBJECTSAFETY
    #include <objsafe.h>
    #endif // L_IMPL_OBJECTSAFETY
    // CurveChartCtrl.h : CCurveChartCtrl ActiveX 控件类的声明。
    #include "clPlot.h"// CCurveChartCtrl : 有关实现的信息,请参阅 CurveChartCtrl.cpp。#include "CriticalSec.h"#include <vector>
    using namespace std;class CCurveChartCtrl : public COleControl
    {
    DECLARE_DYNCREATE(CCurveChartCtrl)public:
    #ifdef L_IMPL_OBJECTSAFETY 
    BEGIN_INTERFACE_PART(ObjectSafety, IObjectSafety)
    STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions);
    STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions);
    END_INTERFACE_PART(ObjectSafety)
    DECLARE_INTERFACE_MAP();
    #endif // L_IMPL_OBJECTSAFET// 构造函数
    public:
    CCurveChartCtrl();// 重写
    public:
    virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
    virtual void DoPropExchange(CPropExchange* pPX);
    virtual void OnResetState();
    virtual int OnCreate(LPCREATESTRUCT lpCreateStruct);// 实现
    protected:
    ~CCurveChartCtrl();

    DECLARE_OLECREATE_EX(CCurveChartCtrl)    // 类工厂和 guid
    DECLARE_OLETYPELIB(CCurveChartCtrl)      // GetTypeInfo
    DECLARE_PROPPAGEIDS(CCurveChartCtrl)     // 属性页 ID
    DECLARE_OLECTLTYPE(CCurveChartCtrl) // 类型名称和杂项状态
    protected:
    // 消息映射
    DECLARE_MESSAGE_MAP()// 调度映射
    DECLARE_DISPATCH_MAP() afx_msg void AboutBox();
    afx_msg void OnTimer(UINT nIDEvent);// 事件映射
    DECLARE_EVENT_MAP()// 调度和事件 ID
    public:
    GETDATA_T m_GetDataCallback;private:
    clPlot m_Plot;
    char m_szSoapEndPoint[256];
    BOOL m_bInitChart;
    BOOL m_bCreateChart;
    BOOL m_bInitData;
    int m_nChartID;
    time_t m_LastPointTime;
    time_t m_MinTime;
    CString m_strCurveTitle;
    int m_nLineType;
    int m_nItem;
    int m_nChartType;
    int m_nTypeFlag;
    int m_nItemIndex;
    int m_IntervalBase;
    char m_szVerify[64];
    HCURSOR m_hCurBusy;
    CTime m_starttime;
    CTime m_endtime;

    list<CString>     m_listStr;
    CCriticalSec m_lock; int m_curveType;
    int m_num;
    CString m_strTitle; CTime m_plotMinTime; //所有线中最小时间
    CTime m_axisMinTime;
    int     m_timeSpan;
    int m_dataType; BOOL m_bCreateThread;public:
    typedef struct
    {
    CTime begin;
    CTime end;
    }STRUCT_TIME;public:
    //静态成员函数与普通成员函数的差别就在于缺少this指针,没有这个this指针自然也就无从知道name是哪一个对象的成员了。
    static void OnDataLoad(CTime begin,CTime end,unsigned long param);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    protected: enum 
    {
    dispidTest = 4L, dispidInitChart = 4L, dispidCurveNoTrend = 5L, eventidOnChange = 1L, dispidConsumeChart = 4L, dispidInitEx_1 = 3L, dispidInitialize = 2L, dispidInit = 1L
    };
    public:
    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); virtual BOOL PreTranslateMessage(MSG* pMsg);
    virtual HRESULT accSelect(long flagsSelect, VARIANT varChild);
    virtual HRESULT get_accFocus(VARIANT *pvarChild);
    virtual DWORD GetControlFlags();
    afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
    afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);public:
    void GetDisplayData( LPCTSTR strVal); 
    void ProcessArriveData(int i, CTime tt, double v);
    CTime ConvertTime(CString t); 
    LONG InitChartData();protected:
    LONG DrawCurveChart(LPCTSTR val);
    public:
    virtual void OnSetClientSite();
    protected: void OnChange(LONG BeginTime, LONG EndTime)
    {
    FireEvent(eventidOnChange, EVENT_PARAM(VTS_I4 VTS_I4), BeginTime, EndTime);
    }
    LONG InitChart(LONG type, LONG dataType, LONG num, LONG timeSpan, LPCTSTR title);
    BSTR Test( LONG type );
    };DWORD WINAPI RecvData(LPVOID pParam);//声明线程
      

  5.   

    你看我的初始化和回收资源的目的是要看里面有没有全局变量吗? 我确定里面没有,现在有的全局变量就是clPlot.h里面的 结构体和全回调函数。 
        我今天上午已经把所有的结构体和一个 回调函数成员化了。 可是还是有同样的问题。 并且还带来了其它的问题。所以我又改回来了。    所以我说我已经没有什么办法了。 如果实在没什么办法,那就只有打开一个页面就重新弹出一个窗口了。
      

  6.   

    你不会先本地啊。或者让他在web上提供一个ftp。你直接上传文件。
      

  7.   

    当然是本地。你真搞。即使你本地没有也是远程下载下来注册在使用。肯定是本地。难道你还真以为是远程用他的dll?
      

  8.   

    你没明白我的意思。 现在有两种情况:情况一: 用我本地的ActiveX,不下载。  不死IE
    情况二: 远程下载同样的ActiveX.  死IE原因在哪里呢?
      

  9.   

    路径有问题吗?你的ActiveX对别的dll之类有依赖吗。
      

  10.   

    不 依赖DLL。,路径是否有问题我不知道 ,我第一次做ActiveX控件,第一次和做web的人合作,没什么经验。 没加数字签名。我问了一个同事。他说数字签名好像不影响,他的回复是“那个只是安装的时候是否弹出提示框,你现在每次都要提示的”
      

  11.   

    你让他加一个数字签名试试。 不要听信别人扯淡的话。 试过再说。
    你的ActiveX实现safety相关了没?情况一: 用我本地的ActiveX,不下载。  不死IE 
    情况二: 远程下载同样的ActiveX.  死IE 上面2个你没有说明怎么死的。是指你打开多个页面。还是单个就死?
      

  12.   

    情况一: 用我本地的ActiveX,不下载。  不死IE 
    情况二: 远程下载同样的ActiveX.  死IE 情况一在什么情况下都不死。就是有一个页面。上面有几个链接 比如:曲线1。曲线2。如果现在显示的是曲线1. 我再点  曲线2 的话。 情况二就会死(弹出新窗口打开不死,在同一窗口中打开会死)。
    数字签名这个。我叫他加。看能不能加上。你的ActiveX实现safety相关了没? 这个概念我没听过。所以实现没实现我还不知道 。
      

  13.   

    activex中实现iobjectsafety
    mfc实现头文件部分
    代码转过来的。 你弄弄看好了。 你说的那个假死我也碰到过。不过我IE设置完以后就不再出现了。
    因为不同IE安全设置还不同。所以这个接口能实现还是实现一下。------------------------------------------------------------------ DECLARE_INTERFACE_MAP() BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety) 
    STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) ( 
    /* [in] */ REFIID riid, 
    /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, 
    /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions 
    ); STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) ( 
    /* [in] */ REFIID riid, 
    /* [in] */ DWORD dwOptionSetMask, 
    /* [in] */ DWORD dwEnabledOptions 
    ); 
    END_INTERFACE_PART(ObjSafe); ------------------------------------------------------------------- 
    实现部分 
    ------------------------------------------------------------------- 
    BEGIN_INTERFACE_MAP( CJyocxsafeCtrl, COleControl ) 
    INTERFACE_PART(CJyocxsafeCtrl, IID_IObjectSafety, ObjSafe) 
    END_INTERFACE_MAP() ///////////////////////////////////////////////////////////////////////////// 
    // IObjectSafety member functions // Delegate AddRef, Release, QueryInterface ULONG FAR EXPORT CJyocxsafeCtrl::XObjSafe::AddRef() 

    METHOD_PROLOGUE(CJyocxsafeCtrl, ObjSafe) 
    return pThis->ExternalAddRef(); 
    } ULONG FAR EXPORT CJyocxsafeCtrl::XObjSafe::Release() 

    METHOD_PROLOGUE(CJyocxsafeCtrl, ObjSafe) 
    return pThis->ExternalRelease(); 
    } HRESULT FAR EXPORT CJyocxsafeCtrl::XObjSafe::QueryInterface( 
    REFIID iid, void FAR* FAR* ppvObj) 

    METHOD_PROLOGUE(CJyocxsafeCtrl, ObjSafe) 
    return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); 
    } const DWORD dwSupportedBits = 
    INTERFACESAFE_FOR_UNTRUSTED_CALLER | 
    INTERFACESAFE_FOR_UNTRUSTED_DATA; 
    const DWORD dwNotSupportedBits = ~ dwSupportedBits; ///////////////////////////////////////////////////////////////////////////// 
    // CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions 
    // Allows container to query what interfaces are safe for what. We're 
    // optimizing significantly by ignoring which interface the caller is 
    // asking for. 
    HRESULT STDMETHODCALLTYPE 
    CJyocxsafeCtrl::XObjSafe::GetInterfaceSafetyOptions( 
    /* [in] */ REFIID riid, 
    /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, 
    /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions) 

    METHOD_PROLOGUE(CJyocxsafeCtrl, ObjSafe) HRESULT retval = ResultFromScode(S_OK); // does interface exist 
    IUnknown FAR* punkInterface; 
    retval = pThis->ExternalQueryInterface(&riid, 
    (void * *)&punkInterface); 
    if (retval != E_NOINTERFACE) { // interface exists 
    punkInterface->Release(); // release it--just checking! 
    } // we support both kinds of safety and have always both set, 
    // regardless of interface 
    *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits; return retval; // E_NOINTERFACE if QI failed 
    } ///////////////////////////////////////////////////////////////////////////// 
    // CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions 
    // Since we're always safe, this is a no-brainer-- but we do check to make 
    // sure the interface requested exists and that the options we're asked to 
    // set exist and are set on (we don't support unsafe mode). 
    HRESULT STDMETHODCALLTYPE 
    CJyocxsafeCtrl::XObjSafe::SetInterfaceSafetyOptions( 
    /* [in] */ REFIID riid, 
    /* [in] */ DWORD dwOptionSetMask, 
    /* [in] */ DWORD dwEnabledOptions) 

    METHOD_PROLOGUE(CJyocxsafeCtrl, ObjSafe) // does interface exist 
    IUnknown FAR* punkInterface; 
    pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface); 
    if (punkInterface) { // interface exists 
    punkInterface->Release(); // release it--just checking! 

    else { // interface doesn't exist 
    return ResultFromScode(E_NOINTERFACE); 
    } // can't set bits we don't support 
    if (dwOptionSetMask & dwNotSupportedBits) { 
    return ResultFromScode(E_FAIL); 
    } // can't set bits we do support to zero 
    dwEnabledOptions &= dwSupportedBits; 
    // (we already know there are no extra bits in mask ) 
    if ((dwOptionSetMask & dwEnabledOptions) != 
    dwOptionSetMask) { 
    return ResultFromScode(E_FAIL); 
    } // don't need to change anything since we're always safe 
    return ResultFromScode(S_OK); 
    }