ATL 封装MSFLEXGRID

Introduction

It is bit tricky to use MSFlexGrid Control in ATL projects (I struggled lot with MSDN and net) because:

  1. MSFlexGrid Control is a Visual Basic control
  2. MSFlexGrid Control requires runtime control license.

To check the problem you can do the following:

  1. Create ATL Server Dll
  2. Add ATL Composite Control
  3. Right Click and insert MSFlexGrid Control
  4. Add Event by right clicking and expose some events.
  5. Build Dll.
  6. Deploy in a test machine along with MSFlex.ocx and other support libraries. Please Note that it will work fine on the development machine (Machine which has visual studio installed) because when you install visual studio it provides design time and runtime license for the current system by default.

See Details on:

Result

It won’t work on test machine (The machine which only has OS installed). If you are Using Visual Basic as client it will display page not found kind of HTML page in place of control.

How To use MSFlexGrid Then?

  1. Create ATL Server Dll.
  2. Add ATL Composite Control.
  3. Import msflxgrd.ocx in control header file.
    #import "C:/WINNT/System32/msflxgrd.ocx" raw_interfaces_only, 
        raw_native_types, no_namespace, named_guids
  4. Add #pragma warning(disable:4146) before #import "...msflxgrid.ocx..." otherwise it will give warning.
  5. Now the problem is: at the time of creating control you need to get the runtime license for MSFlexGrid Control. I had made a function to do so:
    Collapse
     // Create Control
     void CreateObject()
     {
       CComPtr
       
        pUnkCont;
       ComQIPtr 
       
        spPerStm;
       CComPtr
       
        pCF;
       // Add CLSID of MSFlexGrid for Runtime license
       CComBSTR bstrLicKey = "72E67120-5959-11cf-91F6-C2863C385E30";
       HRESULT hr = CoGetClassObject(CLSID_MSFlexGrid,
        CLSCTX_ALL,
        NULL,
            IID_IClassFactory2,
        reinterpret_cast<void**>(&pCF) );
    
       // Call CreateInstanceLic to create instance of control 
       // with runtime license
       if( !FAILED( hr ) )
        hr =pCF->CreateInstanceLic(NULL,NULL,IID_IUnknown,bstrLicKey,
          reinterpret_cast<void**>(&pUnk));
       
       spPerStm=pUnk;
       spPerStm->InitNew();
    
       wnd.Attach(m_hWnd);
       wnd.AttachControl(pUnk, &pUnkCont);
       m_VarGrid = pUnk;
      // Start event connection
      DispEventAdvise(pUnk); 
     }
    
  6. Add the following member variables. I’ve added it the following member variables as public.
        CAxWindow wnd;
        IUnknownPtr pUnk;
        IMSFlexGridPtr m_Grid;
            
  7. Next step is to catch the events of flxgrid control which can be done by adding the following line in class declaration:
    public IDispEventImpl < ID_VAR_GRID,CAuthorVar,&DIID_DMSFlexGridEvents,
        &LIBID_MSFlexGridLib,1,0 >
  8. Add Sink Entry (I’m feeling lazy and just using click event if you want you can use no of events as per ur requirement)
    BEGIN_SINK_MAP(CFlxCtrl)
        //Make sure the Event Handlers have __stdcall calling convention
        SINK_ENTRY_EX(ID_GRID,DIID_DMSFlexGridEvents, DISPID_CLICK, 
          OnClick_grid)
    END_SINK_MAP()   
    
  9. In Resource.h file add #define ID_GRID 201 or any ID which you like.
  10. Add Event Handler:
    VOID __stdcall Click_grid()
    {
        AfxMessageBox("Clicked");
    }
    
  11. You can also add a method to initialize gird i.e..
        void InitGrid()
        {
            CString Cols[5]={"Name","Phone No","MailID"};
            m_VarGrid->put_FixedRows(1);
            m_VarGrid->put_FixedCols(0);
            m_VarGrid->put_Rows(2);
            m_VarGrid->put_Cols(3);
    
            for(int i = 0;i!=3;i++)
            {
                m_VarGrid->put_TextMatrix(0,i,(_bstr_t)Cols[i]);    
                m_VarGrid->put_ColWidth(i,1260);
            }
        } 
    
  12. In the OnInitDialog call CreateObject() function and InitGrid().
  13. Add a method to interface ie.
    STDMETHODIMP CAuthorVar::Stop()
    {
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
    
        if(pUnk)
        {
            HRESULT hr= DispEventUnadvise(pUnk);//
        }
        m_Grid.Release();
        return S_OK;
    }
    
  14. Test the control in ActiveX Control Test Container and don't forget to call stop method before closing.

I also had noticed another problem which is:

Every time you need to call DispEventUnadvise(pUnk)/DispEventAdvise(pUnk) method and it won't process any messages from container window or other controls placed there. The easiest solution I found is just wrap up your first control into another Composite Control and it will make your life easy.

If you are still feeling lazy or has already created control and don’t want to rewrite then you can cheat the test machine by adding the following in registry:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT/Licenses/72E67120-5959-11cf-91F6-C2863C385E30]
@="ibcbbbebqbdbciebmcobmbhifcmciibblgmf"

and be happy but I won’t recommend it. So, Have a fun with MSFlexGrid and ATL Composite Control.

<script src="/script/togglePre.js" type="text/javascript"></script>

Uttam Kumar Unik!

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值