winston 发表于 2012-1-18 10:14:11

DirectUI界面技术和lua脚本

Duilib库地址
http://duilib.googlecode.com/files/duilib%20v1.1.zip


Lua官方地址, for windows.
http://luaforwindows.googlecode.com/files/LuaForWindows_v5.1.4-45.exe


将testapp修改成dll工程FrameSdk,导出5个函数#ifdef __cplusplus

extern "C"
{
#endif

FRAMESDK_API
int CreateApp(HINSTANCE hInstance
            , const char * xmlPath
            , const char * luaPath);

#ifdef __cplusplus
};
#endif



// App.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <exdisp.h>
#include <comdef.h>
#include <string>

/**/
#ifdef __cplusplus
extern "C" {
#endif

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

#ifdef __cplusplus
}
#endif

#pragma comment(lib, "lua5.1.lib")

#include "FrameSdk.h"


#ifdef __cplusplus
extern "C"
{
#endif
    FRAMESDK_API
      int
      FindControl(lua_State * L);

    FRAMESDK_API
      int
      SetAttr(lua_State * L);

    FRAMESDK_API
      int
      GetAttr(lua_State * L);

    FRAMESDK_API
      int
      RegEvent(lua_State * L);


#ifdef __cplusplus
};
#endif


class CFrameWindowWnd : public CWindowWnd, public INotifyUI
{
public:
    CFrameWindowWnd(const char * xmlPath
                  , const char * luaPath)
                  : m_xmlPath(xmlPath)
                  , m_luaPath(luaPath)
                  , m_L(NULL){ }

    LPCTSTR GetWindowClassName() const { return _T("UIMainFrame"); };
    UINT GetClassStyle() const { return CS_DBLCLKS; };
    void OnFinalMessage(HWND /*hWnd*/) { delete this; };

    void Init()
    {
      m_L = lua_open();
      luaL_openlibs(m_L);
            luaL_dofile(m_L, m_luaPath.c_str());
    }

    bool OnHChanged(void* param) {
      TNotifyUI* pMsg = (TNotifyUI*)param;
      if( pMsg->sType == _T("valuechanged") ) {
            short H, S, L;
            CPaintManagerUI::GetHSL(&H, &S, &L);
            CPaintManagerUI::SetHSL(true, (static_cast<CSliderUI*>(pMsg->pSender))->GetValue(), S, L);
      }
      return true;
    }

    bool OnSChanged(void* param) {
      TNotifyUI* pMsg = (TNotifyUI*)param;
      if( pMsg->sType == _T("valuechanged") ) {
            short H, S, L;
            CPaintManagerUI::GetHSL(&H, &S, &L);
            CPaintManagerUI::SetHSL(true, H, (static_cast<CSliderUI*>(pMsg->pSender))->GetValue(), L);
      }
      return true;
    }

    bool OnLChanged(void* param) {
      TNotifyUI* pMsg = (TNotifyUI*)param;
      if( pMsg->sType == _T("valuechanged") ) {
            short H, S, L;
            CPaintManagerUI::GetHSL(&H, &S, &L);
            CPaintManagerUI::SetHSL(true, H, S, (static_cast<CSliderUI*>(pMsg->pSender))->GetValue());
      }
      return true;
    }

    bool OnAlphaChanged(void* param) {
      TNotifyUI* pMsg = (TNotifyUI*)param;
      if( pMsg->sType == _T("valuechanged") ) {
            m_pm.SetTransparent((static_cast<CSliderUI*>(pMsg->pSender))->GetValue());
      }
      return true;
    }

    void OnPrepare()
    {
      CSliderUI* pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("alpha_controlor")));
      if( pSilder )
            pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnAlphaChanged);

      pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("h_controlor")));
      if( pSilder )
            pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnHChanged);

      pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("s_controlor")));
      if( pSilder )
            pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnSChanged);

      pSilder = static_cast<CSliderUI*>(m_pm.FindControl(_T("l_controlor")));
      if( pSilder )
            pSilder->OnNotify += MakeDelegate(this, &CFrameWindowWnd::OnLChanged);

    }

    void Notify(TNotifyUI& msg)
    {
      if( msg.sType == _T("windowinit") ) OnPrepare();
      else if( msg.sType == _T("click") ) {
            if( msg.pSender->GetName() == _T("insertimagebtn") ) {
                CRichEditUI* pRich = static_cast<CRichEditUI*>(m_pm.FindControl(_T("testrichedit")));
                if( pRich ) {
                  pRich->RemoveAll();
                }
            }
            else if( msg.pSender->GetName() == _T("changeskinbtn") ) {
                if( CPaintManagerUI::GetResourcePath() == CPaintManagerUI::GetInstancePath() )
                  CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin\\FlashRes"));
                else
                  CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
                CPaintManagerUI::ReloadSkin();
            }
      }
    }

    LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      if( uMsg == WM_CREATE ) {
            // 设置窗口无边框样式
             LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
             styleValue &= ~WS_CAPTION ; //& ~WS_BORDER & ~WS_THICKFRAME;
             ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

            m_pm.Init(m_hWnd);
            CDialogBuilder builder;
                  //CDialogBuilderCallbackEx cb;
            wchar_t szXmlPath = L"";
            MultiByteToWideChar(CP_ACP, 0, m_xmlPath.c_str(), -1, szXmlPath, _countof(szXmlPath));
            CControlUI* pRoot = builder.Create(szXmlPath, (UINT)0, NULL, &m_pm);
            ASSERT(pRoot && "Failed to parse XML");
            m_pm.AttachDialog(pRoot);
            m_pm.AddNotifier(this);

            // 圆角
            SIZE szRoundCorner = m_pm.GetRoundCorner();
            if( !::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0) ) {
                CRect rcWnd;
                ::GetWindowRect(*this, &rcWnd);
                rcWnd.Offset(-rcWnd.left, -rcWnd.top);
                rcWnd.right++; rcWnd.bottom++;
                HRGN hRgn = ::CreateRoundRectRgn(rcWnd.left, rcWnd.top, rcWnd.right,rcWnd.bottom
                                                , szRoundCorner.cx, szRoundCorner.cy);
                ::SetWindowRgn(*this, hRgn, TRUE);
                ::DeleteObject(hRgn);
            }

            Init();
            return 0;
      }
      else if( uMsg == WM_DESTROY ) {
            ::PostQuitMessage(0L);
      }
      else if( uMsg == WM_ERASEBKGND ) {
            return 1;
      }
      
      LRESULT lRes = 0;
      if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) )
            return lRes;

      return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
    }

public:
    // 绘制管理器
    CPaintManagerUI m_pm;
    // 布局文件
    std::string m_xmlPath;
    // 控制脚本
    std::string m_luaPath;
private:
    // lua脚本状态机
    lua_State * m_L;
};


FRAMESDK_API
int FindControl(lua_State * L)
{
    MessageBoxA(GetActiveWindow(), __FUNCTION__, __FUNCTION__, 0);
    return 0;
}


FRAMESDK_API
int
SetAttr(lua_State * L)
{
    return 0;
}

FRAMESDK_API
int
GetAttr(lua_State * L)
{
    return 0;
}

FRAMESDK_API
int
RegEvent(lua_State * L)
{
    return 0;
}

FRAMESDK_API
int
CreateApp(HINSTANCE hInstance, const char * xmlPath, const char * luaPath)
{
    CPaintManagerUI::SetInstance(hInstance);
    CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());

    HRESULT Hr = ::CoInitialize(NULL);
    if( FAILED(Hr) ) return 0;

    CFrameWindowWnd* pFrame = new CFrameWindowWnd(
      strrchr(xmlPath, '\\')+1
      //, strrchr(luaPath, '\\')+1
      , luaPath
      );

    if( pFrame == NULL ) return 0;
    pFrame->Create(NULL
      , _T("FrameApp")
      , WS_VISIBLE
      | WS_POPUPWINDOW
      //| WS_OVERLAPPEDWINDOW
      , 0L, 0, 0, 400, 300);

    pFrame->CenterWindow();
    pFrame->ShowWindow(true);
    CPaintManagerUI::MessageLoop();

    ::CoUninitialize();
    return 0;
}


作者:wuzh1230 发表于2012-1-17 14:42:43 原文链接

页: [1]
查看完整版本: DirectUI界面技术和lua脚本