Sciter无边框,带阴影,自定义标题栏窗口
来源 https://www.zhihu.com/column/c_1457278851911454720
参考 https://gitlab.com/sciter-engine/sciter-js-sdk
参考 https://gitlab.com/sciter-engine/sciter-webview
参考 https://gitlab.com/sciter-engine/sciter-ffmpeg
在sciter官网下载sciter的SDK,注意下载的是Sciter.JS的SDK,不是Sciter.TIS的SDK,Sciter.JS内置的是QuickJS的解析引擎,几乎支持所有的JavaScript特性,Sciter.TIS内置的是自研的脚本引擎,你要写一种特殊的脚本语言才行。而且这个脚本语言已经被冻结了,以后不会再有任何更新
Download / scitersciter.com/download/接着创建一个VisualStudio C++工程,并设置Include目录
设置编译产出的二进制文件的输出目录:
设置完成之后,在工程根目录下创建一个bin文件夹,把sciter-js-sdk-main\bin\windows\x32下的sciter.dll拷贝到这个bin目录下。(你如果编译64位的程序,那么你就要考x64下的sciter.dll)。
把sciter-sdk/include/sciter-win-main.cpp这个文件复制到你的C++工程内,随便起什么名字都可以。
在工程下创建一个目录放置你的HTML/CSS/JS等界面文件,我们假设这个目录叫做ui,在这个目录下新建一个文件main.html,代码如下:
<html>
<head>
<title>Test</title>
</head>
<body>Hello World!</body>
</html>
在你的C++工程目录的命令行下执行如下指令
path\to\sciter-sdk\bin\packfolder.exe ui resources.cpp -v "resources"
这个命令会在你的C++工程目录下创建一个名为resources.cpp的程序。把这个程序文件包括到你的C++工程中。
你可以把这段指令搞成一个批处理,方便以后执行。
再手动在C++工程内创建一个C++程序,叫什么名字都可以,代码如下:
#include "sciter-x.h"
#include "sciter-x-window.hpp"
class frame : public sciter::window {
public:
frame() : window(SW_TITLEBAR | SW_RESIZEABLE | SW_CONTROLS | SW_MAIN | SW_ENABLE_DEBUG) { }
};
#include "resources.cpp"
int uimain(std::function<int()> run) {
sciter::archive::instance().open(aux::elements_of(resources));
sciter::om::hasset<frame> pwin = new frame();
pwin->load(WSTR("this://app/main.html"));
//or use this to load UI from
// pwin->load( WSTR("file:///home/andrew/Desktop/Project/res/main.htm") );
pwin->expand();
return run();
}
接着启动你的程序,你应该就能看到执行结果了:
如果你的程序出了问题,
看看预处理器是不是没有定义_WINDOWS,没有的话,就加一个。
看看连接器的子系统是不是设置成了:窗口 (/SUBSYSTEM:WINDOWS),如果没有就设置一下。
一般就没别的问题了。
首先看html标签
<html window-frame="extended"
window-icon="http://www.baidu.com/favicon.ico">
window-frame属性有很多可选的值:
none:普通窗口,系统自带的边框、标题栏、窗口控制按钮
solid:无边框窗口,也没有阴影,支持缩放,不支持透明
solid-with-shadow:无边框窗口,有阴影,支持缩放,不支持透明
extended:无边框窗口,有阴影,支持缩放
transparent:透明窗口。
如果值被设置为transparent,那么可以通过如下样式设置不规则窗口
html {
background: transparent;
margin: 0px;
padding: 0px;
}
body {
width: 1*;
height: 1*;
overflow: hidden;
margin: 8px;
padding: 0px;
border-radius: 3px; /*它能支持,就能支持不规则窗口*/
background: #fff;
box-shadow: 0 0 8px #000;
}
如果值被设置成solid-with-shadow,那么最大化后再还原,窗口顶边会多一个白边,如下图所示:
所以这里我们选择了extended。
但用这个值,会导致最大化之后,页面有边缘会超出屏幕边缘,所以我们定义了下面的样式:
html {
margin: 0px;
padding: 0px;
}
body {
width: 1*;
height: 1*;
margin: 0px;
padding: 0px;
}
.bodyPadding {
padding:7px;
}
在窗口最大化之后,我们动态的把bodyPading样式加到body元素上。这个逻辑我们稍后再讲。
body的宽度和高度,用1*表示,这是sciter特有的宽度定义方式,相当于自适应父容器的宽度高度变化;此处不能用100%替代。不然最大化后再还原会出滚动条。
window-icon属性是窗口在任务栏上的图标,这里我们直接借用了百度的图标。
接着我们定义几个图标:关闭、最小化、还原、最大化
icon {
margin-top: 12px;
display: inline-block;
size: 11px;
background-size: contain;
background-repeat: no-repeat;
fill: #363636;
stroke: none;
}
icon.minimize {
margin-top: 18px;
background-image: url(path:M44.521739 472.731826h934.956522v93.495652H44.521739z);
}
icon.maximize {
background-image: url(path:M73.73913031 73.73913031v876.52173938h876.52173938V73.73913031H73.73913031z m788.86956563 788.86956563H161.39130406V161.39130406h701.21739188v701.21739188z);
}
icon.restore {
background-image: url(path:M977.608348 45.412174v751.304348l-190.19687-0.089044v180.891826H45.412174V235.52H226.170435V45.412174h751.393391zM703.888696 319.042783H128.890435v575.087304H703.888696V319.042783z m190.196869-190.152348H309.648696V235.52h477.762782v477.718261l106.718609 0.044522V128.890435z);
}
icon.close {
fill: #363636;
background-image: url(path:M582.95652219 508.95304344l367.3043475 364.71652219-67.82608688 64.36173843-367.30434844-364.71652125L141.56521719 950.26086969 73.73913031 879.59652219l373.89913032-376.86260906-367.72173844-364.63304344L147.82608687 73.73913031l367.30434751 364.75826063L882.43478281 73.73913031 950.26086969 144.19478281z);
}
icon.close.hover {
fill: #fff;
}
.hide {
display: none;
}
sciter是可以直接渲染svg图标信息的,就像代码理展示的那样。
接下来我们看Body里的HTML结构
<div class="titleBar">
<div class="caption" role="window-caption">这是窗口的标题</div>
<div class="captionTool">
<div id="minimizeBtn">
<icon class="minimize"></icon>
</div>
<div id="maximizeBtn">
<icon class="maximize"></icon>
<icon class="restore hide"></icon>
</div>
<div id="closeBtn">
<icon class="close"></icon>
</div>
</div>
</div>
窗口标题我们用了role="window-caption"属性,有这个属性,这个区域就可以被拖动,双击就可以最大化或还原。
icon元素负责加载渲染svg图标。
这些元素的样式如下:
.titleBar {
height: 38px;
line-height: 38px;
background: #eee;
display: flex;
font-size: 13px;
color: #333;
flow: horizontal;
}
.caption {
width: 1*;
padding-left:8px;
}
.captionTool {
width: 140px;
text-align: center;
flow: horizontal;
}
.captionTool div {
width: 1*;
height: 38px;
line-height: 38px;
}
.captionTool div:hover {
background: #ccc;
}
.captionTool div:last-child:hover {
background: rgb(231, 37, 54);
}
sciter是不支持flex布局的,但它可以用自己定义的flow: horizontal这样的样式做到flex布局。
接下来就是与这个页面相关的JavaScript脚本了
let closeBtn = document.querySelector("#closeBtn");
let minimizeBtn = document.querySelector("#minimizeBtn");
let maximizeBtn = document.querySelector("#maximizeBtn");
closeBtn.addEventListener("mouseenter", () => {
closeBtn.firstElementChild.classList.add("hover");
})
closeBtn.addEventListener("mouseleave", () => {
closeBtn.firstElementChild.classList.remove("hover");
})
closeBtn.addEventListener("click", () => {
Window.this.close(true);
})
minimizeBtn.addEventListener("click", () => {
Window.this.state = Window.WINDOW_MINIMIZED;
})
maximizeBtn.addEventListener("click", () => {
if (Window.this.state == Window.WINDOW_MAXIMIZED) {
Window.this.state = Window.WINDOW_SHOWN;
} else {
Window.this.state = Window.WINDOW_MAXIMIZED;
}
})
Window.this.on("statechange", () => {
let maximize = maximizeBtn.firstElementChild;
let restore = maximizeBtn.lastElementChild;
if (Window.this.state == Window.WINDOW_MAXIMIZED) {
maximize.classList.add("hide")
restore.classList.remove("hide")
document.body.classList.add("bodyPadding")
} else {
restore.classList.add("hide")
maximize.classList.remove("hide")
document.body.classList.remove("bodyPadding")
}
})
这段脚本做了以下几个事情:
鼠标移入移出关闭按钮的时候,要改变关闭按钮icon的颜色,这里我们是通过给icon附加样式的手段实现的;
窗口最小化、最大化、还原的功能是通过修改Window.this.state属性的值来实现的;
当窗口最大化状态变化时,改变最大化按钮内两个icon的显隐状态,调该整显示最大化图标还是还原图标;如果是最大化状态,那么要把bodyPadding样式附加到body元素上。避免窗口边缘溢出屏幕。
现在我们在那个批处理脚本前,加一行指令:
del /f /s /q Debug\*.*
path\to\sciter-sdk\bin\packfolder.exe ui resources.cpp -v "resources"
这行指令负责删除Debug子目录下的内容,
它的作用就是下次VS启动项目时,会直接用全新的resources.cpp重新编译,避免使用缓存的编译结果。其实就是起到了清理项目的作用。
接着我们配置一下VS的生成前事件,让它自动执行这个批处理。
这样在VS里启动应用时,VS就直接帮我们完成了打包资源,清理缓存的任务了。开发体验会好很多。
提升调试体验
如果你大部分时间都是在改HTML/JS/CSS的代码,那么你可以通过如下指令查看、调试你的前端代码
"..\..\sciter-js-sdk-main\bin\windows\x32\scapp.exe" "ui\main.html" "--debug"
这个命令执行成功后,会通过scapp.exe这个程序加载你的页面,
接着你在启动sciter-js-sdk-main\bin\windows\x32\inspector.exe程序,如下图所示:
这样你就可以通过inspector.exe来调试你的界面了。
=============== End
标签:最大化,窗口,Sciter,sciter,标题栏,Window,background,icon,自定义 From: https://www.cnblogs.com/lsgxeva/p/17226747.html