Определил логику для взаимодействия между модулями проекта и сборщиками.
Реализовал использование Webpack для сборки backend приложения Hello world, также можно собрать @common в программу и использовать pkg для создания exe. В дальнейшем необходимо будет внедрить ряд компонентов Koa для тестирования корректности сборки.
В процессе отладки backend. На данный момент реализована сборка с использованием Webpack с поддержкой source-map, после чего применяется vscode для отладки сгенерированных файлов. Необходимо исследовать возможность использования devServer Vite вместо вывода файлов Webpack. Если это не удастся, то можно разделить процесс на два этапа, хотя предпочтительно иметь скрипт для объединения этих операций.
Vite devServer оказался бесполезным, так как не удалось найти способ, чтобы при запуске отладки в vscode, Vite запускал сервер разработки (devServer) для HMR компиляции. Vite CLI может запускать devServer, но не выполняет компиляцию. Node API Vite может компилировать код, но логика заключается только в том, что он реагирует на изменения кода и перекомпилирует его в папку app/backend, без связи с выходным файлом сервера.
Поэтому было решено создать две конфигурации: запуск отладки через vscode с последующим использованием Vite CLI для сборки и запуск традиционной задачи отладки (запуск js, сопоставление с ts) с помощью Webpack или Vite.
Следующим шагом должно быть обеспечение корректной сборки backend после внедрения Koa и написание скрипта для использования Vite для разработки Hello world приложения на Electron. Теоретически это не должно быть сложно, поскольку существуют другие фреймворки с готовыми шаблонами.
Если действительно требуется HMR, то в документации vscode есть инструкции. Здесь приведена ссылка на руководство по Vue в репозитории Microsoft/vscode-recipes.
После частичного внедрения Koa, Vite успешно работает, а Webpack сталкивается с ошибками во время выполнения при использовании formidable. Требуется ручная настройка пути к hexoid согласно документации (ссылка), чтобы добиться успешной сборки. Причина проблемы пока неизвестна.
После открытия всего кода backend, все запуски прошли успешно. Vite продолжает работать без проблем, в то время как Webpack зависает на библиотеке ws. Пока не исследованы причины сбоя сборки при использовании этой библиотеки, но в документации (ссылка) содержатся возможные решения. Можно использовать resolve для принудительного указания на файлы в node_module или изменить метод импорта.
Добавлены настройки для renderer, preload и main в конфигурации Vite, и сборка dev-frontend в основном успешна. Проведено небольшое исследование путей импорта. Уже реализован запуск Vue3 Hello world с использованием режима dev.
На данный момент, для Vite:renderer, осталось только скомпилировать index.html, чтобы интегрировать его в electron-builder.
Следующий шаг — разработка интерфейса и основной логики управления. Пока нет чёткого представления о том, с чего начать. Однако известно, что, исходя из предыдущих идей, следует рассмотреть способы обеспечения связи между двумя сторонами. Например, прямое spawn в производственной среде, запуск node --inspect или --inspect-brk в среде разработки.
Способ связи в общих чертах выглядит следующим образом: прямое spawn в рабочей среде, запуск узла с параметрами --inspect или --inspect-brk в среде разработки. После запуска FFBox автоматически запускается backend, и достаточно использовать attach в vscode для входа в режим отладки. Launch.json уже содержит конфигурацию для attach, и остаётся только запустить основной процесс с помощью spawn.
Также завершена работа над index.html. Достаточно удалить config для lib, и после сборки с electron-builder приложение будет готово к запуску.
Поскольку эта версия требует учёта preload, была предпринята попытка его реализации. На текущий момент успешно внедрены методы electron API в preload для использования в renderer. Невозможно просто экспортировать весь объект API, необходимо разделять его на отдельные методы, так как экспорт всего объекта включает элементы, которые не являются частью JavaScript контекста.
Что касается renderer, то был внедрён JSX, но пока не проверено, возможно ли его использование.
Началась работа над дизайном интерфейса, разрабатывается общая структура. Внедрение less прошло успешно без дополнительной настройки.
Похоже, что расширение volar успешно установлено. Ранее использовалась версия v0.36, даже после переустановки плагина, и только после закрытия всех страниц и обновления vscode была установлена версия v1. До этого момента .vue файлы не получали подсказки кода.
Добавлен логотип размером 256px без полей и прозрачности, адаптированы некоторые детали без полей.
Определены элементы меню для начальной стадии. Также реализованы функции трёх золотых кнопок.
Кроме того, electron теперь поддерживает window overlay, позволяя размещать три золотые кнопки на окне. При правильной настройке можно использовать быстрый инструмент разделения экрана Windows 11, однако недостатком является невозможность перемещения позиции.
Пока не планируется включать эту функцию, она используется в собственном решении. Основная цель — возможность перетаскивания заголовка для разделения экрана. Фактически, достаточно отключить прозрачность. Согласно текущему дизайну UI, нет необходимости в прозрачности для достижения определённых эффектов, поэтому используется текущее решение.
Продолжена оптимизация теней для кнопок tab и трёх золотых кнопок. EventEmitter
Вчерашняя проблема была в этом. Нужно было просто подключить библиотеку events.
В хранилище были добавлены функции для добавления серверов и задач, но серверные события ещё не прослушиваются, поэтому данные с сервера пока не передаются на фронтэнд. Следует подумать о начале модульного проектирования.
2023-02-08
После разделения MainFrame на четыре блока стало возможно «свежо» продолжить разработку (на самом деле предыдущие блоки были созданы для реализации элементов TaskItem, которые должны отображать данные из хранилища).
Основная сложность сейчас заключается во внедрении jsx. Сначала внедрение @vitejs/plugin-vue-jsx используется для того, чтобы Vite мог использовать Babel для преобразования (примерно так), но плагин не заботится о других вещах. В результате я столкнулся с двумя проблемами: eslint и TypeScript.
Для eslint решением является добавление полей parser и parserOptions; для TypeScript — изменение значения поля jsx на «preserve». Кроме того, нельзя использовать специфические атрибуты React, такие как className, что указано в документации Vue.
Также я примерно понял роль jsx в Vue. Фактически, Vue сам поддерживает написание компонентов непосредственно на JavaScript вместо использования шаблонов, включая компоненты класса и функциональные компоненты. Плагин jsx просто преобразует их в функцию h. Кроме того, этот плагин работает не только с .jsx и .tsx, но и с .vue, позволяя использовать компоненты jsx внутри тега <script>.
2023-02-10
Как было написано 02-02, пока нет обработчиков для серверных сообщений, поэтому они не передаются на фронтенд. Поэтому сейчас мы работаем над serverEventsHandler.
Раньше, поскольку мы использовали Vuex, было невозможно вызвать одну мутацию из другой, используя mainVue, это был своего рода хакерский способ. Теперь, после перехода на Pinia, мы можем напрямую использовать useStore. Однако в функции initializeServer есть место, где требуется as Server. Я подозреваю, что Pinia каким-то образом преобразовал его, в результате чего данные фактически были глубоко скопированы, но пока не уверен, так ли это (также возможно, что это просто преобразование TypeScript), поэтому сначала нужно убедиться, что связь между сервером и фронтендом работает правильно.
Во время настройки связи между сервером и фронтендом, поскольку это связано с конкретной логикой выполнения, необходимо также адаптировать некоторые функции nodeBridge (включая preload), что сейчас и происходит.
2023-02-11
Процесс подключения к серверу прошёл гладко, почти сразу после подключения всё заработало (и даже можно использовать старый FFBox для запуска сервера, который можно сразу же использовать без изменения структуры данных на сервере).
Затем возникла проблема с адаптацией nodeBridge. В предыдущем коде рендерер всё ещё содержал много кода, связанного с Electron или Node, например, непосредственное создание процесса с помощью spawn, использование remote для flashFrame или открытия DevTools. Чтобы реализовать разделение, лучше всего предположить, что страница не знает, что находится под ней — Electron, поэтому все эти функции должны быть собраны в nodeBridge, а прелоад nodeBridge также был переименован в jsb.
Следующим шагом будет проектирование taskItem. На данный момент разделение списка задач завершено, и работа продолжается.
Кроме того, текущая логика обновления списка может привести к внутренним ошибкам Vue, которые требуют дальнейшего изучения.
2023-02-14
Сегодня я начал с разработки стиля отображения параметров в taskItem, а затем попытался использовать computed значение videoRateControl для решения проблемы внутренних ошибок. Я предполагаю, что причина в том, что я передал объект в качестве ключа для v-for. Это предположение оказалось верным. Затем я нашёл предыдущее решение, которое заключалось в создании другого computed значения, которое вставляет id в каждый элемент списка. Этот подход был использован для экономии одного поля, что довольно «индивидуально».
Кроме того, если вы используете computed, предупреждение об ошибке в консоли может выглядеть как «Invalid VNode type: undefined (undefined)», что может быть связано с тем, что вы забыли получить .value. Уведомления об ошибках в Vue в этом отношении не очень дружелюбны.
На данный момент разработано четыре типа информации для отображения, но ширина списка уже очень большая, что затрудняет размещение имён файлов. Попытка использовать атрибут многострочного переполнения старого FFBox не увенчалась успехом, и необходимо продолжить настройку.
2023-02-15
Продолжаю настраивать стиль taskItem и добавляю значки слева и кнопки действий справа. Одновременно, ссылаясь на дизайн taskItem старого FFBox, я заново реализовал тени. В прошлом для достижения теней требовалось несколько слоёв div, что действительно требовало высокого уровня визуальных эффектов. По сравнению с этим, мои художественные навыки сейчас намного лучше.
2023-02-21
Продолжаем реализацию функций taskItem и добавляем dashboardArea и cmdArea. Конечно, все кнопки ещё не реализованы, и автоматическое переключение и масштабирование некоторых полей в зависимости от ширины элемента также не реализовано, поэтому внешний вид пока не очень приятный.
В процессе я обнаружил селектор CSS :has, который стал доступен в Chromium только в прошлом году, в августе. Это называется своевременным дождём.
2023-02-22
Добавлены несколько свойств класса интерфейса в хранилище, но функции ещё не написаны. Поскольку статический интерфейс разрабатывался слишком долго, я хочу посмотреть, как он взаимодействует. Поэтому я начинаю работать над ParaBox. Во-первых, я разделил файлы, а затем заменил все sidebar-icon на svg. Но я застрял на этапе svg:
<defs><style></style></defs>
. Однако при преобразовании vite-plugin-svg в компонент Vue стиль удаляется, потому что Vue не поддерживает использование <style>
в компонентах. В проблемах vite-svg-loader есть два решения:
<style>
внутрь тега. Однако на самом деле vite-plugin-svg по умолчанию использует настройки svgo по умолчанию, которые уже включают этот плагин, но у него есть ошибка, из-за которой стиль применяется только один раз. Эта ошибка была обнаружена всего месяц назад.<style
на <component is="style"
. Опять же, это было предложено месяц назад.onlyMatchedOnce: false
для inlineStyles. Вы спрашиваете, это ошибка или функция?fill="currentColor"
, который позволяет применять внешние стили CSS для изменения цвета.stroke:currentColor
. Это хлопотно, но может уменьшить размер файла. Перевод текста на русский язык:
Введение элементов — это большая задача, потому что сразу нужно ввести много всего, включая дочерние параметры, страницы с параметрами, используемые элементы управления и элементы управления, в которых используются Tooltip. Обычные элементы управления требуют преобразования их vue2-опций в vue3-композицию setup, а Tooltip требует создания Vue-компонента с нуля.
Мы планируем посмотреть, как это делается в Element Plus, но сервер npmmirror выдал ошибку 502, и мы не смогли его установить, поэтому перешли прямо к GitHub. Мы обнаружили, что его дизайн кажется намного более сложным, чем раньше, и у нас нет времени разбираться в нём, мы увидели только некоторые базовые коды, которые нам нужны.
Тем не менее, после введения мы столкнулись с проблемой отсутствия ссылок на файлы (временно решена путём перемещения файлов), а после решения остальных проблем Tooltip всё ещё не появлялся. Нужно продолжать искать причину (возможно, мы пропустили код контекста).
Уже найдена причина проблемы с отсутствующими ссылками на файлы. В конфигурации vite пропущено расширение файла tsx.
Что касается предыдущей проблемы, то причина, по которой Tooltip не появляется, заключается в том, что props узла является свойством только для чтения, и его нельзя изменить напрямую, необходимо использовать vnode.component.props для изменения. Проще говоря, есть три шага для добавления VNode в DOM для монтирования компонента Vue: 1. Используйте нужный компонент для создания VNode. 2. Создайте узел DOM. 3. render. Очевидно, что я не очень хорошо знаком с принципами Vue3, и мне нужно продолжить обучение позже.
Кроме того, процесс решения проблемы также не был гладким, включая проблему с тем, что окно dev-режима не открывается, и проблему с компиляцией. Проблема с окном dev-режима — это простая проблема, оставьте оператор debugger в first render; проблема с компиляцией по-прежнему связана с vite, в режиме компиляции, хотя используется та же конфигурация, что и в режиме разработки, но в производственном режиме alias resolve не читается, и необходимо использовать path.resolve.
Также было обнаружено одно отличие Vue 2 от Vue 3: имя класса CSS, используемого Transition-компонентом, изменилось. К исходному имени класса добавлено «-from». Это решило проблему, когда после миграции компонентов анимации выполнялись только частично.
В последнее время я занимаюсь миграцией Parabox components, и она в основном завершена, но поскольку связь между интерфейсом и сервером ещё не установлена, я не могу увидеть эффект реализации. Глядя на журнал, цель этой работы — завершить основные функции интерфейса программного обеспечения как можно скорее. Чтобы продолжить разработку, следующим шагом будет написание логики передачи параметров на сервер.
Сейчас я работаю над сохранением параметров, поскольку у меня есть Pinia, я немного упростил дизайн, напрямую изменил globalParams, а затем уведомил store о выполнении приложения. На этом этапе возникла необходимость использования electron-store.
Поскольку была включена защита, getEnv всегда возвращает browser в процессе рендеринга, поэтому я рассматриваю возможность использования preload.
Но на самом деле preload тоже не работает. Согласно этому issue, preload позволяет импортировать только ограниченное количество функций electron. Поэтому использование хранилища должно быть реализовано с помощью jsb.
Кроме того, nodeBridge также должен быть значительно изменён. Поскольку nodeBridge был разработан в соответствии с первоначальным способом прямого доступа к модулям узла в процессе рендеринга. Теперь многие вещи должны выполняться в основном процессе, поэтому его необходимо изменить.
Кроме того, адаптация electron-store также не прошла гладко. Например, во время процесса я столкнулся с ошибкой при вызове ipc An object could not be cloned.
, это бессмысленная ошибка, решение состоит в обновлении страницы. Да, HMR vite всё ещё имеет некоторые проблемы.
Чтобы протестировать эффект работы панели параметров, нам также необходимо позволить ей быть выбираемой. Поэтому недавно мы добавили соответствующую логику выбора в панель параметров и адаптировали стиль. К счастью, эта работа была успешно выполнена за один раз.
После завершения вышеуказанной работы, следующим шагом является завершение работы над панелью параметров. Сейчас мы работаем над первым модулем VcodecView, при работе с rateControlList мы сталкиваемся с некоторой логической операцией, а текущий vcodecs всё ещё является js, который необходимо преобразовать в ts для работы. Одновременно мы также провели некоторую оптимизацию var -> let/const и необязательных цепочек и т. д. AcodecView также был успешно завершён, следуя примеру VcodecView. Поскольку вещей меньше, acodecs можно не переводить в ts, будет только одна ошибка. Однако такая наполовину асимметричная разработка неприемлема для меня, завтра я переведу acodecs в ts.
И, работая над вторым параметром, я также переделал переход. Теперь, глядя на документацию Vue, очевидно, что это намного проще, чем четыре года назад, поэтому я наконец-то научился использовать transition для условной анимации, и сделал несколько тонких настроек. Основная причина заключается в том, что мы изменили анимацию вверх и вниз на анимацию влево и вправо, которая соответствует направлению чтения, если скорость и диапазон по-прежнему меняются слева направо, это кажется не таким удобным (кажется, что он дёргает линию взгляда), поэтому мы отдельно настроили анимацию входа и выхода.
Кроме этого, теперь мы можем стабильно воспроизвести ошибку An object could not be cloned.
, которая появилась ранее. На этот раз это происходит при установке. Proxy не может напрямую взаимодействовать с основным процессом через ipc, требуется JSON.parse(JSON.stringify).
Помимо этого, мы также обнаружили, что Slider не работает должным образом (вероятно, проблема с координатным обнаружением). Позже мы исправим эту проблему.
Завершена остальная часть дизайна панели параметров, включая преобразование acodecs в ts. Я также подумал о RadioList для ShortcutView.
Исправлены ошибки Slider и Checkbox, а также ошибки в трёх View, связанные с неправильным написанием параметров.
Закончив список задач, я планирую добавить сервер. Затем, размышляя о дизайне интерфейса, я обнаружил, что TextField глобальных параметров написан как статические данные. При попытке реализовать upath возникла проблема. После изучения исходного кода я обнаружил, что некоторые методы напрямую вызывают node, что не будет работать в веб-среде. Поэтому я думаю об использовании path-browserify для полифилла.
Вывод таков: upath не поддерживает браузерную среду. Хотя можно использовать path в браузере, установив path-browserify, upath не имеет никакого дизайна, который можно передать для polyfill, и все внутренние вызовы предполагают, что они могут потребовать path для проектирования. В npm нет документированного upath2, который также нельзя использовать. Зачем использовать upath? Потому что он содержит некоторые функции пути, которых нет в path, такие как trimExt. Поэтому я вручную скопировал исходный код в utils и изменил его часть, чтобы успешно включить его. Однако это не элегантно. Первоначально можно было решить проблему с использованием модуля upath, но теперь она разделена на path-browserify и utils, и проверка типов также неполна. Но поскольку автор upath прекратил обслуживание, мы можем сделать это только сейчас, а позже рассмотрим его очистку.
Скорее всего, проблема с серверной частью возникла ещё давно, когда использовался односекундный режим обновления состояния. Оказалось, что команда pkg вводит продукт, который раньше был собран с помощью webpack, а теперь используется vite.
В рабочей среде некоторые изображения не открываются, например, всплывающее окно для перетаскивания файлов в центр экрана. Отсутствие этой функции делает опыт использования довольно недружелюбным, поэтому это легко заметить. После расследования можно сделать вывод о ресурсах:
Подводя итог, можно сказать следующее:
Alt 键不能正常生效,得用 scan code的,но на практике нет необходимости в таких сложностях, ALT 键 можно использовать VK_LMENU для успешного запуска системного меню. Это всё, можно приступать к работе!
Что касается обычных изменений в разработке сегодня:
osBridge был перемещён из renderer в main. Поскольку 4.x процесс рендеринга больше не может запускать процессы самостоятельно, управление helper было перенесено в основной процесс, а вызовы к нему в nodeBridge.
В C++ из-за отсутствия опыта написание кода оказалось немного сложным. Особенно это касается вызова операций Windows API, которые поначалу меня немного запутали. Почему при написании этого helper сначала нужно было определить необходимые определения Windows API и почему это определение нужно искать в документации Microsoft? Почему при вызове необходимо сначала получить этот тип из dll, а затем вызвать его? Не понимая, я мог только скопировать и изменить. Позже я подумал, что это динамический метод поиска функций из dll, и что в наборе инструментов Windows уже есть Windows.h, всё готово, не нужно так заморачиваться. В любом случае, позже я просто использовал его напрямую, оставив предыдущий код как есть.
Сегодня была реализована общая логика большого меню, включая реакцию на нажатие мыши и клавиатуры, логику отображения центра меню и центра сообщений, пользовательский интерфейс приложения меню (функция ещё не реализована) и т. д., а также были скорректированы уровни отношений между двумя центрами и большой кнопкой на экране, и была реализована функция четвёртой кнопки из твёрдого сплава.
Сегодня было реализовано настраиваемое меню. Вы обнаружите, что я сделал один .vue и один .tsx. Недавно я всё ещё размышлял о том, почему Msgbox сделал две настройки, но теперь Menu вынужден сделать две настройки. Я столкнулся с проблемой 2023-03-19
, где используемый тип defineProps не может быть сложным типом. Следуя этой проблеме, я нашёл PR. Хотя проблема была исправлена, она не была полностью решена. Там говорится: «Обратите внимание, что поддержка сложных типов основана на AST (не используется сам TS) и поэтому не является на 100% всеобъемлющей. Например, вы не можете использовать условные типы для самого типа реквизита». Как раз, когда я использовал extends в своём типе, он не поддерживался. Хотя можно заменить extends на &, лучше просто переключиться на tsx.
Затем были проведены обычные изменения, новый стиль меню отличался от предыдущего. Самое большое отличие заключается в параметрах, новое меню более функционально, оно может поддерживать переключение вверх и вниз для мгновенного просмотра эффекта, а также может использоваться в качестве обычного меню для поддержки команд, выбора и подменю.
Проблема с открытием верхнего меню, которое было покрыто слоем маски, из-за чего требовалось сначала закрыть меню, чтобы переключить меню, была решена. Метод не обязательно хорош, просто запомните положение нескольких кнопок меню при открытии меню, затем повесьте прослушиватель mousemove на body, переместите мышь в указанное положение, чтобы переключить меню.
Я изучил другие программные меню. Между различными программами нет единого стандарта. Обычно контекстное меню покрывает весь экран, в то время как меню приложений не покрывает. На самом деле здесь есть ещё вопрос фокуса клавиатуры. Короче говоря, нам всё ещё нужно подумать о том, как это сделать.
Кроме того, проблема с сообщением об ошибке при уничтожении меню была решена. Причина в том, что onClose вызывается дважды, один раз из-за срабатывания onClick. Vue по умолчанию слушает это событие и отправляет его в onClick, изменяя его имя.
Ситуация немного сложная. Потому что MenuComponent нуждается в использовании mounted, но сегодня я обнаружил, что некоторые вещи в компоненте будут повторно отображаться каждый раз, когда изменяется ref. Когда именно будет выполняться функция render? Это проблема, которая осталась давно. Давайте рассмотрим её завтра.
На самом деле проблема, с которой я столкнулся вчера, является одной из проблем, с которыми я столкнулся 08-29 при создании ShortcutView. Тогдашний вывод заключался в том, что функциональные компоненты могут быть вызваны из-за сбора зависимостей, и если ref переменная читается перед рендерингом или считывается как дочерний компонент props, это может привести к ненормальному поведению. Сегодня я воспроизвёл его снова и обнаружил больше закономерностей: ref переменные, помещённые в дочерние компоненты props или DOM, ведут себя ненормально, а помещённые в слоты дочерних компонентов ведут себя нормально.
После беглого просмотра некоторых статей о функциональных компонентах, кажется, я пришёл к некоторым новым выводам — функциональные компоненты подходят только для простых компонентов и быстрого рендеринга, потому что они не имеют состояния, поэтому каждый раз, когда происходит рендеринг, возможно, создаётся новый компонент без выполнения diff, поэтому ref каждый раз рендерится не то же самое.
При таких обстоятельствах вышеупомянутое «ненормальное» поведение на самом деле является нормальным.
Причина, по которой размещение в слоте работает нормально, заключается в следующем: когда сбор зависимостей достигает этой ref переменной, фактический уровень находится в дочернем компоненте. Поэтому, когда значение ref обновляется, текущий компонент не выполняет рендеринг, а дочерний компонент выполняет рендеринг, поэтому сам ref не изменится.
Что касается console.log, который приводит к сбою работы, причина в том, что сбор зависимостей собирает текущую ссылку на уровне компонента во время фазы сбора. Поэтому, когда его значение обновляется, запускается рендеринг, вызывая изменение ref.
Таким образом, становится более ясно: все компоненты с состоянием не должны использовать функциональные компоненты. В настоящее время компонентами, использующими функциональные компоненты, являются: Button, Menu, Msgbox, TaskItem и различные View. Среди них Menu и Msgbox являются компонентами с состоянием, и их следует разрабатывать как компоненты, отличные от функциональных.
Кстати, ранее упоминалось, что использование pinia может нормально работать с ShortcutView. Это легко объяснить: pinia не делает ничего особенного, просто передаёт значение как способ передачи props, так что состояние фактически находится в хранилище, а не в функциональном компоненте.
Почему Msgbox имеет три ref, которые могут нормально работать? Я предполагаю, что они, вероятно, помещены в слот Transition компонента, поэтому уровень рендеринга фактически снижается. Можно сказать, повезло.
Menu должен продолжать полагаться на удачу, помещая его в слот Transition для продолжения использования функциональных компонентов, или вернуться к шаблону компонента? Мне больше нравится второй вариант. Сегодня реализовал большую часть запланированных функций MenuCenter, осталась только одна — добавление задачи.
Ранее добавление задачи осуществлялось путём перетаскивания файла в браузер. Это позволяло получить двоичный поток файла напрямую. Однако если использовать строковый путь к файлу, то потребуется читать двоичный поток с помощью основного процесса и выполнять md5-считывание или добавлять на страницу элемент input. Этот вопрос ещё предстоит продумать.
2023-10-17
Сегодня я работал над меню:
2023-10-18
Успешно реализовал функцию выпадающего меню combobox. Кажется, нет особых мыслей по этому поводу. Возможно, это связано с моей простудой. Я искал информацию о том, как вызвать метод компонента Vue3 из родительского компонента. Ключевое слово для реализации этой функции — defineExpose. Это метод Vue 3 script setup для внешнего раскрытия метода компонента (примерно эквивалентно React useImperativeHandle + forwardRef). Что касается вызова метода в родительском компоненте, я не нашёл хорошего ответа в интернете, поэтому сам попробовал использовать vnode.component.exposed.
Осталось выполнить работу по очистке комментариев и реализовать логику закрытия меню при нажатии на маску. Также нужно разобраться с проблемой, связанной с закрытием меню при открытии нескольких вкладок браузера.
Также добавил ссылки на репозитории Gitee и TTQFTech.
2023-10-20
Указанная выше проблема с закрытием меню при нажатии на маску связана с тем, что после открытия меню несколько кнопок остаются активными. Необходимо решить эту проблему.
Основная проблема заключается в том, что после открытия меню кнопки сохраняют эффект mouseenter. Поскольку меню покрывает их слоем маски, необходимо найти способ передать события через маску. Я изучил разницу между mouseover (всплывает) и mouseenter (не всплывает), но эти методы не подходят для решения проблемы, так как они связаны с отношениями между дочерними и родительскими элементами, а здесь это не так.
Я придумал хакерский способ: после открытия меню запомнить положение нескольких кнопок, затем повесить событие на тело, которое будет отображать меню при наведении курсора на эти позиции. Но это вызывает другую проблему: при непосредственном нажатии на кнопку также срабатывает событие mouseup маски меню, и меню мгновенно закрывается.
Затем я придумал другой хакерский метод: после открытия меню создать невидимые элементы, соответствующие размеру кнопок, на теле, чтобы они могли получать события mouseup. Однако после закрытия одного меню и перед открытием другого может произойти преждевременное срабатывание события onClose предыдущего меню.
2023-10-22
Вот мои мысли:
При открытии меню: — Нужно реализовать переключение разных меню при перемещении курсора по разным кнопкам. Есть четыре способа сделать это: 1. Запомнить положение кнопок меню и повесить слушателя на тело; 2. Запомнить положение кнопок и создать элементы в тех же позициях; 3. Установить disableMask в MenuComponent; 4. Передать дочерние компоненты в MenuComponent и позволить им прослушивать события. — Нужно реализовать закрытие меню при поднятии курсора над пустой областью. Есть три способа сделать это: 1. Использовать событие cancel в маске MenuComponent; 2. Установить disableMask и использовать маску MenuCenter для прослушивания поднятия курсора; 3. Автоматически закрывать меню при поднятии большой кнопки, отслеживая это значение.
При открытии центра меню: — Нужно предотвратить закрытие меню при поднятии курсора. Все вышеперечисленные способы (создание новых компонентов в тех же местах или установка disableMask) могут быть использованы. Также можно отслеживать клики вместо поднятия курсора.
2023-10-23
Перед сном я подумал, что дизайн меню похож на игру в пятнашки. Если вы двигаете одну деталь, другие перестают работать. Если вы перемещаете B, C перестаёт работать, и так далее. Это похоже на то, как несколько компонентов взаимодействуют друг с другом.
В итоге я решил изменить слушатель MenuComponent на клик. Взаимодействие с меню центра становится самым обычным. При открытии меню центра взаимодействие с меню осуществляется с помощью добавления элементов на тело и закрытия меню с помощью комбинации действий: нажатие на пункт меню → showMenuCenter = 0 → selectedMenuIndex.value = -1 → menu.close().
Не ожидал, что меню станет самым сложным компонентом в FFBox.
Сегодня я хотел добавить автоматическую функцию поиска соответствующего пункта в подменю после монтирования компонента, но обнаружил, что управление клавиатурой не работает должным образом. Основная причина заключается в том, что я не до конца понимаю значение indexInFlattened, которое, вероятно, является комбинацией номера и ключа, что приводит к проблемам при переключении подменю.
Однако, учитывая объём проделанной работы, я решил зафиксировать предыдущие функции и продолжить работу позже.
Перед сном я исправил проблему с indexInFlattened в подменю, и всё заработало.
После этого я реализовал автоматическую функцию поиска соответствующих пунктов в подменю после монтажа компонента. Я разделил flattenedMenu на отфильтрованную версию и немного изменил calcSubMenuPosition, и это сработало.
Затем я составил черновик плана очистки меню. Обнаружил, что в Combobox ещё есть анимация и стили прокрутки, которые нужно реализовать.
Потом я также реализовал эту функцию. Шесть часов утра. Спать.
Планирую завершить реализацию меню центра, включая настройки, страницу вознаграждения и страницу разрешения, после чего добавить поддержку Alt-ключа и перейти к разработке гаммы, добавив тег.
2023-10-27
Последние несколько дней я продолжал работать над Combobox.
Основной задачей было заменить тип prop BasicMenuOption на MenuItem в списке Combobox. Для этого необходимо проанализировать, какие компоненты зависят от Combobox. Результаты неплохие: только параметры vcodecs/acodecs/formats и VcodecView/AcodecView зависят от этих списков. Изменение параметров несложно, достаточно просто изменить тип данных. Объём изменений довольно большой, несколько тысяч строк изменены. Хотя изменение такого большого количества параметров, зависящих от типа данных меню, не кажется идеальным решением, ранее оно использовалось таким же образом. После этого изменения данные будут более согласованными. Кроме того, во время этой работы я узнал о некоторых функциях TypeScript: защита типов, сужение типов и извлечение подтипов из объединённых типов.
Завершив эту работу, я наконец смог продолжить разработку меню разрешения с разделением на группы и разрешением экрана.
Опять же, возникли некоторые проблемы с обработкой событий клавиатуры. Раньше мой подход к дизайну меню заключался в следующем: когда нажимаются клавиши со стрелками влево и вправо, в зависимости от наличия подменю определяется, обрабатывает ли событие меню или передаёт его наружу. Когда дело дошло до Combobox, события клавиатуры сначала обрабатываются Combobox, а затем передаются в MenuComponent для принятия решения. Здесь мне нужно позволить MenuComponent повторно передавать эти события в некоторых случаях. Проблему бесконечного цикла легко решить, но основная проблема заключается в невозможности повторного запуска dispatchEvent для одного и того же события, поэтому я попытался создать новое событие KeyboardEvent самостоятельно. Затем, согласно статье, которую я прочитал, созданные мной события клавиатуры нельзя использовать для ввода текста. Поэтому мне пришлось самому определять нажатые клавиши и управлять перемещением курсора ввода. Этого оказалось достаточно для достижения желаемой функциональности. ↑Примечание: на самом деле это не идеально, функция выбора исчезла, и я пока не планирую её восстанавливать.
Наконец, я добавил некоторую информацию в readme.md и переместил основную ветку репозитория на 4.0+.
Последним дополнением стало обновление списка разрешений с длинным списком разрешений эпохи 1.0 до более короткого формата.
2023-10-29
Реализовал функцию сканирования строк и изменил tooltip для MenuItem. Также добавил функцию проверки для Combobox аналогично Inputbox.
2023-10-30
Автоматически фокусируюсь на соответствующем пункте при открытии меню. Пересмотрел функции MenuComponent и добавил комментарии. Затем исключил один шаг в onMounted.
2023-11-04
Разработал боковую панель и содержимое меню центра, включив панель вознаграждений.
Во время разработки боковой панели возникла проблема с созданием значка Ko-Fi — свойство viewBox не работало. После ручного редактирования SVG, удаления лишних тегов и копирования других SVG для изменения путей и размеров, я обнаружил, что проблема, скорее всего, связана с загрузчиком SVG: если размеры SVG совпадают с размерами viewBox, viewBox будет удалён. Решение состоит в удалении атрибутов ширины и высоты. Не ожидал столкнуться с проблемами загрузчика SVG. Год за годом одно и то же: то, что делаешь, не нравится, а если не делаешь – тоже не нравится. Не загадываешь желание – плохо, загадываешь – ещё хуже. Есть идея – плохо, нет идеи – опять плохо. Идёшь по течению – плохо, против течения – тоже плохо. Иногда бывает хорошо, непонятно почему. В общем, выбирай, комбинируй, но в итоге всё равно получается «плохо».
Я не атеист, у меня есть свой бог, которому я не дал имени. Обычно я не верю в этого бога, но, как было сказано выше, верить плохо, не верить – тоже плохо.
С точки зрения более высокой размерности пространства, куда бы я ни шёл в направлении меньшей размерности, результат всегда оказывается в худшем направлении. Я не могу контролировать пространство более высокой размерности и поэтому не могу вернуться назад. Хотя идти по течению или против него одинаково плохо, идти против течения всё же менее привычно. Поэтому можно попробовать пойти против течения.
В этом году на Новый год я загадал желание: «Надеюсь, что следующий год будет ещё хуже, чем 2023-й!» ❤️
Запланированная на 24 января публикация была отменена.
На последней неделе прошлого года я смотрел материалы о спецэффектах с матовым стеклом.
Проще говоря, Microsoft в этой области делает просто кучу дерьма.
Начиная с эпохи Windows Vista, Microsoft внедрила полупрозрачные размытые спецэффекты. Тогда API был довольно простым, и для использования эффектов было достаточно использовать такие функции, как DwmExtendFrameIntoClientArea, DwmEnableBlurBehindWindow и SetWindowLong. Кроме того, они выглядели красиво. Позже даже добавили эту функцию в Windows XP, например, в TrueTransparency, которую я использую.
Начиная с Windows 8, Microsoft сократила количество дизайнеров, объясняя это «плоским дизайном» и «экономией ресурсов», в результате чего пользовательский интерфейс стал выглядеть ещё более рваным и уродливым. Код для полупрозрачных размытых эффектов, по слухам, сохранился, поэтому до некоторых версий Windows 10 можно было включить этот эффект с помощью некоторых хаков (например, я использовал AeroGlassforWin10), и качество заметно улучшалось. К сожалению, хак остаётся хаком, он не поддерживается по умолчанию, поэтому некоторые программы, обнаружив, что они работают на Windows 8 или подобных условиях, сразу же отключают эффекты матового стекла, и хак работает только со старыми программами. Более того, с изменением версий Windows эти программы также должны постоянно обновлять файлы символов, после чего их нельзя использовать, и приходится переходить на другие, такие как WinCenterAero. Но в целом эффект виден только в строке заголовка, где часто возникают ошибки, и он не сочетается с современным дизайном.
Windows 10 наконец добавила эффект Mica, который отличается от матового стекла более мягким и размытым стилем. Однако самое важное заключается в том, что этот API не открыт для приложений Win32, а доступен только для собственных фреймворков, таких как WPF!
Позже, когда я работал над FFBox 3.0, я обнаружил, что люди используют недокументированный API SetWindowCompositionAttribute. Я попытался вызвать его с помощью C++. Это не идеально, но работает. То есть окна потеряли тени, анимация масштабирования исчезла, Snap больше не работает, но эффект матового стекла достигнут. На тот момент это было приемлемо, поскольку можно было выбрать несколько стилей, так что API отличался от эпохи Vista.
Затем появилась Windows 11, и после выпуска 22H1 (примерно в это время) мой FFBox сломался — перемещение окон стало очень медленным, особенно если у вас плохая видеокарта, это было неприятно. В списке проблем FFBox появился этот.
Даже если никто не сообщал мне об этой проблеме, она всё равно неприемлема для меня. Цена слишком высока. Дизайн версии 4.0 также не предусматривает полупрозрачных окон.
К 22H2 недокументированные полупрозрачные размытые эффекты для Win32 наконец-то были открыты. По крайней мере, так предполагается, основываясь на новых функциях electron. BrowserWindow имеет новую функцию setBackgroundMaterial, что означает, что Microsoft наконец-то решила соединить эту цепочку.
Поэтому я обновил electron с версии 23 до версии 24. API есть, но он работает только с заголовком, клиентская область полностью бесполезна.
Я поискал информацию. Эта функция обсуждалась ещё в 2021 году в [Feature Request]: Use new 'Mica' material for BrowserWindow vibrancy in Windows 11 (https://github.com/electron/electron/issues/29937). Там кто-то использовал node-модуль для вызова Windows API и добился определённого эффекта полупрозрачности, а кто-то создал несколько стилей с использованием фреймворка flutter. Также упоминается возможность использования mica-electron, сторонней библиотеки.
Поддержка этой функции в electron, вероятно, началась с PR:feat: support Mica/Acrylic on Windows в 2023 году. Некоторые пользователи выразили удовлетворение, но большинство из них сообщили о проблемах с работой только строки заголовка.
PR:fix: frameless mica/acrylic windows в сентябре 2023 года утверждает, что проблемы безрамочных окон решены. Я думаю, что достаточно обновить до версии 27, и многие связанные проблемы были решены, и это должно работать лучше. Поэтому я обновил версию electron до 28. Результат:
transparent: true,
frame: false,
При такой комбинации эффект есть, но тени, закруглённые углы и максимальное увеличение при потере фокуса исчезли, и размер окна нужно настроить, чтобы эффект работал. При потере фокуса появляется раздражающий тёмно-голубой заголовок.
Проблемы с отсутствием теней и закруглённых углов не решаются установкой thickFrame: true
и hasShadow: true
.
transparent: false,
Эффект отсутствует при отключении прозрачности.
transparent: true,
frame: false,
Эта комбинация даёт эффект, но добавляет ненужную строку заголовка. Кроме того, само окно имеет цвет, прозрачность применяется только к материалу Mica, и она не распространяется на области за пределами окна.
titleBarStyle: 'hidden'
Эквивалентно frame: false.
Другими словами, electron всё ещё не исправлен.
Наконец, я увидел PR:fix: titlebar incorrectly displayed on frameless windows, который ещё не завершён. Этот PR стал «merged» в день, когда я писал журнал, то есть придётся подождать некоторое время, прежде чем увидеть эффект.
Итак, я попробовал mica-electron, третью библиотеку. Это тоже было непросто.
Сначала я попытался скомпилировать модуль узла в соответствии с его readme. Он жёстко закодировал компиляцию в каталог src. Затем компиляция не удалась, и весь каталог src был удалён. Спасибо тебе🙃. Хорошо, что я использую git для управления кодом и у меня открыто много вкладок в vscode, иначе мне пришлось бы заново редактировать временный CSS.
Потом я понял, что у него есть собственный файл .node. Поэтому я подумал, что попробую использовать скомпилированный файл напрямую.
Однако это оказалось не так просто — vite не поддерживает импорт файлов .node.
Согласно issue: Cannot bundle .node files, vite в настоящее время не интегрирует поддержку .node, и, похоже, нет никаких движений (последний раз активность была в сентябре 2023 года). Однако автор проблемы упоминает, что он пробовал несколько плагинов. Хотя он говорит, что это не сработало, я сам попробовал один из них (vite-plugin-native) и смог его использовать — едва.
Пока я пытался использовать electron 28 в сочетании с mica-electron, возникли проблемы, такие как отсутствие анимации масштабирования и появление уродливой синей рамки при потере фокуса. Решение состоит в возврате к версии electron 24. Тем не менее, новые окна, созданные с помощью mica-electron, всё ещё имеют проблему с уменьшением размера окна до минимума.
Дерьмо!
Что касается полупрозрачных размытых спецэффектов, существует три набора связанных API: Windows Vista, Windows 10 и Windows 11. На официальном сайте Microsoft для разработчиков Desktop Window Manager примеры всё ещё показывают устаревшие API Windows Vista, которые больше не поддерживаются, хотя новые операционные системы уже доступны.
С экологической точки зрения electron является продуктом GitHub, дочерней компании Microsoft, и electron и Windows должны работать вместе, как братья и сёстры, но эта функция разрабатывалась несколько лет? Несколько крупных обновлений electron прошли без улучшения.
Дерьма становится всё больше, и Microsoft не может справиться с этим.
Каковы следующие шаги? Попробовать два других загрузчика .node согласно issues/14289? Или согласно issues/29937? Brouilles: попытка реализации с использованием Windows API?
Описание проблемы:
В тексте описывается попытка автора реализовать эффект матового стекла в Windows с помощью Windows API. Автор описывает свои попытки использовать различные методы и инструменты для достижения этой цели, а также возникающие при этом проблемы и ограничения.
Автор начинает с описания различий между эффектами матового стекла в Windows 10 и Windows 11, а затем переходит к описанию процесса установки и использования Windows SDK 22621 для реализации эффекта матового стекла на Windows 11. Он также обсуждает необходимость добавления дополнительных обработчиков событий и настройки для обеспечения корректной работы эффекта.
Далее автор описывает процесс создания нового файла mica.ts для управления событиями и таймерами, а также реализацию трёх функций: включение эффекта, выключение эффекта и включение отрицательного поля. Однако он отмечает, что после некоторого времени работы программы возникают проблемы с её реакцией на действия пользователя.
Наконец, автор решает отказаться от дальнейшей работы над эффектом матового стекла, ссылаясь на отсутствие интереса и возможные проблемы с производительностью и внешним видом эффекта. Вместо этого он решает сосредоточиться на создании лицензии для своего программного обеспечения.
Перевод кода и специальных символов:
Текст не содержит кода или специальных символов, требующих перевода. В запросе представлен текст технической направленности из области разработки и тестирования программного обеспечения. Основной язык текста запроса — китайский язык.
Перевод текста на русский язык:
VS предоставляет способы разработки. Помимо традиционного C#.NET, который я использовал, существует множество других фреймворков. M$ действительно разработал много таких вещей.
В написании первого приложения Windows — Training | Microsoft Learn Microsoft представила несколько фреймворков для создания приложений Windows.
— Во-первых, это Win32, чистая нативная разработка, самый традиционный способ, создание окна через вызов Windows API. Это окончательный выбор на данный момент. — Затем идёт Windows Forms. Это то, что я упоминал ранее — C#.NET. Я попытался использовать .NET 4.7.2 и .NET 6.0 для создания двух проектов. На самом деле только использование старого фреймворка .NET 4.7.2 является нормальным, размер сгенерированного приложения составляет всего 8 КБ, а запуск занимает полсекунды. А при использовании проекта .NET 6.0 даже панель инструментов пуста, размер созданного пустого оконного приложения составляет 146 КБ, но запуск слишком медленный, целых 3 секунды, что не может быть принято. — Далее идёт UWP. Это фреймворк, который Microsoft разработала с Windows 8. Насколько я помню, скорость запуска этого фреймворка также очень впечатляет, возможно, требуется всего 0,2 секунды, чтобы создать окно. В конце концов, окно, вероятно, опирается на системный процесс (я тоже не понимаю, просто предполагаю). Но теперь, похоже, больше нельзя создавать новые приложения UWP, после того как я установил «универсальный» материал с помощью Visual Studio Installer, Visual Studio позволяет мне создать проект только с «Windows Application Packaging Project», без «пустого приложения». Кроме того, Microsoft также упоминает в нескольких местах, что UWP считается WinUI 2, и Microsoft рекомендует использовать WinUI 3. Таким образом, UWP пока не рассматривается. — Затем есть WPF. При попытке использования я обнаружил только .NET 6.0, пока не написал здесь, я не обнаружил, что можно использовать .NET 4.7.2, и скорость запуска аналогична использованию Windows Forms. Так что, может быть, WPF просто заменяет Form Designer на XAML? Можно исследовать позже. — Наконец, есть Win UI 3. Но самое большое препятствие для этого заключается в том, что его необходимо опубликовать в магазине Microsoft, чтобы запустить в режиме выпуска, и он не является независимым exe, а сопровождается множеством dll, которые напрямую передаются.
Наконец, я выбрал нативную разработку Win32. Основная причина в том, что Windows сама написана на C++, поэтому функции, предоставляемые Windows API, использующие C++ являются наиболее оригинальными, теоретически легче найти учебные пособия и помощь, и степень свободы должна быть самой большой, удобно реализовать собственные эффекты. Кроме того, он не использует фреймворк .NET, теоретически загрузка будет немного меньше.
Просто это не так просто, как предполагалось:
Есть две проблемы, которые нужно решить: первая — как использовать Windows API для создания окна, вторая — как рисовать графику. Создание окна относительно просто, я спросил Copilot, поискал в Интернете, как создать новое окно в консольной программе, и сравнил его с приложением Windows с графическим интерфейсом, которое я сделал несколько лет назад с использованием MFC, и проблема была легко решена. Что касается рисования, Copilot предложил мне использовать GDI+ для реализации. Это также относительно просто. Как реализовать прозрачное окно? Copilot сказал мне создать многослойное окно (WS_EX_LAYERED). Прозрачное окно, с которым я играл с начальной школы, впервые ощутил его странность —
Во-первых, если указан только стиль WS_EX_LAYERED, окно сразу исчезнет. Обычно люди вызывают функцию SetLayeredWindowAttributes, передавая alpha и colorKey, чтобы сделать окно полупрозрачным, и окно появится. Но я хочу, чтобы альфа-канал позволял мне самому рисовать, а не делать всё окно полупрозрачным. Дальнейший поиск обнаружил код для создания полупрозрачного окна и рисования простого графика. После понимания того, что такое DC, HDC, CDC, hBitmap, bitmap и другие странные концепции, и после многократного переключения различных констант, я в основном реализовал желаемый эффект и понял следующие принципы:
Когда окну присваивается стиль WS_EX_LAYERED, оно больше не отображается, и событие WM-PAINT больше не используется для рисования. Вместо этого UpdateLayeredWindow используется для наложения изображения на многослойное окно. Функция SetLayeredWindowAttributes делает так, что хотя окно и является многослойным, оно отображает содержимое исходного окна, продолжая использовать старый способ рендеринга, и нет необходимости использовать UpdateLayeredWindow.
Многослойное окно — это странный метод. Например, кажется, что содержимое окна основано на экране для позиционирования! То есть, когда вы создаёте окно, указанное местоположение не используется, и местоположение обновления экрана указывается при вызове UpdateLayeredWindow! Но когда вы думаете, что область холста — это весь экран, это неправильно, потому что в эскизе панели задач можно увидеть область окна, которая соответствует размеру изображения! И если изображение пустое, мышь будет иметь проникающий эффект в пустой области! Кроме того, есть ещё одна странная вещь: если я не устанавливаю многослойное окно, а вместо этого устанавливаю hbrBackground в 0 при создании обычного окна, фон окна будет вырезан из экрана pia в моё окно! Поскольку я не установил высокое разрешение DPI, это особенно заметно. Ещё более странно: вернёмся к многослойному окну, если я захочу нарисовать линию или прямоугольник для отображения прогресса в изображении, что мне делать? Я спросил Copilot, и он дал мне ответ. Затем форма, нарисованная таким образом, смешивается с содержимым позади окна в стиле «наложения»! Я никогда не видел такого странного окна. Часть изображения отображается нормально, а формы, такие как прямоугольники и линии, которые я рисую сам, смешиваются с содержимым за окном в стиле «наложения». Одно и то же окно может иметь разные методы смешивания? Есть ли канал, кроме RGBA, который записывает смешанный метод? Я не понимаю, и Copilot тоже.
Кроме того, использование DC и других вещей всё ещё слишком странно. Функции иногда находятся в одном заголовочном файле, иногда в другом; иногда HDC вызывается напрямую с передачей ссылки на функцию, иногда используется оператор члена класса для вызова DC и bitmap... Я спросил своего одноклассника, и он сказал, что GDI+ слишком старомоден. Я думаю, что это правда. Есть ли более современный способ? Direct2D / Direct3D.
Этот подход также имеет очевидные недостатки: он слишком сложен. Я нашёл статью: Нарисуйте полупрозрачное окно с помощью DirectX (●'◡'●) — Zhihu. Хотя тон статьи довольно лёгкий, объём кода составляет несколько экранов, и его трудно понять. Затем я нашёл другую статью: Ваш первый план Direct2D. Я переписал код в соответствии со статьёй (поскольку она использовала классы, а я нет) в существующем проекте, и успешно реализовал ожидаемый эффект. Но это только для непрозрачных окон. Если вы хотите реализовать полупрозрачный эффект, вам всё равно придётся использовать Direct3D. К этому времени Copilot уже не мог помочь, поэтому основной код по-прежнему взят из вышеупомянутой статьи на Zhihu. Это заняло у меня много времени. Поскольку я плохо знаком с C++, это заняло много времени, и даже компиляция не удалась. Изучение шаблонов, std::format, unichar; изучение throw; из-за предложения #undef interface, приводящего к конфликту включения между верхним и нижним уровнями; из-за отсутствия указания размера окна, что приводит к сбою создания SwapChain; поиск ComPtr — что это такое... всевозможные вещи заняли много времени, но, наконец, удалось нарисовать прямоугольник на полупрозрачном окне.
Наконец, это рисование изображений на основе DirectX. В этой области я ссылаюсь на код [Direct2D] для рисования растровых изображений. Рисование изображений с помощью DirectX немного сложнее, чем с GDI+, поскольку вам приходится самостоятельно обрабатывать декодирование и тому подобное. Здесь ведущий не предоставил ключевую функцию LoadBitmapFromFile, которая была добавлена только после того, как кто-то спросил в разделе комментариев: Как загрузить растровое изображение Direct2D из файла — Win32 apps | Microsoft Learn. Наконец, после некоторой возни, мне удалось отобразить изображения и текст на полупрозрачном окне.
Теперь, когда приложение создано, размер составляет более 200 КБ, время запуска — 0,3 секунды. Затем я сравнил память, вау, 18 МБ памяти, 68 МБ при отправке, что более чем в два раза превышает размер версии C#.NET. Почему бы мне не использовать C#.NET? На самом деле это связано с моей идеей о взаимосвязи вызовов между приложениями. Моя идея состоит в том, чтобы поместить это окно в FFBoxHelper и позволить ему запускать FFBox, поэтому я использую C++. Хотя, вероятно, есть лучший способ, но неважно, раз уж это сделано, пусть будет так.
Технически осуществимо, следующим шагом будет реализация функций. Написал более 5000 слов журнала, почти вырвало. 那样。但是 это опять затрагивает некоторые концепции, которые я не понимаю, например, std::future и std::packaged_task.
Я попытался запустить программу, но она не работала. Тогда я выбрал другой подход и создал ещё один поток для ожидания завершения работы потока initSplashScreen, а затем вывел результат.
Вывод: поток initSplashScreen как будто застрял на половине выполнения.
Тогда я решил добавить вывод cout в ключевые действия в initSplashScreen, чтобы понять, где возникает проблема.
Результат: проблема была в функции ShowWindow. Я подумал, что если убрать действие WM_SHOWWINDOW, то проблема останется? Эксперимент показал, что тогда программа работает без проблем.
То есть проблема была в zhihuPaintPrep. Но как узнать, какое именно действие вызывает ошибку?
Я не стал выводить каждое действие с помощью cout, а посмотрел на существующую функцию TryThrow. Почему ошибка не была выдана после возникновения? Я не знаю, но я изменил throw на std::cout. Так я увидел проблему — в функции CreateDXGIFactory2 возникла ошибка 0x887a0001. На этой странице можно найти описание ошибки: «Приложение предоставило недопустимые данные».
Но я не разбираюсь в DirectX, и я понятия не имею, какие данные были недопустимыми. 🙈~
Я заметил слово «DEBUG», которое показалось мне подозрительным, и попробовал изменить значение DXGI_CREATE_FACTORY_DEBUG на 0. И это сработало! Окно было успешно создано!
ヽ(‘ー`)ノ Это было действительно сложно...
Наконец, я попытался сделать заставку более привлекательной — сначала я попытался заставить индикатор прогресса светиться.
Я прямо сказал Copilot, что мне нужно, и он ответил, что нужен эффект CLSID_D2D1Glow.
Не знаю, откуда он взял CLSID_D2D1Glow, его нет в документации Microsoft, и поисковые системы тоже не могут его найти.
В официальном примере Microsoft для создания теней указано, что тени создаются с использованием CLSID_D2D1Shadow. Однако этот пример кода довольно сложный, и я не могу его понять. Поэтому я снова обратился к Copilot и на основе этого примера создал прямоугольник с тенью. После некоторого экспериментирования с кодом я пришёл к следующим выводам:
Что касается эффекта тени, он не применяется к отдельным прямоугольникам или кистям, а через SetInput применяется ко всему bitmap, который затем рисуется на renderTarget с помощью DrawImage.
В итоге я решил, что не буду разбираться в этом.
Это действительно сложно понять. Всё, что связано с Bitmap и Image, легко реализовать для рисования отдельных элементов, но становится непонятно, когда дело доходит до нескольких элементов.
Я создал отдельную функцию drawRectWithShadow для рисования прямоугольника с границей и эффектом. Функция создаёт новый renderTarget, рисует прямоугольник, применяет эффект, а затем рисует результат на внешнем DC.
Какие проблемы могут возникнуть? Например, если не использовать EndDraw и BeginDraw между двумя операциями рисования, результаты будут накладываться друг на друга, и цвет кисти первого прямоугольника может быть применён ко второму прямоугольнику. Какова цель EndDraw? Применить операции рисования к bitmap? Нет. Если нарисовать прямоугольник на новом renderTarget, применить эффект, а затем очистить renderTarget, эффект не будет отображаться на DC. Моя идея состоит в том, чтобы сначала нарисовать прямоугольник и эффект, затем выполнить резкость на всём изображении и перенести его на DC. Что произойдёт, если я нарисую прямоугольник и добавлю эффект, а затем применю эффект к текущему bitmap? Ответ: результаты будут наложены друг на друга, и цвет кисти первого прямоугольника будет применён ко второму.
Хорошо. Слишком сложно, я не буду этим заниматься. C++ не подходит для разработки интерфейсов. Не так красиво, ну и ладно.
Наконец, я изучил дорогостоящие операции во время запуска FFBox и разделил процесс запуска на пять этапов. Код есть, поэтому я не буду повторять его здесь.
Кроме того, этот коммит также включает некоторые небольшие изменения в других местах, таких как удаление опции языка и очень простой механизм лицензирования (который будет улучшен позже).
Первоначально опция языка была добавлена для привлечения носителей кантонского диалекта и защиты кантонского языка. Причина её удаления связана с динамикой и неопределённостью отношений между языками и диалектами. Подробную причину можно увидеть в B-канале, здесь я не буду вдаваться в подробности.
Что касается механизма лицензирования, я знаю, о чём вы думаете. Да, это просто формальность. Никто не может реально помешать кому-то использовать моё программное обеспечение, если он оскорбляет чьи-то чувства. Это похоже на то, как я не могу избежать причинения вреда себе, оскорбляя чьи-то чувства. Однажды я был похож на Джокера. 💔
Могут ли люди быть искренними по отношению друг к другу? Я не знаю. Но если вы хотите, чтобы другой человек был искренним, вы должны сначала быть искренним сами. Это моя позиция и мой первый принцип.
Итак, используете ли вы моё программное обеспечение искренне? Хотите ли вы стать моим другом искренне?
FFBox приветствует всех, кто хочет построить лучший мир. ❤️
Работа над заставкой заняла два месяца. На самом деле это не заняло столько времени. Просто было немного сложно. Хотя FFBox является важным произведением в моей жизни, известно, что моя основная задача — не писать эту программу. Конечно, я не собираюсь раскрывать свою основную задачу в этом журнале. В общем, в течение месяца я испытывал сильное психологическое давление, а в следующем месяце я сначала получил удар ножом в сердце, а потом физически заболел (необъяснимо заболел после десяти лет отсутствия такой длительной болезни). Только в марте я начал работать. И я хочу вернуться к программному обеспечению, которое я хотел написать десять лет назад. Оно ждало меня слишком долго. Я потратил полмесяца, чтобы начать его. Я написал первую точку.
Вернитесь к моему FFBox. Теперь, глядя на список функций в очереди, сравнивая мои навыки разработки и скорость, кажется, что завершение далеко. А эта версия почти готова к выпуску через два года. С точки зрения локального опыта, FFBox уже готов. Итак, я планирую исправить несколько оставшихся мелких проблем, а затем выпустить его. Дата выпуска назначена на 23 марта. Но позже я решил отложить выпуск до 1 апреля.
Потому что внезапно сказать «выпустить» — значит выпустить, слишком поспешно 😂. Во-первых, Windows в порядке. Но macOS, я не прошёл обычный процесс. macOS имеет песочницу, поэтому для вызова двоичных файлов, таких как ffmpeg, нельзя просто написать «ffmpeg» и позволить системе автоматически находить переменные среды и ffmpeg в той же папке, как в Windows. Эта проблема всё ещё может быть решена в версии 3.0, просто открыв пакет и выполнив Contents/MacOS/FFBox, чтобы вызвать системный ffmpeg. Теперь, помимо ffmpeg, есть отдельный FFBoxService, который нужно вызывать отдельно. Где его искать?
После некоторых исследований я пришёл к выводу, что macOS должна самостоятельно объединять полный путь. FFBoxService упакован вместе с пакетом, и его можно объединить с resourcesPath. Что касается ffmpeg, я планировал найти его в двух местах: /usr/local/bin/ и Resources. Также измените подсказку, если ffmpeg не найден.
Однако это неправильно (≧▽≦). FFBoxService запускается в среде, созданной pkg, а не electron, и у него нет resourcesPath 🤷♂️.
Дальнейшее расследование показало, что после упаковки приложения node с помощью pkg __dirname и __filename будут отображать путь /snapshot/FFBox/app/backend
, то есть путь внутри области действия pkg является виртуальным. Если вы хотите использовать полный путь уровня FFBoxService в производственной среде, используйте process.execPath для объединения.
Таким образом, проблема с вызовом FFBoxService и ffmpeg на macOS была решена. Осталось только привести код в порядок. Позже я также добавлю некоторые функции, которые будут отображать соответствующую информацию, если ffmpex отсутствует, на основе операционной системы сервера.
Далее предстоит ещё немного работы: добавить состояние переподключения сервера после потери соединения и чётко различать его с состоянием первого подключения (уже частично сделано); адаптировать веб-страницу; при наличии возможности настроить Linux-виртуальную машину для соответствующей адаптации. А также FFBox 官网
Если сайт разработчика похож на тот, что описан в тексте, то это очень плохо. Поэтому в выходные я потратил несколько часов на размышления о том, как должен быть разработан новый сайт.
2024-03-26
«Оптимизация логики первого/некоторого соединения с локальным/удаленным сервером» — проще говоря, это оптимизация работы кнопок закрытия вкладок и отображения серверов, а также определение того, когда IP-адрес должен быть localhost и не может быть изменен, и когда localhost автоматически заменяется на 127.0.0.1. «Поддержка работы браузера» — это обеспечение бесперебойной работы цепочки «подключение к серверу — загрузка — перекодировка — скачивание».
2024-03-28
Последний пункт поддержки операционной системы — Linux. В общем, мое личное ощущение заключается в том, что *nix-системы все еще слишком сложны для обычного пользователя. Что касается моего личного опыта, использование такой системы похоже на вождение автомобиля: нужно разбираться в работе аккумулятора, знать, как вручную запустить двигатель, если аккумулятор разряжен, или заменить шины при проколе...
Я выбрал Deepin. Эта система поддерживает отечественные разработки. Четыре года назад я использовал ее для создания FFBox версии 1.x. Когда я достал свой старый виртуальный компьютер, проблем оказалось предостаточно... Во-первых, VSCode устарел, многие функции, вероятно, больше не работают, поэтому я решил обновить его. Я скачал deb-пакет с официального сайта и установил его. Но возникла ошибка: «Зависимости не удовлетворены: visual-studio-code». Конечно, попытка установить его через терминал также не увенчалась успехом: «Невозможно исправить ошибку, потому что вы требуете сохранения некоторых пакетов в текущем состоянии, но они нарушают зависимости между пакетами». На форумах говорят, что это связано с конфликтом с версией магазина. Тогда я открыл магазин — и столкнулся с ошибкой сети. Я подумал об обновлении магазина, но на главной странице Deepin не было никаких ссылок. Я начал искать другие способы. Например, я отредактировал файл /etc/hosts, добавив строку «36.248.208.254 cdn-package-store6.deepin.com», а затем выполнил команду apt update. Команда apt update часто сталкивается с проблемой невозможности получения блокировки /var/lib/apt/lists/lock. В этом случае ни один другой apt не работает. Я попытался перезапустить рабочий стол с помощью команды service lightdm restart, но блокировка осталась. В итоге я просто удалил ее с помощью sudo rm. После этого команда apt update заработала. Однако она выдала ошибку «NO_PUBKEY 3B4FE6ACC0V21F32», связанную с отсутствием публичного ключа и невозможностью проверки подписи. Есть способ решить эту проблему: удалить в файле /etc/apt/sources.list неподтвержденные источники. После удаления всех источников проблема не исчезла. Другой способ — выполнить команду «apt-key adv --keyserver keyserver.ubuntu.com (этот адрес можно изменить) --recv-keys [вышеупомянутая строка]». Но после этого появилась ошибка «Не удалось запустить dirmgr '/usr/bin/dirmgr' — файл или каталог не найден». К счастью, команда apt install dirmgr была выполнена успешно, и ключ был успешно добавлен. Но это не помогло. Я пропустил одну строку: «gpg -a --export [строка] | apt-key add -». Кто-то подсказал мне добавить эту строку, и тогда все заработало. Затем я снова выполнил команду apt update. Появилась ошибка «Невозможно получить статус /var/lib/apt/lists/partial/[несколько строк]...». Я удалил папку partial, и проблема была решена. На форуме предложили использовать команду apt dist-upgrade для обновления всех зависимостей. Я решил попробовать, чтобы обновить все старые зависимости. После нескольких десятков минут выполнения появилась ошибка E: Sub-process /usr/bin/dpkg returned an error code (1). Я не знаю, что такое dpkg. Команда apt предложила выполнить команду apt --fix-broken install, что я и сделал. Затем dpkg снова выдал ошибку. После нескольких попыток выполнения этих команд у меня перестала работать функция включения питания. Я перезагрузил компьютер, но даже рабочий стол не загрузился. Ну что ж...
Решил установить новую версию Deepin. Скачал образ за 5 минут и установил за 5 минут. Переустановка оказалась быстрее, чем решение проблем. Новая версия Deepin больше похожа на UOS. Сейчас не время обсуждать это. Вернемся к FFBox.
Проблемы с Linux по-прежнему связаны с двумя аспектами: FFBoxService и вызов ffmpeg. Подведем итоги.
[Обеспокоенный] Последние дни я засыпаю только после рассвета. Это действительно утомительно — делать многоплатформенное приложение.
Кроме того, во время разработки я также исправил небольшую ошибку: запуск FFBoxService не успевал за запуском рендерера, что приводило к сбою при первом входе в систему. Также в среде разработки deepin я не смог нормально запустить процесс рендеринга, который выдавал ошибку. Эту ошибку я планирую исправить позже. Также я добавил ограничение на размер загружаемых файлов в 100 МБ, чтобы предотвратить сбой страницы из-за CryptoJS.
2024-04-01
Последние несколько дней я занимался разработкой веб-сайта FFBox.
Наконец, я обновил значки для трех платформ (хотя deepin Linux не поддерживает png, требуется icns), а также обнаружил, что LICENSE на Linux и macOS неправильно считывается, и исправил это. Все готово!
Желаю всем приятного использования!
2024-06-04
Недавно я совершил две поездки и обнаружил множество ошибок, некоторые из которых были унаследованы с 2023 года... Раны накладываются друг на друга, делая меня немного чувствительным, забывчивым и ленивым... Затем, из-за обновления Euro Truck Simulator 2 до версии 1.50, я снова увлекся гоночными играми... Это определенно нехорошо. Подожду, пока я решу, что сказать, прежде чем обновлять LICENSE... Я действительно не понимаю, я никогда не хотел никому навредить, почему люди могут так легко говорить и делать вещи, не заботясь о чувствах других... И почему я веду себя таким образом? Является ли это результатом прошлых травм или посттравматического стрессового расстройства?... Это действительно сложно.
Вернемся к FFBox. Продолжаем разработку версии 4.1, и я думаю о том, какие улучшения внести. Возможно, трудно выделить одно «самое желаемое», но есть некоторые общие идеи. Я планирую поработать над некоторыми вещами, связанными с «цифровыми единицами». Во-первых, «предполагаемое оставшееся время» не требует такой точности. Во-вторых, маленькие синие полосы рядом с «временем» и «кадром» кажутся ненужными, поскольку уже существует больше элементов, способных выразить ход задачи. В-третьих, я надеюсь, что при наведении курсора на определенные элементы отображения появится другое представление единиц. Затем я хочу привести в порядок utils (поскольку для реализации переключения единиц необходимо прочитать настройки), а затем сделать формат более понятным. Окончательная идея состоит в том, чтобы сначала изменить текущие параметры. Вместо того чтобы позволить common/utils читать settings, лучше позволить контроллеру выполнять форматирование, а ранее преобразованные предустановки теперь должны быть преобразованы в текстовые форматы. Музыка и установочные пакеты для Music и NetEase Music практически неотличимы.
Он может вызывать duilib из C++ для создания пользовательского интерфейса. Принцип заключается в том, чтобы предоставить функцию, которая будет создавать компоненты с помощью традиционного графического интерфейса пользователя (GUI). Это слишком сложно, и я, как фронтенд-разработчик, не могу смириться с тем, что для создания установочного пакета нужно возвращаться к традиционному режиму разработки.
NSIS — это уникальный язык сценариев, похожий на макроассемблер, со странным синтаксисом. Однако его функциональность считается мощной, он может вызывать Windows API и поддерживает динамические библиотеки расширения. Хотя его синтаксис немного странный, на самом деле он не так сложен для изучения, по крайней мере, по сравнению с Pascal, его легче освоить. (Источник также упоминает платный шаблон Inno, такой как nsetup.)
Наконец-то удалось наладить процесс упаковки! Это было непросто... Никто не следит за прогрессом FFBox, разработчик расслабился, сбился с пути и углубился в детали. Оглядываясь назад, с чего всё началось? Почему другим платформам не нужно заниматься этими вещами, а только Windows? Другие платформы могут генерировать установочные пакеты с помощью electron-builder, но почему Windows не может сделать то же самое? Разве electron-builder не поддерживает создание установочных пакетов с использованием NSIS? Всё это происходит от FFBoxHelper, от экрана приветствия, от желания улучшить скорость загрузки на несколько секунд. Это безумие, и цена слишком высока.
Возвращаясь к теме, я в конечном итоге выбрал Inno Setup. Основная причина в том, что люди говорят, что Inno Setup проще, чем NSIS, и его язык программирования Pascal (точнее, Pascal Script) более универсален, чем «пользовательский» язык NSIS.
Сначала я посмотрел несколько обучающих видео на Bilibili, чтобы получить общее представление о его структуре. Затем я попытался установить Inno Setup самостоятельно и использовал его мастер для создания базовой рабочей версии. Затем я нашёл проект в качестве шаблона для модификации. Конфигурационная часть относительно проста для понимания. Кроме того, проблема медленной скорости может быть решена путём настройки параметров сжатия. Сложность заключается в коде. Учебники по Pascal можно сказать очень редки. Его статус похож на VB (в настоящее время занимает 11-е место на TIOBE, отставая от трёх позиций от VB), но информации действительно мало. К счастью, есть помощь искусственного интеллекта, и многие вещи можно спросить у него. Кроме того, этот инструмент имеет стиль, аналогичный VB (простой и старомодный), и его код также выглядит старомодным. Хотя VS Code имеет расширения для Inno Setup и Pascal, они могут только выделять синтаксис, но не форматировать или предлагать код. Код в шаблоне разбросан повсюду, имена переменных не имеют структуры (нет точек с запятой, пробелов или переносов строк, смешение использования или отсутствия использования). Я могу только потратить много времени на организацию его структуры (поскольку это ручная организация, она не очень аккуратная, но её можно читать без проблем). Из-за отсутствия подсказок кода многие функции должны полагаться на существующий код, чтобы узнать о них. Inno Setup поставляется с chm-документацией, где можно найти много необходимой информации (неожиданно, что однажды мне придётся обратиться к документации IE 4-го поколения). Однако в шаблонах есть много функций, которые требуют помощи DLL. Функции DLL не документированы, и все они полагаются на имена параметров импорта DLL для угадывания их назначения. Что касается дизайна интерфейса, поскольку нет визуального редактора, я могу только настраивать вручную, а затем компилировать каждый раз после настройки. Inno Setup не поддерживает частичное обновление, и каждый раз при компиляции необходимо сжимать все исходные файлы. Таким образом, после всей этой работы объём записи на SSD уменьшился как минимум на 20–30 ГБ. Хотя настройка параметров сжатия ускоряет компиляцию до нескольких секунд, эффективность по-прежнему намного ниже, чем у визуальных редакторов или веб-страниц. Этот инструмент даже имеет canvas, который позволяет рисовать графику самостоятельно. Как фронтенд-разработчику, мне кажется, что этот инструмент слишком неэффективен. Те, кто использует этот инструмент для создания красивых интерфейсов, я могу сказать, что они хороши 😊. В любом случае, я больше не буду вникать в это. Самым неприятным является его IDE. Во-первых, сочетания клавиш хуже, чем в VS Code. Затем, будучи официальной IDE, она не имеет функции подсказки кода, поэтому я полностью отказался от использования её IDE для написания кода. Что касается отладки, хотя у неё есть функция точки останова, у неё нет пошаговой функции, нет окна переменных и нет консоли отладки😯. Мышь зависает над переменной на несколько секунд, и есть вероятность, что появится значение переменной (имя переменной отображается неправильно). Зачем использовать такую неудобную подсказку Tooltip! Есть также некоторые проблемы со старомодными типами переменных. Например, максимальное целое число составляет всего 32 бита, что вынуждает меня использовать числа с плавающей запятой для хранения дискового пространства (официально известно, что целые числа не могут представлять значения больше 2,1 ГБ, поэтому был установлен отдельный параметр для указания, следует ли использовать MiB в качестве единицы измерения). Затем я не смог найти документацию в справке, объясняющую типы переменных, и то, что AI сказал о некоторых типах, которые я поместил в сценарий, оказалось бесполезным. Кроме того, умножение и деление целых чисел по-прежнему приводит к целым числам (необходимо умножить или разделить на числа с плавающей точкой, чтобы получить числа с плавающей точкой), такие как характеристики обучения C, форматирование чисел в строки и т. д. Поскольку отладка настолько сложна, я потратил много времени только на отображение пространства хранения.
В целом, два слова: старомодно. Что касается того, трудно ли им пользоваться, я могу только сказать, что он просто старый. Если бы не было этого шаблона, если бы мне пришлось начинать с нуля, что бы я сделал? Я не знаю. Это старомодно, и информации мало. Но в конце концов цель достигнута.
Наконец, я изменил конфигурацию electron-builder и позволил ему вызывать ISCC после завершения сборки, тем самым завершив всю цепочку компиляции. Перевод текста на русский язык:
Использование parse-path: более универсальный подход
Я посмотрел на его npm-репозиторий. Самая старая версия 0.0.0 была написана 11 лет назад, это просто «Hello World»🤣. Затем, начиная с версии 3.0, он развивался нормально, вплоть до версии 4.0.4, где использовался собственный метод разбора, без использования URL. Это хорошо, я попробовал, но его функциональность всё ещё недостаточна, и он не может распознать пути к сетевым ресурсам Windows.
Copilot помог мне найти место в Node.js, которое поддерживает пути к сетевым ресурсам Windows: функция url.fileURLToPath
. Он продемонстрировал пример распознавания путей к сетевым ресурсам Windows. Поскольку эта функциональность доступна как в самых ранних версиях, так и в последних версиях Node.js, почему у меня не работает? Я хочу проверить это.
Процесс также не проходит гладко. В ViteJS импорт node:url приводит к ошибкам независимо от того, как я пытаюсь это сделать: "fileURLToPath" is not exported by "__vite-browser-external:node:url"
. Следуя подсказкам Copilot, я попытался использовать ssr: { noExternal: ['node:url'] }
и плагин @rollup/plugin-node-resolve
, но это не помогло.
Решением, которое я нашёл, было не импортировать из 'node:url', а импортировать из 'url'. Смеюсь.
Итак, каковы результаты теста? Пример из документации позволяет преобразовать file://
в \\\\
. Но если я передам результат обратно, это не сработает. Смеюсь, это вина Node.js🤣.
Одно из возможных решений, которые я придумал, — это преобразовать \\\\
в file://
перед тем, как передать путь в parse-url. Тогда это будет работать нормально.
2024-08-04
Далее мне нужно внести изменения в интерфейс appStore.addtasks. Задача должна принимать параметр типа FileList. Я думал, что он просто считывает путь, но задача сложнее. Помимо получения имени файла и пути, если это удалённый серверный запрос, необходимо прочитать весь файл, включая его размер и все данные файла. Для локальных файлов и удалённых файлов это легко сделать. Просто проанализируйте путь и возьмите имя и путь. Для задач удалённого сервера необходимо изменить основной процесс, чтобы прочитать размер файла и данные файла. Затем проверку хеша можно поручить основному процессу, а состояние пользовательского интерфейса проверки — процессу рендеринга. Проверка также может включать прогресс, но сначала необходимо реализовать разделение файла на части. Это другая история. Также необходимо создать график загрузки для удалённых задач. Ах...
2024-08-09
Как я уже говорил, изменение интерфейса appStore.addtasks выполнено. Теперь он работает только для взаимодействия в Electron. Веб-версия по-прежнему требует перетаскивания, и эту логику нужно реализовать.
2024-08-10
Получается, я переместил логику проверки файлов из процесса рендеринга в основной процесс, а теперь возвращаю её обратно🌚. Логика getPathsCategorized также должна быть реализована в процессе рендеринга, но логика расширения папок должна быть удалена. Поскольку невозможно вызвать локальные функции в среде браузера, она должна быть специально разработана. Позже я подумал, что в браузере нет смысла в этом поле ввода. Ручной контроль сервера — не очень распространённая потребность, поэтому я решил разделить логику открытия диалогового окна добавления задач и открытия окна выбора файла. Таким образом, функционал, над которым я работал полмесяца, завершён🌚. Подводя итог, для добавления такой функции ручного ввода пути и добавления папки требуется больше работы, чем я ожидал.
2024-08-11
Добавлена кнопка «Добавить файл» в диалоговом окне добавления задачи и двойное нажатие на список задач, чтобы определить действие в зависимости от среды. С этим функционалом, который разрабатывался месяц, покончено🌚. Вкратце, вот что было сделано:
2024-08-16
Уверен, что моё психическое состояние в последнее время ухудшилось... Этот коммит я всегда хотел завершить. Вчерашний журнал уже объявил о завершении, но когда я писал, я обнаружил последнюю проблему: неясно, какой элемент отвечает за прослушивание событий двойного щелчка и перетаскивания в списке задач. На самом деле, такая вещь не сложна, или, скорее, она довольно проста, но мой мозг слишком устал, чтобы думать об этом, поэтому я написал о ситуации «noffmpeg» и продолжил откладывать... На самом деле логика noffmpeg не требует много изменений. Просто замените div, и всё готово. Завершено завершено...
2024-08-21
Исправлена небольшая проблема с взаимодействием: меню не закрывается автоматически после нажатия. Эта проблема похожа на старые компьютерные инструменты — после выполнения операции результат будет перекрыт текущим открытым окном. Это требует добавления логики для закрытия окна вручную. Почему я не сделал этого раньше? Потому что я думал, что существует потребность в одновременном открытии нескольких программ. На самом деле это просто вопрос баланса, который не был сделан должным образом🌚.
2024-08-22
На этом этапе необходимо добавить недостающий прогресс загрузки. ProgressInfo добавляет два типа для представления прогресса передачи и распределения скорости передачи, а затем просто копирует и вставляет. Другие изменения включают добавление атрибутов lastStarted и т. д. в transferProgressLog (но поддержка приостановки всё ещё отсутствует, она просто сохраняет структуру данных в соответствии с progressLog). Кроме того, почти хотел изменить размер и битрейт FFmpegStatus на B/b, потому что они хранятся в kB/kb, каждый раз при вычислении их нужно делить на 1000, что немного неудобно. Однако после изменения нескольких строк я почувствовал, что уже использую B/b в FFmpeg, и изменение основного размера на B не является большой проблемой. Кроме того, основная цель этого состоит в том, чтобы облегчить отображение графика при сохранении одного и того же размера единицы. Поэтому я отказался от этой идеи.
2024-08-23
Продолжайте исправлять некоторые проблемы с единицами измерения. Конкретные исправления не перечислены, и в будущем следует добавлять комментарии к единицам измерения. Оптимизирован стиль отображения прогресса TaskItem. Первоначально я думал, что после этого изменения можно одновременно отображать загрузку и преобразование. Фактически, всё ещё необходимо обработать логику dashboardTimer, поэтому я отказался от этого и оставил отображение аномалий без влияния на функциональность. Затем кнопки на графике были отключены или скрыты. Наконец, проблема оценки оставшегося времени. Я обнаружил, что оценка оставшегося времени неверна после ручного выбора частоты кадров, потому что при расчёте скорости используется текущая разница выходных кадров, делённая на входные кадры. Вместо этого следует использовать выходную частоту кадров (если она есть) для расчёта. Проблемы больше на стороне LoveЭДС.
Не знаю, почему он выпал из бэкапа, да и не буду об этом говорить. В конце концов, дополнительное требование для создания чего-то хорошего — это поддерживать его в рабочем состоянии, но это не так просто. Как и в случае с FFBox, новые функции ещё не успели добавить, а поддержка стала ещё более недостаточной. Постоянно спрашивают, как активировать, но у меня даже нет времени подтвердить учётную запись LoveЭДС, вы могли бы помочь мне активировать её, если бы дали хоть какой-нибудь знак. Также есть небольшое количество сообщений об ошибках, если они говорят только о том, что что-то сломалось, но не говорят о шагах воспроизведения, я действительно не могу помочь.
Поэтому я всё равно буду продолжать выбирать платформу LoveЭДС, потому что она проста. Простое не может остановить некоторых недобросовестных людей от использования, это я не могу контролировать, потому что поведение, вредящее другим ради личной выгоды, не входит в мои жизненные принципы, и такие люди, вероятно, также не будут находиться в пределах разрешённого использования FFBox. Цель LoveЭДС — предоставить авторам простую платформу для стабильного получения дохода от спонсорства фанатов, цель FFBox — создать самый красивый ffmpeg GUI в мире и продвигать добро и красоту. Так должно быть устроено человеческое общество. Все эти сложные процедуры, сложные посредники, избыточное использование информации и соответствующая защита конфиденциальности, высокие комиссионные, Fuck it.
В настоящее время выпадение LoveЭДС из бэкапа влияет на мою сторону тем, что прежняя кнопка спонсорства больше не работает, поскольку доменное имя изменилось. К счастью, сам автор жив, у него есть возможность обновить свою ссылку. Я также должен рассмотреть возможность добавления промежуточного звена, чтобы перейти на сайт спонсорства через мой собственный веб-сайт, таким образом можно реализовать горячее обновление. В конце концов, все хотят, чтобы функции их программного обеспечения работали нормально как можно дольше.
Больше ничего не скажу. Желаю всем весёлого начала учебного года! Желаю вам приятного использования! 😉
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )