25
現在已經很少人會在純文字模式下寫應用程式了吧?_?
所以呢參考參考就好^^!
================================================
這是當初設計前畫的一個主要架構圖
┌-----------------------------(回到主控函數)----┐
| 主 控 制 函 數 |
┌---------(回到主控函數)---------┐ |
| | | |
| | (主流程只有一個,橫為主,直為副時主流程做在直式內) |
| | └-----┐ |
| | | |
| 橫式選單控制函數 直式選單控制函數 |
| | | |
| | | |
| 橫式選單→按鍵行為設定選項旗標 直式選單→按鍵行為設定選項旗標 |
| | | |
| | | |
| 橫式選單->選單顯示 直式選單->選單顯示 |
| | | |
└-------┘ └-----------------┘
在直式選單用遞迴來做多層次選單的實現方法所以還有一個遞迴流程示意圖.....哈!箭頭太多畫不出來>"<
2007.11.01修正...抓一些bug及將程式從開發中的.c檔抽離出來
/home/stlee/include/udfmenu.h
#define GM_ARCFKW 0 /*主選單前置識別關鍵字*/
#define GM_ARCEKW 1 /*主選單結尾識別關鍵字,實際設定時可與副選單前置識別關鍵字相同*/
#define GM_SECFKW 2 /*副選單前置識別關鍵字*/
#define GM_SECEKW 3 /*副選單結尾識別關鍵字,實際設定時可與執行檔前置識別關鍵字相同*/
#define GM_EXEFKW 4 /*執行檔前置識別關鍵字*/
#define GM_EXEEKW 5 /*執行檔結尾識別關鍵字,實際設定時可與執行參數前置識別關鍵字相同*/
#define GM_EXPFKW 6 /*執行參數前置識別關鍵字*/
#define GM_EXPEKW 7 /*執行參數結尾識別關鍵字,實際設定時可與快捷鍵前置識別關鍵字相同*/
#define GM_CACFKW 8 /*快捷鍵前置識別關鍵字*/
#define GM_CACEKW 9 /*快捷鍵結尾識別關鍵字*/
#define GM_ENDRKW 10 /*設定列結束識別關鍵字*/
#define GM_KWSMAX 11 /*供宣告以上相關設定的陣列最大值*/
#define GM_COLORFOOT 0
#define GM_CLARCOPT 0 /*橫式選單一般選項字串顏色設定*/
#define GM_CLARCPRD 1 /*橫式選單反白選項字串顏色設定*/
#define GM_CLSECOPT 2 /*直式選單一般選項字串顏色設定*/
#define GM_CLSECPRD 3 /*直式選單反白選項字串顏色設定*/
#define GM_CLWINCOL 4 /*直式選單視窗顏色設定(外框),作用中副選單*/
#define GM_CLWINBAD 5 /*直式選單視窗顏色設定(外框),多層次的無作用中副選單*/
#define GM_COLOREND 6
#define GM_MUSETFOOT 6
#define GM_ARCGAPCOL 6 /*橫式選單各選項間隔行數設定*/
#define GM_ARCPRDSPC 7 /*橫式選單反白選項間的留邊數*/
#define GM_SECMAXROW 8 /*直列式視窗的固定列數設定*/
#define GM_SECTGSROW 9 /*直列式視窗的下越界基準值設定*/
#define GM_SECRTCCOL 10 /*直列式視的第二層以後的副視窗回縮行數設定*/
#define GM_MUSETEND 11
#define GM_CLOCKFOOT 11
#define GM_CLOCKCX 11 /*時鐘顯示位置的X座標*/
#define GM_CLOCKCY 12 /*時鐘顯示位置的Y座標*/
#define GM_CLOCKMOD 13 /*時鐘顯示位置的Y座標*/
#define GM_CLOCKEND 14
#define GM_USRSETMAX 14 /**/
#define GM_CIRCU 1 /*循環*/
#define GM_PAGE 2 /*翻頁*/
#define GM_STOP 4 /*停止*/
/*................................................................................*/
/*.............................. keyact.c ..............................*/
/*............................已在udfmenu.h中宣告原型.............................*/
/**udf主選單橫式選單按鍵行為的設定*/
void lee_udfmumst_keyact(int keycode,int strn,
int *pg_foot,int *pg_end,int *prd_flag);
/*udf主選單直式選單按鍵行為控制*/
void lee_udfmuslv_keyact(int keycode,int strn,int pagecode,
int pagewit,int *pg_foot,int *prd_flag);
/*................................................................................*/
/*.............................. mudsp.c ..............................*/
/*................................................................................*/
/*udf主選單橫式選單的顯示,當不定長度陣列顯示超出範圍時可以不顯示*/
void lee_udfmumst_mudsp(WINDOW *winptr,
char **arcmustmpp,int arcmustrn,
int pgfoot,int prdflag,
int wlcx,int wrcx,int wmcy,int *usrset,
int *prdlcx,int *pgend);
/*udf主選單直式選單顯示*/
void lee_udfmuslv_mudsp(WINDOW *winptr,char **opttmpp,int optstrn,
int tcx,int tcy,int dcx,int dcy,int *usrset,
int pgfoot,int prdflag,
int *pg_end);
/*................................................................................*/
/*.............................. udfmenu.c ..............................*/
/*................................................................................*/
/*udf主選單主流程控制*/
int lee_udfmenu(WINDOW *win_master,char *musphf,char *setphf);
/*udf主選單橫式選單流程控制*/
int lee_udfmumst(WINDOW *win_master,int keydec,
int lefcx,int rincx,int mmucy,int *usrset,
char **arcmustmpp,int arcmustrn,
int *pg_foot,int *pg_end,int *prd_flag,int *prdlcx);
/*多層次直式選單的視窗範圍控制與隨情況調整翻頁方式設定*/
char *lee_udfmuslv_brdwxy(char *sectmp,int secsize,char *fkws,char *ekws,
int aclcx,int actcy,int *usrset,
int *sectcx,int *sectcy,int *secdcx,int *secdcy,
int *wdcx,int *wdcy,int *pagewit,int *pagecode,
int *optsize,int *optstrn,int *optmlen);
/*udf主選單公用函數:取得設定檔內的設定*/
int *lee_udfmu_getmuset(char *musftmp,int musfsize,char *setftmp,int setfsize);
/*udf主選單公用函數:取得定義檔內的自定義標籤*/
char *lee_udfmu_getdkts(char *setftmp,int setfsize,int *dkkwssize);
/*udf主選單公用函數:取得*setftmp內與mem內所有快捷鍵識別字語鍵值資料列*/
char *lee_udfmu_getcackws(char **dkkwsp,char *mem,int memsize,char *setftmp,int setfsize,
int *cacsize,int *cacstrn,int *cacmlen);
/*udf主選單公用函數:對齊目前按鍵與快捷鍵設定*/
int lee_udfmu_cackws2dn(int keycode,char **cacsp,int cacstrn,char **tmpp,int tmpstrn,
int *pgfoot,int pgend,int *acdn);
/*udf主選單公用函數:副程式的執行,同時擁有副選單與副程式標籤會優先處理副選單*/
int lee_udfmu_callexe(char **dkkwsp,char *str);
/home/stlee/leelib/menu/udfmenu.c
#include "/home/stlee/include/state.h"
/*
*udf主選單主流程控制
int lee_udfmenu(WINDOW *win_master,char *musphf,char *setphf)
*udf主選單橫式選單流程控制
int lee_udfmumst(WINDOW *win_master,int keydec,
int lefcx,int rincx,int mmucy,int *usrset,
char **arcmustmpp,int arcmustrn,
int *pg_foot,int *pg_end,int *prd_flag,int *prdlcx)
*多層次直式選單的視窗範圍控制與隨情況調整翻頁方式設定
char *lee_udfmuslv_brdwxy(char *sectmp,int secsize,char *fkws,char *ekws,
int aclcx,int actcy,int *usrset,
int *sectcx,int *sectcy,int *secdcx,int *secdcy,
int *wdcx,int *wdcy,int *pagewit,int *pagecode,
int *optsize,int *optstrn,int *optmlen)
*取得設定檔內的設定
int *lee_udfmu_getmuset(char *musftmp,int musfsize,char *setftmp,int setfsize)
*取得定義檔內的自定義標籤
char *lee_udfmu_getdkts(char *setftmp,int setfsize,int *dkkwssize)
*取得*setftmp內與mem內所有快捷鍵識別字語鍵值資料列
char *lee_udfmu_getcackws(char **dkkwsp,char *mem,int memsize,char *setftmp,int setfsize,
int *cacsize,int *cacstrn,int *cacmlen)
*對齊目前按鍵與快捷鍵設定
int lee_udfmu_cackws2dn(int keycode,char **cacsp,int cacstrn,char **tmpp,int tmpstrn,
int *pgfoot,int pgend,int *acdn)
*副程式的執行,同時擁有副選單與副程式標籤會優先處理副選單
int lee_udfmu_callexe(char **dkkwsp,char *str)
*/
/*udf主選單主流程控制
WINDOW *win_master 選單顯示的視窗,目前只支援全營幕stdscr模式
如要在營幕某視窗執行還需要四個座標參數搭配*win_master
char *setfna 定義檔檔名(顏色,按鍵,自定義捷取關鍵字的設定)
char *musphf 設定檔檔名(選單行為參數與選項字串的設定檔)
*/
int lee_udfmenu(WINDOW *win_master,char *musphf,char *setphf)
{
/*一些生命週期不超過一頁的變數*/
int x,y,i,n,k,sz,sn,len,keycode;
char *tmp,**tmpp;
int scrx,scry;
/*定義檔相關宣告*/
char *setftmp;
int setfsize;
/*主,副選項設定檔的相關宣告*/
char *musftmp;
int musfsize;
/*顏色定義,是一個定義在設定檔內的陣列*/
int *usrset;
/*標籤關鍵字,同時也是設定檔預定搜尋的自設關鍵字識別字*/
char *dkkwstmp,**dkkwsp;
int dkkwssize;/*標籤無strn其值固定為GM_KWSMAX定義在udfmu.h*/
/*從映射區擷取出有關橫式選單的所有資料*/
char *arctmp,**arctmpp;
int arctmpsize,arctmpstrn;
/*橫式選單顯示用的字串陣列相關宣告(從arctmp擷取出)*/
char *arcmustmp,**arcmustmpp;
int arcmusize,arcmustrn,arcmumlen;
int arcpgfoot,arcpgend,arcacdn,arcaccx,arclcx,arcrcx,arccy;
/*橫式選單的快捷鍵相關宣告*/
char *arccactmp;
char **arccactmpp;
int arccacsize,arccacstrn;
/*在設定檔內自行定義的字串,也就是橫式選單各選項下的副選單識別字*/
char *arc_sdafkw;
/*從映射區擷取出所有非橫式選單的資料*/
char *sectmp;
int secsize,secstrn;
int secpgfoot,secacdn;
int seclayer;/*副選單的遞迴控制參數*/
/*關鍵字與按鍵定義設定檔映射到settmp並消除註解部份*/
setftmp=lee_fout2tmp(setphf,&setfsize,"//","\n");
/*將musphf檔映射到musftmp*/
musftmp=lee_fout2tmp(musphf,&musfsize,"//","\n");
/*mvwprintw(win_master,1,0,"setfsize=%d musfsize=%d ",setfsize,musfsize);
wrefresh(win_master);
/*除錯用*/
/*自定義標簽取出,如檔案內無定義由lee_udfmu_getdkts()內定的字串陣列為標籤*/
dkkwstmp=lee_udfmu_getdkts(setftmp,setfsize,&dkkwssize);
dkkwsp=lee_mem2sp(dkkwstmp,dkkwssize);/*將*dkkwstmp定址*/
/*for(i=0,y=10;i<GM_KWSMAX;i++,y++)
mvwprintw(win_master,y,30,"*(dkkwsp+%02d)=%s",i,*(dkkwsp+i));
wrefresh(win_master);
/*除錯用*/
/*取出檔案內的顏色設定(分析*musftmp及*setftmp後篩選字串後得出一個整數陣列)*/
usrset=lee_udfmu_getmuset(musftmp,musfsize,setftmp,setfsize);
/*for(i=0,y=20;i<GM_USRSETMAX;i++,y++)
mvwprintw(win_master,y,0,"*(usrset+%02d)=%d ",i,*(usrset+i));
wrefresh(win_master);
getchar();
/*除錯用*/
/*將主選單部份從gpltmp分離出來且arcfkw到endrkw間的'\n'會被忽略*/
arctmp=lee_rtvmkwsift(musftmp,musfsize,*(dkkwsp+GM_ARCFKW),*(dkkwsp+GM_ENDRKW),SIFTCOR,
&arctmpsize,&arctmpstrn);
arctmpp=lee_mem2sp(arctmp,arctmpsize);/*將*arctmp定址*/
/*擷取橫式選單的選項字串*/
arcmustmp=lee_rtvmkw2sa(arctmp,arctmpsize,*(dkkwsp+GM_ARCFKW),*(dkkwsp+GM_ARCEKW),YES,RETRB,
&arcmusize,&arcmustrn,&arcmumlen);
arcmustmpp=lee_mem2sp(arcmustmp,arcmusize);/*將*arcmus定址*/
/*擷取橫式選單的快捷鍵*/
arccactmp=lee_udfmu_getcackws(dkkwsp,arctmp,arctmpsize,setftmp,setfsize,
&arccacsize,&arccacstrn,&len);
arccactmpp=lee_mem2sp(arccactmp,arccacsize);/*將*arccactmp定址*/
/*將非主選單部份從gpltmp分離出來*/
sectmp=lee_rtvmkwsift(musftmp,musfsize,*(dkkwsp+GM_ARCFKW),*(dkkwsp+GM_ENDRKW),SIFTOTH,
&secsize,&secstrn);
/*for(i=0,y=15;i<arctmpstrn;i++,y++)
mvwprintw(win_master,y,0,"arctmp[%02d]=%s ",i,*(arctmpp+i));
/**/
/*for(i=0,y=15;i<arcmustrn;i++,y++)
mvwprintw(win_master,y,0,"arcmustmp[%02d]=%s ",i,*(arcmustmpp+i));
/**/
/*for(i=0,y=1;i<arccacstrn;i++,y++)
mvwprintw(win_master,y,0,"arccactmpp[%02d]=%s ",i,*(arccactmpp+i));
/**/
/*tmpp=lee_mem2sp(sectmp,secsize);
for(i=0,y=1;i<secstrn;i++,y++)
mvwprintw(win_master,y,0,"secsp[%02d]=%s ",i,*(tmpp+i));
/**/
/*wrefresh(win_master);
/*除錯用*/
lee_getscrxy(&scrx,&scry);/*取得終端機營幕範圍最大值*/
arclcx=0;
arcrcx=scrx;
arccy=0;
arcpgfoot=0;
arcpgend=0;
arcacdn=0;
arcaccx=0;
secpgfoot=0;
secacdn=0;
seclayer=0;/*遞迴控制參數一定從第0次開始*/
/*將主選單顯示出來,並初始設定第一個副選單的起始x座標*/
lee_udfmumst_mudsp(win_master,
arcmustmpp,arcmustrn,
0,0,
arclcx,arcrcx,arccy,&*usrset,
&arcaccx,&arcpgend);
do
{
/*找出反白主選項是否有副選單關鍵字,有則擷取該關鍵字到arc_sdafkw*/
arc_sdafkw=lee_rtvstr2s(*(arctmpp+arcacdn),
*(dkkwsp+GM_SECFKW),*(dkkwsp+GM_SECEKW),RETRB);
/*控制權交給直式選單,所以lee_udfmuslv()必須在lee_udfmumst()前面*/
keycode=lee_udfmuslv(win_master,NOKEYIN,
arcaccx,arccy+1,&*usrset,
arc_sdafkw,dkkwsp,
sectmp,secsize,
setftmp,setfsize,
arccactmpp,arccacstrn,arctmpp,arctmpstrn,
&secpgfoot,&secacdn,&seclayer);
/*從lee_udfmuslv()出來後下一次進入都是從第0頁第0項開始,如果要保留每次反白所在
可以宣告一個secacdn[]陣列保留每個副選單的上次的反白所在*/
secpgfoot=0;
secacdn=0;
free(arc_sdafkw);
/*橫式選單*/
lee_udfmumst(win_master,keycode,
arclcx,arcrcx,arccy,&*usrset,
arcmustmpp,arcmustrn,
&arcpgfoot,&arcpgend,&arcacdn,&arcaccx);
switch(keycode)
{
case NOKEYIN:
break;
case KDEC_ESC:
free(setftmp);
free(musftmp);
free(usrset);
free(dkkwstmp);
free(dkkwsp);
free(arctmp);
free(arctmpp);
free(arcmustmp);
free(arcmustmpp);
free(arccactmp);
free(arccactmpp);
/*free(arc_sdafkw);arc_sdafkw在lee_udfmuslv()出來後有釋放過了所以這裡不要釋放*/
free(sectmp);
return(keycode);
break;
case KDEC_ENTER:
/*選項命令:副程式標籤所指執行檔的執行;由於lee_udfmu_callexe()會先找副選單標籤
所以同時擁有副選單與副程式標籤時副程式並不會被執行*/
if(lee_udfmu_callexe(dkkwsp,*(arctmpp+arcacdn))==-1)
break;
break;
default:
/*搜尋快捷鍵是否被定義*/
k=lee_udfmu_cackws2dn(keycode,arccactmpp,arccacstrn,arctmpp,arctmpstrn,
&arcpgfoot,arcpgend,&arcacdn);
if(k==-1)
break;
/*將主選單重新顯示出來*/
lee_udfmumst_mudsp(win_master,
arcmustmpp,arcmustrn,
arcpgfoot,arcacdn,
arclcx,arcrcx,arccy,&*usrset,
&arcaccx,&arcpgend);
break;
}
/*mvprintw(25,1,"arctmpsize=%d arctmpstrn=%d arcmusize=%d arcmustrn=%d arcmumlen=%d ",
arctmpsize,arctmpstrn,arcmusize,arcmustrn,arcmumlen);
mvprintw(26,1,"arcpgfoot=%d arcpgend=%d arcacdn=%d arcaccx=%d arclcx=%d arcrcx=%d arccy=%d ",
arcpgfoot,arcpgend,arcacdn,arcaccx,arclcx,arcrcx,arccy);
mvprintw(27,1,"arccacsize=%d arccacstrn=%d ",
arccacsize,arccacstrn);
refresh();
/**/
}while(1);
}
/*udf主選單橫式選單流程控制
WINDOW *win_master 由主流程的呼叫者持有的視窗
int keydec 主流程傳來的按鍵值
int lefcx
int rincx
int mmucy
int *usrset
char **arcmustmpp
int arcmustrn
int *pg_foot
int *pg_end
int *prd_flag
int *prdlcx
*/
int lee_udfmumst(WINDOW *win_master,int keydec,
int lefcx,int rincx,int mmucy,int *usrset,
char **arcmustmpp,int arcmustrn,
int *pg_foot,int *pg_end,int *prd_flag,int *prdlcx
)
{
int keycode;
if(keydec==-1)/*當keydec永遠都傳來-1表示本函數是主要的迴路控制模式則須初始顯示*/
lee_udfmumst_mudsp(win_master,
arcmustmpp,arcmustrn,
*pg_foot,*prd_flag,
lefcx,rincx,mmucy,&*usrset,
&*prdlcx,&*pg_end);
do
{
if(keydec==-1)/*當keydec永遠都傳來-1表示本函數是主要的迴路控制模式*/
keycode=lee_getkb(0);
else
keycode=keydec;
switch(keycode)
{
case NOKEYIN:
/*本函數因為是主要選單模式所以在此攔截住鍵盤控制權(無按鍵時不返回)*/
break;
case KDEC_LEFT:
case KDEC_RIGHT:
case KDEC_HOME:
case KDEC_END:
lee_udfmumst_keyact(keycode,arcmustrn,&*pg_foot,&*pg_end,&*prd_flag);
lee_udfmumst_mudsp(win_master,
arcmustmpp,arcmustrn,
*pg_foot,*prd_flag,
lefcx,rincx,mmucy,&*usrset,
&*prdlcx,&*pg_end);
default:
return(keycode);
}
}while(1);
}
/*udf主選單直式選單流程控制
WINDOW *win_master 由主流程的呼叫者持有的視窗
int keydec 主流程傳來的按鍵值
int aclcx 選單在win_master的左上x座標
int actcy 選單在win_master的左上y座標
int *usrset udf選單行為設定的參數陣列
char *prd_sdafkw 作用中選項(可以是橫式或直式)的下一層副選單識別關鍵字
char **dkkwsp 自定義擷取識別關鍵字
char *sectmp 非橫式選單的arctmp的所有資料集合
int secsize sectmp的長度
char *setftmp 定義檔的映射區資料
int setfsize setftmp的長度
char **arccactmpp 橫式選單的快捷鍵定址指標陣列
int arccacstrn arccactmpp的資料元素數量
char **arctmpp 橫式選單的的所有資料集合定址指標陣列
int arctmpstrn arctmpp的資料元素數量
int *pg_foot 由主流程持有的直式選單本頁顯示選項起點旗標
int *prd_flag 由主流程持有的直式選單反白顯示選項起點旗標
int *win_layer 由主流程持有的直式選單遞迴控制參數
修正第二層以後有副選單的選項會往下偏移1的說明
在多層次選單如下:
<主選單>主選單二<選項>[AAA]<副選單></>
[AAA]aaa-1<選項></>
[AAA]aaa-2 -><選項>[BBB]<副選單>xxx</>
[BBB]bbb-1<選項></>
[BBB]bbb-2<選項></>
[BBB]bbb-3<選項>[CCC]<副選單></>
[CCC]ccc-1<選項></>
[CCC]ccc-2<選項></>
[CCC]ccc-3<選項></>
[BBB]bbb-4<選項></>
[BBB]bbb-5<選項></>
[BBB]bbb-6<選項></>
[AAA]AAA-3<選項></>
[AAA]AAA-4<選項></>
由於prd_sdafkw會隨每往下一層而改變所以當到第2層的[BBB]時傳給lee_rtvmkw2dt()的endkw是"</>"
會發生第2層以後sectab都會往下偏一個選項才能正確的進入[BBB]層以後的副選單[CCC]
因為以inr_sdafkw為起始關鍵字時在B層nvsectmpp要擷取出所有含[CCC]與</>此時擷取到的
第0號字串是"[CCC]<副選單>xxx</>"而正確應該是"[CCC]ccc-1<選項></>",所以必須給予修正
*/
int lee_udfmuslv(WINDOW *win_master,int keydec,
int aclcx,int actcy,int *usrset,
char *prd_sdafkw,char **dkkwsp,
char *sectmp,int secsize,
char *setftmp,int setfsize,
char **arccactmpp,int arccacstrn,char **arctmpp,int arctmpstrn,
int *pg_foot,int *prd_flag,int *win_layer
)
{
/*一些控制用的宣告*/
int keycode,pagewit,pageend,pagecode;
int isarccackey,isoptcackey;
int i,n,k,x,y,mstcac;
/*與視窗顯示相關的宣告*/
WINDOW *winptr,*dstwin;
int sectcx,sectcy,secdcx,secdcy;
int wtcx,wtcy,wdcx,wdcy;
int scrx,scry;
/*供進入遞迴後傳給下層選單對應本函數的控制參數*/
int inr_pgfoot,inr_prdflag,inr_aclcx,inr_actcy,inr_keycode;
char *inr_sdafkw;
/*在*sectmp內所有含*prd_sdafkw字串的資料列*/
char *nvsectmp,**nvsectmpp;
int nvsecsize,nvsecstrn,nvseclen;
/*顯示用的選項字串*/
char *opttmp,**opttmpp;
int optsize,optstrn,optmlen;
/*本作用中直式選單的快捷鍵*/
char *optcactmp,**optcactmpp;
int optcacsize,optcacstrn,optcacmlen;
/*遞迴快速出口(已進入遞迴且參數*prd_sdafkw是一個空字串)*/
if(*win_layer>0 && strlen(prd_sdafkw)<1)
return(keydec);
/*取出與*prd_sdafkw相關的每一列資料(結尾關鍵字是*(dkkwsp+GM_ENDRKW)不是'\n'
且擷取模式為RETRHBR)*/
nvsectmp=lee_rtvmkw2sa(sectmp,secsize,prd_sdafkw,*(dkkwsp+GM_ENDRKW),YES,RETRHBR,
&nvsecsize,&nvsecstrn,&nvseclen);
nvsectmpp=lee_mem2sp(nvsectmp,nvsecsize);/*將*nsectmp定址*/
/*修正第2層遞迴以後有副選單的選項會偏到下一個選項(上面有說明)*/
if(*win_layer>0)
{
/*搜尋被修正前的**nvtmpp第0個字串內是否有快捷鍵,供快捷鍵修正的參考*/
mstcac=lee_memchunt(*(nvsectmpp+0),*(dkkwsp+GM_CACFKW),0,strlen(*(nvsectmpp+0)),FROM);
/*開始修正*/
for(i=0,n=1;n<nvsecstrn;i++,n++)
*(nvsectmpp+i)=*(nvsectmpp+n);
nvsecstrn-=1;
}
/*依旗標值表格sectab在這裡先取得第0項的下一層副選單的prd_sdafkw關鍵字*/
inr_sdafkw=lee_rtvstr2s(*(nvsectmpp+0),*(dkkwsp+GM_SECFKW),*(dkkwsp+GM_SECEKW),RETRB);
/*mvprintw(28,30,"prd_sdafkw=%s nvsecsize=%d nvsecstrn=%d mstcac=%d ",
prd_sdafkw,nvsecsize,nvsecstrn,mstcac);
for(i=0,y=15;i<nvsecstrn;i++,y++)
{
if(y>=25)
break;
mvprintw(y,40,"nsecstmp[%02d]=%s ",i,*(nvsectmpp+i));
}
refresh();
/*除錯用*/
/*一些初值設定,當無副選單時不會進入下面的if(nvsecstrn>0)內但在流程中有可能會用到其中
的某些變數作為參數,例如optstrn,optcacstrn如果沒設初值則將會造成一些函數存取的溢位*/
optsize=0;
optstrn=0;
optmlen=0;
optcacsize=0;
optcacstrn=0;
optcacmlen=0;
/*因為參數scrxx系列已是營幕的絕對座標所以wtcx與wtcy從0,0開始(視窗的左上角)否則當scrdy要
傳固定值(外框底部固定)或浮動值(隨字串數量浮動)的情況時wdcx,wdcy與pagewit會無法定位*/
wtcx=0;
wtcy=0;
/*翻頁模式一律為CIRCU(循環),但在lee_setvmu()內有可能因選項數量超出營幕範圍而被改成PAGE(翻頁)*/
pagecode=CIRCU;
pageend=0;
/*取得終端機營幕範圍最大值*/
lee_getscrxy(&scrx,&scry);
if(nvsecstrn>0)
{
/*將反白選單的"選項字串"篩選出來,並設定視窗的各座標參數*/
opttmp=lee_udfmuslv_brdwxy(nvsectmp,nvsecsize,prd_sdafkw,*(dkkwsp+GM_ARCEKW),
aclcx,actcy,&*usrset,
§cx,§cy,&secdcx,&secdcy,
&wdcx,&wdcy,&pagewit,&pagecode,
&optsize,&optstrn,&optmlen);
opttmpp=lee_mem2sp(opttmp,optsize);/*將*opttmp定址*/
/*取得目前作用中副選單各選項的快捷鍵描述與鍵值*/
optcactmp=lee_udfmu_getcackws(dkkwsp,nvsectmp,nvsecsize,setftmp,setfsize,
&optcacsize,&optcacstrn,&optcacmlen);
optcactmpp=lee_mem2sp(optcactmp,optcacsize);
/*修正第2層遞迴以後有副選單的選項會偏到下一個選項(上面有說明)
但快捷鍵的修正必須在*nvsectmpp修正前的第0個字串內是否快捷鍵辨識值mstcac不是-1的值
(從上層下來的選項內擁有快捷鍵)這樣才不會讓本層的第1個快捷鍵在上層選項無快捷鍵的情
形下被修正掉*/
if(*win_layer>0 && mstcac!=-1)
{
for(i=0,n=1;n<optcacstrn;i++,n++)
*(optcactmpp+i)=*(optcactmpp+n);
optcacstrn-=1;
}
/*將要顯示的區塊先複製起來*/
dstwin=newwin(wdcy,wdcx,sectcy,sectcx);
copywin(curscr,dstwin,sectcy,sectcx,0,0,wdcy-1,wdcx-1,FALSE);
/*宣告要顯示的視窗winptr後顯示出來*/
winptr=newwin(wdcy,wdcx,sectcy,sectcx);
lee_wmuboxl(winptr,wtcx,wtcy,wdcx,wdcy,*(usrset+GM_CLWINCOL),NOT);/*畫出副選單外框及區塊*/
/*顯示出直式選單*/
lee_udfmuslv_mudsp(winptr,opttmpp,optstrn,
wtcx+1,wtcy+1,wdcx-1,wdcy-1,&*usrset,
*pg_foot,*prd_flag,
&pageend);
}
/*mvprintw(1,35,"*win_layer=%d secsize=%d maxrow=%d aclcx=%d actcy=%d *",
*win_layer,secsize,maxrow,aclcx,actcy);
mvprintw(2,35,"prd_sdafkw=%s(len=%d) inr_sdafkw=%s(len=%d)",
prd_sdafkw,strlen(prd_sdafkw),inr_sdafkw,strlen(inr_sdafkw));
mvprintw(3,35,"optstrn=%d vmumlen=%d vmutdn=%d sectdn=%d ",
optstrn,vmumlen,vmutdn,sectdn);
mvprintw(4,35,"sectcx=%d sectcy=%d secdcx=%d secdcy=%d (scrx=%d scry=%d) ",
sectcx,sectcy,secdcx,secdcy,scrx,scry);
mvprintw(5,35,"wtcx=%d wtcy=%d wdcx=%d wdcy=%d pagewit=%d ",
wtcx,wtcy,wdcx,wdcy,pagewit);
refresh();
/**/
do
{
if(keydec==NOKEYIN)/*當keydec永遠都傳來-1表示本函數是主要的迴路控制模式*/
keycode=lee_getkb(0);
else
keycode=keydec;
switch(keycode)
{
case NOKEYIN:
/*當keydec永遠都傳入NOKEYIN則本函數在此攔截住鍵盤控制權(無按鍵時不返回)
而非本函數的控制鍵則傳回按鍵值由主流程控制函數分配流程*/
break;
case KDEC_UP:
case KDEC_DOWN:
case KDEC_PGUP:
case KDEC_PGDOWN:
if(nvsecstrn<1)/*無直式選單選項*/
break;
free(inr_sdafkw);/*釋放上一次(上次反白項目)的下層副選單prd_sdafkw關鍵字*/
/*直列式選單的行為控制*/
lee_udfmuslv_keyact(keycode,optstrn,pagecode,pagewit,&*pg_foot,&*prd_flag);
/*直列式選單整頁顯示*/
lee_udfmuslv_mudsp(winptr,opttmpp,optstrn,
wtcx+1,wtcy+1,wdcx-1,wdcy-1,&*usrset,
*pg_foot,*prd_flag,
&pageend);
/*依旗標值表格sectab取得本次反白選項的下一層副選單的prd_sdafkw關鍵字*/
inr_sdafkw=lee_rtvstr2s(*(nvsectmpp + *prd_flag),
*(dkkwsp+GM_SECFKW),*(dkkwsp+GM_SECEKW),RETRB);
break;
case KDEC_ENTER:/*Enter是遞迴的絕對入口以及選項命令執行入口*/
/*選項命令:副程式標籤所指執行檔的執行;由於lee_udfmu_callexe()會先找副選單標籤
所以同時擁有副選單與副程式標籤時副程式並不會被執行
選項命令執行必須本次叫用有"選項"可執行(nvsecstrn不為0)否則須往下執行返回
呼叫者並傳回按鍵值的動作(執行主選單選項的副程式)*/
if(nvsecstrn>0 && lee_udfmu_callexe(dkkwsp,*(nvsectmpp + *prd_flag))==1)
break;
case KDEC_RIGHT:/*右鍵是有條件的遞回入口*/
/*反白選項下有副選單*/
if(strlen(inr_sdafkw)>0 && nvsecstrn>0 )
{
/*以遞迴叫出的副選單從第0頁的第0項顯示,反白旗標也是從第0項開始*/
inr_pgfoot=0;
inr_prdflag=0;
/*要控制進入遞迴後的副選單在右邊界超出時其它方式的顯示行為由此控制試試2007.10.11*/
inr_aclcx=secdcx - *(usrset+GM_SECRTCCOL);
if(*(usrset+GM_SECMAXROW)<=0)/*不固定列數時以反白選項所在列為下一層選單起始列的參考*/
inr_actcy=*prd_flag+actcy+1;
else/*固定列數時以視窗上框所在列為下一層選單起始列的參考*/
inr_actcy=actcy+1;
/*遞迴控制參數+1*/
*win_layer+=1;
/*目前副選單外框變色*/
lee_wmuboxl(winptr,wtcx,wtcy,wdcx,wdcy,*(usrset+GM_CLWINBAD),YES);/*目前副選單外框變色*/
/*呼叫自己進入遞迴*/
keycode=lee_udfmuslv(win_master,keydec,
inr_aclcx,inr_actcy,&*usrset,
inr_sdafkw,dkkwsp,
sectmp,secsize,
setftmp,setfsize,
arccactmpp,arccacstrn,arctmpp,arctmpstrn,
&inr_pgfoot,&inr_prdflag,&*win_layer);
/*遞迴退出將目前副選單外框顏色還原*/
lee_wmuboxl(winptr,wtcx,wtcy,wdcx,wdcy,*(usrset+GM_CLWINCOL),YES);
/*遞迴返回時的先期處理*/
if(keycode==KDEC_LEFT || keycode==KDEC_ESC)/*內定只退回一層的按鍵*/
break;
else
{
;
}
}
default:/*不是直列式選單的控制鍵*/
/*快捷鍵的處理:非橫式選單程式或本函數內定的按鍵都有可能是被定義的快捷鍵
如果橫式選單或主流程有定義其它的按鍵必須加入這裡排除,否則會在這裡被攔截而失效*/
if(keycode!=KDEC_ENTER && keycode!=KDEC_RIGHT &&
keycode!=KDEC_HOME && keycode!=KDEC_END)
{
/*先看該鍵是不是橫式選單所定義的
由於這裡會做先查看橫式選單的快捷鍵動作所以各層副選單內的快捷鍵如和橫式選單重覆
將以橫式選單優先處理
但在直式選單內各層的快捷鍵是各自獨立的所以可重覆定義(同層以選項順序決定->先找到的)*/
isarccackey=lee_udfmu_cackws2dn(keycode,arccactmpp,arccacstrn,arctmpp,arctmpstrn,
&i,arccacstrn,&k);
if(optcacstrn>0 && isarccackey==-1)/*不是橫式選單定義的按鍵*/
{
/*再找是不是本作用中副選單定義的*/
isoptcackey=lee_udfmu_cackws2dn(keycode,optcactmpp,optcacstrn,nvsectmpp,nvsecstrn,
&*pg_foot,pageend,&*prd_flag);
if(isoptcackey==-1)/*不是本作用中副選單定義的*/
break;
/*直列式選單整頁顯示*/
lee_udfmuslv_mudsp(winptr,opttmpp,optstrn,
wtcx+1,wtcy+1,wdcx-1,wdcy-1,&*usrset,
*pg_foot,*prd_flag,
&pageend);
break;
}
}
case KDEC_LEFT:/*左鍵不管在哪一層都是該層的出口*/
/*函數(遞迴)的唯一出口*/
if(*win_layer<1)
touchwin(win_master);
else
{
*win_layer-=1;
wrefresh(dstwin);
}
/*釋放本函數所有的資源*/
free(nvsectmp);
free(nvsectmpp);
free(inr_sdafkw);
if(nvsecstrn>0)
{
delwin(winptr);
delwin(dstwin);
free(opttmp);
free(opttmpp);
free(optcactmp);
free(optcactmpp);
}
return(keycode);
}
/*時鐘*/
/* lee_wclock(win_master,70,scry-1);*/
/*mvprintw(30,1,"keycode=%d pagewit=%d *pg_foot=%d pageend=%d *prd_flag=%d inr_sdafkw=%s(%d)*",
keycode,pagewit,*pg_foot,pageend,*prd_flag,inr_sdafkw,strlen(inr_sdafkw));
refresh();
/**/
}while(1);
}
/*===============================================================================================*/
/*===============================================================================================*/
/*===============================================================================================*/
/*===============================================================================================*/
/*===============================================================================================*/
/*===============================================================================================*/
/*多層次直式選單的視窗範圍控制與隨情況調整翻頁方式設定
*/
char *lee_udfmuslv_brdwxy(char *sectmp,int secsize,char *fkws,char *ekws,
int aclcx,int actcy,int *usrset,
int *sectcx,int *sectcy,int *secdcx,int *secdcy,
int *wdcx,int *wdcy,int *pagewit,int *pagecode,
int *optsize,int *optstrn,int *optmlen
)
{
int scrx,scry;
char *opttmp;
if(strlen(fkws)<1)
{
*optsize=0;
*optstrn=0;
*pagewit=0;
opttmp=(char *)malloc(1);
return(&*opttmp);
}
lee_getscrxy(&scrx,&scry);/*取得終端機營幕範圍最大值*/
opttmp=lee_rtvmkw2sa(sectmp,secsize,fkws,ekws,NOT,RETRB,
&*optsize,&*optstrn,&*optmlen);
if(optstrn>0)
{
/*這裡所使用的座標是"視窗要在營幕的那裡顯示的絕對座標,不是該視窗的相對座標(視窗都從0,0開始)"
這樣在lee_udfmuslv()會自行計算並顯示該視窗然後在非控制鍵時自動回收視窗資源*/
*sectcx=aclcx;
*sectcy=actcy;
*secdcx=aclcx + *optmlen + 2;
if(*secdcx>=scrx)/*錯誤修正:*secdcx已超出營幕範圍*/
{
*secdcx=scrx-1;/*留邊一行*/
*sectcx=scrx - *optmlen - (2+1);/*減外框兩行及留邊一行*/
}
if(*(usrset+GM_SECMAXROW)<=0)/*不固定列數:maxrow傳入0以下的值表示視窗範圍依字串數量各別增減*/
*secdcy=actcy + *optstrn + 2;/*依選項數量決定副選單列數,如要固定則可令secdcy固定在0以上*/
else
*secdcy=actcy + *(usrset+GM_SECMAXROW) + 2;/*副選單每頁固定列數加上下框2列*/
if(*secdcy>=scry)/*錯誤修正:*secdcy已超出營幕範圍*/
*secdcy=scry-1;/*留邊一列*/
/*錯誤修正:字串數量有5個以上但可顯示列數不足5列--->視窗往上開*/
*pagewit=(*secdcy - *sectcy) - 2;
if((scry-1-*sectcy) < (*(usrset+GM_SECTGSROW)+2))
{
*secdcy=actcy+1;
*sectcy=(actcy+1)-*optstrn-2;
if(*sectcy<=0)/*已超出營幕範圍*/
*sectcy=1;/*留邊一列*/
}
*wdcx=*secdcx - *sectcx;
*wdcy=*secdcy - *sectcy;
/*一頁資料量,只給lee_udfmuslv_keyact()翻頁參考,可大於optstrn(視窗外框固定大小:maxrow非0值)*/
*pagewit=(*secdcy - *sectcy) - 2;
if(*pagewit < *optstrn)
*pagecode=PAGE;
}
else
*pagewit=0;
/*mvprintw(27,0,"*(usrset+GM_SECMAXROW)=%d *(usrset+GM_SECTGSROW)=%d aclcx=%d actcy=%d ",
*(usrset+GM_SECMAXROW),*(usrset+GM_SECTGSROW),aclcx,actcy);
mvprintw(28,0,"*sectcx=%d *sectcy=%d *secdcx=%d *secdcy=%d ",*sectcx,*sectcy,*secdcx,*secdcy);
mvprintw(29,0,"*wdcx=%d *wdcy=%d *pagewit=%d *stgecode=%d ",*wdcx,*wdcy,*pagewit,*stgecode);
mvprintw(30,0,"*optsize=%d *optstrn=%d *optmlen=%d ",*optsize,*optstrn,*optmlen);
refresh();
/*除錯用*/
return(&*opttmp);
}
/*取得設定檔內的設定
*/
int *lee_udfmu_getmuset(char *musftmp,int musfsize,char *setftmp,int setfsize)
{
int i,y,sz;
char *buf,*tmp,**tmpp;
int *usrset;
char *clkws,**clkwsp;
char **dclkwsp;
char dclkws[GM_USRSETMAX][21]={
"CLARCOPT","CLARCPRD",
"CLSECOPT","CLSECPRD",
"CLWINCOL","CLWINBAD",
"ARCGAPCOL","ARCPRDSPC",
"SECMAXROW","SECTGSROW","SECRTCCOL",
"CLOCKCX","CLOCKCY","CLOCKMOD"
};
/*檔內無設定參數時的內定值*/
char ddclkws[GM_USRSETMAX][11]={
"(B7F0)","(B2F0)",
"(B7F0)","(B1F0)",
"(W2B4)","(W6B4)",
"2","1",
"-1","5","1"
"-1","-1","-1"
};
usrset=(int *)malloc(sizeof(int) * GM_USRSETMAX);
/*取得musftmp內所有含dclkws[][]相同字串的資料列給tmp當檔案內沒設定時
以dclkws[][]的內定字串做為描述詞*/
dclkwsp=lee_mem2sp((char *)dclkws,sizeof(dclkws));
tmp=lee_rtvfset2sa(musftmp,musfsize,dclkwsp,GM_USRSETMAX,"=","\n","//",&sz);
tmpp=lee_mem2sp(tmp,sz);
/*取得setftmp內所有與tmp相同字串的資料列在"="號後面的常數值字串當設定檔內的設定是
一個常數時套用這個clkws有可能會有錯誤,比如設定"SECTGSROW = 1"而去setftmp找出來的有
可能是"(B0F1) = 2" 的2,因為在setftmp內會以"1"去找所以找到第一個"1"的"="號後面的2*/
clkws=lee_rtvfset2sa(setftmp,setfsize,tmpp,GM_USRSETMAX,"=","\n","//",&sz);
clkwsp=lee_mem2sp(clkws,sz);
/*迴路內的if()...else if()...else...結構是要排除顏色GM_CLxxx是以取得musftmp內的描述詞後
到setftmp擷取該描述詞的值,而視窗行為是直接設定常數不用到setftmp擷取所需的常數*/
for(i=0;i<GM_USRSETMAX;i++)
{
if(i>=GM_COLORFOOT && i<GM_COLOREND)/*顏色設定的部份*/
{
if(strcasecmp(dclkws[i],*(tmpp+i))==0)/*與內定的參照字串相同(檔內未設定)*/
{
/*以ddckws內定描述詞去setftmp找*/
buf=lee_rtvfset2s(setftmp,setfsize,ddclkws[i],"=","\n","//");
*(usrset+i)=atoi(buf);
free(buf);
}
else/*檔案內有設定*/
*(usrset+i)=atoi(*(clkwsp+i));/*直接取用clkwsp內的值*/
}
/*視窗行為設定的部份與時鐘顯示方式相同(不必透過參照轉換)*/
else if((i>=GM_MUSETFOOT && i<GM_MUSETEND) || (i>=GM_CLOCKFOOT && i<GM_CLOCKEND))
{
if(strcasecmp(dclkws[i],*(tmpp+i))==0)/*與內定的參照字串相同(檔內未設定)*/
*(usrset+i)=atoi(ddclkws[i]);/*直接取用ddclkws內定的值*/
else/*檔案內有設定*/
{
/*擷取musftmp內dclkws[i]字串相同的資料列中"="號後面的常數字串*/
buf=lee_rtvfset2s(musftmp,musfsize,dclkws[i],"=","\n","//");
*(usrset+i)=atoi(buf);
free(buf);
}
}
else
{
;
}
}
/*錯誤設定的檢查*/
/*直列式視窗的下越界基準值不得<=0*/
if(*(usrset+GM_SECTGSROW)<=0)
*(usrset+GM_SECTGSROW) = atoi(ddclkws[GM_SECTGSROW]);
/*橫式選單各選項間的間距行數不得小於0*/
if(*(usrset+GM_ARCGAPCOL)<0)
*(usrset+GM_ARCGAPCOL) = atoi(ddclkws[GM_ARCGAPCOL]);
/*橫式選單反白選項間的留邊數不得小於0*/
if(*(usrset+GM_ARCPRDSPC)<0)
*(usrset+GM_ARCPRDSPC) = atoi(ddclkws[GM_ARCPRDSPC]);
/*橫式選單反白選項間的留邊數大於各選項間的間距行數*/
if(*(usrset+GM_ARCPRDSPC)>*(usrset+GM_ARCGAPCOL))
*(usrset+GM_ARCPRDSPC) = *(usrset+GM_ARCGAPCOL);
/*for(i=0,y=10;i<GM_USRSETMAX;i++,y++)
mvprintw(y,0,"*(dclkwsp%02d)=%9s *(tmpp+%02d)=%9s *(clkwsp+%02d)=%3s *(usrset+%02d)=%d...lee_udfmu_getmuset(",
i,*(dclkwsp+i),i,*(tmpp+i),i,*(clkwsp+i),i,*(usrset+i));
refresh();
/*除錯用*/
free(tmp);
free(tmpp);
free(clkws);
free(clkwsp);
return(&*usrset);
}
/*取得定義檔內的自定義標籤
*/
char *lee_udfmu_getdkts(char *setftmp,int setfsize,int *dkkwssize)
{
/*內定關鍵字,同時也是設定檔預定搜尋的自設關鍵字識別字*/
char *dkkwstmp;
char **ddkkwsp;
char ddkkws[GM_KWSMAX][9]={
"[ARCFKW]","[ARCEKW]",
"[SECFKW]","[SECEKW]",
"[EXEFKW]","[EXEEKW]",
"[EXPFKW]","[EXPEKW]",
"[CACFKW]","[CACEKW]",
"[ENDRKW]"
};
/*將ddkkws[][]定址可讓lee_rtvsetf2sa()依此為參數按順序擷取可能沒按順序排列的映射區資料*/
ddkkwsp=lee_mem2sp((char *)ddkkws,sizeof(ddkkws));
/*依dstkw[][]的順序取出檔內設定的替代字串,如果檔內沒有與dstkw[][]相同的設定則以內定的
dstkw[][]內的字串資料做為關鍵字*/
dkkwstmp=lee_rtvfset2sa(setftmp,setfsize,ddkkwsp,GM_KWSMAX,"=","\n","//",&*dkkwssize);
return(&*dkkwstmp);
}
/*取得*setftmp內與mem內所有快捷鍵識別字語鍵值資料列
*/
char *lee_udfmu_getcackws(char **dkkwsp,char *mem,int memsize,char *setftmp,int setfsize,
int *cacsize,int *cacstrn,int *cacmlen)
{
char *tmp,**tmpp;
char *cacstmp;
int i,y,sz,len;
/*將*mem內所有有關快捷鍵的設定抽取出來*/
tmp=lee_rtvmkw2sa(mem,memsize,*(dkkwsp+GM_CACFKW),*(dkkwsp+GM_CACEKW),YES,RETRB,
&sz,&*cacstrn,&*cacmlen);
/*將*tmp定址供lee_rtvfset2sa()擷取出有效的快捷鍵值*/
tmpp=lee_mem2sp(tmp,sz);
/*將*setftmp內有在*mem定義的快捷鍵的值篩選出來給*cacstmp*/
cacstmp=lee_rtvfset2sa(setftmp,setfsize,tmpp,*cacstrn,"\n","\n","//",&*cacsize);
/**cacstmp定址由呼叫者函數執行否則*cacstmp將無法以free()釋放,這樣會造成如副選單快捷鍵的
取得時每一次副選單都必須取得一塊記憶體空間但回到主選單後卻只能釋放以lee_mem2sp()定址的
指標陣列空間但實際放資料的*cacstmp一直被要求重新取得記憶體空間*/
free(tmp);
free(tmpp);
return(cacstmp);
}
/*對齊目前按鍵與快捷鍵設定
*/
int lee_udfmu_cackws2dn(int keycode,char **cacsp,int cacstrn,char **tmpp,int tmpstrn,
int *pgfoot,int pgend,int *acdn)
{
char keycodestr[11];
char *tmp;
int i,y,k;
/*將目前鍵值轉換成字串*/
snprintf(keycodestr,sizeof(keycodestr),"%d",keycode);
/*擷取該鍵值的描述字串,如"(F1)"或"(F9)"*/
tmp=lee_rtvsp2fore(cacsp,cacstrn,keycodestr,"=");
if(strlen(tmp)<1)/*該鍵值的描述字串未被使用者定義*/
{
free(tmp);/*tmp最少會有一個空白字元所以必須釋放*/
return(-1);
}
/*取得該描述字串在arctmpp的第幾個元素*/
k=lee_memshunt(tmpp,tmp,0,tmpstrn,FROM);
if(k==-1)/*該鍵值的描述字串未被使用者定義*/
{
free(tmp);
return(-1);
}
if(k>=*pgfoot && k<=pgend)/*該元素的選項字串在營幕範圍內*/
*acdn=k;
else/*該元素的選項字串在營幕範圍外*/
{
*pgfoot=k;
*acdn=k;
}
free(tmp);
return(1);
}
/*副程式的執行,同時擁有副選單與副程式標籤會優先處理副選單
*/
int lee_udfmu_callexe(char **dkkwsp,char *str)
{
WINDOW *dstwin;
int scrx,scry;
char *seckws,*exekws,*expkws;
int r;
/*檢查是否有副選單標籤*/
seckws=lee_rtvstr2s(str,*(dkkwsp+GM_SECFKW),*(dkkwsp+GM_SECEKW),RETRB);
if(strlen(seckws)>0)/*選項擁有副選單關鍵字*/
{
free(seckws);
return(0);
}
/*檢查是否有副程式標籤*/
exekws=lee_rtvstr2s(str,*(dkkwsp+GM_EXEFKW),*(dkkwsp+GM_EXEEKW),RETRB);
if(strlen(exekws)<1)
{
free(exekws);
free(seckws);
return(-1);
}
/*檢查是否有參數標籤*/
expkws=lee_rtvstr2s(str,*(dkkwsp+GM_EXPFKW),*(dkkwsp+GM_EXPEKW),RETRB);
r=lee_callexe(exekws,1);
free(seckws);
free(exekws);
free(expkws);
return(1);
}
/home/stlee/leelib/menu/keyact.c
#include "/home/stlee/include/state.h"
/*
*udf主選單橫式選單按鍵行為的設定
void lee_udfmumst_keyact(int keycode,int strn,
int *pg_foot,int *pg_end,int *prd_flag)
*udf主選單直式選單按鍵行為控制
void lee_udfmuslv_keyact(int keycode,int strn,int pagecode,
int pagewit,int *pg_foot,int *prd_flag)
*/
/*udf主選單橫式選單按鍵行為的設定
*/
void lee_udfmumst_keyact(int keycode,int strn,
int *pg_foot,int *pg_end,int *prd_flag)
{
switch(keycode)
{
case KDEC_LEFT:
if(*prd_flag <= 0)
break;
*prd_flag-=1;
if(*pg_foot > *prd_flag)
*pg_foot-=1;
break;
case KDEC_RIGHT:
if(*prd_flag >= strn-1)
break;
*prd_flag+=1;
if(*prd_flag > *pg_end)
*pg_foot=*pg_end;
break;
case KDEC_HOME:
*prd_flag=*pg_foot;
break;
case KDEC_END:
*prd_flag=*pg_end;
break;
}
}
/*udf主選單直式選單按鍵行為控制
*/
void lee_udfmuslv_keyact(int keycode,int strn,int pagecode,
int pagewit,int *pg_foot,int *prd_flag)
{
int pgfoot,pgend,prdflag;
if(pagewit<=0)
return;
prdflag=*prd_flag;/*反白所在旗標*/
pgfoot=*pg_foot;/*本頁起始旗標*/
pgend=pgfoot+(pagewit-1);/*本頁終止旗標*/
switch(keycode)
{
case KDEC_UP:
if(prdflag <= 0 && pagecode!=CIRCU)
break;
prdflag -= 1;
if(pgfoot > prdflag)/*反白已移到頁首須翻頁*/
{
if(pagecode==CIRCU)/*在本頁循環,此模式只有PAGE UP或DOWN才可進行翻頁*/
{
if(pgend > strn-1)
prdflag = strn-1;
else
prdflag = pgend;
}
else if(pagecode==PAGE)/*翻到上一頁*/
pgfoot -= pagewit;
else if(pagecode==STOP)/*停住,此模式只有PAGE UP或DOWN才可進行翻頁*/
{
prdflag += 1;
break;
}
else
break;/*pagecode參數錯誤*/
}
if(pgfoot < 0)
pgfoot = 0;
break;
case KDEC_DOWN:
if(prdflag >= strn-1 && pagecode != CIRCU)
break;
prdflag += 1;
if(prdflag > pgend || prdflag > strn-1)/*反白已移到頁尾須翻頁*/
{
if(pagecode==CIRCU)/*在本頁循環,此模式只有PAGE UP或DOWN才可翻頁*/
prdflag = pgfoot;
else if(pagecode==PAGE)/*翻到下一頁*/
pgfoot = prdflag;
else if(pagecode==STOP)/*頁末停住,此模式只有PAGE UP或DOWN才可翻頁頁*/
{
prdflag -= 1;
break;
}
else
break;/*pagecode參數錯誤*/
}
break;
case KDEC_PGUP:
if(prdflag <= 0 || strn-1 < pagewit)
break;
if(pgfoot-pagewit < 0)/*無上一頁(最前一頁)時等同KDEC_UP鍵*/
prdflag -= 1;
else
{
pgfoot -= pagewit;
prdflag -= pagewit;/*反白旗標與頁首減同值可令翻頁後的反白停在相同位置*/
}
break;
case KDEC_PGDOWN:
if(prdflag >= strn-1 || strn-1 < pagewit)
break;
if(pgfoot+pagewit >= strn)/*無下一頁(最後一頁)時等同KDEC_DOWN鍵*/
prdflag += 1;
else if(prdflag+pagewit > strn-1)/*下頁相對位置的反白超出選單範圍*/
{
pgfoot += pagewit;
prdflag = pgfoot;/*令反白在頁首*/
}
else
{
pgfoot += pagewit;
prdflag += pagewit;/*反白旗標與頁首加同值可令翻頁後的反白停在相同位置*/
}
break;
}
*pg_foot=pgfoot;
*prd_flag=prdflag;
}
/home/stlee/leelib/menu/mudsp.c
[code]
#include "/home/stlee/include/state.h"
/*
*udf主選單橫式選單的顯示,當不定長度陣列顯示超出範圍時可以不顯示
void lee_udfmumst_mudsp(WINDOW *winptr,
char **arcmustmpp,int arcmustrn,
int pgfoot,int prdflag,
int wlcx,int wrcx,int wmcy,int *usrset,
int *prdlcx,int *pgend)
*udf主選單直式選單顯示
void lee_udfmuslv_mudsp(WINDOW *winptr,char **opttmpp,int optstrn,
int tcx,int tcy,int dcx,int dcy,int *usrset,
int pgfoot,int prdflag,
int *pg_end)
*/
/*udf主選單橫式選單的顯示,當不定長度陣列顯示超出範圍時可以不顯示
*/
void lee_udfmumst_mudsp(WINDOW *winptr,
char **arcmustmpp,int arcmustrn,
int pgfoot,int prdflag,
int wlcx,int wrcx,int wmcy,int *usrset,
int *prdlcx,int *pgend
)
{
int i,n,k,x,y,px;
/*清空顯示區*/
lee_wmucls(winptr,wlcx,wmcy,wrcx,wmcy,*(usrset+GM_CLARCOPT),NOT);
x=wlcx+1;
/*顯示到arcmustrn,如已超出顯示範圍dcy則跳出迴路*/
for(i=pgfoot; i < arcmustrn;i++)
{
n=strlen(*(arcmustmpp+i));/*計算每一個字串的長度*/
if(x+n >= wrcx)/*已超出顯示範圍*/
break;
if(i==prdflag)/*反白所在*/
px=x;
mvwprintw(winptr,wmcy,x,"%s",*(arcmustmpp+i));/*顯示字串*/
x+=n+*(usrset+GM_ARCGAPCOL);/*加上下一個顯示字串的間隔*/
}
/*清空反白列*/
k=*(usrset+GM_ARCPRDSPC);
n=strlen(*(arcmustmpp+prdflag));
lee_wmucls(winptr,px-k,wmcy,px+n+k,wmcy,*(usrset+GM_CLARCPRD),NOT);
mvwprintw(winptr,wmcy,px,"%s",*(arcmustmpp+prdflag));
wrefresh(winptr);/*刷新*/
*prdlcx=px;/*設定反白選項的子選單初始x座標*/
*pgend=i-1;
}
/*udf主選單直式選單顯示
*/
void lee_udfmuslv_mudsp(WINDOW *winptr,char **opttmpp,int optstrn,
int tcx,int tcy,int dcx,int dcy,int *usrset,
int pgfoot,int prdflag,
int *pg_end
)
{
int i,n,k,x,y,py;
/*清空顯示區*/
lee_wmucls(winptr,tcx,tcy,dcx,dcy,*(usrset+GM_CLSECOPT),NOT);
/*顯示到optstrn,如已超出顯示範圍dcy則跳出迴路*/
for(i=pgfoot,y=tcy;i<optstrn;i++,y++)
{
if(y>=dcy)/*超出顯示範圍*/
break;
if(i==prdflag)/*反白所在*/
py=y;