资源描述:
《怎样理解脚本》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
理解脚本使用这样一个有限的行为集合,就不再需要复杂的可编译脚本语言了。相反,只需要告诉脚本系统要使用哪些行为,以及这些行为将使用怎样的选项以实现游戏的功能。对于这种方法,最大的好处就是不再需要为指定一个简单的行为而罗列代码行,可以通过编号来引用行为和选项。举个例子,PlaySound行为的编号为4,而且该行为仅要求一个输入,即播放声音的编号。在脚本中只存储两个数值:一个对应于行为,另一个代表了声音。使用数值表示行为(代替文本)的方法可以使这种类型脚本的处理既快速又简单。MadLibScripting系统的设计创建在游戏中想到的行为,可以通过创建或编辑脚本来填充那些空白点(称之为条目entries)。对于每个行为,请明确提供一个可供空白条目填充的选项列表,它的类型可以从一行文本到一串数字。接着将行为和空白条目进行编号,以便脚本系统可以引用它们,以下是一些行为列表的范例:1.Character(*NAME*)takes(*NUMBER*)damage.2.Print(*TEXT*).3.Playsoundeffecttitled(*SOUND_NAME*).4.Playmusictitled(*MUSIC_NAME*).5.Createobject(*OBJECT_NAME*)atcoordinates(*XPOS*),(*YPOS*).6.Endscriptprocessing. 在这6种行为中,都有0个或多个空白条目位于括号内,每个空白条目包含了一个文本字符串或者一个数字,这个行为与可能条目(以及条目的类型)的列表被称之为行为模板(actiontemplate),如下图所示:一旦使用了行为模板,就可以使用它们的编号而不是行为的文本进行引用(文本的存在只是为了使用户能够更容易理解每个行为所实现的功能)。MLS系统的编写为了使MLS系统功能尽可能强大,需要设计它以便可以支持多重行为的模板,而且每个行为模板都包含不受数量限制的行为。以这种方式,就可以将系统复用到任何想要的项目中。当一个脚本完成时,将脚本读入到引擎中,并处理各自的行为,为每个由脚本编辑器所输入的行为使用指定的条目。一个行为模板需要保存行为的列表,包括文本、条目编号以及每个条目的数据。每个行为按它们在列表中的索引值进行编号,同时每个行为中的空白条目也被加以编号。可以为每个条目指定一种类型(文本型、整数型、浮点型、布尔型、多重选择型),如下所示:0.Noentrytype1.Textentry2.Booleanvalue3.Integernumber 4.Floatnumber5.Multiplechoice(achoicefromalistoftextselections)每个条目类型都有一个独特的特征,字符串类型的长度是可以变化的,数字型可以是两个数字范围之间的任何数值,而布尔值可以是TRUE或者FALSE。至于多重选项型,每个选项都有它自己的文本字符串(脚本从一个列表中获取选项,而且所选选项的索引编号比它的文本更适用)。行为可以采用如下格式:Action#1:Spelltargets(*MULTIPLE_CHOICE*).Possiblechoicesforblankentry#1:1.Playercharacter2.Spellcaster3.Spelltarget4.Nobody我们通过创建结构体ENTRY_RULE和ACTION来处理条目规则与行为。enumENTRY_TYPE{ENTRY_NONE=0,ENTRY_TEXT,ENTRY_BOOL,ENTRY_INT,ENTRY_FLOAT,ENTRY_CHOICE};typedefchar*char_ptr;typedefintBOOL;//============================================================================//Structurestostoreinformationaboutasingleblankentry.//============================================================================typedefstructENTRY_RULE{longtype;//typeofblankentry(ENTRY_TEXT,ENTRY_BOOL,) //Thefollowingtwounionscontainthevariousinformationaboutasingleblankentry,//fromthemin/maxvalues(forintandfloattypes),aswellasthenumberofchoices//inamultiplechoiceentry.union{longlong_min;//minvalueoflongtypefloatfloat_min;//minvalueoffloattypelongnum_choices;//numberofchoicesinlist};union{longlong_max;//maxvalueoflongtypefloatfloat_max;//maxvalueoffloattypechar_ptr*choices;//choicetextarray};//structureconstructortocleartodefaultvaluesENTRY_RULE(){memset(this,0,sizeof(*this));}//structuredestructortocleanupusedresources~ENTRY_RULE(){//specialcaseforchoicetype if(type==ENTRY_CHOICE&&choices!=NULL){for(longi=0;inext=NULL;if(act_ptr==NULL)m_root_action=act;elseact_ptr->next=act;act_ptr=act; //copyactiontextstrcpy(act->text,text);//storeactionindexact->index=m_num_actions;//increasethenumberofactionsloadedm_num_actions++;size_ttext_len=strlen(text);//countthenumberofentriesintheactionfor(size_ti=0;inum_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];//geteachentrytextfor(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){//returnerrorifhigherthannumberofactionsif(act_index>=m_num_actions)returnNULL;ACTION_PTRact_ptr=m_root_action;//scanlistwhile(act_ptr){ if(act_ptr->index==act_index)returnact_ptr;act_ptr=act_ptr->next;}returnNULL;}//------------------------------------------------------------------------//Createscriptfromspecifiedactionindex.//------------------------------------------------------------------------SCRIPT_PTRACTION_TEMPLATE::create_script(longact_index){//makesureitisavalidactionif(act_index>=m_num_actions)returnNULL;ACTION_PTRact_ptr;//getpointertoactionif((act_ptr=get_action(act_index))==NULL)returnNULL;//createnewSCRIPTstructureSCRIPT_PTRscript=newSCRIPT;script->action_index=act_index;script->num_entries=act_ptr->num_entries_rule;script->entries=newENTRY[script->num_entries]; //setupeachentryfor(longi=0;inum_entries;i++){script->entries[i].type=act_ptr->entries_rule[i].type;//setupentrydatabasedontypeswitch(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){//getpointertospecifiedactionACTION_PTRact_ptr=get_action(act_index);//return0ifonerrorif(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){//copyactiontextintobufferifnoentriesruleif(action->num_entries_rule==0){strcpy(buffer,action->text);return;}//expandentrytypesintoactiontextsize_tbuf_pos=0;longrule_index=0;size_ttext_len=strlen(action->text);constsize_tmem_size=256;for(size_ti=0;itext[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++;}elsebuffer[buf_pos++]=action->text[i];}buffer[buf_pos]=0;}//------------------------------------------------------------------------//Expandactiontextusingselections.//------------------------------------------------------------------------BOOLACTION_TEMPLATE::expand_action_text(char*buffer,SCRIPT_PTRscript){//getapointertothespecifiedactionACTION_PTRact_ptr=get_action(script->action_index);if(act_ptr==NULL)returnFALSE;//copyactiontextintobufferifnoentriesif(act_ptr->num_entries_rule==0) {strcpy(buffer,act_ptr->text);returnTRUE;}//expandentrytypesintoactiontextsize_tbuf_pos=0;size_tentry_index=0;charmemory[256];size_tmemory_length;size_tact_text_length=strlen(act_ptr->text);for(size_ti=0;itext[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);elsememcpy(&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++;}elsebuffer[buf_pos++]=act_ptr->text[i];}buffer[buf_pos]=0; returnTRUE;}第三篇MLS编辑器的使用MLS系统仅使用到数字:代表行为的编号,随后条目的数量,以及代表条目数据的编号。计算机特别擅长处理数字的工作,但我们的需要更多。需要将脚本构造成易于理解的文本行,并让脚本编辑器将键入的文本转变为脚本系统可以处理的一系列数字。在编辑一个脚本期间,并不处理任何数字方面的问题,所以编辑器的工作还包括加载数字并将它们转换回易于阅读理解的文本行。因此,也可以这么说,仅需要使用一系列的文本命令构造一个脚本,然后使用脚本编辑器将这些命令转换成代表它们数值,反之亦然。MLS编辑器导入那些代表行为的文本行,并赋予用户能力去编辑行为列表,以及在空白条目点填上行为,MLS编辑器的外观如下图所示: 下表详细解释了脚本编辑器每个按钮的用途: 将行为添加到脚本中时(添加脚本或插入脚本),请注意行为的文本将被扩展,并添加到脚本列表框中(位于脚本编辑器顶端的列表框)。脚本行为从上到下进行存储,根节点存储了最顶端的脚本行为,脚本从顶端开始往下处理,与典型的C/C++代码非常类似。请注意,每次添加、插入、或编辑一个脚本条目时,修改行为条目的对话框将出现(如下图所示),将使用这个对话框去修改脚本行为的条目。 MLS编辑器的创建首先,我们设计MLS编辑器主窗口的界面: 接着我们设计修改脚本的对话框: resource.h的定义://{{NO_DEPENDENCIES}}//MicrosoftVisualC++generatedincludefile.//UsedbyMlsEdit.rc//#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#endifMlsEdit.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,262STYLEDS_SETFONT|WS_MINIMIZEBOX|WS_CAPTION|WS_SYSMENUCAPTION"MLSEditor"CLASS"mlseditclass"FONT11,"SegoeUI",400,0,0x0BEGINLISTBOXIDC_SCRIPT,10,17,296,93,LBS_NOINTEGRALHEIGHT|WS_VSCROLL|WS_TABSTOPPUSHBUTTON"AddtoScript",IDC_ADD,312,150,55,15PUSHBUTTON"Delete",IDC_DELETE,312,15,55,15PUSHBUTTON"MoveUp",IDC_UP,312,75,55,15PUSHBUTTON"MoveDown",IDC_DOWN,312,95,55,15PUSHBUTTON"Edit",IDC_EDIT,312,35,55,15PUSHBUTTON"SaveScript",IDC_SAVE,247,115,55,15PUSHBUTTON"LoadScript",IDC_LOAD,127,115,55,15PUSHBUTTON"LoadActions",IDC_LOADACTIONS,312,200,55,15PUSHBUTTON"NewScript",IDC_NEW,10,115,55,15LISTBOXIDC_ACTION,10,150,296,97,LBS_NOINTEGRALHEIGHT|WS_VSCROLL|WS_TABSTOP PUSHBUTTON"InsertinScript",IDC_INSERT,312,175,55,15GROUPBOX"Script",IDC_STATIC,7,7,367,128GROUPBOX"Actions",IDC_STATIC,7,138,367,117LISTBOXIDC_SCRIPT_ADDR,155,86,89,102,LBS_NOINTEGRALHEIGHT|NOTWS_VISIBLE|WS_VSCROLL|WS_TABSTOPENDIDD_MODIFYDIALOGEX0,0,241,138STYLEDS_SETFONT|DS_MODALFRAME|WS_POPUP|WS_CAPTIONCAPTION"ModifyActionEntry"FONT11,"SegoeUI",400,0,0x0BEGINLTEXT"Static",IDC_ACTIONTEXT,7,5,227,35,WS_BORDERDEFPUSHBUTTON"OK",IDC_OK,51,117,50,14LTEXT"Entry#",IDC_STATIC,5,45,25,8GROUPBOX"TITLE",IDC_FRAME,7,60,227,56EDITTEXTIDC_VALUE,97,96,60,12,ES_AUTOHSCROLLLTEXT"Min.",IDC_STATIC_MIN,50,70,20,10LTEXT"Max.",IDC_STATIC_MAX,50,80,20,10LTEXT"Value",IDC_STATIC_VALUE,50,98,20,10LTEXT"MIN#",IDC_MIN,97,70,60,8LTEXT"MAX#",IDC_MAX,97,81,60,8EDITTEXTIDC_TEXT,35,80,165,12,ES_AUTOHSCROLLCOMBOBOXIDC_CHOICE,35,80,165,60,CBS_DROPDOWN|WS_VSCROLL|WS_TABSTOPPUSHBUTTON"Cancel",IDC_CANCEL,126,117,50,14RTEXT"#of#",IDC_NUM,48,45,30,8PUSHBUTTON"<--",IDC_PREV,86,45,20,10PUSHBUTTON"-->",IDC_NEXT,111,45,20,10CONTROL"TRUE",IDC_TRUE,"Button",BS_AUTORADIOBUTTON,69,84,34,10 CONTROL"FALSE",IDC_FALSE,"Button",BS_AUTORADIOBUTTON,128,84,36,10PUSHBUTTON"OK",IDC_OK2,85,117,50,14END/////////////////////////////////////////////////////////////////////////////////DESIGNINFO//#ifdefAPSTUDIO_INVOKEDGUIDELINESDESIGNINFOBEGINIDD_MAIN,DIALOGBEGINLEFTMARGIN,7RIGHTMARGIN,374TOPMARGIN,7BOTTOMMARGIN,255ENDIDD_MODIFY,DIALOGBEGINLEFTMARGIN,7RIGHTMARGIN,234TOPMARGIN,7BOTTOMMARGIN,131ENDEND #endif//APSTUDIO_INVOKED#ifdefAPSTUDIO_INVOKED/////////////////////////////////////////////////////////////////////////////////TEXTINCLUDE//1TEXTINCLUDEBEGIN"resource.h "END2TEXTINCLUDEBEGIN"#include""afxres.h""r "" "END3TEXTINCLUDEBEGIN"r "" "END#endif//APSTUDIO_INVOKED#endif//English(U.S.)resources /////////////////////////////////////////////////////////////////////////////#ifndefAPSTUDIO_INVOKED/////////////////////////////////////////////////////////////////////////////////GeneratedfromtheTEXTINCLUDE3resource.///////////////////////////////////////////////////////////////////////////////#endif//notAPSTUDIO_INVOKED我们首先定义一些全局变量和辅助函数:#include#include#include"resource.h"#include"action.h"#pragmawarning(disable:431243134996)////////////////////////////////////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,thetotalsize inbytesofthe//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函数以及主窗口处理过程的实现://-----------------------------------------------------------------------------------//Routineentry.//-----------------------------------------------------------------------------------intWINAPIWinMain(HINSTANCEinst,HINSTANCE,LPSTRcmd_line,intcmd_show){constchar*class_name="mlseditclass";WNDCLASSwin_class;//createwindowclassandregisteritwin_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.//Createthedialogboxwindowandshowitg_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.mlaload_actions_from_file("..\Data\Default.mla");MSGmsg;//messageloopwhile(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/loaddialogboxinformationZeroMemory(&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; //clearscriptfilenmaeg_script_file[0]=0;g_action_file[0]=0;//clearalllistboxesreset_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函数来加载行为脚本://-----------------------------------------------------------------------------------//Loadactiontemplatefile.//-----------------------------------------------------------------------------------BOOLload_actions_from_file(constchar*filename){ if(filename==NULL)//askforfilenameifnonepassed{//setuptheopendialoginformationg_ofn.hwndOwner=g_hwnd;g_ofn.lpstrFile=g_action_file;g_ofn.lpstrTitle="LoadActionsFile";g_ofn.lpstrFilter="MLSActionFiles(*.mla) *.mla AllFiles(*.*) *.* ";g_ofn.lpstrDefExt="mla";//getactiontemplatefilename////CreatesanOpendialogboxthatletstheuserspecifythedrive,directory,//andthenameofafiletoopen.if(!GetOpenFileName(&g_ofn))returnFALSE;//askifsuretomakenewscriptif(!new_script())returnFALSE;}elsestrcpy(g_action_file,filename);//attempttoloadactionsif(!g_action_template.load_actions(g_action_file)){MessageBox(g_hwnd,g_action_file,"Unabletoopenfile",MB_OK);returnFALSE;} //clearthelistboxreset_listbox(g_action_wnd);//getapointertotheparentactionACTION_PTRact_ptr=g_action_template.get_root_action();longnum_actions=g_action_template.get_num_actions();//loopthroughallactionsfor(longi=0;inext;}returnTRUE;}所有的脚本编辑命令都在wm_command_proc函数中处理://------------------------------------------------------------------------------------------------- //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.//-------------------------------------------------------------------------------------------------voidwm_command_proc(WPARAMword_param){switch(LOWORD(word_param)){ caseIDC_NEW://createanewscriptnew_script();break;caseIDC_LOAD://loadascriptfileload_script();break;caseIDC_SAVE://saveascriptfilesave_script();break;caseIDC_LOADACTIONS://loadanactionfileload_actions_from_file(NULL);break;caseIDC_SCRIPT://editascriptif(HIWORD(word_param)!=LBN_DBLCLK)break;caseIDC_EDIT:edit_script();break;caseIDC_ACTIONS://addanactiotionif(HIWORD(word_param)!=LBN_DBLCLK)break;caseIDC_ADD:add_script();break; caseIDC_INSERT://insertascriptinsert_script();break;caseIDC_DELETE://deleteascriptdelete_script();break;caseIDC_UP://moveupscriptmove_up_script();break;caseIDC_DOWN://movedownscriptmove_down_script();break;}}new_script函数用来提示用户是否真要创建一个脚本,如果是将清除脚本列表框中的脚本://-----------------------------------------------------------------------------------//Newascript. //-----------------------------------------------------------------------------------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;//clearoutlistboxreset_listbox(g_script_wnd);reset_listbox(g_script_addr_wnd);returnTRUE;}returnTRUE;}load_script用来加载脚本并将其添加到脚本列表框中://-----------------------------------------------------------------------------------//Loadscriptfromfile.//-----------------------------------------------------------------------------------BOOLload_script() {//setuptheopendialoginfomationg_ofn.hwndOwner=g_hwnd;g_ofn.lpstrFile=g_script_file;g_ofn.lpstrTitle="LoadScriptFile";g_ofn.lpstrFilter="MLSScriptFiles(*.mls) *.mls AllFiles(*.*) *.* ";g_ofn.lpstrDefExt="mls";//askforfilenameif(!GetOpenFileName(&g_ofn))returnFALSE;FILE*fp;//openthefileforinputif((fp=fopen(g_script_file,"rb"))==NULL){MessageBox(g_hwnd,g_script_file,"Unabletoopenfile.",MB_OK);returnFALSE;}//deletethecurrentscriptdeleteg_root_script;chartext[2048];SCRIPT_PTRscript_ptr=NULL;//getnumberofscriptfread(&g_num_script,1,sizeof(long),fp); //loopthrougheachscriptfor(longi=0;inext=NULL;if(script_ptr==NULL)g_root_script=script;elsescript_ptr->next=script;script_ptr=script;//getindexofactionsandnumberofentriesfread(&script->action_index,1,sizeof(long),fp);fread(&script->num_entries,1,sizeof(long),fp);//getentrydata(ifany)if(script->num_entries){//allocateentryarrayscript->entries=newENTRY[script->num_entries];//loadineachentryfor(longj=0;jnum_entries;j++){//getentrytypeanddatafread(&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){//allocateabufferandgetstringscript->entries[j].text=newchar[length];fread(script->entries[j].text,1,length,fp);}}}}}fclose(fp);//clearthescriptandscriptaddressboxesreset_listbox(g_script_wnd);reset_listbox(g_script_addr_wnd);//addscripttolistboxscript_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);//addscriptpointertolistboxsprintf(text,"%lu",script_ptr);add_string_to_listbox(g_script_addr_wnd,text);script_ptr=script_ptr->next;}returnTRUE;}save_script将脚本存储到文件中://-----------------------------------------------------------------------------------//Savescripttofile.//-----------------------------------------------------------------------------------BOOLsave_script(){//makesurethereissomescriptactionsif(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) *.mls AllFiles(*.*) *.* ";g_ofn.lpstrDefExt="mls";//askforfilenameif(!GetSaveFileName(&g_ofn))returnFALSE;FILE*fp;//openthefileforoutputif((fp=fopen(g_script_file,"wb"))==NULL){MessageBox(g_hwnd,g_script_file,"Unabletosavefile.",MB_OK);returnFALSE;}//outputnumberofscriptsfwrite(&g_num_script,1,sizeof(long),fp);//loopthrougheachscriptfor(longi=0;iaction_index,1,sizeof(long),fp);fwrite(&script_ptr->num_entries,1,sizeof(long),fp);//outputentrydata(ifany)for(longj=0;jnum_entries;j++){//writeentrytypeanddatafwrite(&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用于编辑当前选中的脚本行://-----------------------------------------------------------------------------------//Editscript.//----------------------------------------------------------------------------------- voidedit_script(){intsel;//seeifascriptwasselectedif((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR)return;chartext[2048];//getpointertoscriptentryget_listbox_text(g_script_addr_wnd,sel,text);SCRIPT_PTRscript=(SCRIPT_PTR)atol(text);//setupthescripttoeditg_modify_script=script;//callthemodifyscriptdialogg_show_cancel=FALSE;DialogBox(NULL,MAKEINTRESOURCE(IDD_MODIFY),g_hwnd,modify_dialog_proc);//updatescriptlistboxg_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将行为列表框中选中的行为添加到脚本列表框中: //-----------------------------------------------------------------------------------//Addscript.//-----------------------------------------------------------------------------------voidadd_script(){longsel;//makesureanactionisselectedif((sel=(long)get_listbox_selected(g_action_wnd))==LB_ERR)return;//createanewscriptandadditSCRIPT_PTRscript=g_action_template.create_script(sel);g_modify_script=script;//callthemodifyscriptdialogg_show_cancel=TRUE;if(DialogBox(NULL,MAKEINTRESOURCE(IDD_MODIFY),g_hwnd,modify_dialog_proc)){//addscripttolinklistscript->next=g_root_script;if(g_root_script!=NULL) g_root_script->prev=script;g_root_script=script;//displayscripttextchartext[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);//addpointertoscriptaddresslistboxsprintf(text,"%lu",script);add_string_to_listbox(g_script_addr_wnd,text);//increasecountg_num_script++;}elsedeletescript;}insert_script将行为列表框中选中的行为脚本添加到脚本列表框中选中脚本的上方://-----------------------------------------------------------------------------------//Insertscript.//----------------------------------------------------------------------------------- voidinsert_script(){intact_index,script_index;//getlocationtoinsertactionif((script_index=(int)get_listbox_selected(g_script_wnd))==LB_ERR)return;//makesureanactionisselectedif((act_index=(int)get_listbox_selected(g_action_wnd))==LB_ERR)return;//createanewscriptSCRIPT_PTRscript=g_action_template.create_script(act_index);g_modify_script=script;//callthemodifyscriptdialogg_show_cancel=TRUE;if(DialogBox(NULL,MAKEINTRESOURCE(IDD_MODIFY),g_hwnd,modify_dialog_proc)){//addthescripttolinklistscript->prev=NULL;script->next=g_root_script;g_root_script->prev=script;g_root_script=script;chartext[2048]; //displayscriptactiontextACTION_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);//addpointertoscriptaddresslistboxsprintf(text,"%lu",script);insert_string_to_listbox(g_script_addr_wnd,script_index,text);g_num_script++;}elsedeletescript;}delete_script用于删除脚本列表框中的一条脚本://-----------------------------------------------------------------------------------//Deletescript.//-----------------------------------------------------------------------------------voiddelete_script(){intsel;//makesurethereisaselectionif((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR)return; chartext[2048];//getpointertoscriptentryget_listbox_text(g_script_addr_wnd,sel,text);SCRIPT_PTRscript=(SCRIPT_PTR)atol(text);//removescriptfromlinkedlistif(script->prev)script->prev->next=script->next;elseg_root_script=script->next;if(script->next)script->next->prev=script->prev;script->next=NULL;//sowholelistisnotdeleteddeletescript;//clearfromscriptandscriptlistdelete_listbox_string(g_script_wnd,sel);delete_listbox_string(g_script_addr_wnd,sel);g_num_script--;}move_up_script和move_down_script分别将脚本上移和下移一行://-----------------------------------------------------------------------------------//Moveupscript. //-----------------------------------------------------------------------------------voidmove_up_script(){intsel;//makesurethereisaselectionif((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR)return;//makesureitisnottopmostselectionif(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;//makesurethereisaselectionif((sel=(int)get_listbox_selected(g_script_wnd))==LB_ERR)return;//makesureitisnotbottommostselectionif(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来实现://----------------------------------------------------------------------------------- //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.//Thisisthedefaultclassandisusedwhennoexplicitclassisspecified inthedialogboxtemplate.//Althoughthedialogboxprocedureissimilartoawindowprocedure,itmustnotcalltheDefWindowProc//functiontoprocessunwantedmessages.Unwantedmessagesareprocessedinternallybythedialogbox//windowprocedure.//-----------------------------------------------------------------------------------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;}//editfirstentryentry_index=0;//displayentrytextset_modify_dialog(dlg,g_modify_script,entry_index);//showorhidecancelbuttonShowWindow(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://onlybotherifnotfirstentryif(entry_index>0){//applychanges//gotopreviousentryupdate_entry(dlg,g_modify_script,entry_index);entry_index--;set_modify_dialog(dlg,g_modify_script,entry_index);}break; caseIDC_NEXT://onlybotherifnotlastentryif(entry_indexnum_entries-1){//applychanges//gotonextentryupdate_entry(dlg,g_modify_script,entry_index);entry_index++;set_modify_dialog(dlg,g_modify_script,entry_index);}break;}}returnFALSE;}不同的条目类型修改脚本的对话框外观也不相同,这是通过set_modify_dialog函数来实现://-----------------------------------------------------------------------------------//Setinformationfordialogtobemodified.//-----------------------------------------------------------------------------------voidset_modify_dialog(HWNDdlg,SCRIPT_PTRscript,longentry_index){chartext[2048]; //displayfullactiontextg_action_template.expand_action_text(text,script);SetWindowText(GetDlgItem(dlg,IDC_ACTIONTEXT),text);//getcontrolhandleHWNDpre_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);//hideallcontrolsShowWindow(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);//clearinformationSetWindowText(num_wnd,"");SetWindowText(frame_wnd,"NoEntries");//getpointertoactionACTION_PTRact_ptr=g_action_template.get_action(script->action_index);//returnifnoentriestoeditif(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);//enableandsetspecificfieldsbasedonentrytypeswitch(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来实现://----------------------------------------------------------------------------------- //Updatescriptentries.//-----------------------------------------------------------------------------------voidupdate_entry(HWNDdlg,SCRIPT_PTRscript,longentry_index){//getpointertoactionACTION_PTRact_ptr=g_action_template.get_action(script->action_index);//returnifnoentriestoupdateorincorrectentryindexif(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];//updatefieldsbasedontypeswitch(r_entry_rule.type){caseENTRY_TEXT://deleteoldtextdelete[]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://chooseTRUEorFALSEfromradiobuttonif(get_button_state(GetDlgItem(dlg,IDC_TRUE))==BST_CHECKED)r_entry.bool_value=TRUE;elser_entry.bool_value=FALSE;break;caseENTRY_INT://getintvalueandboundscheckwithmin/maxGetWindowText(GetDlgItem(dlg,IDC_VALUE),text,size);r_entry.long_value=atol(text);if(r_entry.long_valuer_entry_rule.long_max)r_entry.long_value=r_entry_rule.long_max; break;caseENTRY_FLOAT://getintvalueandboundscheckwithmin/maxGetWindowText(GetDlgItem(dlg,IDC_VALUE),text,size);r_entry.float_value=(float)atof(text);if(r_entry.float_valuer_entry_rule.float_max)r_entry.float_value=r_entry_rule.float_max;break;caseENTRY_CHOICE://storechoiceselectionr_entry.selection=(long)get_combo_cur_sel(GetDlgItem(dlg,IDC_CHOICE));break;}}截图: 第五篇事实上,创建可接受脚本的游戏引擎对于大多数的游戏而言,将产生出一个非常开放的源代码以及高效率的项目。MadLibScripts的执行窗口设计: resouce.h://{{NO_DEPENDENCIES}}//MicrosoftDeveloperStudiogeneratedincludefile.//UsedbyMlsDemo.rc//#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#endifMlsDemo.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,198STYLEDS_SETFONT|DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENUCAPTION"MLSDemo"CLASS"MLSDEMO"FONT12,"SegoeUI",400,0,0x0BEGINPUSHBUTTON"LoadScript",IDC_LOAD,254,173,43,14PUSHBUTTON"Execute",IDC_EXECUTE,306,173,43,14LISTBOXIDC_SCRIPT,7,5,342,162,NOTLBS_NOTIFY|LBS_NOINTEGRALHEIGHT|WS_VSCROLL|WS_TABSTOPCONTROL"",IDC_TITLE,"Static",SS_LEFTNOWORDWRAP,7,175,232,14END/////////////////////////////////////////////////////////////////////////////////DESIGNINFO// #ifdefAPSTUDIO_INVOKEDGUIDELINESDESIGNINFOBEGINIDD_DEMO,DIALOGBEGINLEFTMARGIN,7RIGHTMARGIN,349TOPMARGIN,7BOTTOMMARGIN,191ENDEND#endif//APSTUDIO_INVOKED#ifdefAPSTUDIO_INVOKED/////////////////////////////////////////////////////////////////////////////////TEXTINCLUDE//1TEXTINCLUDEBEGIN"resource.h "END2TEXTINCLUDEBEGIN"#include""afxres.h""r "" " END3TEXTINCLUDEBEGIN"r "" "END#endif//APSTUDIO_INVOKED#endif//English(U.S.)resources/////////////////////////////////////////////////////////////////////////////#ifndefAPSTUDIO_INVOKED/////////////////////////////////////////////////////////////////////////////////GeneratedfromtheTEXTINCLUDE3resource.///////////////////////////////////////////////////////////////////////////////#endif//notAPSTUDIO_INVOKED实现: /*************************************************************************PURPOSE:MadLibScriptingdemo.*************************************************************************/#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/loadinglonglength;//lengthoftext(0terminator)longselection;//selectioninchoice BOOLbool_value;//BOOLvaluelonglong_value;//longbaluefloatfloat_value;//floatvalue};char*text;//entrytextbufferENTRY(){memset(this,0,sizeof(*this));}~ENTRY(){delete[]text;}}*ENTRY_PTR;//============================================================================//structurethatstoreall//============================================================================typedefstructSCRIPT{longaction_index;//[0,numberofactions-1]longnum_entries;//numberofentriesinthisactionENTRY_PTRentries;//arrayofentries SCRIPT*prev;//previousinlinkedlistSCRIPT*next;//nextinlinkedlistSCRIPT(){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;//createwindowclassandregisteritwin_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;//TheCreateDialogmacrocreatesamodelessdialogboxfromadialogboxtemplate resource.//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.//Createthedialogboxwindowandshowitg_hwnd=CreateDialog(inst,MAKEINTRESOURCE(IDD_DEMO),0,NULL);ShowWindow(g_hwnd,cmd_show);UpdateWindow(g_hwnd);MSGmsg;//messageloopwhile(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://loadascriptfileif(!GetOpenFileName(&g_ofn))break;//deletethecurrentscriptdeleteg_root_script;if((g_root_script=load_script_from_file(g_script_file))==NULL)MessageBox(hwnd,g_script_file,"Unalbetoopenfile.",MB_OK);//displayscriptfilenameSetWindowText(GetDlgItem(g_hwnd,IDC_TITLE),g_script_file);break;caseIDC_EXECUTE://runascriptfilerun_script();break; }break;caseWM_CREATE://initializethesave/loaddialogboxinformationZeroMemory(&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) *.mls AllFiles(*.*) *.* ";g_ofn.lpstrDefExt="mls";g_ofn.nMaxFileTitle=MAX_PATH;//setdefaultopenpathstrcpy(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;//loopthrougheachscriptfor(longi=0;inext=NULL; if(script_ptr==NULL)root_script=script;elsescript_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];//loadineachentryfor(longj=0;jnum_entries;j++){fread(&script->entries[j].type,1,sizeof(long),fp);fread(&script->entries[j].io_value,1,sizeof(long),fp);//gettextifanyif(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(){//clearflagsfor(shorti=0;i<256;i++)g_flags[i]=FALSE;SCRIPT_PTRscript_ptr;//startatbeginningofscriptif((script_ptr=g_root_script)==NULL)returnFALSE;reset_listbox(GetDlgItem(g_hwnd,IDC_SCRIPT));//loopuntilnomorescriptswhile(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;//seeifaflagmatchessecondentryif(g_flags[flag_index]==script->entries[1].bool_value)skipping=FALSE;elseskipping=TRUE;script=script->next;while(script){//if'else',flipskipmodeif(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);}截图: