HTML的扩展标签
为了方便设计千变万化的程序界面和功能,作者设计了一个新的HTML标签:
<user id=myname src=myfile.cpp>
这个标签叫做user标签,它的功能完全由用户的c/c++代码文件决定。
其中,属性id是用于识别user标签的名字,属性src是实现user标签功能的c/c++文件。
1. 一个使用标签的HTML文件:good.htm
<user id=good src=good.cpp style="border:10 #711 outset;font-family:黑体;
color:white;">
<style> input { position:fixed;left:3cm; font-size:24px; } </style>
<input type=button onclick=set_str(this) value='朝辞白帝彩云间'>
<input type=button onclick=set_str(this) value='千里江陵一日还'>
<input type=button onclick=set_str(this) value='两岸猿声啼不住'>
<input type=button onclick=set_str(this) value='轻舟已过万重山'>
<input id=lastEle style="font-size:24;width:360;background:#333;color:#692;"
onkeyup = good.load(lastEle.value) >
<script>
good.style.fontSize = 32
good.style.width = 760
good.style.height = 400
good.style.backgroundImage = 'url(water.jpg)'
good.style.backgroundSize = '100% 100%'
good.load("点击按钮: 万水千山总是情")
lastEle.value = '湖南'
lastEle.focus()
for(let ii=0; ii<5; ii++)
document.getElementsByTagName("input")[ii].style.top = 170 + 49 * ii;
function get_timeStr()
{
return `${ new Date().toLocaleTimeString() } ${ new Date().getTime() }`;
}
function set_str(pEle)
{
lastEle.value = good.text = pEle.value;
lastEle.focus();
}
function can_exit()
{
return confirm(`确实要
<div style='color:green;font-size:32;'>退出good?</div>`);
}
</script>
<user src=yctree.cpp link=red style='font-size:24;width:400;height:390'>
HTML文件:good.htm
good.htm文件使用了两个user标签,实现它们的c/c++代码文件分别为:good.cpp和yctree.cpp。
2. 标签的c/c++代码需实现的类成员函数
标签的c/c++代码必须实现如下所示的ycuserCLASS类的所有成员函数:
……
struct ycuserCLASS
{
virtual void _stdcall init(YCTRL *pCtrl,WEB_ATTR_DATA *mattr);
virtual void _stdcall setcss(YCTRL *pCtrl,WEB_CSS_DATA *mcss,
WEB_ATTR_DATA *mattr);
virtual void _stdcall resize(YCTRL *pCtrl);
virtual void _stdcall create(YCTRL *pCtrl);
virtual void _stdcall paint(YCTRL *pCtrl,YIMG *pimg);
virtual int _stdcall is_run(YCTRL *pCtrl);
virtual void _stdcall stop(YCTRL *pCtrl);
virtual void _stdcall set_cursor(YCTRL *pCtrl);
virtual int _stdcall is_focus(YCTRL *pCtrl,int posFlag);
virtual void _stdcall wm_focus(YCTRL *pCtrl,int killFlag);
virtual void _stdcall gain_focus(YCTRL *pCtrl);
virtual void _stdcall lost_focus(YCTRL *pCtrl);
virtual int _stdcall keydown(YCTRL *pCtrl,int wParam);
virtual void _stdcall keychar(YCTRL *pCtrl,int wParam);
virtual void _stdcall mousemove(YCTRL *pCtrl);
virtual void _stdcall mouseover(YCTRL *pCtrl);
virtual void _stdcall mouseout(YCTRL *pCtrl);
virtual void _stdcall lbuttonpress(YCTRL *pCtrl);
virtual void _stdcall lbuttondown(YCTRL *pCtrl,int dblclk);
virtual void _stdcall lbuttonup(YCTRL *pCtrl,int dblclk);
virtual void _stdcall rbuttonup(YCTRL *pCtrl);
virtual void _stdcall timer(YCTRL *pCtrl);
virtual int _stdcall wheel(YCTRL *pCtrl,int wParam);
virtual void _stdcall destroy(YCTRL *pCtrl);
};
……
C/C++头文件(部分代码):yc.h
3. 一个决定标签功能的c/c++代码文件:good.cpp
满足要求的c/c++代码文件决定user标签的全部功能。
下面列出一个user标签的c/c++代码:good.cpp,它用于good.htm。分析它可以了解如何书写这种标签的c/c++代码。
#include "yc.h" //必须包含的头文件
struct YUSER //一般根据需要定义一个用户结构
{
char textBuf[1024];
int txtLen;
};
void ycuserCLASS::paint(YCTRL *pCtrl,YIMG *pimg) //绘制user标签的成员函数
{
int pxx0,pyy0,pww,phh; //获取user标签刷新位置大小
YCWEB->inner_paintSize(pCtrl,&pxx0,&pyy0,&pww,&phh);
#include "yczm.h"
static yczmCLASS *YCZM = <yczm.cpp>; //写字符源码文件
static TEXTATTR mattr = {80,80,"黑体", {1,0,1}, {1,5}, {0,0,0,0,19},
{0x88ff3456,0x55ffff11,0x996fff1f,0xa7ffffff,
0x558ffffff,0x88008f66,0x6699ff55,0x88ffff00},
{},{0x99661122,0x66660022,0x33661122}};
mattr.sizex = mattr.sizey = 80;
YCZM->textoutA(pimg,pxx0,pyy0,pCtrl->pUser->textBuf,
pCtrl->pUser->txtLen,&mattr);
int bb = mattr.color[0];
for(int ii=1; ii<8; ii++) mattr.color[ii-1] = mattr.color[ii];
mattr.color[7] = bb;
wchar_t *wiptr;
int chlen = YC_jsRun(pCtrl->phtml,L"get_timeStr()",0,&wiptr);
char *chptr = YC_wideToChar(&chlen,wiptr,chlen);
mattr.sizex = mattr.sizey = 48;
YCZM->textoutA(pimg,pxx0+200, pyy0+90,chptr,chlen,&mattr);
free(chptr);
YCHTML->textoutA(pCtrl->phtml,pimg,pxx0,pyy0+100,pCtrl->pUser->textBuf,
pCtrl->pUser->txtLen,YCCSS->css_color(pCtrl),pCtrl->fntno);
}
void ycuserCLASS::timer(YCTRL *pCtrl) //定时器函数
{
YCHTML->user_paint(pCtrl);
}
void ycuserCLASS::init(YCTRL *pCtrl,WEB_ATTR_DATA *mattr) //初始化函数
{
pCtrl->timer = 50; //启动定时器, 单位ms
}
void ycuserCLASS::resize(YCTRL *pCtrl) //user标签大小有变化时调用该函数
{
}
void ycuserCLASS::set_cursor(YCTRL *pCtrl)
{
YCHTML->show_cursor(cursor_CSS_help);
}
int ycuserCLASS::is_focus(YCTRL *pCtrl,int posFlag)
{
return FALSE;
}
void ycuserCLASS::wm_focus(YCTRL *pCtrl,int killFlag)
{
}
void ycuserCLASS::gain_focus(YCTRL *pCtrl)
{
}
void ycuserCLASS::lost_focus(YCTRL *pCtrl)
{
}
int ycuserCLASS::keydown(YCTRL *pCtrl,int wParam)
{
return 0;
}
void ycuserCLASS::keychar(YCTRL *pCtrl,int wParam)
{
}
void ycuserCLASS::mousemove(YCTRL *pCtrl)
{
}
void ycuserCLASS::mouseover(YCTRL *pCtrl)
{
}
void ycuserCLASS::mouseout(YCTRL *pCtrl)
{
mouseover(pCtrl);
}
int ycuserCLASS::wheel(YCTRL *pCtrl,int wParam)
{
return FALSE;
}
void ycuserCLASS::lbuttonpress(YCTRL *pCtrl)
{
}
void ycuserCLASS::lbuttondown(YCTRL *pCtrl,int dblclk)
{
}
void ycuserCLASS::lbuttonup(YCTRL *pCtrl,int dblclk)
{
}
void ycuserCLASS::rbuttonup(YCTRL *pCtrl)
{
}
int ycuserCLASS::is_run(YCTRL *pCtrl)
{
return false;
}
void ycuserCLASS::stop(YCTRL *pCtrl)
{
}
void ycuserCLASS::create(YCTRL *pCtrl)
{
}
void ycuserCLASS::destroy(YCTRL *pCtrl)
{
}
void ycuserCLASS::setcss(YCTRL *pCtrl,WEB_CSS_DATA *mcss,WEB_ATTR_DATA *mattr)
{
}
void stdcall user_rd_text(YCTRL *pCtrl,JSVAL *pJval)
{
YUSER *syn = pCtrl->pUser; //该函数实现JS语句: var pstr = good.text;
pJval->wptr = YC_charToWide(&pJval->len,syn->textBuf,syn->txtLen);
pJval->stype = JS_string;
}
void stdcall user_wr_text(YCTRL *pCtrl,JSVAL *pJval)
{
js_get_str(pJval); //该函数实现JS语句: good.text = pstr;
YUSER *syn = pCtrl->pUser;
syn->txtLen = YC_wideToCharEx(syn->textBuf,sizeof syn->textBuf,
pJval->wptr,pJval->len);
YCHTML->user_paint(pCtrl);
}
void stdcall user_load(YCTRL *pCtrl,JSVAL *pJval,int argnum,JSVAL *argval)
{
pJval->type = JS_undefined; //该函数实现JS语句: good.load("万水千山总是情")
if(!js_arg_str(0,argnum,argval)) return;
YUSER *syn = pCtrl->pUser;
syn->txtLen = YC_wideToCharEx(syn->textBuf,sizeof(syn->textBuf),
argval[0].wptr,argval[0].len);
}
//定义标签属性
JS_USE_ATTR user_attr[] = { { L"text", user_rd_text, user_wr_text, },
0 };
//定义标签方法
JS_USE_METHOD user_method[] = { { L"load", user_load, },
0 };
//设置标签属性数组和方法数组、用户结构数据地址和大小
ycuserCLASS YCUSER; //声明用户结构数据的变量
usDATA user_data = { user_attr, user_method, &YCUSER, sizeof YUSER};
void main(void **pObj)
{
if((int)pObj < 1000) return; //当本程序独立运行时
*pObj = &user_data; //当本程序被user标签使用时,返回标签数据地址
}
C/C++代码文件:good.cpp
4. Javascript代码调用包含user标签的HTML文件
let pwin = YC_cppLoad("ycwin.cpp")
let frame = pwin.createWindow("good.htm")
frame.loop()
javascript代码文件:look.js
编译:用YC命令: ycc look.js 生成 look.exe。
运行:在cmd界面执行look.exe后,将显示一个窗口界面。