mfcui源码分析一

    一直在寻找一款lua作为界面开发语言脚本框架,类似于web开发,使用html做界面,

lua作为脚本语言进行行为控制,htmlayout是不二选择,但是其搭配的默认脚本并不是lua,这里找到一个

开源的框架,将htmlayout进行了改造,使其支持lua脚本作为逻辑控制语言;

    本系列文章将对mfcui源码进行简要分析,并试图将其改造为自己的界面开发框架,该框架使用的是lua5.1;

我们从作者提供的test/demo.lua说起,该文件源代码如下:

require('mfc');

mfc.register('exctrl.dll');--
加载扩展控件
mfc.init();    --
初始化

local fn = arg[1] or string.format('file://%s/demo.htm', mfc.workdir());
local w = mfc.NewWindow(fn, true);    --
启动模态窗口

 

最后调用了mfc.NewWindow(fn, true)函数来创建一个模态窗口,就显示出来一个窗口;

逐个函数去分析,先从mfc.register('exctrl.dll')函数来,该函数是C库中实现的函数,实现代码如下:

//注册扩展控件
static int register_exctrl(lua_State* L)
{
#ifndef _AFXDLL    
        return 0;
#endif

    HINSTANCE hInstance = LoadLibrary(PAS(L, 1));//加载 exctrl.dll
    if(hInstance == NULL)
        return 0;

    do
    {
        pfnOpenExCtrl pfnFunc = (pfnOpenExCtrl)GetProcAddress(hInstance, "open_mfc_exctrl");        
        if(pfnFunc == NULL)
            break;

        CControlType** pList = pfnFunc(L);//调用 open_mfc_exctrl(L) 函数
        if(pList == NULL)
            break;

        lua_newtable(L);
        int nIndex = 0;        
        for(CControlType* pCtrl = pList[nIndex]; pCtrl != NULL; pCtrl = pList[++nIndex])
        {
            RegisterWidget(pCtrl);
            lua_pushstring(L, pCtrl->GetTypeName());
            lua_rawseti(L, -2, nIndex + 1);
        }
        return 1;

    }while(0);
    FreeLibrary(hInstance);
    return 0;
}

该函数先去加载exctrl.dll动态库,然后获取动态库导出函数open_mfc_exctrl,接着就调用了该函数,该函数代码如下:

extern "C"
CControlType** WINAPI open_mfc_exctrl(lua_State* L)
{    
    if(s_ControlList.empty())
        return NULL;

    CExctrlWrappedWnd::Register();
    lua_getglobal(L, "require");
    lua_pushstring(L, "exctrl");
    lua_pcall(L, 1, -1, 0);

    return &s_ControlList[0];
    
}

这里继续调用了CExctrlWrappedWnd::Register()函数,实现如下,CExctrlWrappedWnd类继承自CWndCWnd是MFC中的窗口类,

static BOOL        Register()
{
    HINSTANCE hInstance;
    hInstance = AfxGetInstanceHandle();
    WNDCLASS wc;    

    if (!(::GetClassInfo(hInstance, EXCTRL_WRAPPED_HWND, &wc))) {
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
        wc.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
        wc.hIcon = NULL;
        wc.hInstance = hInstance;
        wc.lpfnWndProc = ::DefWindowProc;
        wc.lpszClassName = EXCTRL_WRAPPED_HWND;
        wc.lpszMenuName = NULL;
        wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

        if (!AfxRegisterClass(&wc)) {            
            return FALSE;
        }
    }
    return TRUE;
}

以上代码对窗口的样式进行了设置;

 

 

 

 

 

 

 

posted @ 2017-11-11 12:45  Mr.R123  阅读(202)  评论(0编辑  收藏  举报