• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 505  文章 - 1034  trackbacks - 0
            <2007年12月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345


            子曾經曰過:編程無他,唯手熟爾!

            常用鏈接

            留言簿(94)

            隨筆分類(649)

            隨筆檔案(505)

            相冊

            BCB

            Crytek

            • crymod
            • Crytek's Offical Modding Portal

            Game Industry

            OGRE

            other

            Programmers

            Qt

            WOW Stuff

            搜索

            •  

            積分與排名

            • 積分 - 911346
            • 排名 - 14

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            CEGUI version 0.6

            為了便于找到問題,需要打開應用程序的控制臺,并且要知道寫的lua腳本中哪行語法錯了(畢竟不是天天寫lua,語法錯了很正常)

            1.Q:打開應用程序的控制臺
               A:

                     

            如何在窗口程序中使用控制臺(/subsystem /entry)(轉)
            2007-12-18 13:07
            1. 原理
            首先我們來看一下linker的 /subsystem 選項
            該選項的語法形式如下:
            /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|
            EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}
            [,major[.minor]]
            這個鏈接選項告訴操作系統如何運行可執行文件
            CONSOLE:
            win32 字符模式應用程序,此種類型的應用程序在運行的時候會產生一個類似DOS
            窗口的控制臺窗口,如果在應用程序的主函數為main()或者wmain(),在默認情況下
            該應用程序就是一個控制臺應用程序
            Extensible Firmware Interface
            和CPU具體架構相關的一個參數選項,并不常用,在這里暫不詳細介紹.
            如果對此有興趣的可以訪問intel主頁來查看相關內容
            NATIVE;
            設備驅動器選項,如果/DRIVER:WDM選項被設定的話,該鏈接選項(NATIVE)就為默認選項
            POSIX:
            在windows NT 種運行在POSIX子系統上的應用程序
            WINDOWS:
            該類型的應用程序不產生console窗口,該類型的應用程序的窗口由用戶自己創建,簡而言之
            就是一個標準的Win32 application,其入口地址為WinMain()函數或者wWinMain()函數的地址
            如果你在應用程序種定義的主函數為WinMain或者wWinMain,在默認情況下該應用程序就是一個
            Win32 Application !
            WINDOWSCE:
            運行在windows CE上的應用程序
            major and minor (optional):
            主版本號和次版本號,該選項為可選,該選項為0~65535之間的十進制整數
            從上面可以看出如果我們建立一個win32 console application的話,linker的/subsystem選項應該為
            CONSOLE,可以在VC開發環境的project->setting->link->project option中看到!
            接下來我們再看看應用程序是如何運行的!
            我們知道用VC編寫的程序,運行的時候是需要 C\C++運行庫支持的.當我們運行一個C/C++程序的時候
            鏈接器會首先尋找應用程序的啟動函數,例如:
            如果你建立了一個console程序的話,編譯器得鏈接開關會是以下這種形式
            /subsystem:"console" /entry:"mainCRTStartup" (ANSI)
            /subsystem:"console" /entry:"wmainCRTStartuup" (UNICODE)
            如果你建立了一個win32 application,編譯器得鏈接開關則會是一下形式
            /subsystem:"windows" /entry:"WinMain" (ANSI)
            /sbusystem:"windows" /entry:"wWinMain" (UINCODE)
            上面的兩種形式可以再project->setting->link->project option中看到
            上面的subsystem和entry并不需要都設置,如果你只設置了/subsystem:"console"
            的話,那么默認的entry開關在默認情況下應為/entry:"mainCRTStartup"
            反之,如果你在應用程序中定義了main函數的話,默認情況下,你的/subsystem開關
            應該為/system:"console"

            在默認情況下/subsystem 和/entry開關是匹配的,也就是
            console對應mainCRTStartup或者wmainCRTStartup
            windows對應WinMain或者wWinMain
            但是我們也可以通過手動改動的方式使他們不匹配

            例如我們可以這樣改動
            #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 設置入口地址

            int main(int argc, char* argv[])
            {
            MessageBox(NULL, "hello", "Notice", MB_OK);
            return 0;
            }
            在默認情況下鏈接器看到/subsystem下是windows選項的時候,它會自動尋找WinMain或者wWinMain
            但我們強制指定入口地址,這樣運行程序的時候默認的console窗口就會隱藏!

            上面是在代碼中使用#pragma指令來設置,還有一種就是直接在開發環境的
            project->setting->link->project option中手工改動!
            在明白了通過/subsystem選項可以控制鏈接程序的類型后,我們可以根據需要來生成具有控制臺的Windows窗口程序。

            2. 生成具有console窗口的Win32窗口程序(不使用MFC)

            使用Visual Studio.Net 2003建立一個Win 32窗口項目(不使用MFC):Win32WithConsole,在項目的屬性對話框中,依次選擇‘配置屬性’->‘鏈接器’->‘system’,在‘子系統’一項中,將‘Windows (/SUBSYSTEM:WINDOWS)’改為‘控制臺(/SUBSYSTEM:CONSOLE)’ 。現在,該項目所生成的可執行文件的入口函數將是mainCRTStartup或是wmainCRTStartup,我們只需要定義一個main函數,并進行適當的入口參數轉換,同時在該main函數中調用原來的入口函數_tWinMain即可。下面是Win32WithConsole.cpp文件中我們需要添加的main函數:
            int _tmain(int argc, _TCHAR* argv[])
            {
            HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
            HINSTANCE hPreInstance = NULL;
            TCHAR szCmdLine[1024];
            szCmdLine[0] = 0;
            LPTSTR lpCmdLine = szCmdLine;
            for ( int i = 1; i < argc; i++ )
            {
               if ( i > 1 )
               {
                _tcscpy(lpCmdLine, _T(" "));
                lpCmdLine = lpCmdLine + _tcslen(_T(" "));
               }
               _tcscpy(lpCmdLine, argv[i]);
               lpCmdLine = lpCmdLine + _tcslen(argv[i]);
            }
            lpCmdLine = szCmdLine;
            int nCmdShow = SW_SHOWNORMAL;
            int ret = _tWinMain(hInstance, hPreInstance, lpCmdLine, nCmdShow);
            return 0;
            }
            可以參考附加的文件Win32WithConsole.rar。

            3.生成具有console窗口的MFC窗口應用程序

            使用向導生成一個多文檔的MFC應用程序,MFCWithConsole。同樣,將該項目配置為‘控制臺(/SUBSYSTEM:CONSOLE)’,下面我們需要找到MFC應用程序的入口函數。通過調試該程序,我們可以發現,MFC框架通過AfxWinMain來調用項目中全局CWinApp變量theApp的InitInstance成員函數,從而啟動整個應用程序。因此,我們可以使用兩種方式來顯式調用AfxWinMain函數,從而創建一個具有console窗口的MFC窗口應用程序。
            第一種方法是在MFCWithConsole項目中加入AfxWinMain的定義,該函數的定義可以從winmain.cpp文件中,下面是其具體內容:
            int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
            LPTSTR lpCmdLine, int nCmdShow)
            {
            ASSERT(hPrevInstance == NULL);
            int nReturnCode = -1;
            CWinThread* pThread = AfxGetThread();
            CWinApp* pApp = AfxGetApp();
            // AFX internal initialization
            if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
               goto InitFailure;
            // App global initializations (rare)
            if (pApp != NULL && !pApp->InitApplication())
               goto InitFailure;
            // Perform specific initializations
            if (!pThread->InitInstance())
            {
               if (pThread->m_pMainWnd != NULL)
               {
                TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
                pThread->m_pMainWnd->DestroyWindow();
               }
               nReturnCode = pThread->ExitInstance();
               goto InitFailure;
            }
            nReturnCode = pThread->Run();
            InitFailure:
            #ifdef _DEBUG
            // Check for missing AfxLockTempMap calls
            if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
            {
               TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
                AfxGetModuleThreadState()->m_nTempMapLock);
            }
            AfxLockTempMaps();
            AfxUnlockTempMaps(-1);
            #endif
            AfxWinTerm();
            return nReturnCode;
            }

            第二種方法是顯式加載mfc71d.dll或是mfc71.dll,并調用其中的AfxWinMain函數。不過,這兩個動態鏈接庫都是使用NONAME的方式來導出函數的,因此只能通過函數序號的方式來調用AfxWinMain函數。通過在IDA Pro中對這兩個動態鏈接庫進行反編譯,我們可以發現AfxWinMain在mfc71d.dll中的序號為1589,而在mfc71.dll中的序號為1207,下面即是使用動態鏈接庫的方式調用AfxWinMain的方法。
            // wrong
            // typedef int __stdcall (*MYPROC)(HINSTANCE, HINSTANCE,LPTSTR, int);
            typedef int (__stdcall *AFXWINMAIN_FUNC)(HINSTANCE, HINSTANCE,LPTSTR, int);
            #ifdef _DEBUG
            #define MFC_DLL_NAME _T("mfc71d.dll")
            #define AFXWINMAIN_ORDINAL 1589
            #else
            #define MFC_DLL_NAME _T("mfc71.dll")
            #define AFXWINMAIN_ORDINAL 1207
            #endif

            int _tmain()
            {
            #ifndef _AFXDLL
            char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER), atexit(&_AfxTermAppState));
            #else
            char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER));
            #endif
            HINSTANCE hinstLib = LoadLibrary(MFC_DLL_NAME); 
            AFXWINMAIN_FUNC ProcAdd;
            int ret = 0;
            // If the handle is valid, try to get the function address.
            if (hinstLib != NULL) 

               ProcAdd = (AFXWINMAIN_FUNC) GetProcAddress(hinstLib, MAKEINTRESOURCE(AFXWINMAIN_ORDINAL));
               // If the function address is valid, call the function.
               if (NULL != ProcAdd) 
               {
                HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
                HINSTANCE hPrevInstance = NULL;
                LPTSTR lpCmdLine = NULL;
                int nCmdShow = SW_SHOWNORMAL;
                ret = (*ProcAdd)(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
               }
               // Free the DLL module.
               FreeLibrary(hinstLib); 
            }
            return ret;
            }

            需要說明的是,在GetProcAddress函數中,我們需要調用MAKEINTRESOURCE來將函數序號進行轉化。 另外,對于AFXWINMAIN_FUNC的定義一定要加上__stdcall的調用約定,因為AfxWinMain是采用__stdcall方式來調用的。最后還有一點需要注意,我們需要使用AfxInitialize來注冊退出函數,否則程序將不能正確退出。


             2.Q:要知道寫的lua腳本中哪行語法錯了,即lua語法檢查

                 A:

                    添加粗體的兩行就能在控制臺中看到出錯信息,并能定位到那一行

            void LuaScriptModule::executeScriptFile(const String& filename, const String& resourceGroup)
            {
                
            // load file
                RawDataContainer raw;
                System::getSingleton().getResourceProvider()
            ->loadRawDataContainer(filename,
                    raw, resourceGroup.empty() 
            ? d_defaultResourceGroup : resourceGroup);

                
            // load code into lua
                int top = lua_gettop(d_state);
                
            int loaderr = luaL_loadbuffer(d_state, (char*)raw.getDataPtr(), raw.getSize(), filename.c_str());
                System::getSingleton().getResourceProvider()
            ->unloadRawDataContainer( raw );
                
            if (loaderr)
                {
                    String errMsg 
            = lua_tostring(d_state,-1);
                    lua_settop(d_state,top);
            #ifdef _DEBUG
                    ::printf_s(
            "[LuaScriptModule]: %s\n", errMsg.c_str());
            #endif

                    
            throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
                }

                
            // call it
                if (lua_pcall(d_state,0,0,0))
                {
                    String errMsg 
            = lua_tostring(d_state,-1);
                    lua_settop(d_state,top);
            #ifdef _DEBUG
                    ::printf_s(
            "[LuaScriptModule]: %s\n", errMsg.c_str());
            #endif

                    
            throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
                }

                lua_settop(d_state,top); 
            // just in case :P
            }


            3.Q:用字符集Unicode生成lua51_d.lib調用GetModuleFileName為什么會出錯?

                  

            static void setprogdir (lua_State *L) {
              
            char buff[MAX_PATH + 1];
              
            char *lb;
              DWORD nsize 
            = sizeof(buff)/sizeof(char);
              DWORD n 
            = GetModuleFileName(NULL, buff, nsize);
              
            if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
                luaL_error(L, 
            "unable to get ModuleFileName");
              
            else {
                
            *lb = '\0';
                luaL_gsub(L, lua_tostring(L, 
            -1), LUA_EXECDIR, buff);
                lua_remove(L, 
            -2);  /* remove original string */
              }
            }


            A:  因為調用了GetModuleFileNameW,寬字符版本,而buff是char,buff里面就是d0 :0 /0,類似如此

            #ifdef UNICODE
            #define GetModuleFileName  GetModuleFileNameW
            #else
            #define GetModuleFileName  GetModuleFileNameA
            #endif // !UNICODE

            4. Q: CEGUI里面的lua如何使用?
                A:

               // 初始化
             CEGUI::LuaScriptModule
            * pScriptMod = new LuaScriptModule();
             System::getSingleton().setScriptingModule(pScriptMod);

            // 執行lua時
            System::getSingleton().executeScriptFile(
            "Sample_Text.lua");

            // 退出程序時
            CEGUI::ScriptModule* pScriptModule = System::getSingleton().getScriptingModule();
            delete pScriptModule;
            pScriptModule = NULL;




             5.貼lua代碼,以后看起來方便  
            我改了下CEGUI的這個例子 Sample_TextDemo

            print輸出信息到控制臺

            Sample_Text.lua

            Lua語言: Sample_Text.lua
            print("Sample_Text begin")
            local guiSystem = CEGUI.System:getSingleton()
            local schemeMgr = CEGUI.SchemeManager:getSingleton()
            local winMgr = CEGUI.WindowManager:getSingleton();
            local fontMgr = CEGUI.FontManager:getSingleton();

            -- load scheme and set up defaults
            schemeMgr:loadScheme("TaharezLook.scheme");
            guiSystem:setDefaultMouseCursor("TaharezLook", "MouseArrow");
            -- We need a font
            if(false == fontMgr:isFontPresent("DejaVuSans-10")) then
            fontMgr:createFont("DejaVuSans-10.font");
            end
            -- Font defaulting
            if(fontMgr:isFontPresent("DejaVuSans-10")) then
            guiSystem:setDefaultFont("DejaVuSans-10");
            elseif(fontMgr:isFontPresent("Commonwealth-10")) then
            guiSystem:setDefaultFont("Commonwealth-10");
            end

            -- load an image to use as a background
            CEGUI.ImagesetManager:getSingleton():createImagesetFromImageFile("BackgroundImage", "GPN-2000-001437.tga");
            -- here we will use a StaticImage as the root, then we can use it to place a background image
            local background = winMgr:createWindow("TaharezLook/StaticImage", "background_wnd");
            -- set position and size
            local xx = CEGUI.UDim(0,0)
            local yy = CEGUI.UDim(0,0)
            local zz = CEGUI.UVector2(xx,yy)
            background:setPosition(zz);

            background:setSize(CEGUI.UVector2(CEGUI.UDim(1,0), CEGUI.UDim(1,0)));
            -- disable frame and standard background
            background:setProperty("FrameEnabled", "false");
            background:setProperty("BackgroundEnabled", "false");
            -- set the background image
            background:setProperty("Image", "set:BackgroundImage image:full_image");
            -- install this as the root GUI sheet
            guiSystem:setGUISheet(background);

            -- Load our layout as a basic
            background:addChildWindow (winMgr:loadWindowLayout ("TextDemo.layout"));

            print("Sample_Text OK")



             

            posted on 2008-11-05 14:55 七星重劍 閱讀(2078) 評論(7)  編輯 收藏 引用 所屬分類: PL--c/c++PL--LuaC++ lib -- CEGUI

            FeedBack:
            # re: 整CEGUILua過程中遇到的問題及解答 2008-11-20 21:09 小不點
            哥們 能否把CEGUI的整個帶工程的代碼發我一份,我下的一個自己創建工程整合,但是還是差些文件,或DLL,Thanks~  回復  更多評論
              
            # re: 整CEGUILua過程中遇到的問題及解答 2008-11-21 14:16 七星重劍
            @小不點
            還是你自己折騰折騰比較好,能學到很多項目管理的東西的 ^_^  回復  更多評論
              
            # re: 整CEGUILua過程中遇到的問題及解答 2008-11-23 13:15 小不點
            OK ,thank You  回復  更多評論
              
            # re: 整CEGUILua過程中遇到的問題及解答 2008-11-24 00:49 七星重劍
            @小不點
            not at all  回復  更多評論
              
            # re: 整CEGUILua過程中遇到的問題及解答[未登錄] 2008-12-15 15:44 andy
            為什么CEGUI要用LUA啊 我沒弄明白  回復  更多評論
              
            # re: 整CEGUILua過程中遇到的問題及解答 2009-08-05 22:35 輕葉迷彩
            您好,我在將CEGUI與lua合并的過程中碰到了一個很久都沒有解決的問題,中文問題,具體的問題如下

            為CEGUI配置中文字體后,使用C++調用和操作CEGUI,中文能夠正常的處理和顯示

            例如:

            Editbox * editbox = static_cast<Editbox*>(m_WinMgr.getWindow("Demo8/Window1/Controls/Editbox"));
            Listbox * listbox = static_cast<Listbox*>(m_WinMgr.getWindow("Demo8/Window1/Listbox"));

            CEGUI::String edit_str(editbox->getText());

            ListboxTextItem* tempItem = new ListboxTextItem(edit_str);
            listbox->addItem(tempItem);

            testText->setText(mbcs_to_utf8((const char*)"中文測試"));

            等等均可以正確的獲取到控件上輸入的中文,并設置給其它控件等.


            但是將邏輯移到lua中,中文就完全不能處理了

            例如:

            local editbox = winMgr:getWindow("Demo8/Window1/Controls/Editbox")
            local listbox = CEGUI.toListbox(winMgr:getWindow("Demo8/Window1/Listbox"))
            local addbutton = winMgr:getWindow("Demo8/Window1/Controls/Add")

            addbutton:setText(editbox:getText())

            print(editbox:getText())

            CEGUI.Logger:getSingleton():logEvent(editbox:getText())

            local newItem = CEGUI.createListboxTextItem(editbox:getText())

            listbox:addItem(newItem)

            將全部得到亂碼

            getText()得到的 能正常顯示在控件上的中文 ,用于輸出,記log,或者設置給其它控件,均顯示的是亂碼.

            而在lua中單純寫入的中文可以正常顯示

            print("中文測試") --正常

            CEGUI.Logger:getSingleton():logEvent("中文測試") --亂碼


            print是lua自己的東西,如果這樣都出亂碼,那lua也不用玩了-_-

            以上現象分析: lua與cegui的編碼格式可能不同,lua與cegui交互,從cegui獲得的中文字符串,或傳給cegui的中文字符串,兩方均不能正常解析,彼此都認不出,都為亂碼.

            嘗試在lua中將中文字符串編碼方式轉換后再發送給cegui, lua的字符串編碼, 要么為ascii,要么為unicode
            cegui::string的編碼方式, 目前已知的有,接收utf8的構造函數

            所以,寫了N個編碼轉換函數進行嘗試
            AsciiToUnicode , AsciiToUtf8 , unicodeToUtf8 , ..............
            (均進行了測試,轉換正確)

            然后將這些函數導入到lua中

            EditBox:setText(AsciiToUnicode(str))
            EditBox:setText(AsciiToUtf8(str))
            EditBox:setText(unicodeToUtf8(str))

            幾乎常用的所有編碼能試的全試了,結果只是亂碼更亂....  回復  更多評論
              
            # re: 整CEGUILua過程中遇到的問題及解答 2009-08-07 11:18 七星重劍
            @輕葉迷彩
            目前我們項目都是在c++里面配置控件的,所以沒碰到老大的這個問題。
            以后估計會把界面控件相關的代碼放到lua里面。  回復  更多評論
              
            久久久久99精品成人片| 久久久久久毛片免费播放| 综合网日日天干夜夜久久| 精品国产乱码久久久久久浪潮| 久久国产亚洲精品无码| 久久棈精品久久久久久噜噜| 色欲综合久久中文字幕网| 伊人久久综合无码成人网| 国产成人精品久久| 午夜精品久久久久久久久| 色88久久久久高潮综合影院| 久久婷婷五月综合97色| 久久精品国产91久久麻豆自制| 久久免费高清视频| 久久精品一区二区三区中文字幕| 国产精品无码久久综合网| 久久伊人影视| 亚洲AV日韩精品久久久久| 精品午夜久久福利大片| 国产精品综合久久第一页| 婷婷久久精品国产| 伊人久久综合无码成人网| 国产精品久久久福利| 久久国产视频99电影| 亚洲日韩中文无码久久| 久久综合给合久久狠狠狠97色| 国产精品久久国产精麻豆99网站| 99久久99久久精品国产| 综合久久精品色| 97r久久精品国产99国产精| 久久综合亚洲色HEZYO国产| 久久婷婷五月综合色高清| 久久国产成人| 99久久人妻无码精品系列| 999久久久国产精品| 亚洲精品乱码久久久久久蜜桃不卡| 成人资源影音先锋久久资源网| 久久综合亚洲色HEZYO国产| 久久99亚洲网美利坚合众国| 人妻少妇精品久久| 日韩精品国产自在久久现线拍|