YC_window("water.jpg") //设置主函数为 WinMain(),图象water.jpg为程序图标
pwin = YC_cppLoad("ycwin.cpp") //创建界面接口ycwin.cpp的对象pwin
frame = pwin.createWindow("ycs.htm") //创建窗口对象,窗口由ycs.htm页面管理
frame.loop() //执行windows消息循环
Javascript代码文件:ycs.js
编译:用YC命令: ycc ycs.js 生成 ycs.exe
运行:在cmd界面执行ycs.exe后,将进入YC服务器界面。
也可以用下列C/C++源码来生成YC服务器:
#define YCICON water.jpg //设置程序图标
#include "yc.h" //ycwinCLASS类在头文件yc.h中定义
void WinMain()
{
ycwinCLASS *pwin = <ycwin.cpp>; //调入界面接口
pwin->createWindow("ycs.htm"); //创建窗口, 窗口内容为ycs.htm页面
pwin->loop(); //windows消息循环
}
c/c++代码文件:ycs.cpp
编译:用YC命令: ycc ycs.cpp 生成 ycs.exe
运行: ycs.cpp和ycs.js的运行结果完全一样。
YC服务器的功能和界面由下面的ycs.htm文件决定。
<body style="background-color:#d2d3d4;font-family:黑体;overflow:auto;" onload=exit_pos()>
<user id=ycexit src=ycexit.cpp style="position:fixed;width:66;top:0;"><!--user为自定义标签-->
<div id=pblock style="border:1 rgb(110,110,110) outset;text-shadow:1 1 rgb(0,0,0);
position:fixed; top:22px;left:10px;padding:5 12px;">
<div style="display:inline-block;" id=svc_state></div>
<div style='height:32px;color:orange;padding:10px 0 0 0;'>连接数:
<div style="font-size:22;color:white;display:inline-block;" id=numberID></div>
</div>
</div>
<div style="display:inline-block;position:fixed;left:460px;top:22px;text-align:center;
padding:8;border:1 #ddd outset;background:rgba(101,58,10,0.8);">
<style>input { font-family:microsoft yahei; font-size:18px; } </style>
<input value="研究生管理系统: http://127.0.0.1" onclick=run_browser("http://127.0.0.1")
type=button>
<input value="照片上传: http://127.0.0.1/upload.ysp"
type=button onclick=run_browser("http://127.0.0.1/upload.ysp")>
<input value="创建图象: http://127.0.0.1/createimg.ysp"
type=button onclick=run_browser("http://127.0.0.1/createimg.ysp")>
<span style="font-weight:bold;font-family:Arial,Verdana;font-size:60px;text-shadow:2 2 black;
color:#dd5533;" id=timeEle></span> <!--显示时间-->
<span style="font-weight:bold;font-family:黑体;font-size:36px;
text-shadow:1 1 #000;color:#d29;" id=dateEle></span> <!--显示日期-->
<span style="font-weight:bold;font-family:黑体;font-size:28px;
text-shadow:1 1 #000;color:#091;" id=dayer></span> <!--显示星期-->
</div>
<div style="height:100px;"></div>
<div style='text-shadow:1 1 white;color:rgb(0,0,0);height:100px;padding:30 0;font-size:22;'>
在浏览器中输入IP地址:<br>http://127.0.0.1<br>可获得本软件的HTTP服务
</div>
<div style="font-size:18;font-family:microsoft yahei;padding:0 0 100 0;" id=nameID></div>
<script>
[%
#include "yc.h"
#define BUF_LENGTH 1024*8 //每项http数据缓冲区长度
ychttpCLASS *YCHTTP = <ychttp.cpp>; //编译驻留HTTP服务器源码
YHTML *phtml; //ycs.htm页面对象指针
CRITICAL_SECTION ysp_cris; //线程锁结构数据
void *main(YHTML *phtml)
{
::phtml = phtml; //记录ycs.htm页面对象指针
auto user_callback = [](int userSock,const char *headBuf)
{
if(!message_enable) return;
int kk = ptail + 1;
if(kk >= BUF_NUM) kk = 0;
if(kk == phead) return;
ysp_lock();
sockaddr_in saddr;
int addrlen = sizeof(sockaddr_in);
if(!getpeername(userSock, (sockaddr *)&saddr, &addrlen))
{
snprintf(&httpBuf[ptail],BUF_LENGTH-1,"%d.%d.%d.%d:%d\r\n%s",
saddr.sin_addr.s_net,
saddr.sin_addr.s_host,
saddr.sin_addr.s_lh,
saddr.sin_addr.s_impno,
saddr.sin_port,
headBuf);
httpBuf[ptail][BUF_LENGTH-1] = 0;
ptail = kk;
}
ysp_unlock();
};
if(YCHTTP) YCHTTP->start_server(80,user_callback); //起动服务器, 设置端口和回调函数
InitializeCriticalSection(&ysp_cris); //线程锁初始化
return []() //释放ycs.htm页面时执行的lambda函数
{
if(YCHTTP) YCHTTP->stop_server(); //删除服务器对象
DeleteCriticalSection(&ysp_cris); //删除线程锁
};
}
void ysp_lock() //线程加锁函数
{
EnterCriticalSection(&ysp_cris);
}
void ysp_unlock() //线程解锁函数
{
LeaveCriticalSection(&ysp_cris);
}
auto get_author = []()
{
return YC_author();
};
const int BUF_NUM = 32; //http环形缓冲区项数
int message_enable = 1; //是否显示http数据
int phead; //http环形缓冲区头部计数器
int ptail; //http环形缓冲区尾部计数器
char httpBuf[BUF_NUM][BUF_LENGTH]; //http环形缓冲区
char *get_http_headStr() //获取当前http数据
{
char *retStr = NULL;
if(phead != ptail)
{
static char itembuf[BUF_LENGTH];
strcpy(itembuf,&httpBuf[phead]);
phead++;
if(phead >= BUF_NUM) phead = 0;
retStr = itembuf;
}
return retStr;
}
int http_dispSta(int mval)
{
if(mval != -1) message_enable = mval;
return message_enable;
}
int check_server()
{
return YCHTTP && YCHTTP->check_server(); //检查服务是否在运行
}
int can_exit() //退出程序时执行该函数(用于ycwin.cpp)
{
return !check_server() || MessageBoxA(phtml->hwnd, "YC服务器正在运行\r\n是否退出?",
YC_TITLE, MB_ICONEXCLAMATION | MB_YESNOCANCEL) == IDYES;
}
int slot_number()
{
static int old_num = -1;
int new_num = YCHTTP ? YCHTTP->slot_number() : 0; //当前正在连接的http请求个数
if(new_num != old_num)
{
old_num = new_num;
return new_num;
}
return -1;
}
int is_win_popup() //判断是否处于全屏状态
{
return !!(GetWindowLongA(phtml->hwnd, GWL_STYLE) & WS_POPUP);
}
void onExit(int nCmd) //执行 ycexit.cpp 中的按钮功能
{
int wParam;
switch(nCmd)
{
case 0: wParam = VK_F12; break;
case 1: wParam = VK_F11; break;
case 2: wParam = VK_ESCAPE; break;
}
PostMessageA(phtml->hwnd,WM_KEYDOWN,wParam,0);
}
void run_browser(char *addrptr)
{
YCWEB->run_browser(addrptr);
}
%]
document.title = "YC服务器";
let dispCnt = 0;
let dispStr = '';
function exit_pos()
{
if(is_win_popup())
{
ycexit.style.left = document.body.offsetWidth - ycexit.offsetWidth;
ycexit.style.height = 22;
}
else ycexit.style.left = -ycexit.offsetWidth;
}
window.onresize = function()
{
exit_pos()
}
function yc_timer()
{
var pDate = new Date();
dayer.innerHTML = ' 星期' + ['日','一','二','三','四','五','六'][pDate.getDay()];
dateEle.innerHTML = pDate.toLocaleDateString();
timeEle.innerHTML = pDate.toTimeString().split(' ')[0];
var new_num = slot_number();
if(new_num >= 0) numberID.innerHTML = new_num; //显示当前正在连接的http请求个数
if(!http_dispSta(-1)) return;
ysp_lock();
var aStr = get_http_headStr();
if(aStr)
{
aStr = aStr.replace(/\r\n/g,'<br>');
var bStr = sprintf('<hr><nobr>%d: %s</nobr>',dispCnt, unescape(aStr));
dispStr += bStr;
dispCnt++;
if((dispCnt % 16) == 0)
{
nameID.innerHTML = dispStr;
dispStr = '';
}
else nameID.innerHTML += bStr;
window.scrollTo(window.pageXOffset, document.body.clientHeight);
}
ysp_unlock();
}
function set_block_color(notFlag)
{
if(notFlag) http_dispSta(!http_dispSta(-1));
pblock.style.background = http_dispSta(-1) ? 'rgba(110,50,20,0.8)':'rgba(10,100,20,0.4)';
}
setInterval(yc_timer,50);
set_block_color();
var aAry = get_author().split('China.')[1].split('.');
svc_state.innerHTML = `
<input type=button
onclick="nameID.innerHTML=''; set_block_color(true);"
style='background-color:${ check_server() ? "rgb(210,210,210)" : "rgb(100,100,100)" };
color:${ check_server() ? "black" : "rgb(150,150,150)" };
height:32px;
font-size:26;
font-family:黑体;'
value='YC服务器${ check_server() ? "已启动" : "已关闭" }${
aAry[0] }年${ aAry[1] }月${ aAry[2] }日'>`
</script>
HTML文件:ycs.htm