在Win32 SDK中使用Lu模块化编译运行库MLu

Win32 SDK中使用Lu模块化编译运行库MLu

Windows XP系统,使用VC 2008演示)

(欢迎访问:http://www.forcal.net/

演示如何在Windows程序中加入Lu脚本支持,比较快捷的方式是通过MLu使用Lu脚本。图示说明如何在Win32SDK中使用Lu模块化编译运行库MLu。

完整版请参考:http://www.forcal.net/bczl/luc/pwinsdkmlu.doc

以下是基本步骤,未包含相关图片。

 

1、启动VS 2008VC++ 2008),点击红色圈出部分创建项目。

2、创建Win32项目,名称为TestMLu,点击“确定”。


 

3、点击“下一步”。


 

4、选择“空项目”,点击“完成”。


 

5、工程生成后如下图所示。

6、在进行下一步之前,先来看看我们要设计的主程序界面,我们将先实现这个界面。


 

7、实现主程序界面的代码:这些代码没有使用Lu,仅仅实现主程序界面

 

头文件:TestMLu.h(文件创建方法:先创建一个文本文件,输入以下内容并保存,然后更改文件名为TestMLu.h

#define IDM_cal_com           10

#define IDM_cal_cal             11

#define IDM_cal_comcal      12

 

#define IDE_EditCode          30

#define IDE_EditOut            31


(注意:复制到文件中后,最后一条语句后面,请加一个回车,否则容易出现编译错误。下同。)

 

资源文件:TestMLu.rc(文件创建方法:先创建一个文本文件,输入以下内容并保存,然后更改文件名为TestMLu. rc

#include "windows.h"

#include "TestMLu.h"

 

// Menu

mainMenu MENU DISCARDABLE 

{

         POPUP "计算(&J)"

         {

                   MENUITEM "计算(&J)",   IDM_cal_comcal

                   MENUITEM SEPARATOR

                   MENUITEM "编译(&B)",  IDM_cal_com

                   MENUITEM "执行(&Z)",  IDM_cal_cal

         }

}


实现文件:TestMLu.cpp(文件创建方法:先创建一个文本文件,输入以下内容并保存,然后更改文件名为TestMLu.cpp

#include "windows.h"

#include "TestMLu.h"

 

// 全局数据

 

HINSTANCE hInstance;                         //实例句柄

HWND hwndEditCode,hwndEditOut;    //代码窗口和输出窗口

 

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); //窗口函数说明

 

 Windows应用程序入口

 

int WINAPI WinMain(HINSTANCE hhInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow)

{

         HWND hWnd;

         MSG Msg ;

         WNDCLASS wndclass ;

         wchar_t lpszClassName[]=L"classTestMLu";//窗口类名

         wchar_t lpszTitle[]= L"TestMLu";                  //窗口标题名

 

         hInstance=hhInstance;                             //记住实例句柄

 

 

         //窗口类的定义

         wndclass.style = 0;                                  //窗口类型

         wndclass.lpfnWndProc = WndProc ;       //窗口处理函数为WndProc

         wndclass.cbClsExtra    = 0 ;                     //窗口类无扩展

         wndclass.cbWndExtra  = 0 ;                     //窗口实例无扩展

         wndclass.hInstance = hInstance ;            //当前实例句柄

         wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION) ;//窗口的最小化图标为缺省图标

         wndclass.hCursor = LoadCursor( NULL, IDC_ARROW) ;//窗口采用箭头光标

         wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH) ;//窗口背景为白色

         wndclass.lpszMenuName = L"mainMenu" ;    //窗口菜单

         wndclass.lpszClassName = lpszClassName ;//窗口类名

 

         //窗口类注册

         if( !RegisterClass( &wndclass))               //如果注册失败则发出警告声音

         {

                   MessageBeep(0) ;

                   MessageBox(GetFocus(),L"注册失败!",L"TestMLu",MB_OK);

                   return 0;

         }

 

         //创建窗口

         hWnd=CreateWindow(lpszClassName,           //窗口类名

                                               lpszTitle,                      //窗口实例的标题名

                                               WS_OVERLAPPEDWINDOW,//窗口的风格

                                               CW_USEDEFAULT,

                                               CW_USEDEFAULT,            //窗口左上角坐标为缺省值

                                               CW_USEDEFAULT,

                                               CW_USEDEFAULT,            //窗口的高和宽为缺省值

                                               NULL,                                   //此窗口无父窗口

                                               NULL,                                   //此窗口无主菜单

                                               hInstance,                              //创建此窗口的应用程序的当前句柄

                                               NULL) ;                                 //不使用该值

 

         //显示窗口

         ShowWindow( hWnd, SW_SHOWNORMAL) ;

         //绘制用户区

         UpdateWindow(hWnd);

 

         //消息循环

         while( GetMessage(&Msg, NULL, 0, 0))

         {

                   TranslateMessage( &Msg) ;

                   DispatchMessage( &Msg) ;

         }

         if(!UnregisterClass(lpszClassName,hInstance))// Are We Able To Unregister Class

         {

                   MessageBox(NULL,L"Could Not Unregister Class.",L"TestMLu",MB_OK | MB_ICONINFORMATION);

         }

 

         return Msg.wParam;    //消息循环结束即程序终止时将信息返回系统

}

 

//窗口函数

LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM  wParam,      LPARAM  lParam)

{

         switch(Message)

         {

         case WM_CREATE:

                   hwndEditCode=CreateWindow(L"EDIT",NULL,     //创建代码编辑框;

                            WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|WS_BORDER|ES_LEFT|ES_MULTILINE|

                            ES_AUTOHSCROLL|ES_AUTOVSCROLL,

                            0,0,LOWORD(lParam),HIWORD(lParam/2),hWnd,(HMENU)IDE_EditCode,hInstance,NULL);

                   hwndEditOut=CreateWindow(L"EDIT",NULL,       //创建输出编辑框;

                            WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|WS_BORDER|ES_LEFT|ES_MULTILINE|

                            ES_AUTOHSCROLL|ES_AUTOVSCROLL,

                            0,HIWORD(lParam/2+2),LOWORD(lParam),HIWORD(lParam/2-2),hWnd,(HMENU)IDE_EditOut,hInstance,NULL);

                   SetWindowText(hwndEditCode,L"//这里是代码窗口,请将Lu代码写在下面\r\n");

                   SetFocus(hwndEditCode);

                   break;

         case WM_SIZE:

                  MoveWindow(hwndEditCode,0,0,LOWORD(lParam),HIWORD(lParam/2),true);

                   MoveWindow(hwndEditOut,0,HIWORD(lParam/2+2),LOWORD(lParam),HIWORD(lParam/2),true);

                   UpdateWindow(hWnd);

                   break;

         case WM_COMMAND:

                   switch(LOWORD(wParam))

                   {

                   case IDM_cal_com:

                            break;

                   case IDM_cal_cal:

                            break;

                   case IDM_cal_comcal:

                            break;

                   }

                   break;

         case WM_DESTROY:

                   PostQuitMessage(0);                               //调用PostQuitMessage发出WM_QUIT消息

                   break;

         default:                                                               //默认时采用系统消息默认处理函数

                   return  DefWindowProc(hWnd,Message,wParam,lParam);

         }

         return 0;

}


8、将TestMLu.hTestMLu.rcTestMLu.cpp三个文件放到文件夹“D:\lu\lu32\TestMLu\TestMLu”。


 

9、返回VC,点击下图中红色圈出部分“项目->添加现有项”。

10、添加TestMLu.hTestMLu.rcTestMLu.cpp三个文件到工程中。


 

11、新的工程如下图,点击下图中红色圈出部分“生成->生成解决方案”。

12、生成成功。


 

13、点击下图中红色圈出部分“调试->开始执行(不调试)”。

14、程序界面如下图所示,与我们设想一致。


 

15、在“TestMLu.cpp”中加入Lu脚本支持的代码,注意红色青色部分是新加的

/***********************************************************************

使用MLu的一般步骤:

(1)使用函数InitMLu进行初始化(必须)。

(2)使用函数LoadDll加载需要的Lu扩展库。

(3)使用函数ComModule将字符串源代码编译为模块(必须)。

(4)使用函数ExeModule执行模块,或者使用函数GetFor获取需要的表达式进行计算(必须)。

(5)使用函数SearchKey验证操作数据的类型,然后进行数据传送操作。(本例未使用)

(6)使用函数FreeDll卸载Lu扩展库。

(7)使用函数FreeMLu释放资源(必须)。

***********************************************************************/

#include "windows.h"

#include "TestMLu.h"

//使用Lu脚本必须的头文件

#include "lu32.h"

 

//隐式加载MLu时,需要使用的导入库文件

#pragma comment( lib, "lu32.lib" )

#pragma comment( lib, "mlu32.lib" )

 

// 全局数据

 

HINSTANCE hInstance;                         //实例句柄

HWND hwndEditCode,hwndEditOut;    //代码窗口和输出窗口

 

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); //窗口函数说明

 

//友情提示:所有定义的变量和函数,可通过编辑器提供的查找功能查看它在哪里使用

//要加载的Lu扩展动态库

wchar_t AllDllName[]=L"\"dll\\LuSystem32.dll\",\"dll\\LuMath32.dll\",\"dll\\LuOpt32.dll:138413699\",\"dll\\LuIMSL32.dll:dll\\IMSL32.dll\",\"dll\\Lu2D32.dll\",\"dll\\LuWin32.dll\",\"dll\\OpenLuGl32.dll\"";

 

luVOID nModule=0;             //编译模块时所用的起始模块号,一般设为0

void *hModule=NULL;        //模块句柄,记住当前编译的模块。本例中,在编译时将销毁以前编译的模块

 

// MLu使用的函数

 

//输出动态库信息,该函数注册到Lu,由Lu二级函数调用,输出必要的信息

void _stdcall LuMessage(wchar_t *pch) 

{

         int nTextLength;

 

         if(!pch) return;

         nTextLength=GetWindowTextLength(hwndEditOut);

         SendMessage(hwndEditOut,EM_SETSEL,nTextLength,-1);

         SendMessage(hwndEditOut,EM_REPLACESEL,1,(LPARAM)pch);

}

//执行Lu源程序时,仅对无参表达式做计算,以下函数用于输出表达式的结果

void _stdcall OutLuData(LuData *LD)   

{

         wchar_t wchNum[32],*pStr;

         char chNum[32];

         int i;

         luVOID k=0;

         luMessage pMessage;  //输出动态库信息的函数,例如本例中定义的LuMessage即是这样的函数

 

         //获取注册到Lu系统的输出动态库信息的函数,通常即本例中定义的LuMessage函数,但也不一定

         pMessage=(luMessage)SearchKey((char *)&k,sizeof(luVOID),luPubKey_User);

         if(!pMessage) return;

         switch(LD->VType)

         {

         case luStaData_nil:

                   pMessage(L"nil");

                   break;

         case luStaData_int64:

                   _i64tow_s(LD->x,wchNum,22,10);

                   pMessage(wchNum);

                   break;

         case luStaData_double:

                   _gcvt_s(chNum,*(double *)&(LD->x),16);

                   for(i=0;chNum[i];i++) wchNum[i]=chNum[i];

                   wchNum[i]='\0';

                   pMessage(wchNum);

                   break;

         case luStaData_complex:

                   pMessage(L"(");

                   _gcvt_s(chNum,*(double *)&(LD->x),16);

                   for(i=0;chNum[i];i++) wchNum[i]=chNum[i];

                   wchNum[i]='\0';

                   pMessage(wchNum); pMessage(L",");

                   _gcvt_s(chNum,*(double *)&(LD->y),16);

                   for(i=0;chNum[i];i++) wchNum[i]=chNum[i];

                   wchNum[i]='\0';

                   pMessage(wchNum); pMessage(L")");

                   break;

         case luStaData_vector:

                   pMessage(L"(");

                   _gcvt_s(chNum,*(double *)&(LD->x),16);

                   for(i=0;chNum[i];i++) wchNum[i]=chNum[i];

                   wchNum[i]='\0';

                   pMessage(wchNum); pMessage(L",");

                   _gcvt_s(chNum,*(double *)&(LD->y),16);

                   for(i=0;chNum[i];i++) wchNum[i]=chNum[i];

                   wchNum[i]='\0';

                   pMessage(wchNum); pMessage(L",");

                   _gcvt_s(chNum,*(double *)&(LD->z),16);

                   for(i=0;chNum[i];i++) wchNum[i]=chNum[i];

                   wchNum[i]='\0';

                   pMessage(wchNum); pMessage(L")");

                   break;

         case luStaData_logical:

                   if(LD->x)

                            pMessage(L"true");

                   else

                            pMessage(L"false");

                   break;

         case luStaData_string:

         case luDynData_string:

                   pStr=GetStr(LD,NULL,k);

                   if(pStr) pMessage(pStr);

                   break;

         default:

                   pMessage(L"\r\n不可识别类型!\r\n");

         }

         pMessage(L"\r\n");

}

 

bool LoadMLu(void)   //加载MLu

{

         if(!InitMLu()) return false;

         LoadDll(AllDllName); //加载Lu扩展动态库

         return true;

}

 

void comcode(void)      //将Lu源代码编译为模块

{

         wchar_t *pstr=NULL;

         int nCode,nTextLength,k;

         luINT err1,err2;

         int ErrType;                 //运行错误类型

         wchar_t *FunName;     //出错函数名

         void *ForHandle;         //运行出错的表达式句柄

         luVOID m=0;

         wchar_t *ppErrStrS[]=

         {

                   L"\r\n编译错误:递归调用指定的模块。\r\n",//-7

                   L"\r\n编译错误:找不到指定的模块。\r\n",//-6

                   L"\r\n编译错误:缺少模块名。\r\n",//-5

                   L"\r\n编译错误:注释符号/* ... */不成对。\r\n",//-4

                   L"\r\n编译错误:未使用模块编译功能,不能编译指定的模块。\r\n",//-3

                   L"\r\n编译错误:无法加锁模块。\r\n",//-2

                   L"\r\n编译错误:未用。\r\n",//-1

                   L"\r\n编译错误:编译成功。\r\n",//000000000000

                   L"\r\n编译错误:内存分配失败。\r\n",//1

                   L"\r\n编译错误:括号不成对。\r\n",//2

                   L"\r\n编译错误:(等号后)没有表达式。\r\n",//3

                   L"\r\n编译错误:非法的函数句柄。\r\n",//4

                   L"\r\n编译错误:字符串中转义字符错误。\r\n",//5

                   L"\r\n编译错误:字符串无效,即\"...\"不匹配。\r\n",//6

                   L"\r\n编译错误:不可识别字符。\r\n",//7

                   L"\r\n编译错误:表达式名称定义错误。\r\n",//8

                   L"\r\n编译错误:不可识别的自变量,自变量只能以字母或下画线开头。\r\n",//9

                   L"\r\n编译错误:不可识别的自变量定义方法,“(,:,:,:,:,...)”冒号过多。\r\n",//10

                   L"\r\n编译错误:自变量定义错误。\r\n",//11

                   L"\r\n编译错误:continue()函数只能有0个参数。\r\n",//12

                   L"\r\n编译错误:只能在while,until中使用continue函数。\r\n",//13

                   L"\r\n编译错误:break()函数只能有0个参数。\r\n",//14

                   L"\r\n编译错误:只能在while,until中使用break函数。\r\n",//15

                   L"\r\n编译错误:if,while,until,which中的参数个数至少为2个。\r\n",//16

                   L"\r\n编译错误:表达式中的数字错误。\r\n",

                   L"\r\n编译错误:&单目取地址运算符只能用于单独的变量。\r\n",

                   L"\r\n编译错误:单目运算符++、--错误。\r\n",

                   L"\r\n编译错误:括号内没有数字。\r\n",

                   L"\r\n编译错误:单目运算符+、-、!、!!错误。\r\n",

                   L"\r\n编译错误:赋值“=”错误。\r\n",

                   L"\r\n编译错误:不正确的运算方式或其他语法错误。\r\n",

                   L"\r\n编译错误:不可识别变量名。\r\n",

                   L"\r\n编译错误:不可识别函数名。\r\n",

                   L"\r\n编译错误:一级函数只能有一个参数。\r\n",

                   L"\r\n编译错误:二级函数参数不匹配。\r\n",

                   L"\r\n编译错误:关键字Static或Common的位置非法。\r\n",

                   L"\r\n编译错误:(模块中)表达式有重名。\r\n",

                   L"\r\n编译错误:对形如“-2^3”的式子,须用括号给前置单目运算符“-”和乘方运算符“^”(或点乘方运算符“.^”)指出运算顺序。\r\n",

                   L"\r\n编译错误:类成员运算符后只能是变量名、字符串、括号运算符或者类成员函数。\r\n",

                   L"\r\n编译错误:后单目运算符'、.'错误。\r\n",

                   L"\r\n编译错误:调用表达式时参数不匹配。\r\n",

                   L"\r\n编译错误:未使用。\r\n",

                   L"\r\n编译错误:自变量重名。\r\n",

                   L"\r\n编译错误:因检测到运行错误而退出。\r\n",//36

                   L"\r\n编译错误:未使用。\r\n",

                   L"\r\n编译错误:未使用。\r\n",

                   L"\r\n编译错误:表达式太长或表达式中字符串太多。\r\n",//39

                   L""

         };

 

         nTextLength=GetWindowTextLength(hwndEditCode)+1;

         pstr=new wchar_t[nTextLength];

         if(!pstr) return;

         GetWindowText(hwndEditCode,pstr,nTextLength);

 

         k=UseLu(2);       //申请进入Lu工作区,保证了多线程程序中,互斥使用Lu系统

         if(!k)                  //进入Lu工作区

         {

                   DelModule(hModule); //销毁以前编译的模块

                   GetRunErr(ErrType,FunName,nCode,ForHandle); //设置运行错误为无错状态

                   //注册LuMessage函数到Lu系统,使Lu运行时可输出函数信息

                   //其他Lu扩展库也可注册类似的函数到Lu系统,故每次编译前都进行注册

                   InsertKey((char *)&m,sizeof(luVOID),luPubKey_User,LuMessage,NULL,NULL,0,ForHandle);

                   nCode=ComModule(pstr,nModule,hModule,err1,err2); //编译模块

                   UseLu(0);  //离开Lu工作区

                   if(nCode) //有编译错误

                   {

                            hModule=NULL;

                            nTextLength=GetWindowTextLength(hwndEditOut);

                            SendMessage(hwndEditOut,EM_SETSEL,nTextLength,-1);

                            if(nCode>=-7&&nCode<=39) SendMessage(hwndEditOut,EM_REPLACESEL,1,(LPARAM)ppErrStrS[nCode+7]);

                            nTextLength=GetWindowTextLength(hwndEditCode);

                            if(err1>=0&&err1<=nTextLength&&err2>=0&&err2<=nTextLength)

                            {

                                     SendMessage(hwndEditCode,EM_SETSEL,err1,err2+1);

                                     SetFocus(hwndEditCode);

                            }

                   }

         }

         else if(k==1)

         {

                   LuMessage(L"\r\n同一线程不能同时使用Lu工作区!无法编译程序!请稍后再试!\r\n");

         }

         delete[] pstr;

}

 

 Windows应用程序入口

 

int WINAPI WinMain(HINSTANCE hhInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow)

{

         HWND hWnd;

         MSG Msg ;

         WNDCLASS wndclass ;

         wchar_t lpszClassName[]=L"classTestMLu";//窗口类名

         wchar_t lpszTitle[]= L"TestMLu";                  //窗口标题名

 

         hInstance=hhInstance;                             //记住实例句柄

 

 

         //窗口类的定义

         wndclass.style = 0;                                  //窗口类型

         wndclass.lpfnWndProc = WndProc ;       //窗口处理函数为WndProc

         wndclass.cbClsExtra    = 0 ;                     //窗口类无扩展

         wndclass.cbWndExtra  = 0 ;                     //窗口实例无扩展

         wndclass.hInstance = hInstance ;            //当前实例句柄

         wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION) ;//窗口的最小化图标为缺省图标

         wndclass.hCursor = LoadCursor( NULL, IDC_ARROW) ;//窗口采用箭头光标

         wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH) ;//窗口背景为白色

         wndclass.lpszMenuName = L"mainMenu" ;    //窗口菜单

         wndclass.lpszClassName = lpszClassName ;   //窗口类名

 

         //窗口类注册

         if( !RegisterClass( &wndclass))               //如果注册失败则发出警告声音

         {

                   MessageBeep(0) ;

                   MessageBox(GetFocus(),L"注册失败!",L"TestMLu",MB_OK);

                   return 0;

         }

 

         //创建窗口

         hWnd=CreateWindow(lpszClassName,           //窗口类名

                                               lpszTitle,                      //窗口实例的标题名

                                               WS_OVERLAPPEDWINDOW,//窗口的风格

                                               CW_USEDEFAULT,

                                               CW_USEDEFAULT,            //窗口左上角坐标为缺省值

                                               CW_USEDEFAULT,

                                               CW_USEDEFAULT,            //窗口的高和宽为缺省值

                                               NULL,                                   //此窗口无父窗口

                                               NULL,                                   //此窗口无主菜单

                                               hInstance,                              //创建此窗口的应用程序的当前句柄

                                               NULL) ;                                 //不使用该值

 

         //显示窗口

         ShowWindow( hWnd, SW_SHOWNORMAL) ;

         //绘制用户区

         UpdateWindow(hWnd);

 

         LoadMLu();        //加载MLu

 

         //消息循环

         while( GetMessage(&Msg, NULL, 0, 0))

         {

                   TranslateMessage( &Msg) ;

                   DispatchMessage( &Msg) ;

         }

         if(!UnregisterClass(lpszClassName,hInstance))// Are We Able To Unregister Class

         {

                   MessageBox(NULL,L"Could Not Unregister Class.",L"TestMLu",MB_OK | MB_ICONINFORMATION);

         }

 

         FreeMLu();                  //释放MLu

 

         return Msg.wParam;    //消息循环结束即程序终止时将信息返回系统

}

 

//窗口函数

LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM  wParam,      LPARAM  lParam)

{

         int k;

         void *v;

         luVOID m=0;

 

         switch(Message)

         {

         case WM_CREATE:

                   hwndEditCode=CreateWindow(L"EDIT",NULL,     //创建代码编辑框;

                            WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|WS_BORDER|ES_LEFT|ES_MULTILINE|

                            ES_AUTOHSCROLL|ES_AUTOVSCROLL,

                            0,0,LOWORD(lParam),HIWORD(lParam/2),hWnd,(HMENU)IDE_EditCode,hInstance,NULL);

                   hwndEditOut=CreateWindow(L"EDIT",NULL,       //创建输出编辑框;

                            WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|WS_BORDER|ES_LEFT|ES_MULTILINE|

                            ES_AUTOHSCROLL|ES_AUTOVSCROLL,

                            0,HIWORD(lParam/2+2),LOWORD(lParam),HIWORD(lParam/2-2),hWnd,(HMENU)IDE_EditOut,hInstance,NULL);

                   SetWindowText(hwndEditCode,L"//这里是代码窗口,请将Lu代码写在下面\r\n");

                   SetFocus(hwndEditCode);

                   break;

         case WM_SIZE:

                   MoveWindow(hwndEditCode,0,0,LOWORD(lParam),HIWORD(lParam/2),true);

                   MoveWindow(hwndEditOut,0,HIWORD(lParam/2+2),LOWORD(lParam),HIWORD(lParam/2),true);

                   UpdateWindow(hWnd);

                   break;

         case WM_COMMAND:

                   switch(LOWORD(wParam))

                   {

                   case IDM_cal_com:

                            comcode();         //编译模块

                            break;

                   case IDM_cal_cal:

                            k=UseLu(2);       //申请进入Lu工作区

                            if(!k)                  //申请Lu工作区

                            {

                                     //注册LuMessage函数到Lu系统,使Lu运行时可输出函数信息

                                     //其他Lu扩展库也可注册类似的函数到Lu系统,故每次计算前都进行注册

                                     InsertKey((char *)&m,sizeof(luVOID),luPubKey_User,LuMessage,NULL,NULL,0,v);         

                                     if(hModule) ExeModule(hModule,OutLuData); //执行模块

                                     UseLu(0);  //离开Lu工作区

                            }

                            break;

                   case IDM_cal_comcal:

                            comcode();          //编译模块

                            k=UseLu(2);       //申请进入Lu工作区

                            if(!k)                  //申请Lu工作区

                            {

                                     //注册LuMessage函数到Lu系统,使Lu运行时可输出函数信息

                                     InsertKey((char *)&m,sizeof(luVOID),luPubKey_User,LuMessage,NULL,NULL,0,v);         

                                     if(hModule) ExeModule(hModule,OutLuData); //执行模块

                                     UseLu(0);  //离开Lu工作区

                            }

                            break;

                   }

                   break;

         case WM_DESTROY:

                   PostQuitMessage(0);                               //调用PostQuitMessage发出WM_QUIT消息

                   break;

         default:                                                               //默认时采用系统消息默认处理函数

                   return  DefWindowProc(hWnd,Message,wParam,lParam);

         }

         return 0;

}


16、在工程中打开“TestMLu.cpp”文件,已加入了Lu脚本支持代码。

17、从软件包http://www.forcal.net/xiazai/lu1/lu32.rar中找到 lu32.dllMLu32.dlllu32.libMLu32.libC++格式的头文件lu32.h,复制到以下文件夹。


 

18、重新“生成->生成解决方案”。

19、重新运行程序,弹出几个“MLu:加载动态库失败”的窗口。


 

20、运行一段代码,OK

21、打开文件夹 D:\lu\lu32\TestMLu\Debug


 

22、双击运行“TestMLu.exe”。

23、将“lu32.dll”和“MLu32.dll”复制到该文件夹。


 

24、再双击运行“TestMLu.exe”,和前面一样,弹出几个“MLu:加载动态库失败”的窗口,但可以运行Lu程序。

Lu程序及运行结果:


 

25、从软件包http://www.forcal.net/xiazai/lu1/lu32.rar中找到文件夹“dll”,该文件夹中包含了若干Lu扩展动态库,将整个文件夹复制到这里。

26、再次双击运行“TestMLu.exe”,程序顺利启动。


 

27、运行一段OpenLuGl代码。

28、下载工程TestMLu(不包含文件夹“dll”):http://www.forcal.net/bczl/luc/SDKTestMLu.rar

 

29、如果希望得到一个语法高亮的编辑器,可下载(不包含文件夹“dll”):http://www.forcal.net/bczl/luc/RICHEDTestMLu.rar

RICHEDTestMLu是在SDKTestMLu的基础上生成的,使用了Richedit控件。比较一下RICHEDTestMLuSDKTestMLu中的TestMLu.cpp文件,可以了解做了哪些更改。

注意RICHEDTestMLu中添加了三个语法高亮的关键字 whileifnew,你可以修改代码以增加更多的语法高亮关键字。

由于RICHEDTestMLu中的TestMLu.cpp文件较长,故本文未提供,可在TestMLu.cpp中查找字符串Richedit了解新增的代码部分。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值