不需要调接口,想要渲染几个月的数据,手动传入即可
根据思否 Peggy7 这篇文章改了一下。
<view class="freepop_body counter-warp">
<view class="tac bg_ffffff">
<view class="border_bot padtb20 padlr30 tac" v-if="canlendar_data&&canlendar_data.length>0">
<van-icon name="arrow-left" size="20" class="vam" @click="goPrevMonth"/>
<view class="inblock fz28 vam" style="margin: 0 50rpx">{{canlendar_data[cur].year}}年{{canlendar_data[cur].month}}月
<van-icon name="arrow" size="20" class="vam" @click="goNextMonth" />
<view class="week fz28 padtb20 border_bot" id="week">
<view :class="[idx===0||idx===6 ? 'relax':'','week-item']" v-for="(item,idx) inweek_list" :key="idx">{{item}}
<view class="month-block fz28" v-for="(canlendar_item,index) incanlendar_data" :key="index">
<block v-if="index===cur">
<view class="month-content">
<view :class="[item.fullDate>=nowDate&&item.fullDate<=maxDate&&item.available? '':'gray','month-day',checkDate===item.fullDate?'startActive':'']" @click="chooseDate" :data-available="item.fullDate>=nowDate&&item.fullDate<=maxDate&&item.available" :data-fulldate="item.fullDate" v-for="(item,dd) in canlendar_item.allDays" :key="item.fullDate">
<view class="isfull">
{{item.fullDate>=nowDate &&item.fullDate<=maxDate &&!item.available?'满':''}}
<block v-if="checkDate===item.fullDate">
{{checkDate===item.fullDate ? '已选' : ''}}
{{item.day?item.day:''}}
<view style="padding: 40rpx 32rpx 0 32rpx">
<text class="fz26">{{rule}}
<view class="fixedBar bg_f9f9f9" style="padding: 20rpx 50rpx">
<button class="globButton" style="border-radius: 10rpx" :disabled="disable" @click="submitFree">提 交
import {imgObj}from '@/utils/imgs'
import httpsfrom '@/utils/common'
const {get,throttle}=https
let hotel_id='',timer=null,cur_year='',cur_month='',cur_day='',arr=[]
export default {
data () {
return {
imgObj:imgObj,
rule:'',
disable:true,//按钮是否可点击
week_list: ['日','一','二','三','四','五','六'],
checkDate:'',//选择的日期
cur:0,//第几个月份
nowDate:'',//今天
maxDate:'',//最大日期
canlendar_data:[]
}
},
onLoad(options){
hotel_id=options.hotelId
// let {spa_date}=this.$store.state
// this.checkDate=spa_date.date[0]+'-'+spa_date.date[1]+'-'+spa_date.date[2]
this.getDate_()
const date =new Date()
cur_year = date.getFullYear()
cur_month = date.getMonth() +1
cur_day = date.getDate()
let month = cur_month.toString().length ===1 ?`0${cur_month}` : cur_month
let day = cur_day.toString().length ===1 ?`0${cur_day}` : cur_day
let nowDate =`${cur_year}-${month}-${day}`
this.nowDate=nowDate
},
onUnload(){
//this.reset()
clearTimeout(timer)
},
methods: {
reset(){
this.rule=''
this.checkDate=''
},
goPrevMonth(){
if(this.cur==0){
return false
}else{
this.cur--
}
},
goNextMonth(){
if(this.cur==(this.canlendar_data.length-1)){
return false
}else{
this.cur++
}
},
chooseDate(e) {
const available = e.currentTarget.dataset.available
const fullDate = e.currentTarget.dataset.fulldate
if(!available) {
return false
}else{
this.checkDate=fullDate
}
},
// chooseTheDate(data,index){
// this.theCheck=data
// this.theCheckIndex=index
// this.disable=false
// },
async getDate_() {
const loginResult =await get('api_v2/free/reservation',{
hotel_id:hotel_id
})
if (loginResult.code==200) {
let data=loginResult.data
let newBrr=[]
data.options.map((n,index)=>{
let tomo =new Date()
tomo.setTime(tomo.getTime() + index *24 *60 *60 *1000)//1天 以后
let tomoYear=tomo.getFullYear(),tomoMonth=tomo.getMonth() +1,tomoDate=tomo.getDate()
tomoMonth=tomoMonth<10?'0'+tomoMonth:tomoMonth
tomoDate=tomoDate<10?'0'+tomoDate:tomoDate
newBrr.push({
val:tomoYear+'-'+tomoMonth+'-'+tomoDate,
flag:n
})
})
this.maxDate=newBrr[newBrr.length-1].val
arr=newBrr
this.fillCalendar(6)
this.rule=data.rule.replace(/\\n/g,"\n")
this.disable=false
}
},
submitFree:throttle(async function() {
wx.showLoading({
title:'',
mask:true
})
let {checkDate}=this
let that=this
if(checkDate==''){
wx.showToast({
title:'请选择预约日期',
icon:'none',
duration:2000
})
return false
}
const loginResult =await get('api_v2/free/submit',{
hotel_id:hotel_id,
estimated_at:checkDate
})
if (loginResult.code==200) {
wx.hideLoading()
let data=loginResult.data
let orderid=data.order_id
that.goOrderdetail(orderid)
that.$fire.fire('alreadyFree')
}
}),
goBack(){
wx.navigateBack({
delta:1
})
},
goOrderdetail:throttle(function(id) {
wx.redirectTo({
url:'/pages/orderdetailspa/index?orderId='+id
})
}),
// 获取每月总天数
getAllDaysOfMonth(year,month) {
return new Date(year,month,0).getDate()
},
// 获取每月第一天是星期几
getFirstDayOfMonth(year,month) {
return new Date(year, month -1, 1).getDay()
},
// 计算本月前空了几格
getEmptyGrids(year,month) {
// FirstDayOfMonth代表本月的第一天是星期几
const FirstDayOfMonth =this.getFirstDayOfMonth(year, month)
let emptyGrids = []
// 有空格的情况
if (FirstDayOfMonth >0) {
for (let i =0i <FirstDayOfMonthi++) {
emptyGrids.push({
'num':'',
'fullDate':'x' //x是我自己定义的一个值,代表没有日期
})
}
// 将空格放入数组
return emptyGrids
}else{
// 否则返回一个新数组
return []
}
},
// 计算本月日历
getDaysOfThisMonth(year,month) {
let days = []
const AllDaysOfMonth =this.getAllDaysOfMonth(year, month)
let fullMonth = month.toString().length ===1 ?`0${month}`:month
for (let i =0i <AllDaysOfMonthi++) {
let day = i+1, fullDay = day,fullDate=''
fullDay = fullDay.toString().length ===1 ?`0${day}` : fullDay
fullDate=`${year}-${fullMonth}-${fullDay}`
let obj={
day,
fullDay,
fullDate,
'available':true
}
for(let j=0j
if(fullDate==arr[j].val){
obj.available=arr[j].flag
}
}
days.push(obj)
}
// 返回每个月的具体日期
return days
},
// 循环渲染日历
// 从本月开始渲染,n代表包括本月开始连续渲染几个月
fillCalendar(n) {
let year = cur_year, month = cur_month, fullMonth, canlendar_data = []
// 计算年月以及具体日历
for (let i = cur_monthi <cur_month + ni++) {
let EmptyGrids =this.getEmptyGrids(year, month)
let DaysOfThisMonth =this.getDaysOfThisMonth(year, month)
// 把空格和具体日历合为一个数组
let allDays = [...EmptyGrids, ...DaysOfThisMonth]
// 对年份和月份的计算做一些判断
if (month >12) {
year++
month =1
fullMonth ='01'
canlendar_data.push({
year,
month,
fullMonth,
allDays })
month++
}else{
fullMonth = month.toString().length ===1 ?`0${month}` : month
canlendar_data.push({
year,
month,
fullMonth,
allDays })
month++
}
}
this.canlendar_data=canlendar_data
},
}
}
<style lang="less">
@import "../../../styles/freecalendar.less"
/********************************Desc:俄罗斯方块游戏
By:hoodlum1980
Email:jinfd@126.com
Date:2008.03.12 22:30
********************************/
#include <stdio.h>
#include <bios.h>
#include <dos.h>
#include <graphics.h>
#include <string.h>
#include <stdlib.h>
#define true 1
#define false 0
#define BoardWidth 12
#define BoardHeight23
#define _INNER_HELPER /* inner helper method */
/*Scan Codes Define*/
enum KEYCODES
{
K_ESC=0x011b,
K_UP =0x4800,/* upward arrow */
K_LEFT =0x4b00,
K_DOWN =0x5000,
K_RIGHT =0x4d00,
K_SPACE =0x3920,
K_P =0x1970
}
/* the data structure of the block */
typedef struct tagBlock
{
char c[4][4] /* cell fill info array, 0-empty, 1-filled */
int x /* block position cx [ 0,BoardWidht -1] */
int y /* block position cy [-4,BoardHeight-1] */
char color /* block color */
char size /* block max size in width or height */
char name /* block name (the block's shape) */
} Block
/* game's global info */
int FrameTime= 1300
int CellSize= 18
int BoardLeft= 30
int BoardTop=30
/* next block grid */
int NBBoardLeft= 300
int NBBoardTop=30
int NBCellSize= 10
/* score board position */
int ScoreBoardLeft= 300
int ScoreBoardTop=100
int ScoreBoardWidth=200
int ScoreBoardHeight=35
int ScoreColor=LIGHTCYAN
/* infor text postion */
int InfoLeft=300
int InfoTop=200
int InfoColor=YELLOW
int BorderColor=DARKGRAY
int BkGndColor=BLACK
int GameRunning=true
int TopLine=BoardHeight-1 /* top empty line */
int TotalScore=100
char info_score[20]
char info_help[255]
char info_common[255]
/* our board, Board[x][y][0]-isFilled, Board[x][y][1]-fillColor */
unsigned char Board[BoardWidth][BoardHeight][2]
char BufferCells[4][4] /* used to judge if can rotate block */
Block curBlock /* current moving block */
Block nextBlock /* next Block to appear */
/* function list */
int GetKeyCode()
int CanMove(int dx,int dy)
int CanRotate()
int RotateBlock(Block *block)
int MoveBlock(Block *block,int dx,int dy)
void DrawBlock(Block *block,int,int,int)
void EraseBlock(Block *block,int,int,int)
void DisplayScore()
void DisplayInfo(char* text)
void GenerateBlock(Block *block)
void NextBlock()
void InitGame()
int PauseGame()
void QuitGame()
/*Get Key Code */
int GetKeyCode()
{
int key=0
if(bioskey(1))
{
key=bioskey(0)
}
return key
}
/* display text! */
void DisplayInfo(char *text)
{
setcolor(BkGndColor)
outtextxy(InfoLeft,InfoTop,info_common)
strcpy(info_common,text)
setcolor(InfoColor)
outtextxy(InfoLeft,InfoTop,info_common)
}
/* create a new block by key number,
* the block anchor to the top-left corner of 4*4 cells
*/
void _INNER_HELPER GenerateBlock(Block *block)
{
int key=(random(13)*random(17)+random(1000)+random(3000))%7
block->size=3/* because most blocks' size=3 */
memset(block->c,0,16)
switch(key)
{
case 0:
block->name='T'
block->color=RED
block->c[1][0]=1
block->c[1][1]=1, block->c[2][1]=1
block->c[1][2]=1
break
case 1:
block->name='L'
block->color=YELLOW
block->c[1][0]=1
block->c[1][1]=1
block->c[1][2]=1, block->c[2][2]=1
break
case 2:
block->name='J'
block->color=LIGHTGRAY
block->c[1][0]=1
block->c[1][1]=1
block->c[1][2]=1, block->c[0][2]=1
break
case 3:
block->name='z'
block->color=CYAN
block->c[0][0]=1, block->c[1][0]=1
block->c[1][1]=1, block->c[2][1]=1
break
case 4:
block->name='5'
block->color=LIGHTBLUE
block->c[1][0]=1, block->c[2][0]=1
block->c[0][1]=1, block->c[1][1]=1
break
case 5:
block->name='o'
block->color=BLUE
block->size=2
block->c[0][0]=1, block->c[1][0]=1
block->c[0][1]=1, block->c[1][1]=1
break
case 6:
block->name='I'
block->color=GREEN
block->size=4
block->c[1][0]=1
block->c[1][1]=1
block->c[1][2]=1
block->c[1][3]=1
break
}
}
/* get next block! */
void NextBlock()
{
/* copy the nextBlock to curBlock */
curBlock.size=nextBlock.size
curBlock.color=nextBlock.color
curBlock.x=(BoardWidth-4)/2
curBlock.y=-curBlock.size
memcpy(curBlock.c,nextBlock.c,16)
/* generate nextBlock and show it */
EraseBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize)
GenerateBlock(&nextBlock)
nextBlock.x=1,nextBlock.y=0
DrawBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize)
}
/* rotate the block, update the block struct data */
int _INNER_HELPER RotateCells(char c[4][4],char blockSize)
{
char temp,i,j
switch(blockSize)
{
case 3:
temp=c[0][0]
c[0][0]=c[2][0], c[2][0]=c[2][2],c[2][2]=c[0][2], c[0][2]=temp
temp=c[0][1]
c[0][1]=c[1][0], c[1][0]=c[2][1],c[2][1]=c[1][2], c[1][2]=temp
break
case 4:/* only 'I' block arived here! */
c[1][0]=1-c[1][0], c[1][2]=1-c[1][2], c[1][3]=1-c[1][3]
c[0][1]=1-c[0][1], c[2][1]=1-c[2][1],c[3][1]=1-c[3][1]
break
}
}
/* judge if the block can move toward the direction */
int CanMove(int dx,int dy)
{
int i,j,tempX,tempY
for(i=0i<curBlock.sizei++)
{
for(j=0j<curBlock.sizej++)
{
if(curBlock.c[i][j])
{
/* cannot move leftward or rightward */
tempX = curBlock.x + i + dx
if(tempX<0 || tempX>(BoardWidth-1))return false/* make sure x is valid! */
/* cannot move downward */
tempY = curBlock.y + j + dy
if(tempY>(BoardHeight-1))return false/* y is only checked lower bound, maybe negative!!!! */
/* the cell already filled, we must check Y's upper bound before check cell ! */
if(tempY>=0 &&Board[tempX][tempY][0]) return false
}
}
}
return true
}
/* judge if the block can rotate */
int CanRotate()
{
int i,j,tempX,tempY
/* update buffer */
memcpy(BufferCells, curBlock.c, 16)
RotateCells(BufferCells,curBlock.size)
for(i=0i<curBlock.sizei++)
{
for(j=0j<curBlock.sizej++)
{
if(BufferCells[i][j])
{
tempX=curBlock.x+i
tempY=curBlock.y+j
if(tempX<0 || tempX>(BoardWidth-1))
return false
if(tempY>(BoardHeight-1))
return false
if(tempY>=0 &&Board[tempX][tempY][0])
return false
}
}
}
return true
}
/* draw the block */
void _INNER_HELPER DrawBlock(Block *block,int bdLeft,int bdTop,int cellSize)
{
int i,j
setfillstyle(SOLID_FILL,block->color)
for(i=0i<block->sizei++)
{
for(j=0j<block->sizej++)
{
if(block->c[i][j] &&(block->y+j)>=0)
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor)
}
}
}
}
/* Rotate the block, if success, return true */
int RotateBlock(Block *block)
{
char temp,i,j
int b_success
if(curBlock.size==2)
return
if(( b_success=CanRotate()))
{
EraseBlock(block,BoardLeft,BoardTop,CellSize)
memcpy(curBlock.c,BufferCells,16)
DrawBlock(block,BoardLeft,BoardTop,CellSize)
}
return b_success
}
/* erase a block, only fill the filled cell with background color */
void _INNER_HELPER EraseBlock(Block *block,int bdLeft,int bdTop,int cellSize)
{
int i,j
setfillstyle(SOLID_FILL,BkGndColor)
for(i=0i<block->sizei++)
{
for(j=0j<block->sizej++)
{
if(block->c[i][j] &&(block->y+j>=0))
{
floodfill(
bdLeft+cellSize*(i+block->x)+cellSize/2,
bdTop+cellSize*(j+block->y)+cellSize/2,
BorderColor)
}
}
}
}
/* move by the direction if can, donothing if cannot
* return value: true - success, false - cannot move toward this direction
*/
int MoveBlock(Block *block,int dx,int dy)
{
int b_canmove=CanMove(dx,dy)
if(b_canmove)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize)
curBlock.x+=dx
curBlock.y+=dy
DrawBlock(block,BoardLeft,BoardTop,CellSize)
}
return b_canmove
}
/* drop the block to the bottom! */
int DropBlock(Block *block)
{
EraseBlock(block,BoardLeft,BoardTop,CellSize)
while(CanMove(0,1))
{
curBlock.y++
}
DrawBlock(block,BoardLeft,BoardTop,CellSize)
return 0/* return value is assign to the block's alive */
}
/* init the graphics mode, draw the board grid */
void InitGame()
{
int i,j,gdriver=DETECT,gmode
struct time sysTime
/* draw board cells */
memset(Board,0,BoardWidth*BoardHeight*2)
memset(nextBlock.c,0,16)
strcpy(info_help,"P: Pause Game. --by hoodlum1980")
initgraph(&gdriver,&gmode,"c:\\tc\\")
setcolor(BorderColor)
for(i=0i<=BoardWidthi++)
{
line(BoardLeft+i*CellSize, BoardTop, BoardLeft+i*CellSize, BoardTop+ BoardHeight*CellSize)
}
for(i=0i<=BoardHeighti++)
{
line(BoardLeft, BoardTop+i*CellSize, BoardLeft+BoardWidth*CellSize, BoardTop+ i*CellSize)
}
/* draw board outer border rect */
rectangle(BoardLeft-CellSize/4, BoardTop-CellSize/4,
BoardLeft+BoardWidth*CellSize+CellSize/4,
BoardTop+BoardHeight*CellSize+CellSize/4)
/* draw next block grids */
for(i=0i<=4i++)
{
line(NBBoardLeft+i*NBCellSize, NBBoardTop, NBBoardLeft+i*NBCellSize, NBBoardTop+4*NBCellSize)
line(NBBoardLeft, NBBoardTop+i*NBCellSize, NBBoardLeft+4*NBCellSize, NBBoardTop+ i*NBCellSize)
}
/* draw score rect */
rectangle(ScoreBoardLeft,ScoreBoardTop,ScoreBoardLeft+ScoreBoardWidth,ScoreBoardTop+ScoreBoardHeight)
DisplayScore()
/* set new seed! */
gettime(&sysTime)
srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec)
GenerateBlock(&nextBlock)
NextBlock() /* create first block */
setcolor(DARKGRAY)
outtextxy(InfoLeft,InfoTop+20,"Up -rotate Space-drop")
outtextxy(InfoLeft,InfoTop+35,"Left-leftRight-right")
outtextxy(InfoLeft,InfoTop+50,"Esc -exit")
DisplayInfo(info_help)
}
/* set the isFilled and fillcolor data to the board */
void _INNER_HELPER FillBoardData()
{
int i,j
for(i=0i<curBlock.sizei++)
{
for(j=0j<curBlock.sizej++)
{
if(curBlock.c[i][j] &&(curBlock.y+j)>=0)
{
Board[curBlock.x+i][curBlock.y+j][0]=1
Board[curBlock.x+i][curBlock.y+j][1]=curBlock.color
}
}
}
}
/* draw one line of the board */
void _INNER_HELPER PaintBoard()
{
int i,j,fillcolor
for(j=max((TopLine-4),0)j<BoardHeightj++)
{
for(i=0i<BoardWidthi++)
{
fillcolor=Board[i][j][0]? Board[i][j][1]:BkGndColor
setfillstyle(SOLID_FILL,fillcolor)
floodfill(BoardLeft+i*CellSize+CellSize/2,BoardTop+j*CellSize+CellSize/2,BorderColor)
}
}
}
/* check if one line if filled full and increase the totalScore! */
void _INNER_HELPER CheckBoard()
{
int i,j,k,score=10,sum=0,topy,lines=0
/* we find the top empty line! */
j=topy=BoardHeight-1
do
{
sum=0
for(i=0i<BoardWidthi++)
{
sum+=Board[i][topy][0]
}
topy--
} while(sum>0 &&topy>0)
/* remove the full filled line (max remove lines count = 4) */
do
{
sum=0
for(i=0i<BoardWidthi++)
sum+=Board[i][j][0]
if(sum==BoardWidth)/* we find this line is full filled, remove it! */
{
/* move the cells data down one line */
for(k=jk >topyk--)
{
for(i=0i<BoardWidthi++)
{
Board[i][k][0]=Board[i][k-1][0]
Board[i][k][1]=Board[i][k-1][1]
}
}
/* make the top line empty! */
for(i=0i<BoardWidthi++)
{
Board[i][topy][0]=0
Board[i][topy][1]=0
}
topy++ /* move the topline downward one line! */
lines++ /* lines <=4 */
TotalScore+=score
score*=2 /* adding: 10, 30, 70, 150 */
}
else
j--
} while(sum>0 &&j>topy &&lines<4)
/* speed up the game when score is high, minimum is 400 */
FrameTime=max(1200-100*(TotalScore/200), 400)
TopLine=topy/* update the top line */
/* if no lines remove, only add 1: */
if(lines==0)
TotalScore++
}
/* display the score */
void _INNER_HELPER DisplayScore()
{
setcolor(BkGndColor)
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score)
setcolor(ScoreColor)
sprintf(info_score,"Score: %d",TotalScore)
outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score)
}
/* we call this function when a block is inactive. */
void UpdateBoard()
{
FillBoardData()
CheckBoard()
PaintBoard()
DisplayScore()
}
/* pause the game, and timer handler stop move down the block! */
int PauseGame()
{
int key=0
DisplayInfo("Press P to Start or Resume!")
while(key!=K_P &&key!=K_ESC)
{
while(!(key=GetKeyCode())){}
}
DisplayInfo(info_help)
return key
}
/* quit the game and do cleaning work. */
void QuitGame()
{
closegraph()
}
/* the entry point function. */
void main()
{
int i,flag=1,j,key=0,tick=0
InitGame()
if(PauseGame()==K_ESC)
goto GameOver
/* wait until a key pressed */
while(key!=K_ESC)
{
/* wait until a key pressed */
while(!(key=GetKeyCode()))
{
tick++
if(tick>=FrameTime)
{
/* our block has dead! (can't move down), we get next block */
if(!MoveBlock(&curBlock,0,1))
{
UpdateBoard()
NextBlock()
if(!CanMove(0,1))
goto GameOver
}
tick=0
}
delay(100)
}
switch(key)
{
case K_LEFT:
MoveBlock(&curBlock,-1,0)
break
case K_RIGHT:
MoveBlock(&curBlock,1,0)
break
case K_DOWN:
MoveBlock(&curBlock,0,1)
break
case K_UP:
RotateBlock(&curBlock)
break
case K_SPACE:
DropBlock(&curBlock)
break
case K_P:
PauseGame()
break
}
}
GameOver:
DisplayInfo("GAME OVER! Press any key to exit!")
getch()/* wait the user Press any key. */
QuitGame()
}
俄罗斯方块的C语言实现,在WIN-TC上编译通过。
DELPHIDelphi是全新的可视化编程环境,为我们提供了一种方便、快捷的Windows应用程序开发工具。它使用了Microsoft Windows图形用户界面的许多先进特性和设计思想,采用了d性可重复利用的完整的面向对象程序语言(Object-Oriented Language)、当今世界上最快的编辑器、最为领先的数据库技术。对于广大的程序开发人员来讲,使用Delphi开发应用软件,无疑会大大地提高编程效率,而且随着应用的深入,您将会发现编程不再是枯燥无味的工作——Delphi的每一个设计细节,都将带给您一份欣喜。
1.1 Delphi基本概念介绍
1.1.1 Delphi的基本形式
Delphi实际上是Pascal语言的一种版本,但它与传统的Pascal语言有天壤之别。一个Delphi程序首先是应用程序框架,而这一框架正是应用程序的“骨架”。在骨架上即使没有附着任何东西,仍可以严格地按照设计运行。您的工作只是在“骨架”中加入您的程序。缺省的应用程序是一个空白的窗体(Form),您可以运行它,结果得到一个空白的窗口。这个窗口具有Windows窗口的全部性质:可以被放大缩小、移动、最大最小化等,但您却没有编写一行程序。因此,可以说应用程序框架通过提供所有应用程序共有的东西,为用户应用程序的开发打下了良好的基础。Delphi已经为您做好了一切基础工作——程序框架就是一个已经完成的可运行应用程序,只是不处理任何事情。您所需要做的,只是在程序中加入完成您所需功能的代码而已。
在空白窗口的背后,应用程序的框架正在等待用户的输入。由于您并未告诉它接收到用户输入后作何反应,窗口除了响应Windows的基本 *** 作(移动、缩放等)外,它只是接受用户的输入,然后再忽略。Delphi把Windows编程的回调、句柄处理等繁复过程都放在一个不可见的Romulam覆盖物下面,这样您可以不为它们所困扰,轻松从容地对可视部件进行编程。
1.1.2 面向对象编程的概念
面向对象的程序设计(Object-Oriented Programming,简记为OOP)是Delphi诞生的基础。OOP立意于创建软件重用代码,具备更好地模拟现实世界环境的能力,这使它被公认为是自上而下编程的优胜者。它通过给程序中加入扩展语句,把函数“封装”进Windows编程所必需的“对象”中。面向对象的编程语言使得复杂的工作条理清晰、编写容易。说它是一场革命,不是对对象本身而言,而是对它们处理工作的能力而言。对象并不与传统程序设计和编程方法兼容,只是部分面向对象反而会使情形更糟。除非整个开发环境都是面向对象的,否则对象产生的好处还没有带来的麻烦多。而Delphi是完全面向对象的,这就使得Delphi成为一种触手可及的促进软件重用的开发工具,从而具有强大的吸引力。
一些早期的具有OOP性能的程序语言如C++,Pascal,Smalltalk等,虽然具有面向对象的特征,但不能轻松地画出可视化对象,与用户交互能力较差,程序员仍然要编写大量的代码。Delphi的推出,填补了这项空白。您不必自己建立对象,只要在提供的程序框架中加入完成功能的代码,其余的都交给Delphi去做。欲生成漂亮的界面和结构良好的程序丝毫不必绞尽脑汁,Delphi将帮助您轻松地完成。它允许在一个具有真正OOP扩展的可视化编程环境中,使用它的Object Pascal语言。这种革命性的组合,使得可视化编程与面向对象的开发框架紧密地结合起来。
1.2 Delphi 快速入门
在这一节中,我们来开发一个小程序。随着开发的过程,逐步介绍Delphi的主要部件及其 *** 作方法。建议读者按照本书介绍的过程,在您的电脑上直接 *** 作。您将对Delphi的可视化编程有一个直观、快捷的了解,必将起到事半功倍的效果。
1.2.1 进入Delphi的可视化编程环境
1.2.1.1 安装Delphi
Delphi的安装与其它应用软件并无不同。2.0版必须在Windows 95以上的 *** 作系统中使用。启动Windows 95或Windows NT后,将Delphi的光盘放入光驱(CD-ROM)中,运行光盘上的\INSTALL\SETUP.EXE文件,它的安装程序会提示您正确地装入Delphi。如果您是在微软中文Windows环境中安装Delphi,请参照附录A来设置您的BDE环境,以便于处理中文数据。
1.2.1.2 进入Delphi 环境
为避免隐藏在Delphi后的Program Manager和曾经运行过的其它程序扰乱版面,分散您的注意力,不妨在启动Delphi前关掉其它应用程序;启动Delphi后,再最小化隐藏在后面的Delphi 2.0程序组。这样屏幕上就只留下Delphi窗口可见了。
首次加载Delphi,屏幕上会出现四个窗口:
● 标题为“Delphi-Project1”的Delphi主窗口
● Object Inspector窗口
● 标题为“Form1”的窗体(Form)窗口
● 标题为“Unit1.PAS”的代码编辑窗口。刚启动时这一窗口的大部分被“Form1”窗体所掩盖。将“Form1”窗体移开,或单击Form1窗体下方的状态行,可以使其全部可见。在“Form1”窗体的任意可见位置单击鼠标,可以恢复主窗体可见
以下我们将对这四个窗口分别进行介绍。
1.2.2 Delphi可视化编程环境介绍
1.2.2.1 主窗口(Main Form)
Delphi的主窗口位于屏幕的上端,包括Menu(菜单)、Speed Bar(加速条)和Component Panel(部件选项板)。Menu是下拉式主菜单。Speed Bar位于主窗口的左下端,由两排共14个加速按钮组成。这些按钮是菜单功能的快捷方式,各种图标直观地表示了它能执行的动作。Component Panel由一行、若干页对象按钮所组成,利用它来选择需要的部件并将它放到窗体中去。
1.2.2.2 Object Inspector(对象检视器)
Object Inspector窗口含有两页:Properties页显示窗体中当前被选择部件的属性信息,并允许改变对象的属性;Events页列出了当前部件可以响应的事件。按动Object Inspector下端的“Events”页标签,使得Events页可见,这一定的事件后边的空白处,可以定义对象接受到相应事件时执行的动作。首次启动时,Object Inspector窗口显示的是当前窗体Form1的属性。Object Inspector根据对象属性的多少,决定是否有滚行显示。移动滚行条,可以查看当前对象的全部属性。
此外,Object Inspector上还有Object Selector(对象选择器),位于Object Inspector上方的下拉式菜单中。它显示了窗体上所有部件的名称和类型,也包含窗体本身。您可以用Object Selector很容易地在窗体的各个部件之间切换,也可以快速地回到窗体本身。当窗体中含有较多的对象时,您会发现这是切换对象尤其是回到窗体的最快捷途径。
想使Object Inspector一直可见,可将鼠标移到Object Inspector上,按动右键,以启动Object Inspector的d出式菜单,将其设置为Stay On Top。这对初学者常是一个很重要的设置方式。
1.2.2.3 窗体窗口
Forms窗口是开展大部分设计的工作区域。首次启动Delphi 2.0时显示的是窗体Form1。可以把部件放在窗体中,通过移动位置、改变尺寸等 *** 作随心所欲地安排它们,以此来开发应用程序的用户界面。您可以把窗体想象成一个可以放置其它部件的容器。窗体上有栅格(Grids),供放置部件时对齐位置用,在程序运行时Grids是不可见的。
一个真正的应用程序可能有不止一个窗口,您可以选用不同的窗体进行设计。其它窗体可以是对话框(Dialog Box)、数据录入框等。
1.2.2.4 代码窗口
代码窗口一开始处于窗体窗口之下。因为在Delphi中,设计用户界面直接在窗体中进行,运行结果和设计样板完全一致。当部件被放到窗体上时,Delphi会自动生成大部分的用户界面代码。您所应做的只是在它为您生成的框架中加入完成所需功能的程序段而已。点动Form1的状态行使代码窗口可见。
这个窗口中是代码编辑器。可以在其中书写Delphi应用程序的源代码。当程序中含有不止一个窗口时,会有几个库单元的源程序出现在代码编辑器中。代码编辑器的标题条中显示了当前正在编辑的库单元文件名。要查看某一特定程序的源代码,只需用鼠标点动写有该库单元文件名的页标签,就可以对该库单元进行编辑了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)