首页 > 其他分享 >Sciter无边框,带阴影,自定义标题栏窗口

Sciter无边框,带阴影,自定义标题栏窗口

时间:2023-03-17 14:45:10浏览次数:62  
标签:最大化 窗口 Sciter sciter 标题栏 Window background icon 自定义

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 / sciter​sciter.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

相关文章

  • Uniapp自定义基座
    1.打自定义基座包点击菜单栏“运行”->“运行到手机或模拟器”->“制作自定义基座”生成自定义基座安装包。  2.点击打包,等待打包成功之后会在unpackage/debug路径中......
  • ALV带有自定义事件
    *&---------------------------------------------------------------------**&ReportZ2023015105*&*&---------------------------------------------------------......
  • PebbleTemplates 自定义tag&filter&function 开发简单说明
    PebbleTemplates的扩展能力还是很强大的,开发起来也比较方便,以下是一个简单的说明,更加复杂的推荐查看官方源码学习filter开发参考代码此filter直接返回rongfenglian......
  • leaflet 自定义事件
    leaflet 自定义事件主要使用fire()方法,如下图所示,我在区域热力层点击方法中自定义一个handClick方法,并传值。  再去进行监听  预览单击就会触发我们自定义的方......
  • 五、自定义登录逻辑
    ​ 当进行自定义登录逻辑时需要用到之前讲解的UserDetailsService和PasswordEncoder。但是SpringSecurity要求:当进行自定义登录逻辑时容器内必须有PasswordEncoder实例......
  • 五、自定义登录逻辑
    ​ 当进行自定义登录逻辑时需要用到之前讲解的UserDetailsService和PasswordEncoder。但是SpringSecurity要求:当进行自定义登录逻辑时容器内必须有PasswordEncoder实例......
  • cnblogs 博客园自定义样式
    在博客园搜索资料时,发现很多博友的园子装饰的非常炫酷。想着也装饰一下自己的园子,搜索后发现一个不错的插件,记录一下。使用、配置教程:https://bndong.github.io/Cnblog......
  • wpf自定义控件库(二)——伪3D按钮
    1、以学习wpf为目的,同时也为了增加控件代码的复用性,开始建立自己的自定义控件库;2、目前主要是根据项目需求去增加,完善控件库。希望之后能一步步扩展更多更丰富的控件;3、......
  • wpf 自定义控件库(一)
    1、以学习wpf为目的,同时也为了增加控件代码的复用性,开始建立自己的自定义控件库;2、目前主要是根据项目需求去增加,完善控件库。希望之后能一步步扩展更多更丰富的控件;3、......
  • QT5笔记: 22. 自定义代理
    代理作用:在界面发生编辑时可以指定编辑所用的组件,可以沟通Model和View自定义代理需要继承的基类和需要实现的方法使用步骤:继承QStyledItemDelegate,实现上面的四个......