BASIC語言歷史悠久,近年來發展迅速。BASIC語言的結構化程度高,易於理解,很適合廣大的編程人員使用。而第三代BASIC語言的功能更是日臻完善、強大,使用人員更多。
本文意在向編程經驗不十分豐富的讀者介紹用BASIC語言設計Windows風格的圖形用戶接口,起一點拋磚引玉的作用,不妥之處望不吝賜教。程序
在VGA(用Screen12語句設置)方式下運行,可在QuickBASIC、MSBASIC或VisualBASICforMS-DOS下編譯。另外需要說明的是程序中設置顏色使用的都是調色板位置號,一個調色板位置號並不固定代表某種特定顏色,而是可以由編程者通過PALETTE語句或PALETTEUSING語句自行指定的。當然,一般情況下我們使用系統缺省的調色板顏色。
1.讀點陣字模交叉顯示漢字及ASCII字符。
這裡要用到UCDOS3.1的HZK16和ASC16兩個字模文件,該功能模塊的代碼如下:
SUBDispHz(HzCol,HzRow,Color,HzStr$)
DIMi1,i2,i3,I,c1,c2,f,g,HzChar,AscCharASINTEGER
DIMHzByASSTRING*32
DIMAscByASSTRING*16
DIMl,HzRecASLONG
OPEN"HZK16"FORBINARYAS#1`打開漢字庫文件
OPEN"ASC16"FORBINARYAS#2`打開ASCII碼字庫文件
HzLen=LEN(HzStr$)`計算字符串長度
HzPos=1`置字符串的首字節為當前字節
WHILEHzPos<=HzLen`字符串顯示完前一直循環
I=ASC(MID$(HzStr$,HzPos,1))`獲取當前字符的ASCII值
IFI>&HA0THEN`判斷是否為漢字內碼
IFf=0THEN`f為零則該字節為漢字區碼
c1=I-&HA1`計算區碼
f=-1`置f為非零
ELSE`f不為零則該字節為漢字位碼
c2=I-&HA1`計算位碼
f=0`置f為零
HzRec=c1*94 c2`計算漢字在字庫中的記錄號
l=HzRec*32 1`計算漢字在字庫中的起始字節位置
GET#1,l,HzBy`從l開始讀取32字節
FORi1=0TO15`字模垂直方向16行點
FORi2=0TO1`每行16個點對應的兩個字節
HzChar=ASC(MID$(HzBy,i1*2 i2 1,1))`每個字節的ASCII值
FORi3=0TO7`每個字節的8位
IF(HzChar(2&(7-i3)))AND&H1THEN`若該位是1
PSET(HzCol i2*8 i3,HzRow i1),Color`畫點
ENDIF
NEXTi3
NEXTi2
NEXTi1
HzCol=HzCol 16`將光標置於下一個字符的左上角
ENDIF
ELSE`不是漢字內碼則為ASCII碼
l=I*16 1`計算ASCII字符在字庫中的起始字節位置
GET#2,l,AscBy`從l開始讀取16字節
FORi1=0TO15
`字模垂直方向16行點,每行對應1個字節
AscChar=ASC(MID$(AscBy,i1 1,1))`每個字節的ASCII值
FORi3=0TO7`每個字節的8位
IF(AscChar(2&(7-i3)))AND&H1THEN`若該位是1
PSET(HzCol i3,HzRow i1),Color`畫點
ENDIF
NEXTi3
NEXTi1
HzCul=HzCul 8`光標置於下一個字符的左上角
ENDIF
HzPos=HzPos 1`置字符串的下一個字節為當前字節
WEND
CLOSE
ENDSUB
參數HzCol、HzRow是所要顯示字符串的左上角坐標,Color是字符串的顏色,HzStr$是要顯示的字符串,其中可包含漢字、圖形符號和ASCII字符。
2.Windows風格圖形界面。
Windows界面簡潔、美觀、標准,用BASIC語言的圖形函數可以很方便地生成一個Windows風格界面。
先用VIEW(0,0)-(639,479),3設置背景色,再調用下面的過程生成窗口,調用一次生成一個窗口。參數Le、Top、Ri、Bo指定窗口左上角和右下角的坐標,FrmCol、TitCol是工作區和標題欄背景色,Title$、Menu$是標題和菜單的文字內容。例如,以下調用將生成一個主窗口和一個子窗口:
MyForm30,30,609,440,7,4,"程序主窗口","文件[F]選項[O]窗口[W]幫助[H]"
MyForm70,90,569,400,15,1,"程序子窗口","文件[F]編輯[E]搜索[S]運行[R]幫助[H]"
過程代碼如下:
SUBMyForm(Le,Top,Ri,Bo,FrmCol,TitCol,Title$,Menu$)
x=Ri-Le:y=Bo-Top
VIEW(Le,Top)-(Ri,Bo),
LINE(0,0)-(x,y),0,B`畫窗體
LINE(3,3)-(x-3,y-3),0,
LINE(0,22)-(x,22),
LINE(4,41)-(x-4,41),
PAINT(30,30),15,0`填充顏色
PAINT(30,10),TitCol,
PAINT(10,50),FrmCol,
VIEW(Le 3,Top 3)-(Le 22,Top 22),
LINE(0,0)-(19,19),0,B`畫控制鈕
LINE(4,9)-(16,11),8,
LINE(3,8)-(15,10),0,
LINE(4,9)-(14,9),15
VIEW(Le,Top)-(Ri,Bo)
DispHz(x-LEN(Title$)*8)/2-9,5,15,Ti-tle$`標題
DispHz12,23,0,Menu$`主菜單
ENDSUB
用類似方法還可以生成其它Windows風格部件,包括三維風格部件。
3.下拉菜單
下拉菜單是通過用GET語句保存菜單彈出前的屏幕內容,用PUT語句恢復先前保存的屏幕內容實現的,有關內容許多書上都有介紹,這裡不再贅述。
4.鍵盤和鼠標控制
鍵盤和鼠標操作通過BIOS中斷調用的循環檢測來實現。
INT16H是鍵盤中斷、INT33H是Microsoft鼠標中斷,通過這兩個中斷的功能調用就可以分別用鍵盤和鼠標控制程序。僅僅使用鍵盤操作的程序在需要鍵盤控制時可以用INT16H的功能00H在鍵盤緩沖區中無鍵入碼時等待鍵盤輸入,一旦有鍵入碼就讀取並進行相應處理。倘若還要同時使用鼠標進行程序控制,就不能用這種終止程序運行等待用戶操作的方法,這是因為程序要不斷查詢鼠標驅動程序以實時確定鼠標的狀態。為此可以在每次循環內調用INT16H的功能00H前,先調用功能01H弄清鍵盤緩沖區中是否有按鍵等待處理,若無則不執行對功能00H的調用,直接執行鼠標功能。限於篇幅這裡只簡單舉例說明,讀者可照此在自己的程序中加入響應特定鍵盤按鍵和鼠標輸入的代碼,實現對程序的"鍵盤-鼠標"雙重控制。
先定義鍵盤和鼠標的中斷調用模塊:
STATICSUBKeyStroke(k0,k1,k2)
DIMregsASRegType
regs.ax=k0
INTERRUPT&H16,regs,regs
k1=regs.ax
k2=regs.flagsAND&H40`得到標志寄存器的零標志位
ENDSUB
STATICSUBMouDrv(m0,m1,m2,m3)
DIMregsASRegType
regs.ax=m0
regs.bx=m1
regs.cx=m2
regs.dx=m3
INTERRUPT&H33,regs,regs
m0=regs.ax
m1=regs.bx
m2=regs.cx
m3=regs.dx
ENDSUB
函數MouPoll用來查詢鼠標光標的坐標和左右按鍵是否被按下:
STATICSUBMouPoll(row,col,lButton,rButton)
MouDrv3,button,col,row
IFButtonAND1THENlButton=-1ELSElButton=
IFButtonAND2THENrButton=-1ELSErButton=
ENDSUB
下面是本例的主程序,其中的循環將實時檢測且在屏幕上顯示鍵盤擊鍵的ASCII鍵值和掃描碼、鼠標按鍵狀況和光標坐標,程序將一直運行直到按了"Alt-X"為止。
`$INCLUDE:`QBX.BI`
MouDrv0,0,0,0`初始化鼠標驅動程序
MouDrv1,0,0,0`顯示鼠標光標
LOCATE16,1:PRINT"Press`Alt-X`toendprogram."
WHILE(NOTAlt_X)
KeyStroke&H100,Code,ZF`檢查是否有擊鍵碼
IFZF=0THEN`零標志位是零表示有擊鍵可用
KeyStroke&H0,Code,ZF`取得擊鍵
KeyCode=CodeAND&HFF`取出擊鍵的ASCII鍵值
ScanCode=(CodeAND&HFF00)256`取出擊鍵的掃描碼
IFScanCode=45THENAltlt_X=-1`按"Alt-X"鍵則退出循環
LOCATE18,1:PRINT"KeyCode:";KeyCode
LOCATE19,1:PRINT"ScanCode:";ScanCode
ELSE`零標志位是1表示無擊鍵可用,進入鼠標例程
MouPollrow,col,lButton,rButton`取得鼠標狀態
IFlButtonTHEN`左鍵按下
Button$="Left
ELSEIFrButtonTHENButton$="Right"`右鍵按下
ELSEButton$="None"`左右鍵均未按下
ENDIF
LOCATE21,1:PRINT"Button:";Button$
LOCATE22,1:PRINT"Position:";row;",";col
ENDIF
WEND
MouDrv2,0,0,0`隱藏鼠標光標->