首页 > 其他分享 >WPF 应用迁移到 Electron 框架过程记录

WPF 应用迁移到 Electron 框架过程记录

时间:2024-03-05 09:13:01浏览次数:25  
标签:function ipc const selectedEmoji Electron path 迁移 WPF emoji

前一段时间我用 WPF 开发了一个查看 emoji 表情的小工具 https://github.com/he55/EmojiViewer ,由于最近我使用 macOS 系统比较多,我想能在 macOS 系统上也能使用这个工具。于是我尝试将 WPF 应用迁移到 Electron 框架,感觉这个框架很强大,在这里记录一下应用迁移的过程。

安装 Electron 环境

  • 安装 nodejs。到官网 https://nodejs.org/en 下载最新的 nodejs,然后安装
  • 打开命令行输入 git clone https://github.com/electron/electron-quick-start.git 命令克隆 Electron 模板项目,使用模板可以快速搭建应用。
  • 然后使用 cd electron-quick-start 目录进入到目录,接着运行 npm install 命令还原项目。
  • 使用 vscode 打开文件夹,项目文件如下

编写代码

  • Electron 分为主进程和渲染进程,对文件、系统和窗口的操作需要在主线程,界面渲染在渲染进程。创建窗口属于主进程的工作,需要到 main.js 文件编写代码。创建窗口使用 BrowserWindow 对象,widthheight 分别设置窗口宽度和高度,autoHideMenuBar 设置是否隐藏菜单,最后使用 loadFile 加载页面文件并显示窗口。
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 915,
    height: 560,
    autoHideMenuBar: true,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  mainWindow.loadFile('index.html')
}
  • 监听 whenReady 事件,等待应用初始化完成后显示窗口
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})
  • 修改 index.html 文件,界面部分使用了 vue 进行渲染
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <script src="vue.global.js"></script>
  <link href="./styles.css" rel="stylesheet">
  <title>EmojiViewer</title>
</head>

<body>
  <div id="app" class="container">
    <ul class="left">
      <li v-for="(item, key) in categories" :class="{active: item.isActive}" @click="catetoryItemClick(item)">{{ key }}</li>
    </ul>
    <ul class="main" ref="mainElement">
      <li v-for="emoji in emojis" :class="{active: emoji.isActive}" @click="emojiItemClick(emoji)">
        <img :src="emoji.previewImage" alt="">
        <p>{{emoji.name}}</p>
      </li>
    </ul>
    <div class="right">
      <img :src="selectedEmoji.previewImage">
      <p>{{ selectedEmoji.name }}</p>
      <button @click="copyEmoji(selectedEmoji)" type="button">Copy Emoji</button>
      <button @click="copyImage(selectedEmoji)" type="button">Copy Image</button>
      <button @click="openFile(selectedEmoji)" type="button">Open File</button>
    </div>
  </div>

  <script src="./renderer.js"></script>
</body>

</html>
  • renderer.js 文件中编写页面处理代码
window.addEventListener('DOMContentLoaded', async () => {
    const { createApp, ref, onMounted } = Vue
    let emojiData = await ipc.getData()

    createApp({
        setup() {
            const mainElement = ref(null)

            const categories = ref(emojiData)
            const emojis = ref([])
            const selectedEmoji = ref({})

            function copyEmoji(emoji) {
                ipc.ipc('writeText', emoji.metadata.glyph)
            }
            function copyImage(emoji) {
                ipc.ipc('writeImage', emoji.previewImage)
            }
            function openFile(emoji) {
                ipc.ipc('showItemInFolder', emoji.previewImage)
            }

            let lastSelectedEmojis
            function catetoryItemClick(items) {
                if (lastSelectedEmojis) {
                    lastSelectedEmojis.isActive = false
                }

                items.isActive = true
                lastSelectedEmojis = items

                // const main = document.querySelector('.main')
                mainElement.value.scrollTop = 0
                emojis.value = items
            }

            function emojiItemClick(emoji) {
                if (selectedEmoji.value) {
                    selectedEmoji.value.isActive = false
                }

                emoji.isActive = true
                selectedEmoji.value = emoji
            }

            onMounted(() => {
                catetoryItemClick(emojiData['Activities'])
                emojiItemClick(emojiData['Activities'][0])
            })

            return {
                mainElement,
                categories,
                emojis,
                selectedEmoji,
                catetoryItemClick,
                emojiItemClick,
                copyEmoji,
                copyImage,
                openFile,
            }
        }
    }).mount('#app')
})
  • 读取文件,node 提供了文件操作相关的 api 可以很方便的操作文件系统。
function loadData(assetPath) {
  const dirs = fs.readdirSync(assetPath)
  const data = []
  const groupData = {}
  for (const dir of dirs) {
    const fullPath = path.resolve(assetPath, dir)
    const metadata = require(path.resolve(fullPath, 'metadata.json'))
    let previewImage

    let imagePaths = [path.resolve(fullPath, '3D'), path.resolve(fullPath, 'Default', '3D')]
    for (const imagePath of imagePaths) {
      if (fs.existsSync(imagePath)) {
        let files = fs.readdirSync(imagePath)
        if (files.length === 0)
          return
        previewImage = path.resolve(imagePath, files[0])
      }
    }

    const { unicode, group } = metadata
    const obj = {
      metadata,
      id: unicode,
      name: dir,
      previewImage,
    }
    data.push(obj)

    if (!groupData[group])
      groupData[group] = []
    groupData[group].push(obj)
  }
  return groupData
}

完整代码(WPF 版本) https://github.com/he55/EmojiViewer
完整代码(vue 版本) https://github.com/he55/web-learn/tree/main/9.electron-emoji-viewer(vue)
完整代码(js 原生版本) https://github.com/he55/web-learn/tree/main/6.electron-emoji-viewer

标签:function,ipc,const,selectedEmoji,Electron,path,迁移,WPF,emoji
From: https://www.cnblogs.com/he55/p/18046511

相关文章

  • 浅谈WPF之Binding时数据校验和类型转换
    在WPF开发中,Binding实现了数据在Source和Target之间的传递和流通,就像现实生活中的一条条道路,建立起了城镇与城镇之间的衔接,而数据校验和类型转换,就像高速公路之间的收费站和安检站。那在WPF开发中,如何实现数据的校验和类型转换呢?本文以一个简单的小例子,简述在WPF开发中,实现数据校......
  • 触控:WPF捕捉触控事件
    1注册触控事件2注册键盘事件3注册鼠标点击事件4注册鼠标滚轮事件usingSystem;usingSystem.Diagnostics;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Input;namespaceWindows{///<summary>///触控源///</summar......
  • 解决WPF下popup不随着window一起移动的问题
    解决WPF下popup不随着window一起移动的问题_小戴BOTAOY演示博客(yii666.com)///<summary>///Popup帮助类,解决Popup设置StayOpen="True"时,移动窗体或者改变窗体大小时,Popup不随窗体移动的问题///</summary>publicclassPopopHelper{publicstaticDependency......
  • 技术实践|数据迁移中GBK转UTF8字符集问题分析
    导语:在国产化创新的大背景下,数据库迁移项目逐渐增多,在数据库迁移过程中,源数据库和目标数据库字符集有时会不同,这时如何进行字符集转换则成为了一个重要的问题,同时在转换过程中还需要确保数据的完整性和一致性。 字符集转换算法是一个复杂的领域,因此各个操作系统和库实现可能会......
  • wpf中treeview和ICollectionView接口实现数据过滤
    privateICollectionView_collectionView;privatevoidbinddata(List<obj>list){//创建CollectionViewSource并绑定到TreeViewCollectionViewSourcecollectionViewSource=newCollectionViewSource{Source=li......
  • vue——使用yarn安装electron依赖时报错:RequestError: read ECONNRESET
    参考:1.Electron安装报错RequestError:readECONNRESEThttps://blog.csdn.net/qq_33835370/article/details/123612429?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-123612429-blog-122476584.235^v43^control&spm=1......
  • WPF Binding 绑定标记扩展
    参考绑定标记扩展Binding类环境软件/系统版本说明WindowsWindows10专业版22H219045.4046MicrosoftVisualStudioMicrosoftVisualStudioCommunity2022(64位)-17.6.5Microsoft.NetSDK8.0.101手动安装Microsoft.NetSDK7.0.306Mi......
  • VS2019 打包WPF安装程序
    说明最近开发了一个WPF的小工具,最初想发布成一个非安装版的可执行程序,发现有点困难,因为是基于.NetFramework4.7开发,还引用了一些其他库,WPF程序的运行是依赖.NetFramework环境的,所以必须提前安装。于是在官网上找到ClickOne的相关说明,可以把WPF打包成安装程序,当安装时会校......
  • ssts-hospital-web-master项目实战记录三十:项目迁移-Hook实现(useSystemService)
    记录时间:2024-02-29一、useSystemService模块实现service/system-service/useTerminalService.tsimporthydatefrom'@/utils/date-format'import{LogInfo}from'@/framework/utils/log-local'import{Device}from'@/types/device'impor......
  • Oracle 12C数据库从文件系统迁移到ASM
     查看参数文件位置SQL>showparameterspfileNAMETYPEVALUE-----------------------------------------------------------------------------spfilestring/u01/app/oracle/product/12.......