更多名人名博

上市公司专栏

实时股价每分更新

纳斯达克(美元)(市值:亿美元)
综指: 涨跌幅:
公司 股价 涨幅度 市值
盛大
网易
九城
畅游
完美
巨人
新浪
百度
恒生指数(港币)(市值:亿港币)
综指: 涨跌幅:
公司 股价 涨幅度 市值
腾讯
金山
网龙
创业板
综指: 涨跌幅:
公司 股价 涨幅度 市值
宝网
d

游戏脚本的实现

来源:互联网02-26-2010

  创建一个角色扮演游戏项目时,会发现在源码中编写游戏相关信息十分困难(这样做也是非常鲁莽的)。最好的办法就是使用外部数据源(类似于程序的代码),称之为游戏脚本(例如对话)。以这种方式,可以控制游戏的流程并节省宝贵的时间,因为不需要在每次做出改变后重新进行编译。

  理解脚本

  当创建游戏时,游戏脚本与所编写的程序代码非常类似,只是游戏脚本相对于游戏引擎而言是外部的。正因为它们是外部的,所以才可以迅速地对脚本做出更改,而不用重新编译整个游戏引擎。否则对于一个超过100万行代码的项目,仅仅为了改变一个对话行就要重新编译整个项目。

  脚本的使用并不会非常困难,而且游戏的每个方面都可以从脚本的运用中获益,比如导航菜单、战斗控制、处理玩家的物品清单,都可以使用脚本。举个例子,进行游戏开发时,把自己想象成处于战斗的用户,他们有规律地使用一系列的法术发起攻击。但在游戏开发过程中可能决定改变部分法术,如果法术的资料是硬编码的话,将面临一个非常麻烦的问题,必须更改控制法术的那些程序代码的每个实例,更不用说去调试和检验那些代码直到正确为止。为什么要花费如此多的时间去做这些改变呢?

  相反,可以将法术以及它们对游戏中人物的影响编写到几个小小的脚本里。每当战斗打响时,这些脚本被加载,并显示可供选择的法术。一旦该法术被施展,一个脚本将发挥自己的作用,从造成损伤到产生运动或法术图形的动画。

  有两种类型的脚本系统可供使用,第一种涉及到使用某种脚本编程语言,在脚本文件中输入命令,编译该文件,并在游戏中执行编译好的脚本文件。第二种是第一种的简化版本,将命令输入到一个文件中,系统通过从一个预先定义好的命令集里选择命令来创建脚本。

  为了简化问题的处理,我们使用第二种脚本系统来创建自己的脚本命令集,称之为Mad Lib ScriptingMLS)系统,它使用一个预先定义好的命令集合(称为行为action),同时每个定义好的命令都与一个游戏功能相关联。

  下图是一个脚本命令集示例:

  使用这样一个有限的行为集合,就不再需要复杂的可编译脚本语言了。相反,只需要告诉脚本系统要使用哪些行为,以及这些行为将使用怎样的选项以实现游戏的功能。对于这种方法,最大的好处就是不再需要为指定一个简单的行为而罗列代码行,可以通过编号来引用行为和选项。

  举个例子,Play Sound行为的编号为4,而且该行为仅要求一个输入,即播放声音的编号。在脚本中只存储两个数值:一个对应于行为,另一个代表了声音。使用数值表示行为(代替文本)的方法可以使这种类型脚本的处理既快速又简单。

  Mad Lib Scripting系统的设计

  创建在游戏中想到的行为,可以通过创建或编辑脚本来填充那些空白点(称之为条目entries)。对于每个行为,请明确提供一个可供空白条目填充的选项列表,它的类型可以从一行文本到一串数字。接着将行为和空白条目进行编号,以便脚本系统可以引用它们,以下是一些行为列表的范例:

  1. Character (*NAME*) takes (*NUMBER*) damage.

  在这6种行为中,都有0个或多个空白条目位于括号内,每个空白条目包含了一个文本字符串或者一个数字,这个行为与可能条目(以及条目的类型)的列表被称之为行为模板(action template),如下图所示:

  一旦使用了行为模板,就可以使用它们的编号而不是行为的文本进行引用(文本的存在只是为了使用户能够更容易理解每个行为所实现的功能)。

  MLS系统的编写

  为了使MLS系统功能尽可能强大,需要设计它以便可以支持多重行为的模板,而且每个行为模板都包含不受数量限制的行为。以这种方式,就可以将系统复用到任何想要的项目中。当一个脚本完成时,将脚本读入到引擎中,并处理各自的行为,为每个由脚本编辑器所输入的行为使用指定的条目。

  一个行为模板需要保存行为的列表,包括文本、条目编号以及每个条目的数据。每个行为按它们在列表中的索引值进行编号,同时每个行为中的空白条目也被加以编号。可以为每个条目指定一种类型(文本型、整数型、浮点型、布尔型、多重选择型),如下所示:

  0. No entry type

  每个条目类型都有一个独特的特征,字符串类型的长度是可以变化的,数字型可以是两个数字范围之间的任何数值,而布尔值可以是TRUE或者FALSE。至于多重选项型,每个选项都有它自己的文本字符串(脚本从一个列表中获取选项,而且所选选项的索引编号比它的文本更适用)。

  行为可以采用如下格式:

  Action #1: Spell targets (*MULTIPLE_CHOICE*).

  Possible choices for blank entry #1:

  我们通过创建结构体ENTRY_RULE和ACTION来处理条目规则与行为。

enumENTRY_TYPE{ENTRY_NONE=0,ENTRY_TEXT,ENTRY_BOOL,ENTRY_INT,ENTRY_FLOAT,ENTRY_CHOICE};char*char_ptr; typedefintBOOL; //============================================================================ //Structurestostoreinformationaboutasingleblankentry. //============================================================================ typedefstructENTRY_RULE { longtype;//typeofblankentry(ENTRY_TEXT,ENTRY_BOOL,) //Thefollowingtwounionscontainthevariousinformationaboutasingleblankentry, //fromthemin/maxvalues(forintandfloattypes),aswellasthenumberofchoices //inamultiplechoiceentry. union { longlong_min;//minvalueoflongtype floatfloat_min;//minvalueoffloattype longnum_choices;//numberofchoicesinlist }; union { longlong_max;//maxvalueoflongtype floatfloat_max;//maxvalueoffloattype char_ptr*choices;//choicetextarray }; //structureconstructortocleartodefaultvalues ENTRY_RULE() { memset(this,0,sizeof(*this)); } //structuredestructortocleanupusedresources ~ENTRY_RULE() { //specialcaseforchoicetype if(type==ENTRY_CHOICE&&choices!=NULL) { for(longi=0;i//============================================================================ //Structurethatstoreasingleaction. //============================================================================ typedefstructACTION { longindex;//actionindex[0,numberofaction-1] chartext[256];//actiontext shortnum_entries_rule;//numberofentriesinaction ENTRY_RULE_PTRentries_rule;//arrayofentrystructures ACTION*next;//nextactioninlinkedlist ACTION() { memset(this,0,sizeof(*this)); } ~ACTION() { delete[]entries_rule; deletenext; } }*ACTION_PTR; 行为模板被存储为文本文件,同时每个行为的文本被包括在括号中。每个包含条目的行为(标记为文本中的波浪字符)紧跟着是条目数据的列表。每个条目由一个描述条目类型(文本型、布尔型、整型、浮点型或选项型)的单词开始。对于文本类型而言并没有更多的需要信息,对于布尔类型来说也是如此。而作为整数和浮点型,则要求一个最小值和最大值。最后,选项类型条目后跟着的是可供选择的编号以及每个选项的文本(包括在引号里)。如下所示:

  "If flag #~ is ~ then"

INT 0 255 BOOL "Else" "Endif" "Set flag #~ to ~" INT 0 255 BOOL "Print ~" TEXT "Move character to ~, ~, ~" FLOAT 0.0 2048.0 FLOAT 0.0 2048.0 FLOAT 0.0 2048.0 "Character ~ ~ ~ ~ points" CHOICE 3 "Main Character" "Caster" "Target" CHOICE 2 "Gains" "Looses" INT 0 128 CHOICE 2 "Hit" "Magic" "Engage in battle sequence #~" INT 0 65535 "End Script"

  脚本条目的创建

  因为ENREY_RULE结构仅包含了行为和条目的规则,所以需要另外的结构数组去存储每个条目的数据。这些新的结构包括了在条目中所使用的文本、布尔值、多重选项,我们使用结构体ENTRY来表示。

//============================================================================typedefstructENTRY { longtype;//typeofblankentry(ENTRY_TEXT,ENTRY_BOOL,) union { longio_value;//usedforsaving/loading longlength;//lengthoftext(0terminator) longselection;//selectioninchoice BOOLbool_value;//BOOLvalue longlong_value;//longbalue floatfloat_value;//floatvalue }; char*text;//entrytextbuffer ENTRY() { memset(this,0,sizeof(*this)); } ~ENTRY() { delete[]text; } }*ENTRY_PTR; 在处理脚本条目的过程中,当一个脚本出现了许多条目时,最麻烦的问题也就接踵而来。脚本中的每个行为都要求一个相匹配的ENTRY_RULE结构,其依次包含了一定数量的ENTRY结构。为了更好地处理一个脚本的结构,还需要其他的结构来记录属于脚本行为的每个条目,我们将它命名为SCRPT。

  //============================================================================typedefstructSCRIPT { longaction_index;//[0,numberofactions-1] longnum_entries;//numberofentriesinthisaction ENTRY_PTRentries;//arrayofentries SCRIPT*prev;//previousinlinkedlist SCRIPT*next;//nextinlinkedlist SCRIPT() { memset(this,0,sizeof(*this)); } ~SCRIPT() { delete[]entries; deletenext; } }*SCRIPT_PTR; prev和next维护了整个脚本的连接列表,为了构造SCRIPT结构的连接列表,从代表脚本的第一个行为的根结构开始,然后使用next和prev将SCRIPT结构连接起来,如下图所示:

  ACTION_TEMPLATE类的整合

  理解了行为模板所使用的结构以及所容纳的脚本后,现在开始将它们整合到一起创建一个加载并处理脚本的类。

  //============================================================================typedefclassACTION_TEMPLATE { private: longm_num_actions;//numberofactionsintemplate ACTION_PTRm_root_action;//listoftemplateactions public: ACTION_TEMPLATE(); ~ACTION_TEMPLATE(); BOOLload_actions(constchar*filename); voidfree(); longget_num_actions(); ACTION_PTRget_root_action(); ACTION_PTRget_action(longact_index); SCRIPT_PTRcreate_script(longact_index); longget_num_entries_rule(longact_index); ENTRY_RULE_PTRget_entry_rule(longact_index,longentry_rule_index); voidexpand_default_action_text(char*buffer,ACTION_PTRaction); BOOLexpand_action_text(char*buffer,SCRIPT_PTRscript); }*ACTION_TEMPLATE_PTR; 实现:

  //------------------------------------------------------------------------staticBOOL_get_quoted_line(FILE*fp,char*data,longmax_data_size) { intc; longpos=0; //readuntilaquoteisreached(orEOF) while(1) { if((c=fgetc(fp))==EOF) returnFALSE; if(c=='"') { //readuntilnextquot(orEOF) while(1) { if((c=fgetc(fp))==EOF) returnFALSE; //returntextwhen2ndquotefound if(c=='"') { data[pos]=0; break; } //addacceptabletexttoline if(c!=0x0a&&c!=0x0d)//ifcharacterisnotlinefeed,notcarriage. { if(posbreak; } } returnTRUE; } //------------------------------------------------------------------------ //Getwordfromfile. //------------------------------------------------------------------------ staticBOOL_get_word(FILE*fp,char*data,longmax_data_size) { intc; longpos=0; //resetwordtoempty data[0]=0; //readuntilanacceptablecharacterfound while(1) { if((c=fgetc(fp))==EOF) { data[0]=0; returnFALSE; } //checkforstartofword if(c!=32&&c!=0x0a&&c!=0x0d)//ifcharacterisnotblank,notlinefeed,notcarriage. { data[pos++]=c; //loopuntilendofword(orEOF) while((c=fgetc(fp))!=EOF) { //breakonacceptablewordseperators if(c==32||c==0x0a||c==0x0d) break; //addifenoughroomleft if(pos//addendoflinetotext data[pos]=0; break; } } returnTRUE; } //------------------------------------------------------------------------ //Constructor,zeromemberdata. //------------------------------------------------------------------------ ACTION_TEMPLATE::ACTION_TEMPLATE() { memset(this,0,sizeof(*this)); } //------------------------------------------------------------------------ //Destructor,releaseallocatedmemory. //------------------------------------------------------------------------ ACTION_TEMPLATE::~ACTION_TEMPLATE() { free(); } //------------------------------------------------------------------------ //Releaseallocatedmemory. //------------------------------------------------------------------------ voidACTION_TEMPLATE::free() { deletem_root_action; m_num_actions=0; } //------------------------------------------------------------------------ //Loadanactiontemplate. //------------------------------------------------------------------------ BOOLACTION_TEMPLATE::load_actions(constchar*filename) { constintsize=256; //freepreviousactionstructures free(); FILE*fp; //opentheactionfile if((fp=fopen(filename,"rb"))==NULL) returnFALSE; ACTION_PTRact_ptr=NULL; //keeploopinguntilendoffilefound while(1) { chartext[size]; //getnextquotedaction if(!_get_quoted_line(fp,text,size)) break; //quitifnoactiontext if(text[0]==0) break; //allocateonactionstructureandappendittolist ACTION_PTRact=newACTION; act->next=NULL; if(act_ptr==NULL) m_root_action=act; else act_ptr->next=act; act_ptr=act; //copyactiontext strcpy(act->text,text); //storeactionindex act->index=m_num_actions; //increasethenumberofactionsloaded m_num_actions++; size_ttext_len=strlen(text); //countthenumberofentriesintheaction for(size_ti=0;iif(text[i]=='~') act->num_entries_rule++; } //allocatedandreadinentries(ifany) if(act->num_entries_rule!=0) { act->entries_rule=newENTRY_RULE[act->num_entries_rule]; for(shortentry_index=0;entry_indexnum_entries_rule;entry_index++) { ENTRY_RULE_PTRentry_rule=&act->entries_rule[entry_index]; //gettypeofentry _get_word(fp,text,size); if(!stricmp(text,"TEXT"))//TEXTtype,nothingdata. { entry_rule->type=ENTRY_TEXT; } elseif(!stricmp(text,"INT"))//LONGtype,getminandmaxvalues { entry_rule->type=ENTRY_INT; //getminvalue _get_word(fp,text,size); entry_rule->long_min=atol(text); //getmaxvalue _get_word(fp,text,size); entry_rule->long_max=atol(text); } elseif(!stricmp(text,"FLOAT"))//FLOATtype,getminandmaxvalues { entry_rule->type=ENTRY_FLOAT; //getminvalue _get_word(fp,text,size); entry_rule->float_min=(float)atof(text); //getmaxvalue _get_word(fp,text,size); entry_rule->float_max=(float)atof(text); } elseif(!stricmp(text,"BOOL"))//BOOLtype,nooptions. { entry_rule->type=ENTRY_BOOL; } elseif(!stricmp(text,"CHOICE"))//CHOICEtype,getnumberofentriesandentry'stexts. { entry_rule->type=ENTRY_CHOICE; //getthenumberofchoices _get_word(fp,text,size); entry_rule->num_choices=atol(text); entry_rule->choices=newchar_ptr[entry_rule->num_choices]; //geteachentrytext for(longchoice_index=0;choice_indexnum_choices;choice_index++) { _get_quoted_line(fp,text,size); entry_rule->choices[choice_index]=strdup(text); } } } } } fclose(fp); returnTRUE; } //------------------------------------------------------------------------ //Returnnumberofactionsintemplate. //------------------------------------------------------------------------ longACTION_TEMPLATE::get_num_actions() { returnm_num_actions; } //------------------------------------------------------------------------ //ReturnrootACTIONstructure. //------------------------------------------------------------------------ ACTION_PTRACTION_TEMPLATE::get_root_action() { returnm_root_action; } //------------------------------------------------------------------------ //ReturnspecifiedACTIONstructure. //------------------------------------------------------------------------ ACTION_PTRACTION_TEMPLATE::get_action(longact_index) { //returnerrorifhigherthannumberofactions if(act_index>=m_num_actions) returnNULL; ACTION_PTRact_ptr=m_root_action; //scanlist while(act_ptr) { if(act_ptr->index==act_index) returnact_ptr; act_ptr=act_ptr->next; } returnNULL; } //------------------------------------------------------------------------ //Createscriptfromspecifiedactionindex. //------------------------------------------------------------------------ SCRIPT_PTRACTION_TEMPLATE::create_script(longact_index) { //makesureitisavalidaction if(act_index>=m_num_actions) returnNULL; ACTION_PTRact_ptr; //getpointertoaction if((act_ptr=get_action(act_index))==NULL) returnNULL; //createnewSCRIPTstructure SCRIPT_PTRscript=newSCRIPT; script->action_index=act_index; script->num_entries=act_ptr->num_entries_rule; script->entries=newENTRY[script->num_entries]; //setupeachentry for(longi=0;inum_entries;i++) { script->entries[i].type=act_ptr->entries_rule[i].type; //setupentrydatabasedontype switch(script->entries[i].type) { caseENTRY_TEXT: script->entries[i].text=NULL; break; caseENTRY_INT: script->entries[i].long_value=act_ptr->entries_rule[i].long_min; break; caseENTRY_FLOAT: script->entries[i].float_value=act_ptr->entries_rule[i].float_min; break; caseENTRY_BOOL: script->entries[i].bool_value=TRUE; break; caseENTRY_CHOICE: script->entries[i].selection=0; break; } } returnscript; } //------------------------------------------------------------------------ //Returnnumberofentriesruleinthespecifiedaction. //------------------------------------------------------------------------ longACTION_TEMPLATE::get_num_entries_rule(longact_index) { //getpointertospecifiedaction ACTION_PTRact_ptr=get_action(act_index); //return0ifonerror if(act_ptr==NULL) return0; returnact_ptr->num_entries_rule; } //------------------------------------------------------------------------ //Returnspecifiedentryruleinspecifiedaction. //------------------------------------------------------------------------ ENTRY_RULE_PTRACTION_TEMPLATE::get_entry_rule(longact_index,longentry_rule_index) { ACTION_PTRact_ptr=get_action(act_index); if(act_ptr==NULL||entry_rule_index>=act_ptr->num_entries_rule) returnNULL; return&(act_ptr->entries_rule[entry_rule_index]); } //------------------------------------------------------------------------ //Expandactiontextusingmin/first/TRUEchoicevalues. //------------------------------------------------------------------------ voidACTION_TEMPLATE::expand_default_action_text(char*buffer,ACTION_PTRaction) { //copyactiontextintobufferifnoentriesrule if(action->num_entries_rule==0) { strcpy(buffer,action->text); return; } //expandentrytypesintoactiontext size_tbuf_pos=0; longrule_index=0; size_ttext_len=strlen(action->text); constsize_tmem_size=256; for(size_ti=0;icharmemory[mem_size]; //expandtheentryintotextbasedonvalue,text,etc. if(action->text[i]=='~') { if(action->entries_rule[rule_index].type==ENTRY_TEXT) { memcpy(&buffer[buf_pos],"(*TEXT*)",8); buf_pos+=8; } elseif(action->entries_rule[rule_index].type==ENTRY_INT) { sprintf(memory,"(*%lu*)",action->entries_rule[rule_index].long_min); memcpy(&buffer[buf_pos],memory,strlen(memory)); buf_pos+=strlen(memory); } elseif(action->entries_rule[rule_index].type==ENTRY_FLOAT) { sprintf(memory,"(*%lf*)",action->entries_rule[rule_index].float_min); memcpy(&buffer[buf_pos],memory,strlen(memory)); buf_pos+=strlen(memory); } elseif(action->entries_rule[rule_index].type==ENTRY_BOOL) { memcpy(&buffer[buf_pos],"(*TRUE*)",8); buf_pos+=8; } elseif(action->entries_rule[rule_index].type==ENTRY_CHOICE) { memcpy(&buffer[buf_pos],"(*",2); buf_pos+=2; char*choice=action->entries_rule[rule_index].choices[0]; size_tchoice_len=strlen(choice); memcpy(&buffer[buf_pos],choice,choice_len); buf_pos+=choice_len; memcpy(&buffer[buf_pos],"*)",2); buf_pos+=2; } rule_index++; } else buffer[buf_pos++]=action->text[i]; } buffer[buf_pos]=0; } //------------------------------------------------------------------------ //Expandactiontextusingselections. //------------------------------------------------------------------------ BOOLACTION_TEMPLATE::expand_action_text(char*buffer,SCRIPT_PTRscript) { //getapointertothespecifiedaction ACTION_PTRact_ptr=get_action(script->action_index); if(act_ptr==NULL) returnFALSE; //copyactiontextintobufferifnoentries if(act_ptr->num_entries_rule==0) { strcpy(buffer,act_ptr->text); returnTRUE; } //expandentrytypesintoactiontext size_tbuf_pos=0; size_tentry_index=0; charmemory[256]; size_tmemory_length; size_tact_text_length=strlen(act_ptr->text); for(size_ti=0;i//expandtheentryintotextbasedonvalues,text,etc. if(act_ptr->text[i]=='~') { if(act_ptr->entries_rule[entry_index].type==ENTRY_TEXT&& script->entries[entry_index].type==ENTRY_TEXT) { memcpy(&buffer[buf_pos],"(*",2); buf_pos+=2; if(script->entries[entry_index].text) { for(longj=0;j<32;j++)//copyatmost32charaters { if(script->entries[entry_index].text[j]==0) break; buffer[buf_pos++]=script->entries[entry_index].text[j]; } } memcpy(&buffer[buf_pos],"*)",2); buf_pos+=2; } elseif(act_ptr->entries_rule[entry_index].type==ENTRY_INT) { sprintf(memory,"(*%lu*)",script->entries[entry_index].long_value); memory_length=strlen(memory); memcpy(&buffer[buf_pos],memory,memory_length); buf_pos+=memory_length; } elseif(act_ptr->entries_rule[entry_index].type==ENTRY_FLOAT) { sprintf(memory,"(*%lf*)",script->entries[entry_index].float_value); memory_length=strlen(memory); memcpy(&buffer[buf_pos],memory,memory_length); buf_pos+=memory_length; } elseif(act_ptr->entries_rule[entry_index].type==ENTRY_BOOL) { if(script->entries[entry_index].bool_value) memcpy(&buffer[buf_pos],"(*TRUE*)",9); else memcpy(&buffer[buf_pos],"(*FALSE*)",9); buf_pos+=9; } elseif(act_ptr->entries_rule[entry_index].type==ENTRY_CHOICE) { memcpy(&buffer[buf_pos],"(*",2); buf_pos+=2; longsel=script->entries[entry_index].selection; char*choice=act_ptr->entries_rule[entry_index].choices[sel]; size_tchoice_len=strlen(choice); memcpy(&buffer[buf_pos],choice,choice_len); buf_pos+=choice_len; memcpy(&buffer[buf_pos],"*)",2); buf_pos+=2; } entry_index++; } else buffer[buf_pos++]=act_ptr->text[i]; } buffer[buf_pos]=0; returnTRUE; }

  MLS编辑器的使用

  MLS系统仅使用到数字:代表行为的编号,随后条目的数量,以及代表条目数据的编号。计算机特别擅长处理数字的工作,但我们的需要更多。需要将脚本构造成易于理解的文本行,并让脚本编辑器将键入的文本转变为脚本系统可以处理的一系列数字。

  在编辑一个脚本期间,并不处理任何数字方面的问题,所以编辑器的工作还包括加载数字并将它们转换回易于阅读理解的文本行。因此,也可以这么说,仅需要使用一系列的文本命令构造一个脚本,然后使用脚本编辑器将这些命令转换成代表它们数值,反之亦然。

  MLS编辑器导入那些代表行为的文本行,并赋予用户能力去编辑行为列表,以及在空白条目点填上行为,MLS编辑器的外观如下图所示:

  下表详细解释了脚本编辑器每个按钮的用途:

  将行为添加到脚本中时(添加脚本或插入脚本),请注意行为的文本将被扩展,并添加到脚本列表框中(位于脚本编辑器顶端的列表框)。脚本行为从上到下进行存储,根节点存储了最顶端的脚本行为,脚本从顶端开始往下处理,与典型的C/C++代码非常类似。

  请注意,每次添加、插入、或编辑一个脚本条目时,修改行为条目的对话框将出现(如下图所示),将使用这个对话框去修改脚本行为的条目。

  MLS编辑器的创建

  首先,我们设计MLS编辑器主窗口的界面:

  接着我们设计修改脚本的对话框:

  resource.h的定义:

  //{{NO_DEPENDENCIES}}#defineIDD_MAIN101 #defineIDD_MODIFY102 #defineIDC_SCRIPT1000 #defineIDC_SCRIPTLIST1001 #defineIDC_SCRIPT_ADDR1001 #defineIDC_ADD1002 #defineIDC_PREV1002 #defineIDC_DELETE1003 #defineIDC_NEXT1003 #defineIDC_UP1004 #defineIDC_OK21004 #defineIDC_DOWN1005 #defineIDC_ACTIONS1006 #defineIDC_ACTION1006 #defineIDC_EDIT1007 #defineIDC_SAVE1008 #defineIDC_LOAD1009 #defineIDC_INSERT1010 #defineIDC_LOADACTIONS1013 #defineIDC_NEW1014 #defineIDC_TRUE1015 #defineIDC_FALSE1016 #defineIDC_VALUE1017 #defineIDC_MIN1018 #defineIDC_MAX1019 #defineIDC_TEXT1020 #defineIDC_CHOICE1023 #defineIDC_OK1024 #defineIDC_CANCEL1025 #defineIDC_APPLY1027 #defineIDC_ACTIONTEXT1028 #defineIDC_FRAME1029 #defineIDC_NUM1033 #defineIDC_STATIC_MIN1034 #defineIDC_STATIC_VALUE1035 #defineIDC_STATIC_MAX1036 //Nextdefaultvaluesfornewobjects // #ifdefAPSTUDIO_INVOKED #ifndefAPSTUDIO_READONLY_SYMBOLS #define_APS_NEXT_RESOURCE_VALUE105 #define_APS_NEXT_COMMAND_VALUE40001 #define_APS_NEXT_CONTROL_VALUE1042 #define_APS_NEXT_SYMED_VALUE101 #endif #endif

  MlsEdit.rc的定义:

//MicrosoftVisualC++generatedresourcescript.#include"resource.h" #defineAPSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // //GeneratedfromtheTEXTINCLUDE2resource. // #include"afxres.h" ///////////////////////////////////////////////////////////////////////////// #undefAPSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// //English(U.S.)resources #if!defined(AFX_RESOURCE_DLL)||defined(AFX_TARG_ENU) #ifdef_WIN32 LANGUAGELANG_ENGLISH,SUBLANG_ENGLISH_US #pragmacode_page(1252) #endif//_WIN32 ///////////////////////////////////////////////////////////////////////////// // //Dialog // IDD_MAINDIALOGEX0,0,381,262 STYLEDS_SETFONT|WS_MINIMIZEBOX|WS_CAPTION|WS_SYSMENU CAPTION"MLSEditor" CLASS"mlseditclass" FONT11,"SegoeUI",400,0,0x0 BEGIN LISTBOXIDC_SCRIPT,10,17,296,93,LBS_NOINTEGRALHEIGHT|WS_VSCROLL|WS_TABSTOP PUSHBUTTON"AddtoScript",IDC_ADD,312,150,55,15 PUSHBUTTON"Delete",IDC_DELETE,312,15,55,15 PUSHBUTTON"MoveUp",IDC_UP,312,75,55,15 PUSHBUTTON"MoveDown",IDC_DOWN,312,95,55,15 PUSHBUTTON"Edit",IDC_EDIT,312,35,55,15 PUSHBUTTON"SaveScript",IDC_SAVE,247,115,55,15 PUSHBUTTON"LoadScript",IDC_LOAD,127,115,55,15 PUSHBUTTON"LoadActions",IDC_LOADACTIONS,312,200,55,15 PUSHBUTTON"NewScript",IDC_NEW,10,115,55,15 LISTBOXIDC_ACTION,10,150,296,97,LBS_NOINTEGRALHEIGHT|WS_VSCROLL|WS_TABSTOP PUSHBUTTON"InsertinScript",IDC_INSERT,312,175,55,15 GROUPBOX"Script",IDC_STATIC,7,7,367,128 GROUPBOX"Actions",IDC_STATIC,7,138,367,117 LISTBOXIDC_SCRIPT_ADDR,155,86,89,102,LBS_NOINTEGRALHEIGHT|NOTWS_VISIBLE|WS_VSCROLL|WS_TABSTOP END IDD_MODIFYDIALOGEX0,0,241,138 STYLEDS_SETFONT|DS_MODALFRAME|WS_POPUP|WS_CAPTION CAPTION"ModifyActionEntry" FONT11,"SegoeUI",400,0,0x0 BEGIN LTEXT"Static",IDC_ACTIONTEXT,7,5,227,35,WS_BORDER DEFPUSHBUTTON"OK",IDC_OK,51,117,50,14 LTEXT"Entry#",IDC_STATIC,5,45,25,8 GROUPBOX"TITLE",IDC_FRAME,7,60,227,56 EDITTEXTIDC_VALUE,97,96,60,12,ES_AUTOHSCROLL LTEXT"Min.",IDC_STATIC_MIN,50,70,20,10 LTEXT"Max.",IDC_STATIC_MAX,50,80,20,10 LTEXT"Value",IDC_STATIC_VALUE,50,98,20,10 LTEXT"MIN#",IDC_MIN,97,70,60,8 LTEXT"MAX#",IDC_MAX,97,81,60,8 EDITTEXTIDC_TEXT,35,80,165,12,ES_AUTOHSCROLL COMBOBOXIDC_CHOICE,35,80,165,60,CBS_DROPDOWN|WS_VSCROLL|WS_TABSTOP PUSHBUTTON"Cancel",IDC_CANCEL,126,117,50,14 RTEXT"#of#",IDC_NUM,48,45,30,8 PUSHBUTTON"<--",IDC_PREV,86,45,20,10 PUSHBUTTON"-->",IDC_NEXT,111,45,20,10 CONTROL"TRUE",IDC_TRUE,"Button",BS_AUTORADIOBUTTON,69,84,34,10 CONTROL"FALSE",IDC_FALSE,"Button",BS_AUTORADIOBUTTON,128,84,36,10 PUSHBUTTON"OK",IDC_OK2,85,117,50,14 END ///////////////////////////////////////////////////////////////////////////// // //DESIGNINFO // #ifdefAPSTUDIO_INVOKED GUIDELINESDESIGNINFO BEGIN IDD_MAIN,DIALOG BEGIN LEFTMARGIN,7 RIGHTMARGIN,374 TOPMARGIN,7 BOTTOMMARGIN,255 END IDD_MODIFY,DIALOG BEGIN LEFTMARGIN,7 RIGHTMARGIN,234 TOPMARGIN,7 BOTTOMMARGIN,131 END END #endif//APSTUDIO_INVOKED #ifdefAPSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // //TEXTINCLUDE // 1TEXTINCLUDE BEGIN "resource.h\0" END 2TEXTINCLUDE BEGIN "#include""afxres.h""\r\n" "\0" END 3TEXTINCLUDE BEGIN "\r\n" "\0" END #endif//APSTUDIO_INVOKED #endif//English(U.S.)resources ///////////////////////////////////////////////////////////////////////////// #ifndefAPSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // //GeneratedfromtheTEXTINCLUDE3resource. // ///////////////////////////////////////////////////////////////////////////// #endif//notAPSTUDIO_INVOKED

  我们首先定义一些全局变量和辅助函数:

  #include////////////////////////////////////globalvariable//////////////////////////////////// HWNDg_hwnd; ACTION_TEMPLATEg_action_template; longg_num_script; BOOLg_show_cancel; SCRIPT_PTRg_root_script; SCRIPT_PTRg_modify_script;//pointertoscripttomodify //TheOPENFILENAMEstructurecontainsinformationthattheGetOpenFileNameandGetSaveFileName //functionsusetoinitializeanOpenorSaveAsdialogbox.Aftertheuserclosesthedialogbox, //thesystemreturnsinformationabouttheuser'sselectioninthisstructure. OPENFILENAMEg_ofn; charg_action_file[MAX_PATH]; charg_script_file[MAX_PATH]; HWNDg_script_wnd; HWNDg_script_addr_wnd; HWNDg_action_wnd; BOOLCALLBACKmodify_dialog_proc(HWNDhwnd,UINTmsg_id,WPARAMword_param,LPARAMlong_param); ////////////////////////////////////function//////////////////////////////////// //----------------------------------------------------------------------------------- //Removeallitemsfromlistbox. //----------------------------------------------------------------------------------- voidreset_listbox(HWNDlistbox) { //AnapplicationsendsanLB_RESETCONTENTmessagetoremoveallitemsfromalistbox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_RESETCONTENT,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam;); // //wParam: //Notused;mustbezero. // //lParam: //Notused;mustbezero. // //Thismessagedoesnotreturnavalue. SendMessage(listbox,LB_RESETCONTENT,0,0); } //----------------------------------------------------------------------------------- //Returnindexofcurrentselectediteminlistbox. //----------------------------------------------------------------------------------- LRESULTget_listbox_selected(HWNDlistbox) { //SendanLB_GETCURSELmessagetoretrievetheindexofthecurrentlyselecteditem,ifany, //inasingle-selectionlistbox. // // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_GETCURSEL,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Notused;mustbezero. // //lParam: //Notused;mustbezero. // //ReturnValue //Inasingle-selectionlistbox,thereturnvalueisthezero-basedindexofthecurrently //selecteditem.Ifthereisnoselection,thereturnvalueisLB_ERR. returnSendMessage(listbox,LB_GETCURSEL,0,0); } //----------------------------------------------------------------------------------- //Setcurrentselectediteminlistbox. //----------------------------------------------------------------------------------- LRESULTset_listbox_selected(HWNDlistbox,intselection) { //AnapplicationsendsanLB_SETCURSELmessagetoselectastringandscrollitintoview,ifnecessary. //Whenthenewstringisselected,thelistboxremovesthehighlightfromthepreviouslyselectedstring. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_SETCURSEL,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Specifiesthezero-basedindexofthestringthatisselected. //Ifthisparameteris-1,thelistboxissettohavenoselection. // //MicrosoftWindows95/Windows98/WindowsMillenniumEdition(WindowsMe): //ThewParamparameterislimitedto16-bitvalues.Thismeanslistboxescannotcontainmore //than32,767items.Althoughthenumberofitemsisrestricted,thetotalsizeinbytesofthe //itemsinalistboxislimitedonlybyavailablememory. // //lParam: //Thisparameterisnotused. // //ReturnValue: //Ifanerroroccurs,thereturnvalueisLB_ERR.IfthewParamparameteris–1,thereturnvalue //isLB_ERReventhoughnoerroroccurred. // //Remarks: //Usethismessageonlywithsingle-selectionlistboxes.Youcannotuseittosetorremovea //selectioninamultiple-selectionlistbox. returnSendMessage(listbox,LB_SETCURSEL,selection,NULL); } //----------------------------------------------------------------------------------- //Gettextofcurrentselectediteminlistbox. //----------------------------------------------------------------------------------- LRESULTget_listbox_text(HWNDlistbox,intindex,char*text) { //AnapplicationsendsanLB_GETTEXTmessagetoretrieveastringfromalistbox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_GETTEXT,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Specifiesthezero-basedindexofthestringtoretrieve. // //MicrosoftWindows95/Windows98/WindowsMillenniumEdition(WindowsMe): //ThewParamparameterislimitedto16-bitvalues.Thismeanslistboxescannotcontainmorethan //32,767items.Althoughthenumberofitemsisrestricted,thetotalsizeinbytesoftheitems //inalistboxislimitedonlybyavailablememory. // //lParam: //Pointertothebufferthatwillreceivethestring;itistypeLPTSTRwhichissubsequentlycastto //anLPARAM.Thebuffermusthavesufficientspaceforthestringandaterminatingnullcharacter. //AnLB_GETTEXTLENmessagecanbesentbeforetheLB_GETTEXTmessagetoretrievethelength,inTCHARs, //ofthestring. // //ReturnValue: //Thereturnvalueisthelengthofthestring,inTCHARs,excludingtheterminatingnullcharacter. //IfwParamdoesnotspecifyavalidindex,thereturnvalueisLB_ERR. // //Remarks //Ifyoucreatethelistboxwithanowner-drawnstylebutwithouttheLBS_HASSTRINGSstyle, //thebufferpointedtobythelParamparameterwillreceivethevalueassociatedwiththeitem //(theitemdata). returnSendMessage(listbox,LB_GETTEXT,index,(LPARAM)text); } //----------------------------------------------------------------------------------- //Countlistboxitemsnumber. //----------------------------------------------------------------------------------- LRESULTcount_listbox(HWNDlistbox) { //AnapplicationsendsanLB_GETCOUNTmessagetoretrievethenumberofitemsinalistbox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_GETCOUNT,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Notused;mustbezero. // //lParam: //Notused;mustbezero. // //ReturnValue: //Thereturnvalueisthenumberofitemsinthelistbox,orLB_ERRifanerroroccurs. // //Remarks: //Thereturnedcountisonegreaterthantheindexvalueofthelastitem(theindexiszero-based). returnSendMessage(listbox,LB_GETCOUNT,0,0); } //----------------------------------------------------------------------------------- //Addstringtolistbox. //----------------------------------------------------------------------------------- LRESULTadd_string_to_listbox(HWNDlistbox,constchar*string) { //AnapplicationsendsanLB_ADDSTRINGmessagetoaddastringtoalistbox.Ifthelistboxdoesnothave //theLBS_SORTstyle,thestringisaddedtotheendofthelist.Otherwise,thestringisinsertedinto //thelistandthelistissorted. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_ADDSTRING,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Thisparameterisnotused. // //lParam: //Pointertothenull-terminatedstringthatistobeadded. // //Ifyoucreatethelistboxwithanowner-drawnstylebutwithouttheLBS_HASSTRINGSstyle, //thisparameterisstoredasitemdatainsteadofthestringtowhichitwouldotherwisepoint. //YoucansendtheLB_GETITEMDATAandLB_SETITEMDATAmessagestoretrieveormodifytheitemdata. // //ReturnValue: //Thereturnvalueisthezero-basedindexofthestringinthelistbox.Ifanerroroccurs, //thereturnvalueisLB_ERR.Ifthereisinsufficientspacetostorethenewstring,thereturnvalue //isLB_ERRSPACE. returnSendMessage(listbox,LB_ADDSTRING,0,(LPARAM)string); } //----------------------------------------------------------------------------------- //Insertstringintolistboxatspecifiedposition. //----------------------------------------------------------------------------------- LRESULTinsert_string_to_listbox(HWNDlistbox,intindex,constchar*string) { //AnapplicationsendsanLB_INSERTSTRINGmessagetoinsertastringintoalistbox. //UnliketheLB_ADDSTRINGmessage,theLB_INSERTSTRINGmessagedoesnotcausealistwith //theLBS_SORTstyletobesorted. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_INSERTSTRING,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Specifiesthezero-basedindexofthepositionatwhichtoinsertthestring. //Ifthisparameteris–1,thestringisaddedtotheendofthelist. // //MicrosoftWindows95/Windows98/WindowsMillenniumEdition(WindowsMe): //ThewParamparameterislimitedto16-bitvalues.Thismeanslistboxescannotcontainmore //than32,767items.Althoughthenumberofitemsisrestricted,thetotalsizeinbytesof //theitemsinalistboxislimitedonlybyavailablememory. // //lParam: //Pointertothenull-terminatedstringtobeinserted.Ifyoucreatethelistboxwithan //owner-drawnstylebutwithouttheLBS_HASSTRINGSstyle,thevalueofthelParamparameteris //storedasitemdatainsteadofthestringitwouldotherwisepointto.Youcansendthe //LB_GETITEMDATAandLB_SETITEMDATAmessagestoretrieveormodifytheitemdata. // //ReturnValue: //Thereturnvalueistheindexofthepositionatwhichthestringwasinserted. //Ifanerroroccurs,thereturnvalueisLB_ERR.Ifthereisinsufficientspacetostorethenew //string,thereturnvalueisLB_ERRSPACE. // //Remarks: //TheLB_INITSTORAGEmessagehelpsspeeduptheinitializationoflistboxesthathavealarge //numberofitems(morethan100).Itreservesthespecifiedamountofmemorysothatsubsequent //LB_INSERTSTRINGmessagestaketheshortestpossibletime.YoucanuseestimatesforthewParam //andlParamparameters.Ifyouoverestimate,theextramemoryisallocated;ifyouunderestimate, //thenormalallocationisusedforitemsthatexceedtherequestedamount. // //IfthelistboxhasWS_HSCROLLstyleandyouinsertastringwiderthanthelistbox,sendan //LB_SETHORIZONTALEXTENTmessagetoensurethehorizontalscrollbarappears. // //MicrosoftWindowsNT/Windows2000/WindowsXP:ForanANSIapplication,thesystemconvertsthetext //inalistboxtoUnicodeusingCP_ACP.Thiscancauseproblems.Forexample,accentedRomancharacters //inanon-UnicodelistboxinJapaneseWindowswillcomeoutgarbled.Tofixthis,eithercompile //theapplicationasUnicodeoruseanowner-drawnlistbox. returnSendMessage(listbox,LB_INSERTSTRING,index,(LPARAM)string); } //----------------------------------------------------------------------------------- //Deletestringinspecifiedindexfromlistbox. //----------------------------------------------------------------------------------- LRESULTdelete_listbox_string(HWNDlistbox,intselection) { //AnapplicationsendsanLB_DELETESTRINGmessagetodeleteastringinalistbox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_DELETESTRING,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Specifiesthezero-basedindexofthestringtobedeleted. // //MicrosoftWindows95/Windows98/WindowsMillenniumEdition(WindowsMe):T //hewParamparameterislimitedto16-bitvalues.Thismeanslistboxescannotcontainmorethan //32,767items.Althoughthenumberofitemsisrestricted,thetotalsizeinbytesoftheitems //inalistboxislimitedonlybyavailablememory. // //lParam: //Thisparameterisnotused. // //ReturnValue: //Thereturnvalueisacountofthestringsremaininginthelist.ThereturnvalueisLB_ERRif //thewParamparameterspecifiesanindexgreaterthanthenumberofitemsinthelist. // //Remarks: //Ifanapplicationcreatesthelistboxwithanowner-drawnstylebutwithouttheLBS_HASSTRINGSstyle, //thesystemsendsaWM_DELETEITEMmessagetotheownerofthelistboxsotheapplicationcanfree //anyadditionaldataassociatedwiththeitem. returnSendMessage(listbox,LB_DELETESTRING,selection,0); } //----------------------------------------------------------------------------------- //Setbuttonstate. //----------------------------------------------------------------------------------- LRESULTset_button_state(HWNDbutton,UINTstate) { //AnapplicationsendsaBM_SETCHECKmessagetosetthecheckstateofaradiobuttonorcheckbox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)BM_SETCHECK,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=0;notused,mustbezero //); // //wParam: //Specifiesthecheckstate.Thisparametercanbeoneofthefollowingvalues. // //BST_CHECKED: //Setsthebuttonstatetochecked. //BST_INDETERMINATE: //Setsthebuttonstatetograyed,indicatinganindeterminatestate. //UsethisvalueonlyifthebuttonhastheBS_3STATEorBS_AUTO3STATEstyle. //BST_UNCHECKED: //Setsthebuttonstatetocleared. // //lParam: //Thisparameterisnotused. // //ReturnValue //Thismessagealwaysreturnszero. // //Remarks //TheBM_SETCHECKmessagehasnoeffectonpushbuttons. returnSendMessage(button,BM_SETCHECK,state,0); } //----------------------------------------------------------------------------------- //Returnbuttonstate. //----------------------------------------------------------------------------------- LRESULTget_button_state(HWNDbutton) { returnSendMessage(button,BM_GETCHECK,0,0); } //----------------------------------------------------------------------------------- //Resetcombobox. //----------------------------------------------------------------------------------- LRESULTreset_combo_content(HWNDcombo) { //AnapplicationsendsaCB_RESETCONTENTmessagetoremoveallitemsfromthelistboxandedit //controlofacombobox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsCB_OKAYinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)CB_RESETCONTENT,//messageID //(WPARAM)wParam,//=0;notused,mustbezero //(LPARAM)lParam//=0;notused,mustbezero //); // //wParam: //Notused;mustbezero. //lParam: //Notused;mustbezero. // //ReturnValue: //ThismessagealwaysreturnsCB_OKAY. // //Remarks: //Ifyoucreatethecomboboxwithanowner-drawnstylebutwithouttheCBS_HASSTRINGSstyle, //theownerofthecomboboxreceivesaWM_DELETEITEMmessageforeachiteminthecombobox. returnSendMessage(combo,CB_RESETCONTENT,0,0); } //----------------------------------------------------------------------------------- //Addstringtocombobox. //----------------------------------------------------------------------------------- LRESULTadd_string_to_combo(HWNDcombo,char*string) { returnSendMessage(combo,CB_ADDSTRING,0,(LPARAM)string); } //----------------------------------------------------------------------------------- //Setcurrentselctionincombobox. //----------------------------------------------------------------------------------- LRESULTset_combo_cur_sel(HWNDcombo,UINTcur_sel) { //AnapplicationsendsaCB_SETCURSELmessagetoselectastringinthelistofacombobox. //Ifnecessary,thelistscrollsthestringintoview.Thetextintheeditcontrolofthe //comboboxchangestoreflectthenewselection,andanypreviousselectioninthelistisremoved. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)CB_SETCURSEL,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=0;notused,mustbezero //); // //wParam: //Specifiesthezero-basedindexofthestringtoselect.Ifthisparameteris–1, //anycurrentselectioninthelistisremovedandtheeditcontroliscleared. // //lParam: //Thisparameterisnotused. // //ReturnValue: //Ifthemessageissuccessful,thereturnvalueistheindexoftheitemselected. //IfwParamisgreaterthanthenumberofitemsinthelistorifwParamis–1, //thereturnvalueisCB_ERRandtheselectioniscleared. returnSendMessage(combo,CB_SETCURSEL,cur_sel,0); } //----------------------------------------------------------------------------------- //Getcurrentselctionincombobox. //----------------------------------------------------------------------------------- LRESULTget_combo_cur_sel(HWNDcombo) { //AnapplicationsendsaCB_GETCURSELmessagetoretrievetheindexofthecurrentlyselecteditem, //ifany,inthelistboxofacombobox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)CB_GETCURSEL,//messageID //(WPARAM)wParam,//=0;notused,mustbezero //(LPARAM)lParam//=0;notused,mustbezero //); // //wParam: //Notused;mustbezero. // //lParam: //Notused;mustbezero. // //ReturnValue: //Thereturnvalueisthezero-basedindexofthecurrentlyselecteditem. //Ifnoitemisselected,itisCB_ERR. returnSendMessage(combo,CB_GETCURSEL,0,0); }

  首先来看看WinMain函数以及主窗口处理过程的实现:

  //-----------------------------------------------------------------------------------intWINAPIWinMain(HINSTANCEinst,HINSTANCE,LPSTRcmd_line,intcmd_show) { constchar*class_name="mlseditclass"; WNDCLASSwin_class; //createwindowclassandregisterit win_class.style=CS_HREDRAW|CS_VREDRAW; win_class.lpfnWndProc=window_proc; win_class.cbClsExtra=0; win_class.cbWndExtra=DLGWINDOWEXTRA; win_class.hInstance=inst; win_class.hIcon=LoadIcon(inst,IDI_APPLICATION); win_class.hCursor=LoadCursor(NULL,IDC_ARROW); win_class.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1); win_class.lpszMenuName=NULL; win_class.lpszClassName=class_name; if(!RegisterClass(&win_class)) returnFALSE; //TheCreateDialogmacrocreatesamodelessdialogboxfromadialogboxtemplateresource. //TheCreateDialogmacrousestheCreateDialogParamfunction. // //HWNDCreateDialog( //HINSTANCEhInstance, //LPCTSTRlpTemplate, //HWNDhWndParent, //DLGPROClpDialogFunc); // //hInstance: //[in]Handletothemodulewhoseexecutablefilecontainsthedialogboxtemplate. // //lpTemplate //[in]Specifiesthedialogboxtemplate.Thisparameteriseitherthepointertoanull-terminated //characterstringthatspecifiesthenameofthedialogboxtemplateoranintegervaluethat //specifiestheresourceidentifierofthedialogboxtemplate.Iftheparameterspecifiesaresource //identifier,itshigh-orderwordmustbezeroanditslow-orderwordmustcontaintheidentifier. //YoucanusetheMAKEINTRESOURCEmacrotocreatethisvalue. // //hWndParent: //[in]Handletothewindowthatownsthedialogbox. // //lpDialogFunc: //[in]Pointertothedialogboxprocedure.Formoreinformationaboutthedialogboxprocedure, //seeDialogProc. // //ReturnValue: //Ifthefunctionsucceeds,thereturnvalueisthehandletothedialogbox. //Ifthefunctionfails,thereturnvalueisNULL.Togetextendederrorinformation,callGetLastError. //Createthedialogboxwindowandshowit g_hwnd=CreateDialog(inst,MAKEINTRESOURCE(IDD_MAIN),0,NULL); ShowWindow(g_hwnd,cmd_show); UpdateWindow(g_hwnd); g_script_wnd=GetDlgItem(g_hwnd,IDC_SCRIPT); g_script_addr_wnd=GetDlgItem(g_hwnd,IDC_SCRIPT_ADDR); g_action_wnd=GetDlgItem(g_hwnd,IDC_ACTION); //forcealoadofactionindefault.mla load_actions_from_file("..\\Data\\Default.mla"); MSGmsg; //messageloop while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } deleteg_root_script; UnregisterClass(class_name,inst); return0; } //------------------------------------------------------------------------------------------------ //Mainwindowprocedure. //------------------------------------------------------------------------------------------------ LRESULTCALLBACKwindow_proc(HWNDhwnd,UINTmsg_id,WPARAMword_param,LPARAMlong_param) { switch(msg_id) { caseWM_COMMAND: wm_command_proc(word_param); break; caseWM_CREATE: //initializethesave/loaddialogboxinformation ZeroMemory(&g_ofn,sizeof(OPENFILENAME)); g_ofn.lStructSize=sizeof(OPENFILENAME); g_ofn.nMaxFile=MAX_PATH; g_ofn.nMaxFileTitle=MAX_PATH; g_ofn.Flags=OFN_HIDEREADONLY|OFN_CREATEPROMPT|OFN_OVERWRITEPROMPT; //clearscriptfilenmae g_script_file[0]=0; g_action_file[0]=0; //clearalllistboxes reset_listbox(g_script_wnd); reset_listbox(g_script_addr_wnd); reset_listbox(g_action_wnd); break; caseWM_DESTROY: PostQuitMessage(0); break; default: returnDefWindowProc(hwnd,msg_id,word_param,long_param); } return0; }

  使用load_actions_from_file函数来加载行为脚本:

  //-----------------------------------------------------------------------------------BOOLload_actions_from_file(constchar*filename) { if(filename==NULL)//askforfilenameifnonepassed { //setuptheopendialoginformation g_ofn.hwndOwner=g_hwnd; g_ofn.lpstrFile=g_action_file; g_ofn.lpstrTitle="LoadActionsFile"; g_ofn.lpstrFilter="MLSActionFiles(*.mla)\0*.mla\0AllFiles(*.*)\0*.*\0\0"; g_ofn.lpstrDefExt="mla"; //getactiontemplatefilename // //CreatesanOpendialogboxthatletstheuserspecifythedrive,directory, //andthenameofafiletoopen. if(!GetOpenFileName(&g_ofn)) returnFALSE; //askifsuretomakenewscript if(!new_script()) returnFALSE; } else strcpy(g_action_file,filename); //attempttoloadactions if(!g_action_template.load_actions(g_action_file)) { MessageBox(g_hwnd,g_action_file,"Unabletoopenfile",MB_OK); returnFALSE; } //clearthelistbox reset_listbox(g_action_wnd); //getapointertotheparentaction ACTION_PTRact_ptr=g_action_template.get_root_action(); longnum_actions=g_action_template.get_num_actions(); //loopthroughallactions for(longi=0;ichartext[2048]; //getexpandedactiontext g_action_template.expand_default_action_text(text,act_ptr); //addactiontexttoactionlist add_string_to_listbox(g_action_wnd,text); //gotonextaction act_ptr=act_ptr->next; } returnTRUE; } 所有的脚本编辑命令都在wm_command_proc函数中处理:

  //-------------------------------------------------------------------------------------------------voidwm_command_proc(WPARAMword_param) { switch(LOWORD(word_param)) { caseIDC_NEW://createanewscript new_script(); break; caseIDC_LOAD://loadascriptfile load_script(); break; caseIDC_SAVE://saveascriptfile save_script(); break; caseIDC_LOADACTIONS://loadanactionfile load_actions_from_file(NULL); break; caseIDC_SCRIPT://editascript if(HIWORD(word_param)!=LBN_DBLCLK) break; caseIDC_EDIT: edit_script(); break; caseIDC_ACTIONS://addanactiotion if(HIWORD(word_param)!=LBN_DBLCLK) break; caseIDC_ADD: add_script(); break; caseIDC_INSERT://insertascript insert_script(); break; caseIDC_DELETE://deleteascript delete_script(); break; caseIDC_UP://moveupscript move_up_script(); break; caseIDC_DOWN://movedownscript move_down_script(); break; } } new_script函数用来提示用户是否真要创建一个脚本,如果是将清除脚本列表框中的脚本:

  //-----------------------------------------------------------------------------------BOOLnew_script() { constchar*msg_info="Areyousure?(Discardsanyunsavedscriptinformation)"; if(MessageBox(g_hwnd,msg_info,"NewScript",MB_YESNO)==IDYES) { deleteg_root_script; g_root_script=NULL; g_num_script=0; //clearoutlistbox reset_listbox(g_script_wnd); reset_listbox(g_script_addr_wnd); returnTRUE; } returnTRUE; } load_script用来加载脚本并将其添加到脚本列表框中:

  //-----------------------------------------------------------------------------------BOOLload_script() { //setuptheopendialoginfomation g_ofn.hwndOwner=g_hwnd; g_ofn.lpstrFile=g_script_file; g_ofn.lpstrTitle="LoadScriptFile"; g_ofn.lpstrFilter="MLSScriptFiles(*.mls)\0*.mls\0AllFiles(*.*)\0*.*\0\0"; g_ofn.lpstrDefExt="mls"; //askforfilename if(!GetOpenFileName(&g_ofn)) returnFALSE; FILE*fp; //openthefileforinput if((fp=fopen(g_script_file,"rb"))==NULL) { MessageBox(g_hwnd,g_script_file,"Unabletoopenfile.",MB_OK); returnFALSE; } //deletethecurrentscript deleteg_root_script; chartext[2048]; SCRIPT_PTRscript_ptr=NULL; //getnumberofscript fread(&g_num_script,1,sizeof(long),fp); //loopthrougheachscript for(longi=0;i//allocateascriptstructureandlinkin SCRIPT_PTRscript=newSCRIPT; script->next=NULL; if(script_ptr==NULL) g_root_script=script; else script_ptr->next=script; script_ptr=script; //getindexofactionsandnumberofentries fread(&script->action_index,1,sizeof(long),fp); fread(&script->num_entries,1,sizeof(long),fp); //getentrydata(ifany) if(script->num_entries) { //allocateentryarray script->entries=newENTRY[script->num_entries]; //loadineachentry for(longj=0;jnum_entries;j++) { //getentrytypeanddata fread(&script->entries[j].type,1,sizeof(long),fp); fread(&script->entries[j].io_value,1,sizeof(long),fp); //gettext(ifany) if(script->entries[j].type==ENTRY_TEXT) { longlength=script->entries[j].length; if(length) { //allocateabufferandgetstring script->entries[j].text=newchar[length]; fread(script->entries[j].text,1,length,fp); } } } } } fclose(fp); //clearthescriptandscriptaddressboxes reset_listbox(g_script_wnd); reset_listbox(g_script_addr_wnd); //addscripttolistbox script_ptr=g_root_script; while(script_ptr) { //addscripttexttolistbox g_action_template.expand_action_text(text,script_ptr); add_string_to_listbox(g_script_wnd,text); //addscriptpointertolistbox sprintf(text,"%lu",script_ptr); add_string_to_listbox(g_script_addr_wnd,text); script_ptr=script_ptr->next; } returnTRUE; } save_script将脚本存储到文件中:

  //-----------------------------------------------------------------------------------BOOLsave_script() { //makesurethereissomescriptactions if(g_num_script==0) { MessageBox(g_hwnd,"Noscriptactionsexist!","Error",MB_OK); returnFALSE; } //setuptheopendialoginformation g_ofn.hwndOwner=g_hwnd; g_ofn.lpstrFile=g_script_file; g_ofn.lpstrTitle="SaveScriptFile"; g_ofn.lpstrFilter="MLSScriptFiles(*.mls)\0*.mls\0AllFiles(*.*)\0*.*\0\0"; g_ofn.lpstrDefExt="mls"; //askforfilename if(!GetSaveFileName(&g_ofn)) returnFALSE; FILE*fp; //openthefileforoutput if((fp=fopen(g_script_file,"wb"))==NULL) { MessageBox(g_hwnd,g_script_file,"Unabletosavefile.",MB_OK); returnFALSE; } //outputnumberofscripts fwrite(&g_num_script,1,sizeof(long),fp); //loopthrougheachscript for(longi=0;ichartext[256]; //getapointertothescriptstructure(donotdependonlist) get_listbox_text(g_script_addr_wnd,i,text); SCRIPT_PTRscript_ptr=(SCRIPT_PTR)atol(text); //outputindexofactionandnumberofentries fwrite(&script_ptr->action_index,1,sizeof(long),fp); fwrite(&script_ptr->num_entries,1,sizeof(long),fp); //outputentrydata(ifany) for(longj=0;jnum_entries;j++) { //writeentrytypeanddata fwrite(&script_ptr->entries[j].type,1,sizeof(long),fp); fwrite(&script_ptr->entries[j].io_value,1,sizeof(long),fp); //writetext(ifany) if(script_ptr->entries[j].type==ENTRY_TEXT&&script_ptr->entries[j].text) fwrite(script_ptr->entries[j].text,1,script_ptr->entries[j].length,fp); } } fclose(fp); returnTRUE; } edit_script用于编辑当前选中的脚本行:

  //-----------------------------------------------------------------------------------voidedit_script() { intsel; //seeifascriptwasselected if((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR) return; chartext[2048]; //getpointertoscriptentry get_listbox_text(g_script_addr_wnd,sel,text); SCRIPT_PTRscript=(SCRIPT_PTR)atol(text); //setupthescripttoedit g_modify_script=script; //callthemodifyscriptdialog g_show_cancel=FALSE; DialogBox(NULL,MAKEINTRESOURCE(IDD_MODIFY),g_hwnd,modify_dialog_proc); //updatescriptlistbox g_action_template.expand_action_text(text,script); delete_listbox_string(g_script_wnd,sel); insert_string_to_listbox(g_script_wnd,sel,text); }

  add_script将行为列表框中选中的行为添加到脚本列表框中:

  //-----------------------------------------------------------------------------------voidadd_script() { longsel; //makesureanactionisselected if((sel=(long)get_listbox_selected(g_action_wnd))==LB_ERR) return; //createanewscriptandaddit SCRIPT_PTRscript=g_action_template.create_script(sel); g_modify_script=script; //callthemodifyscriptdialog g_show_cancel=TRUE; if(DialogBox(NULL,MAKEINTRESOURCE(IDD_MODIFY),g_hwnd,modify_dialog_proc)) { //addscripttolinklist script->next=g_root_script; if(g_root_script!=NULL) g_root_script->prev=script; g_root_script=script; //displayscripttext chartext[2048]; ACTION_PTRact_ptr=g_action_template.get_action(sel); g_action_template.expand_action_text(text,script); add_string_to_listbox(g_script_wnd,text); //addpointertoscriptaddresslistbox sprintf(text,"%lu",script); add_string_to_listbox(g_script_addr_wnd,text); //increasecount g_num_script++; } else deletescript; }

  insert_script将行为列表框中选中的行为脚本添加到脚本列表框中选中脚本的上方:

  //-----------------------------------------------------------------------------------voidinsert_script() { intact_index,script_index; //getlocationtoinsertaction if((script_index=(int)get_listbox_selected(g_script_wnd))==LB_ERR) return; //makesureanactionisselected if((act_index=(int)get_listbox_selected(g_action_wnd))==LB_ERR) return; //createanewscript SCRIPT_PTRscript=g_action_template.create_script(act_index); g_modify_script=script; //callthemodifyscriptdialog g_show_cancel=TRUE; if(DialogBox(NULL,MAKEINTRESOURCE(IDD_MODIFY),g_hwnd,modify_dialog_proc)) { //addthescripttolinklist script->prev=NULL; script->next=g_root_script; g_root_script->prev=script; g_root_script=script; chartext[2048]; //displayscriptactiontext ACTION_PTRact_ptr=g_action_template.get_action(act_index); g_action_template.expand_action_text(text,script); insert_string_to_listbox(g_script_wnd,script_index,text); //addpointertoscriptaddresslistbox sprintf(text,"%lu",script); insert_string_to_listbox(g_script_addr_wnd,script_index,text); g_num_script++; } else deletescript; } delete_script用于删除脚本列表框中的一条脚本:

  //-----------------------------------------------------------------------------------voiddelete_script() { intsel; //makesurethereisaselection if((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR) return; chartext[2048]; //getpointertoscriptentry get_listbox_text(g_script_addr_wnd,sel,text); SCRIPT_PTRscript=(SCRIPT_PTR)atol(text); //removescriptfromlinkedlist if(script->prev) script->prev->next=script->next; else g_root_script=script->next; if(script->next) script->next->prev=script->prev; script->next=NULL;//sowholelistisnotdeleted deletescript; //clearfromscriptandscriptlist delete_listbox_string(g_script_wnd,sel); delete_listbox_string(g_script_addr_wnd,sel); g_num_script--; }

  move_up_script和move_down_script分别将脚本上移和下移一行:

  //-----------------------------------------------------------------------------------voidmove_up_script() { intsel; //makesurethereisaselection if((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR) return; //makesureitisnottopmostselection if(sel==0) return; chartext[2048]; get_listbox_text(g_script_wnd,sel,text); delete_listbox_string(g_script_wnd,sel); insert_string_to_listbox(g_script_wnd,sel-1,text); get_listbox_text(g_script_addr_wnd,sel,text); delete_listbox_string(g_script_addr_wnd,sel); insert_string_to_listbox(g_script_addr_wnd,sel-1,text); set_listbox_selected(g_script_wnd,sel-1); } //----------------------------------------------------------------------------------- //Movedownscript. //----------------------------------------------------------------------------------- voidmove_down_script() { intsel; //makesurethereisaselection if((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR) return; //makesureitisnotbottommostselection if(sel>=count_listbox(g_script_wnd)-1) return; chartext[2048]; get_listbox_text(g_script_wnd,sel,text); delete_listbox_string(g_script_wnd,sel); insert_string_to_listbox(g_script_wnd,sel+1,text); get_listbox_text(g_script_addr_wnd,sel,text); delete_listbox_string(g_script_addr_wnd,sel); insert_string_to_listbox(g_script_addr_wnd,sel+1,text); set_listbox_selected(g_script_wnd,sel+1); } 修改脚本对话框的窗口处理过程通过modify_dialog_proc来实现:

  //-----------------------------------------------------------------------------------BOOLCALLBACKmodify_dialog_proc(HWNDdlg,UINTmsg_id,WPARAMword_param,LPARAMlong_param) { staticlongentry_index=0; switch(msg_id) { caseWM_INITDIALOG: if(g_modify_script==NULL)//returnanerrorifthereisnoscripttomodify { //TheEndDialogfunctiondestroysamodaldialogbox,causingthesystemtoendanyprocessing //forthedialogbox. // //BOOLEndDialog(HWNDhDlg, //INT_PTRnResult //); // //hDlg: //[in]Handletothedialogboxtobedestroyed. // //nResult: //[in]Specifiesthevaluetobereturnedtotheapplicationfromthefunctionthatcreated //thedialogbox. // //ReturnValue: //Ifthefunctionsucceeds,thereturnvalueisnonzero. // //Ifthefunctionfails,thereturnvalueiszero.Togetextendederrorinformation, //callGetLastError. EndDialog(dlg,FALSE); returnFALSE; } //editfirstentry entry_index=0; //displayentrytext set_modify_dialog(dlg,g_modify_script,entry_index); //showorhidecancelbutton ShowWindow(GetDlgItem(dlg,IDC_CANCEL),g_show_cancel); if(g_show_cancel==FALSE) { ShowWindow(GetDlgItem(dlg,IDC_OK),false); ShowWindow(GetDlgItem(dlg,IDC_OK2),true); } else ShowWindow(GetDlgItem(dlg,IDC_OK2),false); returnTRUE; caseWM_COMMAND: switch(LOWORD(word_param)) { caseIDC_OK: caseIDC_OK2: update_entry(dlg,g_modify_script,entry_index); EndDialog(dlg,TRUE); returnTRUE; caseIDC_CANCEL: EndDialog(dlg,FALSE); returnTRUE; caseIDC_PREV: //onlybotherifnotfirstentry if(entry_index>0) { //applychanges //gotopreviousentry update_entry(dlg,g_modify_script,entry_index); entry_index--; set_modify_dialog(dlg,g_modify_script,entry_index); } break; caseIDC_NEXT: //onlybotherifnotlastentry if(entry_indexnum_entries-1) { //applychanges //gotonextentry update_entry(dlg,g_modify_script,entry_index); entry_index++; set_modify_dialog(dlg,g_modify_script,entry_index); } break; } } returnFALSE; } 不同的条目类型修改脚本的对话框外观也不相同,这是通过set_modify_dialog函数来实现:

  //-----------------------------------------------------------------------------------voidset_modify_dialog(HWNDdlg,SCRIPT_PTRscript,longentry_index) { chartext[2048]; //displayfullactiontext g_action_template.expand_action_text(text,script); SetWindowText(GetDlgItem(dlg,IDC_ACTIONTEXT),text); //getcontrolhandle HWNDpre_wnd=GetDlgItem(dlg,IDC_PREV); HWNDnext_wnd=GetDlgItem(dlg,IDC_NEXT); HWNDtext_wnd=GetDlgItem(dlg,IDC_TEXT); HWNDchoice_wnd=GetDlgItem(dlg,IDC_CHOICE); HWNDtrue_wnd=GetDlgItem(dlg,IDC_TRUE); HWNDfalse_wnd=GetDlgItem(dlg,IDC_FALSE); HWNDmin_wnd=GetDlgItem(dlg,IDC_MIN); HWNDmax_wnd=GetDlgItem(dlg,IDC_MAX); HWNDvalue_wnd=GetDlgItem(dlg,IDC_VALUE); HWNDstatic_min_wnd=GetDlgItem(dlg,IDC_STATIC_MIN); HWNDstatic_max_wnd=GetDlgItem(dlg,IDC_STATIC_MAX); HWNDstatic_value_wnd=GetDlgItem(dlg,IDC_STATIC_VALUE); HWNDnum_wnd=GetDlgItem(dlg,IDC_NUM); HWNDframe_wnd=GetDlgItem(dlg,IDC_FRAME); //hideallcontrols ShowWindow(pre_wnd,FALSE); ShowWindow(next_wnd,FALSE); ShowWindow(text_wnd,FALSE); ShowWindow(choice_wnd,FALSE); ShowWindow(true_wnd,FALSE); ShowWindow(false_wnd,FALSE); ShowWindow(min_wnd,FALSE); ShowWindow(max_wnd,FALSE); ShowWindow(value_wnd,FALSE); ShowWindow(static_min_wnd,FALSE); ShowWindow(static_max_wnd,FALSE); ShowWindow(static_value_wnd,FALSE); //clearinformation SetWindowText(num_wnd,""); SetWindowText(frame_wnd,"NoEntries"); //getpointertoaction ACTION_PTRact_ptr=g_action_template.get_action(script->action_index); //returnifnoentriestoedit if(act_ptr->num_entries_rule==0) return; if(act_ptr->num_entries_rule>1) { ShowWindow(pre_wnd,TRUE); ShowWindow(next_wnd,TRUE); } sprintf(text,"%luof%lu",entry_index+1,act_ptr->num_entries_rule); SetWindowText(num_wnd,text); EnableWindow(num_wnd,TRUE); //enableandsetspecificfieldsbasedonentrytype switch(script->entries[entry_index].type) { caseENTRY_TEXT: SetWindowText(frame_wnd,"Textentry"); if(script->entries[entry_index].text) SetWindowText(text_wnd,script->entries[entry_index].text); ShowWindow(text_wnd,TRUE); EnableWindow(text_wnd,TRUE); break; caseENTRY_BOOL: SetWindowText(frame_wnd,"Booleanentry"); if(script->entries[entry_index].bool_value) { set_button_state(true_wnd,BST_CHECKED); set_button_state(false_wnd,BST_UNCHECKED); } else { set_button_state(true_wnd,BST_UNCHECKED); set_button_state(false_wnd,BST_CHECKED); } ShowWindow(true_wnd,TRUE); ShowWindow(false_wnd,TRUE); break; caseENTRY_INT: SetWindowText(frame_wnd,"Integerentry"); sprintf(text,"%lu",act_ptr->entries_rule[entry_index].long_min); SetWindowText(min_wnd,text); sprintf(text,"%lu",act_ptr->entries_rule[entry_index].long_max); SetWindowText(max_wnd,text); sprintf(text,"%lu",script->entries[entry_index].long_value); SetWindowText(value_wnd,text); ShowWindow(min_wnd,TRUE); ShowWindow(max_wnd,TRUE); ShowWindow(value_wnd,TRUE); ShowWindow(static_min_wnd,TRUE); ShowWindow(static_max_wnd,TRUE); ShowWindow(static_value_wnd,TRUE); break; caseENTRY_FLOAT: SetWindowText(frame_wnd,"Floatentry"); sprintf(text,"%lu",act_ptr->entries_rule[entry_index].float_min); SetWindowText(min_wnd,text); sprintf(text,"%lu",act_ptr->entries_rule[entry_index].float_max); SetWindowText(max_wnd,text); sprintf(text,"%lu",script->entries[entry_index].float_value); SetWindowText(value_wnd,text); ShowWindow(min_wnd,TRUE); ShowWindow(max_wnd,TRUE); ShowWindow(value_wnd,TRUE); ShowWindow(static_min_wnd,TRUE); ShowWindow(static_max_wnd,TRUE); ShowWindow(static_value_wnd,TRUE); break; caseENTRY_CHOICE: SetWindowText(frame_wnd,"Choiceentry"); reset_combo_content(choice_wnd); if(act_ptr->entries_rule[entry_index].num_choices) { for(longi=0;ientries_rule[entry_index].num_choices;i++) add_string_to_combo(choice_wnd,act_ptr->entries_rule[entry_index].choices[i]); set_combo_cur_sel(choice_wnd,script->entries[entry_index].selection); ShowWindow(choice_wnd,TRUE); } break; } } 布尔型:

  整型或浮点型:

  多重选项型:

  文本型:

  脚本信息的更新通过update_entry来实现:

  //-----------------------------------------------------------------------------------voidupdate_entry(HWNDdlg,SCRIPT_PTRscript,longentry_index) { //getpointertoaction ACTION_PTRact_ptr=g_action_template.get_action(script->action_index); //returnifnoentriestoupdateorincorrectentryindex if(act_ptr->num_entries_rule==0||entry_index>=script->num_entries) return; constintsize=2048; chartext[size]; ENTRY&r_entry=script->entries[entry_index]; ENTRY_RULE&r_entry_rule=act_ptr->entries_rule[entry_index]; //updatefieldsbasedontype switch(r_entry_rule.type) { caseENTRY_TEXT: //deleteoldtext delete[]r_entry.text; r_entry.text=NULL; r_entry.length=0; GetWindowText(GetDlgItem(dlg,IDC_TEXT),text,size); if(text) { r_entry.length=(long)strlen(text)+1; r_entry.text=newchar[r_entry.length]; strcpy(r_entry.text,text); } break; caseENTRY_BOOL: //chooseTRUEorFALSEfromradiobutton if(get_button_state(GetDlgItem(dlg,IDC_TRUE))==BST_CHECKED) r_entry.bool_value=TRUE; else r_entry.bool_value=FALSE; break; caseENTRY_INT: //getintvalueandboundscheckwithmin/max GetWindowText(GetDlgItem(dlg,IDC_VALUE),text,size); r_entry.long_value=atol(text); if(r_entry.long_valueif(r_entry.long_value>r_entry_rule.long_max) r_entry.long_value=r_entry_rule.long_max; break; caseENTRY_FLOAT: //getintvalueandboundscheckwithmin/max GetWindowText(GetDlgItem(dlg,IDC_VALUE),text,size); r_entry.float_value=(float)atof(text); if(r_entry.float_valueif(r_entry.float_value>r_entry_rule.float_max) r_entry.float_value=r_entry_rule.float_max; break; caseENTRY_CHOICE: //storechoiceselection r_entry.selection=(long)get_combo_cur_sel(GetDlgItem(dlg,IDC_CHOICE)); break; } } 截图:

  事实上,创建可接受脚本的游戏引擎对于大多数的游戏而言,将产生出一个非常开放的源代码以及高效率的项目。

  Mad Lib Scripts的执行

  窗口设计:

  resouce.h:

  //{{NO_DEPENDENCIES}}#defineIDD_DEMO101 #defineIDC_LOAD1000 #defineIDC_EXECUTE1001 #defineIDC_SCRIPT1002 #defineIDC_TITLE1003 //Nextdefaultvaluesfornewobjects // #ifdefAPSTUDIO_INVOKED #ifndefAPSTUDIO_READONLY_SYMBOLS #define_APS_NEXT_RESOURCE_VALUE102 #define_APS_NEXT_COMMAND_VALUE40001 #define_APS_NEXT_CONTROL_VALUE1004 #define_APS_NEXT_SYMED_VALUE101 #endif #endif MlsDemo.rc:

  //MicrosoftVisualC++generatedresourcescript.#include"resource.h" #defineAPSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // //GeneratedfromtheTEXTINCLUDE2resource. // #include"afxres.h" ///////////////////////////////////////////////////////////////////////////// #undefAPSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// //English(U.S.)resources #if!defined(AFX_RESOURCE_DLL)||defined(AFX_TARG_ENU) #ifdef_WIN32 LANGUAGELANG_ENGLISH,SUBLANG_ENGLISH_US #pragmacode_page(1252) #endif//_WIN32 ///////////////////////////////////////////////////////////////////////////// // //Dialog // IDD_DEMODIALOGEX0,0,356,198 STYLEDS_SETFONT|DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENU CAPTION"MLSDemo" CLASS"MLSDEMO" FONT12,"SegoeUI",400,0,0x0 BEGIN PUSHBUTTON"LoadScript",IDC_LOAD,254,173,43,14 PUSHBUTTON"Execute",IDC_EXECUTE,306,173,43,14 LISTBOXIDC_SCRIPT,7,5,342,162,NOTLBS_NOTIFY|LBS_NOINTEGRALHEIGHT|WS_VSCROLL|WS_TABSTOP CONTROL"",IDC_TITLE,"Static",SS_LEFTNOWORDWRAP,7,175,232,14 END ///////////////////////////////////////////////////////////////////////////// // //DESIGNINFO // #ifdefAPSTUDIO_INVOKED GUIDELINESDESIGNINFO BEGIN IDD_DEMO,DIALOG BEGIN LEFTMARGIN,7 RIGHTMARGIN,349 TOPMARGIN,7 BOTTOMMARGIN,191 END END #endif//APSTUDIO_INVOKED #ifdefAPSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // //TEXTINCLUDE // 1TEXTINCLUDE BEGIN "resource.h\0" END 2TEXTINCLUDE BEGIN "#include""afxres.h""\r\n" "\0" END 3TEXTINCLUDE BEGIN "\r\n" "\0" END #endif//APSTUDIO_INVOKED #endif//English(U.S.)resources ///////////////////////////////////////////////////////////////////////////// #ifndefAPSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // //GeneratedfromtheTEXTINCLUDE3resource. // ///////////////////////////////////////////////////////////////////////////// #endif//notAPSTUDIO_INVOKED 实现:

/************************************************************************* #include #include #include #include"resource.h" #pragmawarning(disable:4996) enumENTRY_TYPE{ENTRY_NONE=0,ENTRY_TEXT,ENTRY_BOOL,ENTRY_INT,ENTRY_FLOAT,ENTRY_CHOICE}; //============================================================================ //structurethatstoreallentriesfactinformation. //============================================================================ typedefstructENTRY { longtype;//typeofblankentry(ENTRY_TEXT,ENTRY_BOOL,) union { longio_value;//usedforsaving/loading longlength;//lengthoftext(0terminator) longselection;//selectioninchoice BOOLbool_value;//BOOLvalue longlong_value;//longbalue floatfloat_value;//floatvalue }; char*text;//entrytextbuffer ENTRY() { memset(this,0,sizeof(*this)); } ~ENTRY() { delete[]text; } }*ENTRY_PTR; //============================================================================ //structurethatstoreall //============================================================================ typedefstructSCRIPT { longaction_index;//[0,numberofactions-1] longnum_entries;//numberofentriesinthisaction ENTRY_PTRentries;//arrayofentries SCRIPT*prev;//previousinlinkedlist SCRIPT*next;//nextinlinkedlist SCRIPT() { memset(this,0,sizeof(*this)); } ~SCRIPT() { delete[]entries; deletenext; } }*SCRIPT_PTR; /////////////////////////////////////functiondeclaration///////////////////////////////////// SCRIPT_PTRscript_if_flag_then(SCRIPT_PTRscript); SCRIPT_PTRscript_else(SCRIPT_PTRscript); SCRIPT_PTRscript_endif(SCRIPT_PTRscript); SCRIPT_PTRscript_set_flag(SCRIPT_PTRscript); SCRIPT_PTRscript_print(SCRIPT_PTRscript); SCRIPT_PTRscript_move(SCRIPT_PTRscript); SCRIPT_PTRscript_gain_loss(SCRIPT_PTRscript); SCRIPT_PTRscript_battle(SCRIPT_PTRscript); SCRIPT_PTRscript_end(SCRIPT_PTRscript); LRESULTCALLBACKwindow_proc(HWNDhwnd,UINTmsg_id,WPARAMword_param,LPARAMlong_param); SCRIPT_PTRload_script_from_file(constchar*filename); BOOLrun_script(); voidreset_listbox(HWNDlistbox); LRESULTadd_string_to_listbox(HWNDlistbox,constchar*string); /////////////////////////////////////globalvariables///////////////////////////////////// HWNDg_hwnd; SCRIPT_PTRg_root_script; BOOLg_flags[256]; OPENFILENAMEg_ofn; charg_script_file[MAX_PATH]; typedefSCRIPT_PTR(*SCRIPT_FUNC)(SCRIPT_PTRscript); SCRIPT_FUNCg_script_list[]= { script_if_flag_then, script_else, script_endif, script_set_flag, script_print, script_move, script_gain_loss, script_battle, script_end, }; //----------------------------------------------------------------------------------- //Routineentry. //----------------------------------------------------------------------------------- intWINAPIWinMain(HINSTANCEinst,HINSTANCE,LPSTRcmd_line,intcmd_show) { constchar*class_name="MLSDEMO"; WNDCLASSwin_class; //createwindowclassandregisterit win_class.style=CS_HREDRAW|CS_VREDRAW; win_class.lpfnWndProc=window_proc; win_class.cbClsExtra=0; win_class.cbWndExtra=DLGWINDOWEXTRA; win_class.hInstance=inst; win_class.hIcon=LoadIcon(inst,IDI_APPLICATION); win_class.hCursor=LoadCursor(NULL,IDC_ARROW); win_class.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1); win_class.lpszMenuName=NULL; win_class.lpszClassName=class_name; if(!RegisterClass(&win_class)) returnFALSE; //TheCreateDialogmacrocreatesamodelessdialogboxfromadialogboxtemplateresource. //TheCreateDialogmacrousestheCreateDialogParamfunction. // //HWNDCreateDialog( //HINSTANCEhInstance, //LPCTSTRlpTemplate, //HWNDhWndParent, //DLGPROClpDialogFunc); // //hInstance: //[in]Handletothemodulewhoseexecutablefilecontainsthedialogboxtemplate. // //lpTemplate //[in]Specifiesthedialogboxtemplate.Thisparameteriseitherthepointertoanull-terminated //characterstringthatspecifiesthenameofthedialogboxtemplateoranintegervaluethat //specifiestheresourceidentifierofthedialogboxtemplate.Iftheparameterspecifiesaresource //identifier,itshigh-orderwordmustbezeroanditslow-orderwordmustcontaintheidentifier. //YoucanusetheMAKEINTRESOURCEmacrotocreatethisvalue. // //hWndParent: //[in]Handletothewindowthatownsthedialogbox. // //lpDialogFunc: //[in]Pointertothedialogboxprocedure.Formoreinformationaboutthedialogboxprocedure, //seeDialogProc. // //ReturnValue: //Ifthefunctionsucceeds,thereturnvalueisthehandletothedialogbox. //Ifthefunctionfails,thereturnvalueisNULL.Togetextendederrorinformation,callGetLastError. //Createthedialogboxwindowandshowit g_hwnd=CreateDialog(inst,MAKEINTRESOURCE(IDD_DEMO),0,NULL); ShowWindow(g_hwnd,cmd_show); UpdateWindow(g_hwnd); MSGmsg; //messageloop while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } deleteg_root_script; UnregisterClass(class_name,inst); return0; } //------------------------------------------------------------------------------------------------ //Mainwindowprocedure. //------------------------------------------------------------------------------------------------ LRESULTCALLBACKwindow_proc(HWNDhwnd,UINTmsg_id,WPARAMword_param,LPARAMlong_param) { switch(msg_id) { caseWM_COMMAND: switch(LOWORD(word_param)) { caseIDC_LOAD://loadascriptfile if(!GetOpenFileName(&g_ofn)) break; //deletethecurrentscript deleteg_root_script; if((g_root_script=load_script_from_file(g_script_file))==NULL) MessageBox(hwnd,g_script_file,"Unalbetoopenfile.",MB_OK); //displayscriptfilename SetWindowText(GetDlgItem(g_hwnd,IDC_TITLE),g_script_file); break; caseIDC_EXECUTE://runascriptfile run_script(); break; } break; caseWM_CREATE: //initializethesave/loaddialogboxinformation ZeroMemory(&g_ofn,sizeof(OPENFILENAME)); g_ofn.lStructSize=sizeof(OPENFILENAME); g_ofn.nMaxFile=MAX_PATH; g_ofn.Flags=OFN_HIDEREADONLY; g_ofn.lpstrFile=g_script_file; g_ofn.lpstrTitle="LoadScriptFile"; g_ofn.lpstrFilter="MLSScriptFiles(*.mls)\0*.mls\0AllFiles(*.*)\0*.*\0\0"; g_ofn.lpstrDefExt="mls"; g_ofn.nMaxFileTitle=MAX_PATH; //setdefaultopenpath strcpy(g_script_file,"..\\data\\test.mls"); reset_listbox(GetDlgItem(g_hwnd,IDC_SCRIPT)); break; caseWM_DESTROY: PostQuitMessage(0); break; default: returnDefWindowProc(hwnd,msg_id,word_param,long_param); } return0; } //---------------------------------------------------------------------------------------- //Loadscriptsfromfileandreturnrootscript. //---------------------------------------------------------------------------------------- SCRIPT_PTRload_script_from_file(constchar*filename) { FILE*fp; if((fp=fopen(filename,"rb"))==NULL) returnNULL; longnum_script; fread(&num_script,1,sizeof(long),fp); SCRIPT_PTRroot_script; SCRIPT_PTRscript_ptr=NULL; //loopthrougheachscript for(longi=0;i//allocateascriptstructureandlinkin SCRIPT_PTRscript=newSCRIPT; script->next=NULL; if(script_ptr==NULL) root_script=script; else script_ptr->next=script; script_ptr=script; fread(&script->action_index,1,sizeof(long),fp); fread(&script->num_entries,1,sizeof(long),fp); //getentrydata(ifany) if(script->num_entries) { script->entries=newENTRY[script->num_entries]; //loadineachentry for(longj=0;jnum_entries;j++) { fread(&script->entries[j].type,1,sizeof(long),fp); fread(&script->entries[j].io_value,1,sizeof(long),fp); //gettextifany if(script->entries[j].type==ENTRY_TEXT&&script->entries[j].length) { script->entries[j].text=newchar[script->entries[j].length]; fread(script->entries[j].text,1,script->entries[j].length,fp); } } } } fclose(fp); returnroot_script; } //---------------------------------------------------------------------------------------- //Executeallscripts. //---------------------------------------------------------------------------------------- BOOLrun_script() { //clearflags for(shorti=0;i<256;i++) g_flags[i]=FALSE; SCRIPT_PTRscript_ptr; //startatbeginningofscript if((script_ptr=g_root_script)==NULL) returnFALSE; reset_listbox(GetDlgItem(g_hwnd,IDC_SCRIPT)); //loopuntilnomorescripts while(script_ptr) { //CallscriptfunctionandbreakonNULLreturnvalue, //anyotherreturntypeisthepointertothenextfunction. script_ptr=g_script_list[script_ptr->action_index](script_ptr); } returnTRUE; } //---------------------------------------------------------------------------------------- //Handle'ifthen'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_if_flag_then(SCRIPT_PTRscript) { BOOLskipping; longflag_index=script->entries[0].long_value%256; //seeifaflagmatchessecondentry if(g_flags[flag_index]==script->entries[1].bool_value) skipping=FALSE; else skipping=TRUE; script=script->next; while(script) { //if'else',flipskipmode if(script->action_index==1) skipping=!skipping; //breakon'endif' if(script->action_index==2) returnscript->next; //Processscriptfunctioninconditionalblock, //makingsuretoskipactionswhenconditionnotmet. if(skipping) script=script->next; else { if((script=g_script_list[script->action_index](script))==NULL) break; } } returnNULL; } //---------------------------------------------------------------------------------------- //Handle'else'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_else(SCRIPT_PTRscript) { returnscript->next; } //---------------------------------------------------------------------------------------- //Handle'endif'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_endif(SCRIPT_PTRscript) { returnscript->next; } //---------------------------------------------------------------------------------------- //Handle'setflag'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_set_flag(SCRIPT_PTRscript) { g_flags[script->entries[0].long_value%256]=script->entries[1].bool_value; returnscript->next; } //---------------------------------------------------------------------------------------- //Handle'print'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_print(SCRIPT_PTRscript) { HWNDlistbox=GetDlgItem(g_hwnd,IDC_SCRIPT); add_string_to_listbox(listbox,"Printstring:"); add_string_to_listbox(listbox,script->entries[0].text); add_string_to_listbox(listbox,""); returnscript->next; } //---------------------------------------------------------------------------------------- //Handle'Movecharacter'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_move(SCRIPT_PTRscript) { chartext[256]; HWNDlistbox=GetDlgItem(g_hwnd,IDC_SCRIPT); add_string_to_listbox(listbox,"Movingcharacterto:"); sprintf(text,"%lf,%lf,%lf", script->entries[0].float_value, script->entries[1].float_value, script->entries[2].float_value); add_string_to_listbox(listbox,text); add_string_to_listbox(listbox,""); returnscript->next; } //---------------------------------------------------------------------------------------- //Handle'gainloss'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_gain_loss(SCRIPT_PTRscript) { charoptions[7][64]= { {"Maincharacter"}, {"Caster"}, {"Target"}, {"Gains"}, {"Looses"}, {"Hit"}, {"Magic"} }; chartext[1024]; sprintf(text,"%s%s%lu%spoints", options[script->entries[0].selection], options[script->entries[1].selection+3], script->entries[2].long_value, options[script->entries[3].selection+5]); HWNDlistbox=GetDlgItem(g_hwnd,IDC_SCRIPT); add_string_to_listbox(listbox,text); add_string_to_listbox(listbox,""); returnscript->next; } //---------------------------------------------------------------------------------------- //Handle'engaginginbattle'scriptstatement. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_battle(SCRIPT_PTRscript) { chartext[256]; sprintf(text,"Engaginginbattle#%lu",script->entries[0].long_value); HWNDlistbox=GetDlgItem(g_hwnd,IDC_SCRIPT); add_string_to_listbox(listbox,text); add_string_to_listbox(listbox,""); returnscript->next; } //---------------------------------------------------------------------------------------- //Handleforscriptend. //---------------------------------------------------------------------------------------- SCRIPT_PTRscript_end(SCRIPT_PTRscript) { HWNDlistbox=GetDlgItem(g_hwnd,IDC_SCRIPT); add_string_to_listbox(listbox,"EndofScript"); add_string_to_listbox(listbox,""); returnNULL; } //----------------------------------------------------------------------------------- //Removeallitemsfromlistbox. //----------------------------------------------------------------------------------- voidreset_listbox(HWNDlistbox) { //AnapplicationsendsanLB_RESETCONTENTmessagetoremoveallitemsfromalistbox. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_RESETCONTENT,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam;); // //wParam: //Notused;mustbezero. // //lParam: //Notused;mustbezero. // //Thismessagedoesnotreturnavalue. SendMessage(listbox,LB_RESETCONTENT,0,0); } //----------------------------------------------------------------------------------- //Addstringtolistbox. //----------------------------------------------------------------------------------- LRESULTadd_string_to_listbox(HWNDlistbox,constchar*string) { //AnapplicationsendsanLB_ADDSTRINGmessagetoaddastringtoalistbox.Ifthelistboxdoesnothave //theLBS_SORTstyle,thestringisaddedtotheendofthelist.Otherwise,thestringisinsertedinto //thelistandthelistissorted. // //Tosendthismessage,calltheSendMessagefunctionasfollows. // //lResult=SendMessage(//returnsLRESULTinlResult //(HWND)hWndControl,//handletodestinationcontrol //(UINT)LB_ADDSTRING,//messageID //(WPARAM)wParam,//=(WPARAM)()wParam; //(LPARAM)lParam//=(LPARAM)()lParam; //); // //wParam: //Thisparameterisnotused. // //lParam: //Pointertothenull-terminatedstringthatistobeadded. // //Ifyoucreatethelistboxwithanowner-drawnstylebutwithouttheLBS_HASSTRINGSstyle, //thisparameterisstoredasitemdatainsteadofthestringtowhichitwouldotherwisepoint. //YoucansendtheLB_GETITEMDATAandLB_SETITEMDATAmessagestoretrieveormodifytheitemdata. // //ReturnValue: //Thereturnvalueisthezero-basedindexofthestringinthelistbox.Ifanerroroccurs, //thereturnvalueisLB_ERR.Ifthereisinsufficientspacetostorethenewstring,thereturnvalue //isLB_ERRSPACE. returnSendMessage(listbox,LB_ADDSTRING,0,(LPARAM)string); } 截图:

  

PURPOSE: MadLibScriptingdemo. *************************************************************************/

  

//

  

//MicrosoftDeveloperStudiogeneratedincludefile. //UsedbyMlsDemo.rc //

  

//Updatescriptentries. //-----------------------------------------------------------------------------------

  

//Setinformationfordialogtobemodified. //-----------------------------------------------------------------------------------

  

//TheDialogProcfunctionisanapplication-definedcallbackfunctionusedwiththeCreateDialog //andDialogBoxfamiliesoffunctions.Itprocessesmessagessenttoamodalormodelessdialogbox. //TheDLGPROCtypedefinesapointertothiscallbackfunction.DialogProcisaplaceholderfor //theapplication-definedfunctionname. // //INT_PTRCALLBACKDialogProc(HWNDhwndDlg, //UINTuMsg, //WPARAMwParam, //LPARAMlParam //); // //hwndDlg: //[in]Handletothedialogbox. //uMsg: //[in]Specifiesthemessage. //wParam: //[in]Specifiesadditionalmessage-specificinformation. //lParam: //[in]Specifiesadditionalmessage-specificinformation. // //ReturnValue: //Typically,thedialogboxprocedureshouldreturnTRUEifitprocessedthemessage, //andFALSEifitdidnot.IfthedialogboxprocedurereturnsFALSE,thedialogmanagerperforms //thedefaultdialogoperationinresponsetothemessage. // //Ifthedialogboxprocedureprocessesamessagethatrequiresaspecificreturnvalue, //thedialogboxprocedureshouldsetthedesiredreturnvaluebycalling //SetWindowLong(hwndDlg,DWL_MSGRESULT,lResult)immediatelybeforereturningTRUE. //NotethatyoumustcallSetWindowLongimmediatelybeforereturningTRUE;doingsoearliermay //resultintheDWL_MSGRESULTvaluebeingoverwrittenbyanesteddialogboxmessage. // //Thefollowingmessagesareexceptionstothegeneralrulesstatedabove.Consultthedocumentation //forthespecificmessagefordetailsonthesemanticsofthereturnvalue. // //WM_CHARTOITEM //WM_COMPAREITEM //WM_CTLCOLORBTN //WM_CTLCOLORDLG //WM_CTLCOLOREDIT //WM_CTLCOLORLISTBOX //WM_CTLCOLORSCROLLBAR //WM_CTLCOLORSTATIC //WM_INITDIALOG //WM_QUERYDRAGICON //WM_VKEYTOITEM // //Remarks: //Youshouldusethedialogboxprocedureonlyifyouusethedialogboxclassforthedialogbox. //Thisisthedefaultclassandisusedwhennoexplicitclassisspecifiedinthedialogboxtemplate. //Althoughthedialogboxprocedureissimilartoawindowprocedure,itmustnotcalltheDefWindowProc //functiontoprocessunwantedmessages.Unwantedmessagesareprocessedinternallybythedialogbox //windowprocedure. //-----------------------------------------------------------------------------------

  

//Moveupscript. //-----------------------------------------------------------------------------------

  

//Deletescript. //-----------------------------------------------------------------------------------

  

//Insertscript. //-----------------------------------------------------------------------------------

  

//Addscript. //-----------------------------------------------------------------------------------

  

//Editscript. //-----------------------------------------------------------------------------------

  

//Savescripttofile. //-----------------------------------------------------------------------------------

  

//Loadscriptfromfile. //-----------------------------------------------------------------------------------

  

//Newascript. //-----------------------------------------------------------------------------------

  

//TheWM_COMMANDmessageissentwhentheuserselectsacommanditemfromamenu,whenacontrol //sendsanotificationmessagetoitsparentwindow,orwhenanacceleratorkeystrokeistranslated. // //WM_COMMAND //WPARAMwParam //LPARAMlParam; // //wParam: //Thehigh-orderwordspecifiesthenotificationcodeifthemessageisfromacontrol. //Ifthemessageisfromanaccelerator,thisvalueis1.Ifthemessageisfromamenu, //thisvalueiszero. // //Thelow-orderwordspecifiestheidentifierofthemenuitem,control,oraccelerator. // //lParam: //Handletothecontrolsendingthemessageifthemessageisfromacontrol. //Otherwise,thisparameterisNULL. // //Ifanapplicationprocessesthismessage,itshouldreturnzero. //-------------------------------------------------------------------------------------------------

  

//Loadactiontemplatefile. //-----------------------------------------------------------------------------------

  

//Routineentry. //-----------------------------------------------------------------------------------

  

#include #include"resource.h" #include"action.h" #pragmawarning(disable:431243134996)

  

//

  

//MicrosoftVisualC++generatedincludefile. //UsedbyMlsEdit.rc //

  

//Getquotedlinefromfile. //------------------------------------------------------------------------

  

//Thisclassencapsulatescriptsaveandload. //============================================================================

  

//structurethatstoreall //============================================================================

  

//structurethatstoreallentriesfactinformation. //============================================================================

  

typedef

  

1. Player character 2. Spell caster 3. Spell target 4. Nobody

  

1. Text entry 2. Boolean value 3. Integer number 4. Float number 5. Multiple choice (a choice from a list of text selections)

  

2. Print (*TEXT*). 3. Play sound effect titled (*SOUND_NAME*). 4. Play music titled (*MUSIC_NAME*). 5. Create object (*OBJECT_NAME*) at coordinates (*XPOS*),(*YPOS*). 6. End script processing.