├── .github ├── ISSUE_TEMPLATE │ ├── 1_feature_request.yml │ └── 2_bug_report.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── build.yml ├── .gitignore ├── Images ├── catime.png └── catime_resize.png ├── LICENSE ├── PRIVACY.md ├── README-zh.md ├── README.md ├── asset ├── font │ ├── MIT │ │ ├── LICENSE │ │ └── ProFont IIx Nerd Font Essence.ttf │ ├── OFL │ │ ├── Arbutus Essence.ttf │ │ ├── Berkshire Swash Essence.ttf │ │ ├── Caveat Brush Essence.ttf │ │ ├── Creepster Essence.ttf │ │ ├── DotGothic16 Essence.ttf │ │ ├── Doto ExtraBold Essence.ttf │ │ ├── Foldit SemiBold Essence.ttf │ │ ├── Fredericka the Great Essence.ttf │ │ ├── Frijole Essence.ttf │ │ ├── Gwendolyn Essence.ttf │ │ ├── Handjet Essence.ttf │ │ ├── Inknut Antiqua Medium Essence.ttf │ │ ├── Jacquard 12 Essence.ttf │ │ ├── Jacquarda Bastarda 9 Essence.ttf │ │ ├── Kavoon Essence.ttf │ │ ├── Kumar One Essence.ttf │ │ ├── Kumar One Outline Essence.ttf │ │ ├── Lakki Reddy Essence.ttf │ │ ├── Licorice Essence.ttf │ │ ├── Ma Shan Zheng Essence.ttf │ │ ├── Moirai One Essence.ttf │ │ ├── Mystery Quest Essence.ttf │ │ ├── Noto Nastaliq Urdu Medium Essence.ttf │ │ ├── OFL.txt │ │ ├── Piedra Essence.ttf │ │ ├── Pinyon Script Essence.ttf │ │ ├── Pixelify Sans Medium Essence.ttf │ │ ├── Press Start 2P Essence.ttf │ │ ├── Rubik Bubbles Essence.ttf │ │ ├── Rubik Burned Essence.ttf │ │ ├── Rubik Glitch Essence.ttf │ │ ├── Rubik Marker Hatch Essence.ttf │ │ ├── Rubik Puddles Essence.ttf │ │ ├── Rubik Vinyl Essence.ttf │ │ ├── Rubik Wet Paint Essence.ttf │ │ ├── Ruge Boogie Essence.ttf │ │ ├── Sevillana Essence.ttf │ │ ├── Silkscreen Essence.ttf │ │ ├── Stick Essence.ttf │ │ ├── Underdog Essence.ttf │ │ ├── Wallpoet Essence.ttf │ │ ├── Yesteryear Essence.ttf │ │ └── ZCOOL KuaiLe Essence.ttf │ └── SIL │ │ ├── DaddyTimeMono Nerd Font Propo Essence.ttf │ │ ├── DepartureMono Nerd Font Propo Essence.ttf │ │ ├── RecMonoCasual Nerd Font Mono Essence.ttf │ │ ├── SIL Open Font License.txt │ │ └── Terminess Nerd Font Propo Essence.ttf └── icon │ └── catime.ico ├── build └── .gitkeep ├── include ├── async_update_checker.h ├── audio_player.h ├── color.h ├── config.h ├── dialog_language.h ├── dialog_procedure.h ├── drag_scale.h ├── drawing.h ├── font.h ├── hotkey.h ├── language.h ├── log.h ├── media.h ├── notification.h ├── pomodoro.h ├── shortcut_checker.h ├── startup.h ├── timer.h ├── timer_events.h ├── tray.h ├── tray_events.h ├── tray_menu.h ├── update_checker.h ├── window.h ├── window_events.h └── window_procedure.h ├── libs └── miniaudio │ ├── miniaudio.c │ └── miniaudio.h ├── resource ├── about_dialog.rc ├── app.manifest ├── catime.rc ├── color_dialog.rc ├── countdown_dialog.rc ├── error_dialog.rc ├── hotkey_dialog.rc ├── languages.rc ├── languages │ ├── de.ini │ ├── en.ini │ ├── es.ini │ ├── fr.ini │ ├── ja.ini │ ├── ko.ini │ ├── pt.ini │ ├── ru.ini │ ├── zh-Hant.ini │ └── zh_CN.ini ├── notification_dialog.rc ├── pomodoro_combo_dialog.rc ├── pomodoro_loop_dialog.rc ├── pomodoro_time_dialog.rc ├── resource.h ├── resource.rc ├── shortcut_dialog.rc ├── startup_dialog.rc ├── update_dialog.rc └── website_dialog.rc ├── src ├── async_update_checker.c ├── audio_player.c ├── color.c ├── config.c ├── dialog_language.c ├── dialog_procedure.c ├── drag_scale.c ├── drawing.c ├── font.c ├── hotkey.c ├── language.c ├── log.c ├── main.c ├── media.c ├── notification.c ├── shortcut_checker.c ├── startup.c ├── timer.c ├── timer_events.c ├── tray.c ├── tray_events.c ├── tray_menu.c ├── update_checker.c ├── window.c ├── window_events.c └── window_procedure.c └── xmake.lua /.github/ISSUE_TEMPLATE/1_feature_request.yml: -------------------------------------------------------------------------------- 1 | name: ✨ Feature Request ✨ 2 | description: "💡 Got a great idea? Share your creativity with us!" 3 | title: "[✨Feature Request]: " 4 | labels: ['enhancement'] 5 | body: 6 | - type: input 7 | id: problem 8 | attributes: 9 | label: 🌈 Feature You'd Like 10 | description: "Briefly describe the feature you'd like to add or improve. Let's make the software even better together!" 11 | validations: 12 | required: false 13 | - type: textarea 14 | id: way-to-solve 15 | attributes: 16 | label: 🚀 Ideal Solution 17 | description: "What does your perfect solution look like? Feel free to use your imagination - don't worry about technical details!" 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: instead 22 | attributes: 23 | label: 🤔 Alternative Solutions (Optional) 24 | description: "If you have other ideas, please share them here. The more, the merrier!" 25 | validations: 26 | required: false 27 | - type: checkboxes 28 | id: "latest-version" 29 | attributes: 30 | label: "✅ Final Step" 31 | description: "Before submitting your brilliant idea, please confirm the following:" 32 | options: 33 | - label: "🌟 I've checked the latest version and confirmed my requested feature isn't already implemented." 34 | required: true 35 | - label: "📋 I've reviewed existing feature requests to make sure this isn't a duplicate." 36 | required: true 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2_bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: "🛠️ Found a problem? Let us know here!" 3 | title: "[Bug]: " 4 | labels: ["bug"] 5 | body: 6 | - type: input 7 | id: "expectation" 8 | attributes: 9 | label: "✨ What You Expected" 10 | description: "How should the software work? Describe what you expected to happen." 11 | validations: 12 | required: false 13 | - type: textarea 14 | id: "describe-the-bug" 15 | attributes: 16 | label: "❓ What Actually Happened" 17 | description: "Oops! Something went wrong? Please tell us what you saw - the more details, the better!" 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: "reproduction-method" 22 | attributes: 23 | label: "📝 Steps to Reproduce the Issue" 24 | description: "Can you tell us how you encountered this bug? List the steps so we can find the problem faster." 25 | placeholder: "For example:\n1. Click on Edit mode\n2. Then this happened...\n3. Oops! Problem occurred!" 26 | validations: 27 | required: false 28 | - type: textarea 29 | id: "more" 30 | attributes: 31 | label: "📌 Additional Information" 32 | description: "Anything else you'd like to tell us? System information, version numbers, etc." 33 | placeholder: "Example:\nSystem: Windows 11\nVersion: 23H2" 34 | validations: 35 | required: false 36 | - type: checkboxes 37 | id: "latest-version" 38 | attributes: 39 | label: "✅ Final Checklist" 40 | description: "Before submitting your bug report, please confirm the following:" 41 | options: 42 | - label: "⚡ I've confirmed I'm using the latest version, not an older one." 43 | required: true 44 | - label: "📋 I've checked the FAQ and known issues list to confirm this is a new bug." 45 | required: true 46 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## 👋 Thank You for Your Contribution! 2 | 3 | Please read the following content before submitting your PR, and fill out this template as completely as possible: 4 | 5 | --- 6 | 7 | ### 1. What problem does this PR solve? (Required) 8 | 9 | Please briefly describe the background and motivation for your changes, and include related Issue numbers if applicable: 10 | 11 | > Example: Fixes #123, resolves component misalignment issues on small screens. 12 | 13 | --- 14 | 15 | ### 2. Overview of Changes (Required) 16 | 17 | - [ ] Bug fix 18 | - [ ] New feature 19 | - [ ] Documentation update 20 | - [ ] Style/structure optimization 21 | - [ ] Other (please describe): 22 | 23 | Briefly describe which files, modules, or features were modified: 24 | 25 | --- 26 | 27 | ### 3. Has it been tested? (Required) 28 | 29 | - [ ] Passed local testing ✅ 30 | - [ ] Added relevant test cases 31 | - [ ] Not tested (please explain why) 32 | 33 | --- 34 | 35 | ### 4. Special considerations or future plans? 36 | 37 | Please list any areas that might impact existing functionality, or content you'd like to improve further in the future: 38 | 39 | --- 40 | 41 | ### ⚠️ Before submitting, please confirm: 42 | 43 | - [ ] I have read and followed the project's contribution guidelines (CONTRIBUTING.md) 44 | - [ ] I have communicated with or am communicating with the maintainers (through Issues or other means) 45 | - [ ] I understand that major changes without prior discussion may not be accepted 46 | 47 | --- 48 | 49 | Thank you for your involvement! We hope to work together in an open and respectful manner to make the project better 🙌 50 | 51 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build catime 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths-ignore: 7 | - 'README.md' 8 | - 'README_EN.md' 9 | pull_request: 10 | branches: [ main ] 11 | paths-ignore: 12 | - 'README.md' 13 | - 'README_EN.md' 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - name: Checkout code 21 | uses: actions/checkout@v3 22 | 23 | - name: Set up China timezone 24 | run: | 25 | sudo timedatectl set-timezone Asia/Shanghai 26 | echo "Current timezone: $(date +%Z)" 27 | echo "Current time: $(date)" 28 | 29 | - name: Install MinGW compiler 30 | run: | 31 | sudo apt-get update 32 | sudo apt-get install -y mingw-w64 33 | 34 | - name: Install XMake 35 | run: | 36 | bash <(curl -fsSL https://xmake.io/shget.text) 37 | source ~/.xmake/profile 38 | xmake --version 39 | 40 | - name: Extract version number 41 | id: get_version 42 | run: | 43 | VERSION=$(grep -oP '#define CATIME_VERSION "\K[^"]+' resource/resource.h) 44 | echo "VERSION=$VERSION" >> $GITHUB_ENV 45 | echo "Version: $VERSION" 46 | 47 | - name: Build application 48 | run: | 49 | # Create output directory 50 | mkdir -p output 51 | # Execute xmake build 52 | xmake -y 53 | # Find build artifacts and copy to output directory 54 | find . -name "catime.exe" -type f -print -exec cp {} output/ \; 55 | echo "Build completed using xmake" 56 | 57 | - name: Install UPX compression tool 58 | run: | 59 | sudo apt-get install -y upx 60 | upx --version 61 | 62 | - name: Create compressed and uncompressed versions 63 | run: | 64 | # Copy original file as uncompressed version 65 | cp output/catime.exe output/catime_original.exe 66 | 67 | # Save pre-compression size 68 | BEFORE_SIZE=$(stat -c %s output/catime.exe) 69 | BEFORE_SIZE_KB=$((BEFORE_SIZE / 1024)) 70 | 71 | # Compress the original catime.exe 72 | upx --ultra-brute --lzma output/catime.exe 73 | 74 | # Save post-compression size and display results 75 | AFTER_SIZE=$(stat -c %s output/catime.exe) 76 | AFTER_SIZE_KB=$((AFTER_SIZE / 1024)) 77 | 78 | echo "UPX compression: ${BEFORE_SIZE_KB}KiB → ${AFTER_SIZE_KB}KiB" 79 | 80 | - name: Add version information file 81 | run: | 82 | echo "# Catime ${{ env.VERSION }} 版本说明" > output/README.txt 83 | echo "感谢您使用 catime_${{ env.VERSION }} 测试版!" >> output/README.txt 84 | echo "" >> output/README.txt 85 | echo "## 版本信息" >> output/README.txt 86 | echo "- 版本号:${{ env.VERSION }}" >> output/README.txt 87 | echo "- 版本类型:测试版" >> output/README.txt 88 | echo "- 构建日期:$(date '+%Y-%m-%d %H:%M:%S') (UTC+8)" >> output/README.txt 89 | echo "- 构建编号:${GITHUB_RUN_NUMBER:-未知}" >> output/README.txt 90 | echo "" >> output/README.txt 91 | echo "## 重要提示" >> output/README.txt 92 | echo "如遇到问题,请通过 Issues 页面向我们反馈。您的意见将帮助我们改进产品质量。" >> output/README.txt 93 | echo "" >> output/README.txt 94 | echo "## 文件说明" >> output/README.txt 95 | echo "- catime_${{ env.VERSION }}_${{ github.run_number }}.exe: 原始版本" >> output/README.txt 96 | echo "- catime_${{ env.VERSION }}_${{ github.run_number }}_upx.exe: UPX压缩版本,体积更小" >> output/README.txt 97 | echo "" >> output/README.txt 98 | echo "-----------------------------------" >> output/README.txt 99 | echo "" >> output/README.txt 100 | echo "# catime_${{ env.VERSION }} Version Information" >> output/README.txt 101 | echo "Thank you for using Catime ${{ env.VERSION }} Beta version!" >> output/README.txt 102 | echo "" >> output/README.txt 103 | echo "## Version Information" >> output/README.txt 104 | echo "- Version: ${{ env.VERSION }}" >> output/README.txt 105 | echo "- Version Type: Beta" >> output/README.txt 106 | echo "- Build Date: $(date '+%Y-%m-%d %H:%M:%S') (UTC+8)" >> output/README.txt 107 | echo "- Build Number: ${GITHUB_RUN_NUMBER:-Unknown}" >> output/README.txt 108 | echo "" >> output/README.txt 109 | echo "## File Description" >> output/README.txt 110 | echo "- catime_${{ env.VERSION }}_${{ github.run_number }}.exe: Original version" >> output/README.txt 111 | echo "- catime_${{ env.VERSION }}_${{ github.run_number }}_upx.exe: UPX compressed version, smaller size" >> output/README.txt 112 | echo "" >> output/README.txt 113 | echo "## Important Notes" >> output/README.txt 114 | echo "If you encounter any issues, please provide feedback through the Issues page. Your opinions will help us improve product quality." >> output/README.txt 115 | 116 | - name: Rename files 117 | run: | 118 | # Rename uncompressed version 119 | mv output/catime_original.exe output/catime_${{ env.VERSION }}_${{ github.run_number }}.exe 120 | # Rename compressed version 121 | mv output/catime.exe output/catime_${{ env.VERSION }}_${{ github.run_number }}_upx.exe 122 | 123 | - name: Create release package 124 | run: | 125 | mkdir -p release 126 | cp output/catime_${{ env.VERSION }}_${{ github.run_number }}.exe release/ 127 | cp output/catime_${{ env.VERSION }}_${{ github.run_number }}_upx.exe release/ 128 | cp output/README.txt release/ 129 | cd release 130 | zip -r catime_${{ env.VERSION }}_${{ github.run_number }}.zip * 131 | mv catime_${{ env.VERSION }}_${{ github.run_number }}.zip ../output/ 132 | 133 | - name: Upload build artifacts 134 | uses: actions/upload-artifact@v4 135 | with: 136 | name: catime-windows-${{ env.VERSION }}-${{ github.run_number }} 137 | path: | 138 | output/catime_${{ env.VERSION }}_${{ github.run_number }}.exe 139 | output/catime_${{ env.VERSION }}_${{ github.run_number }}_upx.exe 140 | output/README.txt -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 忽略build文件夹中的所有内容,但保留目录本身 2 | build/* 3 | !build/.gitkeep 4 | 5 | 6 | # 可执行文件 7 | *.exe 8 | *.out 9 | *.app 10 | 11 | # 编译中间文件 12 | *.o 13 | *.obj 14 | 15 | # 其他临时文件 16 | *.log 17 | *.tmp 18 | 19 | # 忽略资源编译生成文件 20 | *.res 21 | *.aps 22 | 23 | # 忽略xmake生成的临时文件 24 | .xmake/ 25 | 26 | #jb idea 27 | .idea/ 28 | -------------------------------------------------------------------------------- /Images/catime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/Images/catime.png -------------------------------------------------------------------------------- /Images/catime_resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/Images/catime_resize.png -------------------------------------------------------------------------------- /PRIVACY.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy 2 | 3 | ## Introduction 4 | 5 | **Catime** is a desktop application focused on personal time management. We highly value your privacy, and this policy explains how we handle your data. 6 | 7 | ## Data Collection and Usage 8 | 9 | ### Information We Do **Not** Collect 10 | 11 | Catime explicitly commits to: 12 | 13 | * **Not** creating any unique identifiers, trackers, or similar tools 14 | * **Not** collecting usage statistics, performance metrics, or any user behavior information 15 | * **Not** uploading any user or system data to remote servers 16 | * **Not** incorporating advertisements or analytics tools 17 | * **Not** selling or sharing your personal data with third parties 18 | 19 | ### Locally Stored Data 20 | 21 | Catime only saves the following information locally: 22 | 23 | 1. **Configuration Data** 24 | Includes interface settings, timer configurations, and user preferences, stored in `%LOCALAPPDATA%\Catime\config.ini`. 25 | 26 | 2. **Log Information** 27 | Saved in the `Catime_Logs.log` file, containing: 28 | 29 | * Basic system information (OS version, CPU architecture, memory capacity, etc.) 30 | * Program startup and operation records 31 | * Error and warning logs 32 | *All logs are used for local troubleshooting only and are **never** uploaded.* 33 | 34 | 3. **Recent Files List** 35 | Stores paths of recently opened files for quick access. 36 | 37 | ### Network Access Information 38 | 39 | Catime only accesses the internet in the following circumstances: 40 | 41 | * **Update Checking** 42 | When you manually check for updates or enable the automatic update feature, the program connects to the GitHub API: 43 | `https://api.github.com/repos/vladelaina/Catime/releases/latest` 44 | It only sends basic HTTP requests and the user agent string `"Catime Update Checker"`, **without any personal data**. 45 | 46 | ## Data Protection and Deletion 47 | 48 | All data is stored locally, and Catime does not perform any remote synchronization or uploads. 49 | To completely remove data, you can manually delete the configuration files and log files. 50 | 51 | ## Permission Usage Information 52 | 53 | System permissions requested by Catime are only used to implement core functions: 54 | 55 | * **File System Access**: For reading and writing configuration and log files 56 | * **Network Access**: Only for update checking 57 | * **Reading System Information**: Recorded to local log files 58 | * **Startup Item Modification**: Only used when the "Start with System" feature is enabled 59 | 60 | ## Privacy Policy Changes 61 | 62 | If there are significant changes, we will post notifications within the application or on the project homepage. 63 | 64 | ## Contact Information 65 | 66 | If you have questions or suggestions about this privacy policy, please contact us through the GitHub project page. 67 | 68 | > Last Updated: May 28, 2025 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /asset/font/MIT/LICENSE: -------------------------------------------------------------------------------- 1 | (c) 2013-2021, type agaric 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /asset/font/MIT/ProFont IIx Nerd Font Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/MIT/ProFont IIx Nerd Font Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Arbutus Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Arbutus Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Berkshire Swash Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Berkshire Swash Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Caveat Brush Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Caveat Brush Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Creepster Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Creepster Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/DotGothic16 Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/DotGothic16 Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Doto ExtraBold Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Doto ExtraBold Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Foldit SemiBold Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Foldit SemiBold Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Fredericka the Great Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Fredericka the Great Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Frijole Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Frijole Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Gwendolyn Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Gwendolyn Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Handjet Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Handjet Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Inknut Antiqua Medium Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Inknut Antiqua Medium Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Jacquard 12 Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Jacquard 12 Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Jacquarda Bastarda 9 Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Jacquarda Bastarda 9 Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Kavoon Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Kavoon Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Kumar One Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Kumar One Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Kumar One Outline Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Kumar One Outline Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Lakki Reddy Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Lakki Reddy Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Licorice Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Licorice Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Ma Shan Zheng Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Ma Shan Zheng Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Moirai One Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Moirai One Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Mystery Quest Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Mystery Quest Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Noto Nastaliq Urdu Medium Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Noto Nastaliq Urdu Medium Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright 2023 The Soft Type Project Authors (https://github.com/scfried/soft-type-jacquarda-bastarda) 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | https://openfontlicense.org 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /asset/font/OFL/Piedra Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Piedra Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Pinyon Script Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Pinyon Script Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Pixelify Sans Medium Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Pixelify Sans Medium Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Press Start 2P Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Press Start 2P Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Rubik Bubbles Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Rubik Bubbles Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Rubik Burned Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Rubik Burned Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Rubik Glitch Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Rubik Glitch Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Rubik Marker Hatch Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Rubik Marker Hatch Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Rubik Puddles Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Rubik Puddles Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Rubik Vinyl Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Rubik Vinyl Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Rubik Wet Paint Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Rubik Wet Paint Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Ruge Boogie Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Ruge Boogie Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Sevillana Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Sevillana Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Silkscreen Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Silkscreen Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Stick Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Stick Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Underdog Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Underdog Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Wallpoet Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Wallpoet Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/Yesteryear Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/Yesteryear Essence.ttf -------------------------------------------------------------------------------- /asset/font/OFL/ZCOOL KuaiLe Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/OFL/ZCOOL KuaiLe Essence.ttf -------------------------------------------------------------------------------- /asset/font/SIL/DaddyTimeMono Nerd Font Propo Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/SIL/DaddyTimeMono Nerd Font Propo Essence.ttf -------------------------------------------------------------------------------- /asset/font/SIL/DepartureMono Nerd Font Propo Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/SIL/DepartureMono Nerd Font Propo Essence.ttf -------------------------------------------------------------------------------- /asset/font/SIL/RecMonoCasual Nerd Font Mono Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/SIL/RecMonoCasual Nerd Font Mono Essence.ttf -------------------------------------------------------------------------------- /asset/font/SIL/SIL Open Font License.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 2 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 3 | 4 | ----------------------------------------------------------- 5 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 6 | ----------------------------------------------------------- 7 | 8 | PREAMBLE 9 | The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. 10 | 11 | The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. 12 | 13 | DEFINITIONS 14 | "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. 15 | 16 | "Reserved Font Name" refers to any names specified as such after the copyright statement(s). 17 | 18 | "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). 19 | 20 | "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. 21 | 22 | "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. 23 | 24 | PERMISSION & CONDITIONS 25 | Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 26 | 27 | 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 28 | 29 | 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 30 | 31 | 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 32 | 33 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 34 | 35 | 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. 36 | 37 | TERMINATION 38 | This license becomes null and void if any of the above conditions are not met. 39 | 40 | DISCLAIMER 41 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /asset/font/SIL/Terminess Nerd Font Propo Essence.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/font/SIL/Terminess Nerd Font Propo Essence.ttf -------------------------------------------------------------------------------- /asset/icon/catime.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/asset/icon/catime.ico -------------------------------------------------------------------------------- /build/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vladelaina/Catime/420d8d70070e1ac5b5805cfb6d7cb741ed52b4ba/build/.gitkeep -------------------------------------------------------------------------------- /include/async_update_checker.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file async_update_checker.h 3 | * @brief 极简的异步应用程序更新检查功能接口 4 | * 5 | * 本文件定义了应用程序异步检查更新的功能接口,确保更新检查不会阻塞主线程。 6 | */ 7 | 8 | #ifndef ASYNC_UPDATE_CHECKER_H 9 | #define ASYNC_UPDATE_CHECKER_H 10 | 11 | #include 12 | 13 | /** 14 | * @brief 异步检查应用程序更新 15 | * @param hwnd 窗口句柄 16 | * @param silentCheck 是否为静默检查(仅在有更新时显示提示) 17 | * 18 | * 在单独的线程中连接到GitHub检查是否有新版本。 19 | * 此函数立即返回,不会阻塞主线程。 20 | */ 21 | void CheckForUpdateAsync(HWND hwnd, BOOL silentCheck); 22 | 23 | /** 24 | * @brief 清理更新检查线程资源 25 | * 26 | * 在程序退出前调用此函数,确保释放所有更新检查线程相关资源, 27 | * 防止内存泄漏和资源泄漏。 28 | */ 29 | void CleanupUpdateThread(void); 30 | 31 | #endif // ASYNC_UPDATE_CHECKER_H -------------------------------------------------------------------------------- /include/audio_player.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file audio_player.h 3 | * @brief 音频播放功能接口 4 | * 5 | * 提供通知音频播放功能的接口,支持多种音频格式的后台播放。 6 | */ 7 | 8 | #ifndef AUDIO_PLAYER_H 9 | #define AUDIO_PLAYER_H 10 | 11 | #include 12 | 13 | /** 14 | * @brief 音频播放完成回调函数类型 15 | * @param hwnd 窗口句柄 16 | * 17 | * 当音频播放完成时,系统会调用此回调函数通知应用程序。 18 | */ 19 | typedef void (*AudioPlaybackCompleteCallback)(HWND hwnd); 20 | 21 | /** 22 | * @brief 设置音频播放完成回调函数 23 | * @param hwnd 回调窗口句柄 24 | * @param callback 回调函数 25 | * 26 | * 设置音频播放完成时的回调函数,当音频播放结束后, 27 | * 系统会调用该回调函数通知应用程序。 28 | */ 29 | void SetAudioPlaybackCompleteCallback(HWND hwnd, AudioPlaybackCompleteCallback callback); 30 | 31 | /** 32 | * @brief 播放通知音频 33 | * @param hwnd 父窗口句柄 34 | * @return BOOL 成功返回TRUE,失败返回FALSE 35 | * 36 | * 当配置了有效的NOTIFICATION_SOUND_FILE并且文件存在时,系统会播放该音频文件。 37 | * 如果文件不存在或播放失败,则会播放系统默认提示音。 38 | * 播放失败时会显示错误提示对话框。 39 | */ 40 | BOOL PlayNotificationSound(HWND hwnd); 41 | 42 | /** 43 | * @brief 暂停当前播放的通知音频 44 | * @return BOOL 成功返回TRUE,失败返回FALSE 45 | * 46 | * 暂停当前正在播放的通知音频,用于在用户暂停计时器时同步暂停音频。 47 | * 仅当音频处于播放状态且使用miniaudio播放时有效。 48 | */ 49 | BOOL PauseNotificationSound(void); 50 | 51 | /** 52 | * @brief 继续播放已暂停的通知音频 53 | * @return BOOL 成功返回TRUE,失败返回FALSE 54 | * 55 | * 继续播放之前被暂停的通知音频,用于在用户继续计时器时同步继续音频播放。 56 | * 仅当音频处于暂停状态时有效。 57 | */ 58 | BOOL ResumeNotificationSound(void); 59 | 60 | /** 61 | * @brief 停止播放通知音频 62 | * 63 | * 停止当前正在播放的任何通知音频 64 | */ 65 | void StopNotificationSound(void); 66 | 67 | /** 68 | * @brief 设置音频播放音量 69 | * @param volume 音量百分比(0-100) 70 | * 71 | * 设置音频播放的音量大小,影响所有通知音频的播放 72 | */ 73 | void SetAudioVolume(int volume); 74 | 75 | #endif // AUDIO_PLAYER_H -------------------------------------------------------------------------------- /include/color.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file color.h 3 | * @brief 颜色处理功能接口 4 | * 5 | * 本文件定义了应用程序的颜色处理功能接口,包括颜色结构体、 6 | * 全局变量声明以及颜色管理相关的函数声明。 7 | */ 8 | 9 | #ifndef COLOR_H 10 | #define COLOR_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 预定义颜色结构体 16 | * 17 | * 存储预定义的颜色十六进制值 18 | */ 19 | typedef struct { 20 | const char* hexColor; ///< 十六进制颜色值,格式如 "#RRGGBB" 21 | } PredefinedColor; 22 | 23 | /** 24 | * @brief CSS颜色名称结构体 25 | * 26 | * 存储CSS标准颜色名称与对应的十六进制值 27 | */ 28 | typedef struct { 29 | const char* name; ///< 颜色名称,如 "red" 30 | const char* hex; ///< 对应的十六进制值,如 "#FF0000" 31 | } CSSColor; 32 | 33 | /// @name 全局变量声明 34 | /// @{ 35 | extern PredefinedColor* COLOR_OPTIONS; ///< 预定义颜色选项数组 36 | extern size_t COLOR_OPTIONS_COUNT; ///< 预定义颜色选项数量 37 | extern char PREVIEW_COLOR[10]; ///< 预览颜色值 38 | extern BOOL IS_COLOR_PREVIEWING; ///< 是否正在预览颜色 39 | extern char CLOCK_TEXT_COLOR[10]; ///< 当前文本颜色值 40 | /// @} 41 | 42 | /// @name 颜色管理函数 43 | /// @{ 44 | 45 | /** 46 | * @brief 初始化默认语言和颜色设置 47 | * 48 | * 读取配置文件中的颜色设置,若未找到则创建默认配置。 49 | */ 50 | void InitializeDefaultLanguage(void); 51 | 52 | /** 53 | * @brief 添加颜色选项 54 | * @param hexColor 颜色的十六进制值 55 | * 56 | * 添加一个颜色选项到全局颜色选项数组中。 57 | */ 58 | void AddColorOption(const char* hexColor); 59 | 60 | /** 61 | * @brief 清除所有颜色选项 62 | * 63 | * 释放所有颜色选项占用的内存,并重置颜色选项计数。 64 | */ 65 | void ClearColorOptions(void); 66 | 67 | /** 68 | * @brief 将颜色写入配置文件 69 | * @param color_input 要写入的颜色值 70 | * 71 | * 将指定的颜色值写入应用程序配置文件。 72 | */ 73 | void WriteConfigColor(const char* color_input); 74 | 75 | /** 76 | * @brief 标准化颜色格式 77 | * @param input 输入的颜色字符串 78 | * @param output 输出的标准化颜色字符串 79 | * @param output_size 输出缓冲区大小 80 | * 81 | * 将各种格式的颜色字符串转换为标准的十六进制颜色格式。 82 | */ 83 | void normalizeColor(const char* input, char* output, size_t output_size); 84 | 85 | /** 86 | * @brief 检查颜色是否有效 87 | * @param input 要检查的颜色字符串 88 | * @return BOOL 如果颜色有效则返回TRUE,否则返回FALSE 89 | * 90 | * 验证给定的颜色表示是否可以被解析为有效的颜色。 91 | */ 92 | BOOL isValidColor(const char* input); 93 | 94 | /** 95 | * @brief 颜色编辑框子类化处理过程 96 | * @param hwnd 窗口句柄 97 | * @param msg 消息ID 98 | * @param wParam 消息参数 99 | * @param lParam 消息参数 100 | * @return LRESULT 消息处理结果 101 | * 102 | * 处理颜色编辑框的消息事件,实现颜色预览功能。 103 | */ 104 | LRESULT CALLBACK ColorEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 105 | 106 | /** 107 | * @brief 颜色设置对话框处理过程 108 | * @param hwndDlg 对话框窗口句柄 109 | * @param msg 消息ID 110 | * @param wParam 消息参数 111 | * @param lParam 消息参数 112 | * @return INT_PTR 消息处理结果 113 | * 114 | * 处理颜色设置对话框的消息事件。 115 | */ 116 | INT_PTR CALLBACK ColorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); 117 | 118 | /** 119 | * @brief 检查颜色是否已存在 120 | * @param hexColor 十六进制颜色值 121 | * @return BOOL 如果颜色已存在则返回TRUE,否则返回FALSE 122 | * 123 | * 检查指定的颜色是否已存在于颜色选项列表中。 124 | */ 125 | BOOL IsColorExists(const char* hexColor); 126 | 127 | /** 128 | * @brief 显示颜色选择对话框 129 | * @param hwnd 父窗口句柄 130 | * @return COLORREF 选择的颜色值,如果用户取消则返回(COLORREF)-1 131 | * 132 | * 显示Windows标准颜色选择对话框,允许用户选择颜色。 133 | */ 134 | COLORREF ShowColorDialog(HWND hwnd); 135 | 136 | /** 137 | * @brief 颜色对话框钩子过程 138 | * @param hdlg 对话框窗口句柄 139 | * @param msg 消息ID 140 | * @param wParam 消息参数 141 | * @param lParam 消息参数 142 | * @return UINT_PTR 消息处理结果 143 | * 144 | * 处理颜色选择对话框的自定义消息事件,实现颜色预览功能。 145 | */ 146 | UINT_PTR CALLBACK ColorDialogHookProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); 147 | /// @} 148 | 149 | #endif // COLOR_H -------------------------------------------------------------------------------- /include/dialog_language.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dialog_language.h 3 | * @brief 对话框多语言支持模块头文件 4 | * 5 | * 本文件定义了用于对话框多语言支持的函数接口,使对话框文本可以根据应用程序语言设置进行本地化。 6 | */ 7 | 8 | #ifndef DIALOG_LANGUAGE_H 9 | #define DIALOG_LANGUAGE_H 10 | 11 | #include 12 | 13 | /** 14 | * @brief 初始化对话框多语言支持 15 | * 16 | * 在应用程序启动时调用此函数以初始化对话框多语言支持系统。 17 | * 18 | * @return BOOL 初始化是否成功 19 | */ 20 | BOOL InitDialogLanguageSupport(void); 21 | 22 | /** 23 | * @brief 对对话框应用多语言支持 24 | * 25 | * 根据当前应用程序语言设置,更新对话框中的文本元素。 26 | * 此函数应在对话框 WM_INITDIALOG 消息处理期间调用。 27 | * 28 | * @param hwndDlg 对话框句柄 29 | * @param dialogID 对话框资源ID 30 | * @return BOOL 操作是否成功 31 | */ 32 | BOOL ApplyDialogLanguage(HWND hwndDlg, int dialogID); 33 | 34 | /** 35 | * @brief 获取对话框元素的本地化文本 36 | * 37 | * 根据当前应用程序语言设置,获取对话框元素的本地化文本。 38 | * 39 | * @param dialogID 对话框资源ID 40 | * @param controlID 控件资源ID 41 | * @return const wchar_t* 本地化文本,如果找不到则返回NULL 42 | */ 43 | const wchar_t* GetDialogLocalizedString(int dialogID, int controlID); 44 | 45 | #endif /* DIALOG_LANGUAGE_H */ -------------------------------------------------------------------------------- /include/dialog_procedure.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dialog_procedure.h 3 | * @brief 对话框消息处理过程接口 4 | * 5 | * 本文件定义了应用程序的对话框消息处理回调函数接口, 6 | * 处理对话框的所有消息事件包括初始化、颜色管理、按钮点击和键盘事件。 7 | */ 8 | 9 | #ifndef DIALOG_PROCEDURE_H 10 | #define DIALOG_PROCEDURE_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 输入对话框过程 16 | * @param hwndDlg 对话框句柄 17 | * @param msg 消息类型 18 | * @param wParam 消息参数 19 | * @param lParam 消息参数 20 | * @return INT_PTR 消息处理结果 21 | * 22 | * 处理倒计时输入对话框的: 23 | * 1. 控件初始化与焦点设置 24 | * 2. 背景/控件颜色管理 25 | * 3. 确定按钮点击处理 26 | * 4. 回车键响应 27 | * 5. 资源清理 28 | */ 29 | INT_PTR CALLBACK DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); 30 | 31 | /** 32 | * @brief 显示关于对话框 33 | * @param hwndParent 父窗口句柄 34 | * 35 | * 显示包含程序版本、作者和第三方库信息的关于对话框。 36 | * 包含以下链接按钮: 37 | * - 鸣谢 (IDC_CREDITS) - 打开网页 https://vladelaina.github.io/Catime/#thanks 38 | * - 反馈 (IDC_FEEDBACK) 39 | * - GitHub (IDC_GITHUB) 40 | * - 版权声明 (IDC_COPYRIGHT_LINK) - 打开网页 https://github.com/vladelaina/Catime?tab=readme-ov-file#%EF%B8%8F%E7%89%88%E6%9D%83%E5%A3%B0%E6%98%8E 41 | * - 支持 (IDC_SUPPORT) - 打开网页 https://vladelaina.github.io/Catime/support.html 42 | */ 43 | void ShowAboutDialog(HWND hwndParent); 44 | 45 | INT_PTR CALLBACK AboutDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); 46 | 47 | /** 48 | * @brief 显示错误对话框 49 | * @param hwndParent 父窗口句柄 50 | * 51 | * 显示统一的错误提示对话框。 52 | */ 53 | void ShowErrorDialog(HWND hwndParent); 54 | 55 | /** 56 | * @brief 显示番茄钟循环次数设置对话框 57 | * @param hwndParent 父窗口句柄 58 | * 59 | * 显示用于设置番茄钟循环次数的对话框。 60 | * 允许用户输入1-99之间的循环次数。 61 | */ 62 | void ShowPomodoroLoopDialog(HWND hwndParent); 63 | 64 | INT_PTR CALLBACK PomodoroLoopDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); 65 | 66 | /** 67 | * @brief 显示网站URL输入对话框 68 | * @param hwndParent 父窗口句柄 69 | * 70 | * 显示用于输入超时时打开的网站URL的对话框。 71 | */ 72 | void ShowWebsiteDialog(HWND hwndParent); 73 | 74 | /** 75 | * @brief 显示番茄钟组合对话框 76 | * @param hwndParent 父窗口句柄 77 | * 78 | * 显示用于设置番茄钟时间组合的对话框。 79 | * 允许用户输入自定义的番茄钟时间序列。 80 | */ 81 | void ShowPomodoroComboDialog(HWND hwndParent); 82 | 83 | /** 84 | * @brief 解析时间输入 85 | * @param input 输入字符串 (如 "25m", "30s", "1h30m") 86 | * @param seconds 输出秒数 87 | * @return BOOL 解析成功返回TRUE,失败返回FALSE 88 | */ 89 | BOOL ParseTimeInput(const char* input, int* seconds); 90 | 91 | /** 92 | * @brief 显示通知消息设置对话框 93 | * @param hwndParent 父窗口句柄 94 | * 95 | * 显示通知消息设置对话框,用于修改各种通知提示文本。 96 | */ 97 | void ShowNotificationMessagesDialog(HWND hwndParent); 98 | 99 | /** 100 | * @brief 显示通知显示设置对话框 101 | * @param hwndParent 父窗口句柄 102 | * 103 | * 显示通知显示设置对话框,用于修改通知显示时间和透明度。 104 | */ 105 | void ShowNotificationDisplayDialog(HWND hwndParent); 106 | 107 | /** 108 | * @brief 显示整合后的通知设置对话框 109 | * @param hwndParent 父窗口句柄 110 | * 111 | * 显示同时包含通知内容和通知显示设置的整合对话框。 112 | * 与之前的两个单独对话框不同,这个对话框整合了所有通知相关设置。 113 | */ 114 | void ShowNotificationSettingsDialog(HWND hwndParent); 115 | 116 | /** 117 | * @brief 全局倒计时输入对话框句柄 118 | * 119 | * 用于跟踪当前显示的倒计时输入对话框。 120 | * 如果为NULL,表示没有输入对话框正在显示。 121 | */ 122 | extern HWND g_hwndInputDialog; 123 | 124 | #endif // DIALOG_PROCEDURE_H -------------------------------------------------------------------------------- /include/drag_scale.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file drag_scale.h 3 | * @brief 窗口拖动和缩放功能接口 4 | * 5 | * 本文件定义了应用程序窗口的拖动和缩放功能接口, 6 | * 包括鼠标拖动窗口和滚轮缩放窗口的功能。 7 | */ 8 | 9 | #ifndef DRAG_SCALE_H 10 | #define DRAG_SCALE_H 11 | 12 | #include 13 | 14 | // 记录编辑模式前的置顶状态 15 | extern BOOL PREVIOUS_TOPMOST_STATE; 16 | 17 | /** 18 | * @brief 处理窗口拖动事件 19 | * @param hwnd 窗口句柄 20 | * @return BOOL 是否处理了事件 21 | * 22 | * 在编辑模式下,处理鼠标拖动窗口的事件。 23 | * 根据鼠标移动距离更新窗口位置。 24 | */ 25 | BOOL HandleDragWindow(HWND hwnd); 26 | 27 | /** 28 | * @brief 处理窗口缩放事件 29 | * @param hwnd 窗口句柄 30 | * @param delta 鼠标滚轮增量 31 | * @return BOOL 是否处理了事件 32 | * 33 | * 在编辑模式下,处理鼠标滚轮缩放窗口的事件。 34 | * 根据滚轮方向调整窗口和字体大小。 35 | */ 36 | BOOL HandleScaleWindow(HWND hwnd, int delta); 37 | 38 | /** 39 | * @brief 开始拖动窗口 40 | * @param hwnd 窗口句柄 41 | * 42 | * 在编辑模式下,开始拖动窗口操作。 43 | * 记录初始鼠标位置并设置捕获。 44 | */ 45 | void StartDragWindow(HWND hwnd); 46 | 47 | /** 48 | * @brief 结束拖动窗口 49 | * @param hwnd 窗口句柄 50 | * 51 | * 结束拖动窗口操作。 52 | * 释放鼠标捕获并调整窗口位置。 53 | */ 54 | void EndDragWindow(HWND hwnd); 55 | 56 | /** 57 | * @brief 开始编辑模式 58 | * @param hwnd 窗口句柄 59 | * 60 | * 启用编辑模式前,确保窗口为置顶状态, 61 | * 记录原始置顶状态以便退出编辑模式时恢复。 62 | */ 63 | void StartEditMode(HWND hwnd); 64 | 65 | /** 66 | * @brief 结束编辑模式 67 | * @param hwnd 窗口句柄 68 | * 69 | * 退出编辑模式,恢复窗口原始置顶状态, 70 | * 清除模糊效果并更新相关设置。 71 | */ 72 | void EndEditMode(HWND hwnd); 73 | 74 | #endif // DRAG_SCALE_H -------------------------------------------------------------------------------- /include/drawing.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file drawing.h 3 | * @brief 窗口绘图功能接口 4 | * 5 | * 本文件定义了应用程序窗口绘图相关的函数接口, 6 | * 包括文本渲染、颜色设置和窗口内容绘制等功能。 7 | */ 8 | 9 | #ifndef DRAWING_H 10 | #define DRAWING_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 处理窗口绘制 16 | * @param hwnd 窗口句柄 17 | * @param ps 绘制结构体 18 | * 19 | * 处理窗口的WM_PAINT消息,执行以下操作: 20 | * 1. 创建内存DC双缓冲防止闪烁 21 | * 2. 根据模式计算剩余时间/获取当前时间 22 | * 3. 动态加载字体资源(支持实时预览) 23 | * 4. 解析颜色配置(支持HEX/RGB格式) 24 | * 5. 使用双缓冲机制绘制文本 25 | * 6. 自动调整窗口尺寸适应文本内容 26 | */ 27 | void HandleWindowPaint(HWND hwnd, PAINTSTRUCT *ps); 28 | 29 | #endif // DRAWING_H -------------------------------------------------------------------------------- /include/font.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file font.h 3 | * @brief 字体管理模块头文件 4 | * 5 | * 本文件定义了应用程序的字体管理相关接口,包括字体加载、设置和管理功能。 6 | */ 7 | 8 | #ifndef FONT_H 9 | #define FONT_H 10 | 11 | #include 12 | #include 13 | 14 | /// 字体资源结构体,用于管理字体资源 15 | typedef struct { 16 | int menuId; 17 | int resourceId; 18 | const char* fontName; 19 | } FontResource; 20 | 21 | /// 字体资源数组,存储所有可用的字体资源 22 | extern FontResource fontResources[]; 23 | 24 | /// 字体资源数组的大小 25 | extern const int FONT_RESOURCES_COUNT; 26 | 27 | /// 字体文件名 28 | extern char FONT_FILE_NAME[100]; 29 | 30 | /// 字体内部名称 31 | extern char FONT_INTERNAL_NAME[100]; 32 | 33 | /// 预览字体名称 34 | extern char PREVIEW_FONT_NAME[100]; 35 | 36 | /// 预览字体内部名称 37 | extern char PREVIEW_INTERNAL_NAME[100]; 38 | 39 | /// 是否正在预览字体 40 | extern BOOL IS_PREVIEWING; 41 | 42 | /** 43 | * @brief 从资源加载字体 44 | * @param hInstance 应用程序实例句柄 45 | * @param resourceId 字体资源ID 46 | * @return 加载是否成功 47 | */ 48 | BOOL LoadFontFromResource(HINSTANCE hInstance, int resourceId); 49 | 50 | /** 51 | * @brief 根据字体名称加载字体 52 | * @param hInstance 应用程序实例句柄 53 | * @param fontName 字体名称 54 | * @return 加载是否成功 55 | */ 56 | BOOL LoadFontByName(HINSTANCE hInstance, const char* fontName); 57 | 58 | /** 59 | * @brief 写入字体配置到配置文件 60 | * @param font_file_name 字体文件名 61 | */ 62 | void WriteConfigFont(const char* font_file_name); 63 | 64 | /** 65 | * @brief 列出系统中可用的字体 66 | */ 67 | void ListAvailableFonts(void); 68 | 69 | /** 70 | * @brief 预览字体 71 | * @param hInstance 应用程序实例句柄 72 | * @param fontName 要预览的字体名称 73 | * @return 预览是否成功 74 | */ 75 | BOOL PreviewFont(HINSTANCE hInstance, const char* fontName); 76 | 77 | /** 78 | * @brief 取消字体预览 79 | */ 80 | void CancelFontPreview(void); 81 | 82 | /** 83 | * @brief 应用字体预览 84 | */ 85 | void ApplyFontPreview(void); 86 | 87 | /** 88 | * @brief 切换字体 89 | * @param hInstance 应用程序实例句柄 90 | * @param fontName 要切换的字体名称 91 | * @return 切换是否成功 92 | */ 93 | BOOL SwitchFont(HINSTANCE hInstance, const char* fontName); 94 | 95 | #endif /* FONT_H */ -------------------------------------------------------------------------------- /include/hotkey.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file hotkey.h 3 | * @brief 热键管理接口 4 | * 5 | * 本文件定义了应用程序的热键管理接口, 6 | * 处理全局热键的设置、对话框交互和配置保存。 7 | */ 8 | 9 | #ifndef HOTKEY_H 10 | #define HOTKEY_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 显示热键设置对话框 16 | * @param hwndParent 父窗口句柄 17 | * 18 | * 显示热键设置对话框,用于设置全局热键。 19 | */ 20 | void ShowHotkeySettingsDialog(HWND hwndParent); 21 | 22 | /** 23 | * @brief 热键设置对话框消息处理过程 24 | * @param hwndDlg 对话框句柄 25 | * @param msg 消息类型 26 | * @param wParam 消息参数 27 | * @param lParam 消息参数 28 | * @return INT_PTR 消息处理结果 29 | * 30 | * 处理热键设置对话框的所有消息事件,包括初始化、背景颜色和按钮点击。 31 | */ 32 | INT_PTR CALLBACK HotkeySettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); 33 | 34 | /** 35 | * @brief 热键控件子类化处理函数 36 | * @param hwnd 热键控件窗口句柄 37 | * @param uMsg 消息类型 38 | * @param wParam 消息参数 39 | * @param lParam 消息参数 40 | * @param uIdSubclass 子类ID 41 | * @param dwRefData 引用数据 42 | * @return LRESULT 消息处理结果 43 | * 44 | * 处理热键控件的消息,特别是拦截Alt键和Alt+Shift组合键 45 | * 防止Windows系统发出提示音 46 | */ 47 | LRESULT CALLBACK HotkeyControlSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, 48 | LPARAM lParam, UINT_PTR uIdSubclass, 49 | DWORD_PTR dwRefData); 50 | 51 | #endif // HOTKEY_H -------------------------------------------------------------------------------- /include/language.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language.h 3 | * @brief 多语言支持模块头文件 4 | * 5 | * 本文件定义了应用程序支持的语言枚举和本地化字符串获取接口。 6 | */ 7 | 8 | #ifndef LANGUAGE_H 9 | #define LANGUAGE_H 10 | 11 | #include 12 | #include 13 | 14 | /** 15 | * @enum AppLanguage 16 | * @brief 应用程序支持的语言枚举 17 | * 18 | * 定义应用程序支持的所有语言选项,用于国际化功能实现。 19 | */ 20 | typedef enum { 21 | APP_LANG_CHINESE_SIMP, ///< 简体中文 (Simplified Chinese) 22 | APP_LANG_CHINESE_TRAD, ///< 繁体中文 (Traditional Chinese) 23 | APP_LANG_ENGLISH, ///< 英语 (English) 24 | APP_LANG_SPANISH, ///< 西班牙语 (Spanish) 25 | APP_LANG_FRENCH, ///< 法语 (French) 26 | APP_LANG_GERMAN, ///< 德语 (German) 27 | APP_LANG_RUSSIAN, ///< 俄语 (Russian) 28 | APP_LANG_PORTUGUESE, ///< 葡萄牙语 (Portuguese) 29 | APP_LANG_JAPANESE, ///< 日语 (Japanese) 30 | APP_LANG_KOREAN, ///< 韩语 (Korean) 31 | APP_LANG_COUNT ///< 语言总数,用于范围检查 32 | } AppLanguage; 33 | 34 | /// 当前应用程序使用的语言,默认根据系统语言自动检测 35 | extern AppLanguage CURRENT_LANGUAGE; 36 | 37 | /** 38 | * @brief 获取本地化字符串 39 | * @param chinese 简体中文版本的字符串 40 | * @param english 英语版本的字符串 41 | * @return 根据当前语言设置返回对应语言的字符串指针 42 | * 43 | * 示例用法: 44 | * @code 45 | * const wchar_t* text = GetLocalizedString(L"你好", L"Hello"); 46 | * @endcode 47 | */ 48 | const wchar_t* GetLocalizedString(const wchar_t* chinese, const wchar_t* english); 49 | 50 | /** 51 | * @brief 设置应用程序语言 52 | * @param language 要设置的语言 53 | * @return 是否设置成功 54 | * 55 | * 手动设置应用程序语言,会自动重新加载对应语言的翻译文件。 56 | */ 57 | BOOL SetLanguage(AppLanguage language); 58 | 59 | /** 60 | * @brief 获取当前应用程序语言 61 | * @return 当前设置的语言 62 | */ 63 | AppLanguage GetCurrentLanguage(void); 64 | 65 | #endif /* LANGUAGE_H */ 66 | -------------------------------------------------------------------------------- /include/log.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file log.h 3 | * @brief 日志记录功能头文件 4 | * 5 | * 提供日志记录功能,记录应用程序错误和关键事件信息 6 | */ 7 | 8 | #ifndef LOG_H 9 | #define LOG_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | // 日志级别枚举 16 | typedef enum { 17 | LOG_LEVEL_DEBUG, // 调试信息 18 | LOG_LEVEL_INFO, // 一般信息 19 | LOG_LEVEL_WARNING, // 警告信息 20 | LOG_LEVEL_ERROR, // 错误信息 21 | LOG_LEVEL_FATAL // 致命错误 22 | } LogLevel; 23 | 24 | /** 25 | * @brief 初始化日志系统 26 | * 27 | * 设置日志文件路径,根据应用配置文件所在目录自动创建日志目录 28 | * 29 | * @return BOOL 初始化是否成功 30 | */ 31 | BOOL InitializeLogSystem(void); 32 | 33 | /** 34 | * @brief 写入日志 35 | * 36 | * 根据指定的日志级别写入日志信息 37 | * 38 | * @param level 日志级别 39 | * @param format 格式化字符串 40 | * @param ... 可变参数列表 41 | */ 42 | void WriteLog(LogLevel level, const char* format, ...); 43 | 44 | /** 45 | * @brief 获取最后一个Windows错误的描述 46 | * 47 | * @param errorCode Windows错误代码 48 | * @param buffer 用于存储错误描述的缓冲区 49 | * @param bufferSize 缓冲区大小 50 | */ 51 | void GetLastErrorDescription(DWORD errorCode, char* buffer, int bufferSize); 52 | 53 | /** 54 | * @brief 设置全局异常处理器 55 | * 56 | * 捕获标准C信号(SIGFPE, SIGILL, SIGSEGV等)并处理 57 | */ 58 | void SetupExceptionHandler(void); 59 | 60 | /** 61 | * @brief 清理日志系统资源 62 | * 63 | * 程序正常退出时关闭日志文件并释放相关资源 64 | */ 65 | void CleanupLogSystem(void); 66 | 67 | // 宏定义,便于调用 68 | #define LOG_DEBUG(format, ...) WriteLog(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__) 69 | #define LOG_INFO(format, ...) WriteLog(LOG_LEVEL_INFO, format, ##__VA_ARGS__) 70 | #define LOG_WARNING(format, ...) WriteLog(LOG_LEVEL_WARNING, format, ##__VA_ARGS__) 71 | #define LOG_ERROR(format, ...) WriteLog(LOG_LEVEL_ERROR, format, ##__VA_ARGS__) 72 | #define LOG_FATAL(format, ...) WriteLog(LOG_LEVEL_FATAL, format, ##__VA_ARGS__) 73 | 74 | // 带错误代码的日志宏 75 | #define LOG_WINDOWS_ERROR(format, ...) do { \ 76 | DWORD errorCode = GetLastError(); \ 77 | char errorMessage[256] = {0}; \ 78 | GetLastErrorDescription(errorCode, errorMessage, sizeof(errorMessage)); \ 79 | WriteLog(LOG_LEVEL_ERROR, format " (错误码: %lu, 描述: %s)", ##__VA_ARGS__, errorCode, errorMessage); \ 80 | } while(0) 81 | 82 | #endif // LOG_H 83 | -------------------------------------------------------------------------------- /include/media.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file media.h 3 | * @brief 媒体控制功能接口 4 | * 5 | * 本文件定义了应用程序媒体控制相关的函数接口, 6 | * 包括暂停、播放等媒体控制操作。 7 | */ 8 | 9 | #ifndef CLOCK_MEDIA_H 10 | #define CLOCK_MEDIA_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 暂停媒体播放 16 | * 17 | * 通过模拟媒体控制键的按键事件来暂停当前正在播放的媒体。 18 | * 包括停止和暂停/播放的组合操作,以确保媒体被正确暂停。 19 | */ 20 | void PauseMediaPlayback(void); 21 | 22 | #endif // CLOCK_MEDIA_H -------------------------------------------------------------------------------- /include/notification.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file notification.h 3 | * @brief 应用通知系统接口 4 | * 5 | * 本文件定义了应用程序的通知系统接口,包括自定义样式的弹出通知和系统托盘通知。 6 | */ 7 | 8 | #ifndef NOTIFICATION_H 9 | #define NOTIFICATION_H 10 | 11 | #include 12 | #include "config.h" // 引入通知类型枚举 13 | 14 | // 全局变量:通知显示持续时间(毫秒) 15 | extern int NOTIFICATION_TIMEOUT_MS; // 新增:通知显示时间变量 16 | 17 | /** 18 | * @brief 显示通知(根据配置的通知类型) 19 | * @param hwnd 父窗口句柄,用于获取应用实例和计算位置 20 | * @param message 要显示的通知消息文本(UTF-8编码) 21 | * 22 | * 根据配置的通知类型显示不同风格的通知: 23 | * - NOTIFICATION_TYPE_CATIME: 使用Catime自定义通知窗口 24 | * - NOTIFICATION_TYPE_SYSTEM_MODAL: 使用系统模态对话框 25 | * - NOTIFICATION_TYPE_OS: 使用系统托盘通知 26 | */ 27 | void ShowNotification(HWND hwnd, const char* message); 28 | 29 | /** 30 | * @brief 显示自定义样式的提示通知 31 | * @param hwnd 父窗口句柄,用于获取应用实例和计算位置 32 | * @param message 要显示的通知消息文本(UTF-8编码) 33 | * 34 | * 在屏幕右下角显示一个带动画效果的自定义通知窗口 35 | */ 36 | void ShowToastNotification(HWND hwnd, const char* message); 37 | 38 | /** 39 | * @brief 显示系统模态对话框通知 40 | * @param hwnd 父窗口句柄 41 | * @param message 要显示的通知消息文本(UTF-8编码) 42 | * 43 | * 显示一个阻塞的系统消息框通知 44 | */ 45 | void ShowModalNotification(HWND hwnd, const char* message); 46 | 47 | /** 48 | * @brief 关闭所有当前显示的Catime通知窗口 49 | * 50 | * 查找并关闭所有由Catime创建的通知窗口,无视它们当前的显示时间设置, 51 | * 直接开始淡出动画。通常在切换计时器模式时调用,确保通知不会继续显示。 52 | */ 53 | void CloseAllNotifications(void); 54 | 55 | // 系统托盘通知已在tray.h中定义:void ShowTrayNotification(HWND hwnd, const char* message); 56 | 57 | #endif // NOTIFICATION_H -------------------------------------------------------------------------------- /include/pomodoro.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file pomodoro.h 3 | * @brief 番茄钟相关定义 4 | * 5 | * 定义番茄钟的阶段和共享变量 6 | */ 7 | 8 | #ifndef POMODORO_H 9 | #define POMODORO_H 10 | 11 | // 番茄钟阶段枚举 12 | typedef enum { 13 | POMODORO_PHASE_IDLE = 0, // 空闲状态 14 | POMODORO_PHASE_WORK, // 工作阶段 15 | POMODORO_PHASE_BREAK, // 休息阶段 16 | POMODORO_PHASE_LONG_BREAK // 长休息阶段 17 | } POMODORO_PHASE; 18 | 19 | // 当前番茄钟阶段 20 | extern POMODORO_PHASE current_pomodoro_phase; 21 | 22 | // 当前正在执行的番茄钟时间索引 23 | extern int current_pomodoro_time_index; 24 | 25 | // 完成的番茄钟循环次数 26 | extern int complete_pomodoro_cycles; 27 | 28 | // 初始化番茄钟状态为工作阶段 29 | void InitializePomodoro(void); 30 | 31 | #endif // POMODORO_H 32 | -------------------------------------------------------------------------------- /include/shortcut_checker.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file shortcut_checker.h 3 | * @brief 检测和创建桌面快捷方式的功能 4 | * 5 | * 提供检测程序是否从应用商店或WinGet安装, 6 | * 并在需要时在桌面创建快捷方式的功能。 7 | */ 8 | 9 | #ifndef SHORTCUT_CHECKER_H 10 | #define SHORTCUT_CHECKER_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 检查并创建桌面快捷方式 16 | * 17 | * 检查程序是否从Windows应用商店或WinGet安装, 18 | * 如果是且配置中没有标记为已检查过,则检查桌面 19 | * 是否有程序的快捷方式,如果没有则创建一个。 20 | * 21 | * @return int 0表示无需创建或创建成功,1表示创建失败 22 | */ 23 | int CheckAndCreateShortcut(void); 24 | 25 | #endif /* SHORTCUT_CHECKER_H */ -------------------------------------------------------------------------------- /include/startup.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file startup.h 3 | * @brief 开机自启动功能接口 4 | * 5 | * 本文件定义了应用程序开机自启动相关的函数接口, 6 | * 包括检查是否已启用自启动、创建和删除自启动快捷方式的功能。 7 | */ 8 | 9 | #ifndef STARTUP_H 10 | #define STARTUP_H 11 | 12 | #include 13 | #include 14 | 15 | /** 16 | * @brief 检查应用程序是否已设置为开机自启动 17 | * @return BOOL 如果已启用开机自启动则返回TRUE,否则返回FALSE 18 | * 19 | * 通过检查启动文件夹中是否存在应用程序的快捷方式来判断是否已启用自启动。 20 | */ 21 | BOOL IsAutoStartEnabled(void); 22 | 23 | /** 24 | * @brief 创建开机自启动快捷方式 25 | * @return BOOL 如果创建成功则返回TRUE,否则返回FALSE 26 | * 27 | * 在系统启动文件夹中创建应用程序的快捷方式,使其能够在系统启动时自动运行。 28 | */ 29 | BOOL CreateShortcut(void); 30 | 31 | /** 32 | * @brief 删除开机自启动快捷方式 33 | * @return BOOL 如果删除成功则返回TRUE,否则返回FALSE 34 | * 35 | * 从系统启动文件夹中删除应用程序的快捷方式,禁用其开机自启动功能。 36 | */ 37 | BOOL RemoveShortcut(void); 38 | 39 | /** 40 | * @brief 更新开机自启动快捷方式 41 | * 42 | * 检查是否已启用自启动,如果已启用,则删除旧的快捷方式并创建新的, 43 | * 确保即使应用程序位置发生变化,自启动功能也能正常工作。 44 | * 45 | * @return BOOL 如果更新成功则返回TRUE,否则返回FALSE 46 | */ 47 | BOOL UpdateStartupShortcut(void); 48 | 49 | #endif // STARTUP_H 50 | -------------------------------------------------------------------------------- /include/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file timer.h 3 | * @brief 计时器核心功能定义 4 | * 5 | * 本头文件定义计时器相关数据结构、状态枚举及全局变量, 6 | * 包含倒计时/正计时模式切换、超时动作处理等核心功能声明。 7 | */ 8 | 9 | #ifndef TIMER_H 10 | #define TIMER_H 11 | 12 | #include 13 | #include 14 | 15 | /// 最大预设时间选项数量 16 | #define MAX_TIME_OPTIONS 10 17 | 18 | /// 番茄钟时间变量(单位:秒) 19 | extern int POMODORO_WORK_TIME; ///< 番茄钟工作时间(默认25分钟) 20 | extern int POMODORO_SHORT_BREAK; ///< 番茄钟短休息时间(默认5分钟) 21 | extern int POMODORO_LONG_BREAK; ///< 番茄钟长休息时间(默认15分钟) 22 | extern int POMODORO_LOOP_COUNT; ///< 番茄钟循环次数(默认1次) 23 | 24 | /** 25 | * @brief 超时动作类型枚举 26 | * 27 | * 定义计时器超时后执行的不同操作类型: 28 | * - MESSAGE: 显示提示信息 29 | * - LOCK: 锁定计算机 30 | * - SHUTDOWN: 关闭系统 31 | * - RESTART: 重启系统 32 | * - OPEN_FILE: 打开指定文件 33 | * - SHOW_TIME: 显示当前时间 34 | * - COUNT_UP: 正计时 35 | * - OPEN_WEBSITE: 打开网站 36 | * - SLEEP: 睡眠 37 | */ 38 | typedef enum { 39 | TIMEOUT_ACTION_MESSAGE = 0, 40 | TIMEOUT_ACTION_LOCK = 1, 41 | TIMEOUT_ACTION_SHUTDOWN = 2, 42 | TIMEOUT_ACTION_RESTART = 3, 43 | TIMEOUT_ACTION_OPEN_FILE = 4, 44 | TIMEOUT_ACTION_SHOW_TIME = 5, 45 | TIMEOUT_ACTION_COUNT_UP = 6, 46 | TIMEOUT_ACTION_OPEN_WEBSITE = 7, 47 | TIMEOUT_ACTION_SLEEP = 8 48 | } TimeoutActionType; 49 | 50 | // 计时器状态 -------------------------------------------------- 51 | extern BOOL CLOCK_IS_PAUSED; ///< 暂停状态标识 52 | extern BOOL CLOCK_SHOW_CURRENT_TIME; ///< 显示实时时钟模式 53 | extern BOOL CLOCK_USE_24HOUR; ///< 24小时制显示 54 | extern BOOL CLOCK_SHOW_SECONDS; ///< 显示秒数 55 | extern BOOL CLOCK_COUNT_UP; ///< 正计时模式开关 56 | extern char CLOCK_STARTUP_MODE[20]; ///< 启动模式(COUNTDOWN/COUNTUP) 57 | 58 | // 时间相关 ---------------------------------------------------- 59 | extern int CLOCK_TOTAL_TIME; ///< 总计时时间(秒) 60 | extern int countdown_elapsed_time; ///< 倒计时已用时间 61 | extern int countup_elapsed_time; ///< 正计时累计时间 62 | extern time_t CLOCK_LAST_TIME_UPDATE;///< 最后更新时间戳 63 | extern int last_displayed_second; ///< 上一次显示的秒数,用于同步时间显示 64 | 65 | // 消息状态 ---------------------------------------------------- 66 | extern BOOL countdown_message_shown; ///< 倒计时提示显示状态 67 | extern BOOL countup_message_shown; ///< 正计时提示显示状态 68 | extern int pomodoro_work_cycles; ///< 番茄钟工作周期计数 69 | 70 | // 超时动作配置 ------------------------------------------------ 71 | extern TimeoutActionType CLOCK_TIMEOUT_ACTION; ///< 当前超时动作类型 72 | extern char CLOCK_TIMEOUT_TEXT[50]; ///< 超时提示文本内容 73 | extern char CLOCK_TIMEOUT_FILE_PATH[MAX_PATH]; ///< 超时打开文件路径 74 | extern char CLOCK_TIMEOUT_WEBSITE_URL[MAX_PATH]; ///< 超时打开网站URL 75 | 76 | // 时间选项配置 ------------------------------------------------ 77 | extern int time_options[MAX_TIME_OPTIONS]; ///< 预设时间选项数组 78 | extern int time_options_count; ///< 有效选项数量 79 | 80 | /** 81 | * @brief 格式化时间显示 82 | * @param remaining_time 剩余时间(秒) 83 | * @param time_text 输出缓冲区(至少9字节) 84 | * 85 | * 根据当前计时模式(24小时制/显示秒数)将秒数转换为"HH:MM:SS"格式, 86 | * 自动处理倒计时/正计时的显示差异。 87 | */ 88 | void FormatTime(int remaining_time, char* time_text); 89 | 90 | /** 91 | * @brief 解析用户输入时间 92 | * @param input 用户输入字符串 93 | * @param total_seconds 输出解析后的总秒数 94 | * @return int 解析成功返回1,失败返回0 95 | * 96 | * 支持"MM:SS"、"HH:MM:SS"及纯数字秒数格式, 97 | * 最大支持99小时59分59秒(359999秒)。 98 | */ 99 | int ParseInput(const char* input, int* total_seconds); 100 | 101 | /** 102 | * @brief 验证时间输入格式 103 | * @param input 待验证字符串 104 | * @return int 有效返回1,无效返回0 105 | * 106 | * 检查输入是否符合以下格式: 107 | * - 纯数字(秒数) 108 | * - MM:SS (1-59分 或 00-59秒) 109 | * - HH:MM:SS (00-99小时 00-59分 00-59秒) 110 | */ 111 | int isValidInput(const char* input); 112 | 113 | /** 114 | * @brief 写入默认启动时间配置 115 | * @param seconds 默认启动时间(秒) 116 | * 117 | * 更新配置文件中的CLOCK_DEFAULT_START_TIME项, 118 | * 影响计时器初始值及重置操作。 119 | */ 120 | void WriteConfigDefaultStartTime(int seconds); 121 | 122 | /** 123 | * @brief 写入启动模式配置 124 | * @param mode 启动模式字符串("COUNTDOWN"/"COUNTUP") 125 | * 126 | * 修改配置文件中的STARTUP_MODE项, 127 | * 控制程序启动时的默认计时模式。 128 | */ 129 | void WriteConfigStartupMode(const char* mode); 130 | 131 | #endif // TIMER_H -------------------------------------------------------------------------------- /include/timer_events.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file timer_events.h 3 | * @brief 计时器事件处理接口 4 | * 5 | * 本文件定义了应用程序计时器事件处理相关的函数接口, 6 | * 包括倒计时和正计时模式的事件处理。 7 | */ 8 | 9 | #ifndef TIMER_EVENTS_H 10 | #define TIMER_EVENTS_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 处理计时器消息 16 | * @param hwnd 窗口句柄 17 | * @param wp 消息参数 18 | * @return BOOL 是否处理了消息 19 | * 20 | * 处理WM_TIMER消息,包括: 21 | * 1. 倒计时模式:更新剩余时间并执行超时动作 22 | * 2. 计时模式:累计已过时间 23 | * 3. 显示当前时间模式 24 | */ 25 | BOOL HandleTimerEvent(HWND hwnd, WPARAM wp); 26 | 27 | #endif // TIMER_EVENTS_H -------------------------------------------------------------------------------- /include/tray.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tray.h 3 | * @brief 系统托盘功能接口 4 | * 5 | * 本文件定义了应用程序的系统托盘操作接口,包括初始化、移除和通知显示功能。 6 | */ 7 | 8 | #ifndef TRAY_H 9 | #define TRAY_H 10 | 11 | #include 12 | 13 | /// @name 系统托盘消息常量 14 | /// @{ 15 | #define CLOCK_WM_TRAYICON (WM_USER + 2) ///< 自定义托盘图标消息ID 16 | /// @} 17 | 18 | /// @name 系统托盘标识常量 19 | /// @{ 20 | #define CLOCK_ID_TRAY_APP_ICON 1001 ///< 托盘图标标识ID 21 | /// @} 22 | 23 | /// TaskbarCreated消息ID 24 | extern UINT WM_TASKBARCREATED; 25 | 26 | /** 27 | * @brief 注册TaskbarCreated消息 28 | * 29 | * 注册系统发送的TaskbarCreated消息,用于在资源管理器重启后重新创建托盘图标 30 | */ 31 | void RegisterTaskbarCreatedMessage(void); 32 | 33 | /** 34 | * @brief 初始化系统托盘图标 35 | * @param hwnd 与托盘图标关联的窗口句柄 36 | * @param hInstance 应用程序实例句柄 37 | * 38 | * 创建并显示带有默认设置的系统托盘图标。 39 | * 该图标将通过CLOCK_WM_TRAYICON回调接收消息。 40 | */ 41 | void InitTrayIcon(HWND hwnd, HINSTANCE hInstance); 42 | 43 | /** 44 | * @brief 删除系统托盘图标 45 | * 46 | * 从系统托盘中移除应用程序的图标。 47 | * 应在应用程序关闭时调用。 48 | */ 49 | void RemoveTrayIcon(void); 50 | 51 | /** 52 | * @brief 在系统托盘中显示通知 53 | * @param hwnd 与通知关联的窗口句柄 54 | * @param message 要在通知中显示的文本消息 55 | * 56 | * 从系统托盘图标显示气球提示通知。 57 | * 通知使用NIIF_NONE样式(无图标)并在3秒后超时。 58 | */ 59 | void ShowTrayNotification(HWND hwnd, const char* message); 60 | 61 | /** 62 | * @brief 重新创建托盘图标 63 | * @param hwnd 窗口句柄 64 | * @param hInstance 实例句柄 65 | * 66 | * 在Windows资源管理器重启后重新创建托盘图标。 67 | * 应在收到TaskbarCreated消息时调用此函数。 68 | */ 69 | void RecreateTaskbarIcon(HWND hwnd, HINSTANCE hInstance); 70 | 71 | /** 72 | * @brief 更新托盘图标和菜单 73 | * @param hwnd 窗口句柄 74 | * 75 | * 在应用程序语言或设置更改后更新托盘图标和菜单。 76 | * 用于确保托盘菜单显示的文本与当前语言设置一致。 77 | */ 78 | void UpdateTrayIcon(HWND hwnd); 79 | 80 | #endif // TRAY_H -------------------------------------------------------------------------------- /include/tray_events.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tray_events.h 3 | * @brief 系统托盘事件处理接口 4 | * 5 | * 本文件定义了应用程序系统托盘事件处理相关的函数接口, 6 | * 包括托盘图标的点击事件处理等功能。 7 | */ 8 | 9 | #ifndef CLOCK_TRAY_EVENTS_H 10 | #define CLOCK_TRAY_EVENTS_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 处理系统托盘消息 16 | * @param hwnd 窗口句柄 17 | * @param uID 托盘图标ID 18 | * @param uMouseMsg 鼠标消息类型 19 | * 20 | * 处理系统托盘的鼠标事件,包括: 21 | * - 左键点击:显示上下文菜单 22 | * - 右键点击:显示颜色菜单 23 | */ 24 | void HandleTrayIconMessage(HWND hwnd, UINT uID, UINT uMouseMsg); 25 | 26 | /** 27 | * @brief 暂停或继续计时器 28 | * @param hwnd 窗口句柄 29 | * 30 | * 根据当前状态暂停或继续计时器,并更新相关状态变量 31 | */ 32 | void PauseResumeTimer(HWND hwnd); 33 | 34 | /** 35 | * @brief 重新开始计时器 36 | * @param hwnd 窗口句柄 37 | * 38 | * 重置计时器到初始状态并继续运行 39 | */ 40 | void RestartTimer(HWND hwnd); 41 | 42 | /** 43 | * @brief 设置启动模式 44 | * @param hwnd 窗口句柄 45 | * @param mode 启动模式字符串 46 | * 47 | * 根据给定的模式设置启动模式,并更新相关状态变量 48 | */ 49 | void SetStartupMode(HWND hwnd, const char* mode); 50 | 51 | /** 52 | * @brief 打开用户指南 53 | * 54 | * 打开用户指南,提供应用程序的使用说明和帮助 55 | */ 56 | void OpenUserGuide(void); 57 | 58 | /** 59 | * @brief 打开支持页面 60 | * 61 | * 打开支持页面,提供支持开发者的渠道 62 | */ 63 | void OpenSupportPage(void); 64 | 65 | /** 66 | * @brief 打开反馈页面 67 | * 68 | * 根据当前语言设置打开不同的反馈渠道: 69 | * - 简体中文:打开bilibili私信页面 70 | * - 其他语言:打开GitHub Issues页面 71 | */ 72 | void OpenFeedbackPage(void); 73 | 74 | #endif // CLOCK_TRAY_EVENTS_H -------------------------------------------------------------------------------- /include/tray_menu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tray_menu.h 3 | * @brief 系统托盘菜单功能接口 4 | * 5 | * 本文件定义了系统托盘菜单相关的常量和函数接口, 6 | * 包括菜单项ID定义和菜单显示函数声明。 7 | */ 8 | 9 | #ifndef CLOCK_TRAY_MENU_H 10 | #define CLOCK_TRAY_MENU_H 11 | 12 | #include 13 | 14 | /// @name 时间显示相关菜单项 15 | /// @{ 16 | #define CLOCK_IDM_SHOW_CURRENT_TIME 150 ///< 显示当前时间选项 17 | #define CLOCK_IDM_24HOUR_FORMAT 151 ///< 24小时制显示格式 18 | #define CLOCK_IDM_SHOW_SECONDS 152 ///< 显示秒数选项 19 | /// @} 20 | 21 | /// @name 计时功能菜单项 22 | /// @{ 23 | #define CLOCK_IDM_TIMER_MANAGEMENT 159 ///< 计时管理主菜单 24 | #define CLOCK_IDM_TIMER_PAUSE_RESUME 158 ///< 暂停/继续计时 25 | #define CLOCK_IDM_TIMER_RESTART 177 ///< 重新开始计时 26 | #define CLOCK_IDM_COUNT_UP_START 171 ///< 开始/暂停正计时 27 | #define CLOCK_IDM_COUNT_UP_RESET 172 ///< 重置正计时 28 | #define CLOCK_IDM_COUNTDOWN_START_PAUSE 154 ///< 开始/暂停倒计时 29 | #define CLOCK_IDM_COUNTDOWN_RESET 155 ///< 重置倒计时 30 | /// @} 31 | 32 | /// @name 编辑与设置菜单项 33 | /// @{ 34 | #define CLOCK_IDC_EDIT_MODE 113 ///< 编辑模式选项 35 | /// @} 36 | 37 | /// @name 超时动作菜单项 38 | /// @{ 39 | #define CLOCK_IDM_SHOW_MESSAGE 121 ///< 显示消息动作 40 | #define CLOCK_IDM_LOCK_SCREEN 122 ///< 锁定屏幕动作 41 | #define CLOCK_IDM_SHUTDOWN 123 ///< 关机动作 42 | #define CLOCK_IDM_RESTART 124 ///< 重启动作 43 | #define CLOCK_IDM_SLEEP 125 ///< 睡眠动作 44 | #define CLOCK_IDM_BROWSE_FILE 131 ///< 浏览文件选项 45 | #define CLOCK_IDM_RECENT_FILE_1 126 ///< 最近文件起始ID 46 | #define CLOCK_IDM_TIMEOUT_SHOW_TIME 135 ///< 显示当前时间动作 47 | #define CLOCK_IDM_TIMEOUT_COUNT_UP 136 ///< 正计时动作 48 | /// @} 49 | 50 | /// @name 时间选项管理菜单项 51 | /// @{ 52 | #define CLOCK_IDC_MODIFY_TIME_OPTIONS 156 ///< 修改时间选项 53 | /// @} 54 | 55 | /// @name 启动设置菜单项 56 | /// @{ 57 | #define CLOCK_IDC_SET_COUNTDOWN_TIME 173 ///< 启动时设为倒计时 58 | #define CLOCK_IDC_START_COUNT_UP 175 ///< 启动时设为正计时 59 | #define CLOCK_IDC_START_SHOW_TIME 176 ///< 启动时显示当前时间 60 | #define CLOCK_IDC_START_NO_DISPLAY 174 ///< 启动时不显示 61 | #define CLOCK_IDC_AUTO_START 160 ///< 开机自启动 62 | /// @} 63 | 64 | /// @name 通知设置菜单项 65 | /// @{ 66 | #define CLOCK_IDM_NOTIFICATION_SETTINGS 193 ///< 通知设置主菜单 67 | #define CLOCK_IDM_NOTIFICATION_CONTENT 191 ///< 通知内容设置 68 | #define CLOCK_IDM_NOTIFICATION_DISPLAY 192 ///< 通知显示设置 69 | /// @} 70 | 71 | /// @name 番茄钟菜单项 72 | /// @{ 73 | #define CLOCK_IDM_POMODORO_START 181 ///< 开始番茄钟 74 | #define CLOCK_IDM_POMODORO_WORK 182 ///< 设置工作时间 75 | #define CLOCK_IDM_POMODORO_BREAK 183 ///< 设置短休息时间 76 | #define CLOCK_IDM_POMODORO_LBREAK 184 ///< 设置长休息时间 77 | #define CLOCK_IDM_POMODORO_LOOP_COUNT 185 ///< 设置循环次数 78 | #define CLOCK_IDM_POMODORO_RESET 186 ///< 重置番茄钟 79 | /// @} 80 | 81 | /// @name 颜色选择菜单项 82 | /// @{ 83 | #define CLOCK_IDC_COLOR_VALUE 1301 ///< 颜色值编辑项 84 | #define CLOCK_IDC_COLOR_PANEL 1302 ///< 颜色面板项 85 | /// @} 86 | 87 | /// @name 语言选择菜单项 88 | /// @{ 89 | #define CLOCK_IDM_LANG_CHINESE 161 ///< 简体中文选项 90 | #define CLOCK_IDM_LANG_CHINESE_TRAD 163 ///< 繁体中文选项 91 | #define CLOCK_IDM_LANG_ENGLISH 162 ///< 英语选项 92 | #define CLOCK_IDM_LANG_SPANISH 164 ///< 西班牙语选项 93 | #define CLOCK_IDM_LANG_FRENCH 165 ///< 法语选项 94 | #define CLOCK_IDM_LANG_GERMAN 166 ///< 德语选项 95 | #define CLOCK_IDM_LANG_RUSSIAN 167 ///< 俄语选项 96 | #define CLOCK_IDM_LANG_KOREAN 170 ///< 韩语选项 97 | /// @} 98 | 99 | /** 100 | * @brief 显示托盘右键菜单 101 | * @param hwnd 窗口句柄 102 | * 103 | * 创建并显示系统托盘右键菜单,包含时间设置、显示模式切换和快捷时间选项。 104 | * 根据当前应用程序状态动态调整菜单项。 105 | */ 106 | void ShowContextMenu(HWND hwnd); 107 | 108 | /** 109 | * @brief 显示颜色和设置菜单 110 | * @param hwnd 窗口句柄 111 | * 112 | * 创建并显示应用程序的主设置菜单,包括编辑模式、超时动作、 113 | * 预设管理、字体选择、颜色设置和关于信息等选项。 114 | */ 115 | void ShowColorMenu(HWND hwnd); 116 | 117 | #endif // CLOCK_TRAY_MENU_H -------------------------------------------------------------------------------- /include/update_checker.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file update_checker.h 3 | * @brief 极简的应用程序更新检查功能接口 4 | * 5 | * 本文件定义了应用程序检查更新、打开浏览器下载和删除配置文件的功能接口。 6 | */ 7 | 8 | #ifndef UPDATE_CHECKER_H 9 | #define UPDATE_CHECKER_H 10 | 11 | #include 12 | 13 | /** 14 | * @brief 检查应用程序更新 15 | * @param hwnd 窗口句柄 16 | * 17 | * 连接到GitHub检查是否有新版本。如果有,会提示用户是否通过浏览器下载。 18 | * 如果用户确认,将打开浏览器到下载页面,删除配置文件,并退出程序。 19 | */ 20 | void CheckForUpdate(HWND hwnd); 21 | 22 | /** 23 | * @brief 静默检查应用程序更新 24 | * @param hwnd 窗口句柄 25 | * @param silentCheck 是否仅在有更新时显示提示 26 | * 27 | * 连接到GitHub检查是否有新版本。 28 | * 如果silentCheck为TRUE,仅在有更新时才显示提示; 29 | * 如果为FALSE,则无论是否有更新都会显示结果。 30 | */ 31 | void CheckForUpdateSilent(HWND hwnd, BOOL silentCheck); 32 | 33 | /** 34 | * @brief 比较版本号 35 | * @param version1 第一个版本号字符串 36 | * @param version2 第二个版本号字符串 37 | * @return 如果version1 > version2返回1,如果相等返回0,如果version1 < version2返回-1 38 | */ 39 | int CompareVersions(const char* version1, const char* version2); 40 | 41 | #endif // UPDATE_CHECKER_H -------------------------------------------------------------------------------- /include/window.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file window.h 3 | * @brief 窗口管理功能接口 4 | * 5 | * 本文件定义了应用程序窗口管理相关的常量和函数接口, 6 | * 包括窗口创建、位置调整、透明度、点击穿透和拖拽功能。 7 | */ 8 | 9 | #ifndef WINDOW_H 10 | #define WINDOW_H 11 | 12 | #include 13 | #include 14 | 15 | /// @name 窗口尺寸和位置常量 16 | /// @{ 17 | extern int CLOCK_BASE_WINDOW_WIDTH; ///< 基础窗口宽度 18 | extern int CLOCK_BASE_WINDOW_HEIGHT; ///< 基础窗口高度 19 | extern float CLOCK_WINDOW_SCALE; ///< 窗口缩放比例 20 | extern int CLOCK_WINDOW_POS_X; ///< 窗口X坐标 21 | extern int CLOCK_WINDOW_POS_Y; ///< 窗口Y坐标 22 | /// @} 23 | 24 | /// @name 窗口状态变量 25 | /// @{ 26 | extern BOOL CLOCK_EDIT_MODE; ///< 是否处于编辑模式 27 | extern BOOL CLOCK_IS_DRAGGING; ///< 是否正在拖拽窗口 28 | extern POINT CLOCK_LAST_MOUSE_POS; ///< 上次鼠标位置 29 | extern BOOL CLOCK_WINDOW_TOPMOST; ///< 窗口是否置顶 30 | /// @} 31 | 32 | /// @name 文本区域变量 33 | /// @{ 34 | extern RECT CLOCK_TEXT_RECT; ///< 文本区域矩形 35 | extern BOOL CLOCK_TEXT_RECT_VALID; ///< 文本区域是否有效 36 | /// @} 37 | 38 | /// @name 缩放限制常量 39 | /// @{ 40 | #define MIN_SCALE_FACTOR 0.5f ///< 最小缩放比例 41 | #define MAX_SCALE_FACTOR 100.0f ///< 最大缩放比例 42 | /// @} 43 | 44 | /// @name 字体相关常量 45 | /// @{ 46 | extern float CLOCK_FONT_SCALE_FACTOR; ///< 字体缩放比例 47 | extern int CLOCK_BASE_FONT_SIZE; ///< 基础字体大小 48 | /// @} 49 | 50 | /** 51 | * @brief 设置窗口点击穿透属性 52 | * @param hwnd 窗口句柄 53 | * @param enable 是否启用点击穿透 54 | * 55 | * 控制窗口是否让鼠标点击事件穿透到下层窗口。 56 | * 在启用时,窗口将不接收任何鼠标事件。 57 | */ 58 | void SetClickThrough(HWND hwnd, BOOL enable); 59 | 60 | /** 61 | * @brief 设置窗口背景模糊效果 62 | * @param hwnd 窗口句柄 63 | * @param enable 是否启用模糊效果 64 | * 65 | * 控制窗口背景是否应用DWM模糊效果, 66 | * 使背景半透明并具有磨砂玻璃效果。 67 | */ 68 | void SetBlurBehind(HWND hwnd, BOOL enable); 69 | 70 | /** 71 | * @brief 调整窗口位置 72 | * @param hwnd 窗口句柄 73 | * @param forceOnScreen 是否强制窗口在屏幕内 74 | * 75 | * 当forceOnScreen为TRUE时,确保窗口位置在屏幕边界内, 76 | * 当窗口位置超出边界时自动调整到合适位置。 77 | * 在编辑模式下可以将forceOnScreen设置为FALSE,允许窗口拖出屏幕。 78 | */ 79 | void AdjustWindowPosition(HWND hwnd, BOOL forceOnScreen); 80 | 81 | /** 82 | * @brief 保存窗口设置 83 | * @param hwnd 窗口句柄 84 | * 85 | * 将窗口的当前位置、大小和缩放状态保存到配置文件。 86 | */ 87 | void SaveWindowSettings(HWND hwnd); 88 | 89 | /** 90 | * @brief 加载窗口设置 91 | * @param hwnd 窗口句柄 92 | * 93 | * 从配置文件加载窗口的位置、大小和缩放状态, 94 | * 并应用到指定窗口。 95 | */ 96 | void LoadWindowSettings(HWND hwnd); 97 | 98 | /** 99 | * @brief 初始化DWM模糊功能 100 | * @return BOOL 初始化是否成功 101 | * 102 | * 加载并初始化DWM API函数指针,用于窗口模糊效果。 103 | */ 104 | BOOL InitDWMFunctions(void); 105 | 106 | /** 107 | * @brief 处理窗口鼠标滚轮消息 108 | * @param hwnd 窗口句柄 109 | * @param delta 滚轮滚动量 110 | * @return BOOL 是否处理了消息 111 | * 112 | * 处理鼠标滚轮事件,在编辑模式下调整窗口大小。 113 | */ 114 | BOOL HandleMouseWheel(HWND hwnd, int delta); 115 | 116 | /** 117 | * @brief 处理窗口鼠标移动消息 118 | * @param hwnd 窗口句柄 119 | * @return BOOL 是否处理了消息 120 | * 121 | * 处理鼠标移动事件,在编辑模式下拖拽窗口。 122 | */ 123 | BOOL HandleMouseMove(HWND hwnd); 124 | 125 | /** 126 | * @brief 创建并初始化主窗口 127 | * @param hInstance 应用实例句柄 128 | * @param nCmdShow 显示命令参数 129 | * @return HWND 创建的窗口句柄 130 | * 131 | * 创建应用程序的主窗口,并设置初始属性。 132 | */ 133 | HWND CreateMainWindow(HINSTANCE hInstance, int nCmdShow); 134 | 135 | /** 136 | * @brief 初始化应用程序 137 | * @param hInstance 应用程序实例句柄 138 | * @return BOOL 初始化是否成功 139 | * 140 | * 执行应用程序启动时的初始化工作,包括设置控制台代码页、 141 | * 初始化语言、更新自启动快捷方式、读取配置文件和加载字体资源。 142 | */ 143 | BOOL InitializeApplication(HINSTANCE hInstance); 144 | 145 | /** 146 | * @brief 打开文件选择对话框 147 | * @param hwnd 父窗口句柄 148 | * @param filePath 存储选中文件路径的缓冲区 149 | * @param maxPath 缓冲区最大长度 150 | * @return BOOL 是否成功选择文件 151 | */ 152 | BOOL OpenFileDialog(HWND hwnd, char* filePath, DWORD maxPath); 153 | 154 | /** 155 | * @brief 设置窗口置顶状态 156 | * @param hwnd 窗口句柄 157 | * @param topmost 是否置顶 158 | * 159 | * 控制窗口是否始终显示在其他窗口之上。 160 | * 同时更新全局状态变量并保存配置。 161 | */ 162 | void SetWindowTopmost(HWND hwnd, BOOL topmost); 163 | 164 | #endif // WINDOW_H 165 | -------------------------------------------------------------------------------- /include/window_events.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file window_events.h 3 | * @brief 基本窗口事件处理接口 4 | * 5 | * 本文件定义了应用程序窗口的基本事件处理功能接口, 6 | * 包括窗口创建、销毁、大小调整和位置调整等基本功能。 7 | */ 8 | 9 | #ifndef WINDOW_EVENTS_H 10 | #define WINDOW_EVENTS_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 处理窗口创建事件 16 | * @param hwnd 窗口句柄 17 | * @return BOOL 处理结果 18 | */ 19 | BOOL HandleWindowCreate(HWND hwnd); 20 | 21 | /** 22 | * @brief 处理窗口销毁事件 23 | * @param hwnd 窗口句柄 24 | */ 25 | void HandleWindowDestroy(HWND hwnd); 26 | 27 | /** 28 | * @brief 处理窗口重置事件 29 | * @param hwnd 窗口句柄 30 | */ 31 | void HandleWindowReset(HWND hwnd); 32 | 33 | /** 34 | * @brief 处理窗口大小调整事件 35 | * @param hwnd 窗口句柄 36 | * @param delta 鼠标滚轮增量 37 | * @return BOOL 是否处理了事件 38 | */ 39 | BOOL HandleWindowResize(HWND hwnd, int delta); 40 | 41 | /** 42 | * @brief 处理窗口位置调整事件 43 | * @param hwnd 窗口句柄 44 | * @return BOOL 是否处理了事件 45 | */ 46 | BOOL HandleWindowMove(HWND hwnd); 47 | 48 | #endif // WINDOW_EVENTS_H -------------------------------------------------------------------------------- /include/window_procedure.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file window_procedure.h 3 | * @brief 窗口消息处理过程接口 4 | * 5 | * 本文件定义了应用程序的主窗口消息处理回调函数接口, 6 | * 处理窗口的所有消息事件包括绘制、鼠标、键盘、菜单和定时器事件。 7 | */ 8 | 9 | #ifndef WINDOW_PROCEDURE_H 10 | #define WINDOW_PROCEDURE_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief 热键ID定义 16 | */ 17 | #define HOTKEY_ID_SHOW_TIME 100 // 显示当前时间热键ID 18 | #define HOTKEY_ID_COUNT_UP 101 // 正计时热键ID 19 | #define HOTKEY_ID_COUNTDOWN 102 // 倒计时热键ID 20 | #define HOTKEY_ID_QUICK_COUNTDOWN1 103 // 快捷倒计时1热键ID 21 | #define HOTKEY_ID_QUICK_COUNTDOWN2 104 // 快捷倒计时2热键ID 22 | #define HOTKEY_ID_QUICK_COUNTDOWN3 105 // 快捷倒计时3热键ID 23 | #define HOTKEY_ID_POMODORO 106 // 番茄钟热键ID 24 | #define HOTKEY_ID_TOGGLE_VISIBILITY 107 // 隐藏/显示热键ID 25 | #define HOTKEY_ID_EDIT_MODE 108 // 编辑模式热键ID 26 | #define HOTKEY_ID_PAUSE_RESUME 109 // 暂停/继续热键ID 27 | #define HOTKEY_ID_RESTART_TIMER 110 // 重新开始热键ID 28 | 29 | /** 30 | * @brief 主窗口消息处理函数 31 | * @param hwnd 窗口句柄 32 | * @param msg 消息ID 33 | * @param wp 消息参数 34 | * @param lp 消息参数 35 | * @return LRESULT 消息处理结果 36 | * 37 | * 处理应用程序主窗口的所有窗口消息,包括: 38 | * - 创建和销毁事件 39 | * - 绘制和重绘 40 | * - 鼠标和键盘输入 41 | * - 窗口位置和大小变化 42 | * - 托盘图标事件 43 | * - 菜单命令消息 44 | * - 定时器事件 45 | */ 46 | LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); 47 | 48 | /** 49 | * @brief 注册全局热键 50 | * @param hwnd 窗口句柄 51 | * 52 | * 从配置文件读取并注册全局热键设置,用于快速切换显示当前时间、正计时和默认倒计时。 53 | * 如果热键已注册,会先取消注册再重新注册。 54 | * 55 | * @return BOOL 是否成功注册至少一个热键 56 | */ 57 | BOOL RegisterGlobalHotkeys(HWND hwnd); 58 | 59 | /** 60 | * @brief 取消注册全局热键 61 | * @param hwnd 窗口句柄 62 | * 63 | * 取消注册所有已注册的全局热键。 64 | */ 65 | void UnregisterGlobalHotkeys(HWND hwnd); 66 | 67 | /** 68 | * @brief 切换到显示当前时间模式 69 | * @param hwnd 窗口句柄 70 | */ 71 | void ToggleShowTimeMode(HWND hwnd); 72 | 73 | /** 74 | * @brief 开始正计时 75 | * @param hwnd 窗口句柄 76 | */ 77 | void StartCountUp(HWND hwnd); 78 | 79 | /** 80 | * @brief 开始默认倒计时 81 | * @param hwnd 窗口句柄 82 | */ 83 | void StartDefaultCountDown(HWND hwnd); 84 | 85 | /** 86 | * @brief 开始番茄钟 87 | * @param hwnd 窗口句柄 88 | */ 89 | void StartPomodoroTimer(HWND hwnd); 90 | 91 | /** 92 | * @brief 切换编辑模式 93 | * @param hwnd 窗口句柄 94 | */ 95 | void ToggleEditMode(HWND hwnd); 96 | 97 | /** 98 | * @brief 暂停/继续计时 99 | * @param hwnd 窗口句柄 100 | */ 101 | void TogglePauseResume(HWND hwnd); 102 | 103 | /** 104 | * @brief 重新开始当前计时 105 | * @param hwnd 窗口句柄 106 | */ 107 | void RestartCurrentTimer(HWND hwnd); 108 | 109 | /** 110 | * @brief 快捷倒计时1函数 111 | * @param hwnd 窗口句柄 112 | * 113 | * 使用预设时间选项中的第一项启动倒计时 114 | */ 115 | void StartQuickCountdown1(HWND hwnd); 116 | 117 | /** 118 | * @brief 快捷倒计时2函数 119 | * @param hwnd 窗口句柄 120 | * 121 | * 使用预设时间选项中的第二项启动倒计时 122 | */ 123 | void StartQuickCountdown2(HWND hwnd); 124 | 125 | /** 126 | * @brief 快捷倒计时3函数 127 | * @param hwnd 窗口句柄 128 | * 129 | * 使用预设时间选项中的第三项启动倒计时 130 | */ 131 | void StartQuickCountdown3(HWND hwnd); 132 | 133 | #endif // WINDOW_PROCEDURE_H -------------------------------------------------------------------------------- /libs/miniaudio/miniaudio.c: -------------------------------------------------------------------------------- 1 | #define MINIAUDIO_IMPLEMENTATION 2 | #include "miniaudio.h" 3 | -------------------------------------------------------------------------------- /resource/about_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 关于对话框资源定义 8 | IDD_ABOUT_DIALOG DIALOGEX 0, 0, 255, 80 9 | // 对话框样式:模态框架、居中显示、弹出式窗口、带标题栏和系统菜单 10 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 11 | // 对话框标题 12 | CAPTION IDC_ABOUT_TITLE_TEXT 13 | // 使用微软雅黑字体,大小为9 14 | FONT 12, "Microsoft YaHei UI" 15 | BEGIN 16 | // 程序图标 17 | CONTROL "", IDC_ABOUT_ICON, "Static", SS_ICON, 18 | 5, -10, ABOUT_ICON_SIZE, ABOUT_ICON_SIZE 19 | 20 | // 版本信息组 21 | LTEXT "", IDC_VERSION_TEXT, 130, 15, 160, 12 22 | LTEXT "", IDC_BUILD_DATE, 100, 25, 180, 12 23 | LTEXT "", IDC_COPYRIGHT, 100, 35, 180, 12 24 | 25 | // 感谢信息 26 | CONTROL "", IDC_CREDIT_LINK, "Static", SS_NOTIFY | SS_CENTERIMAGE, 27 | 100, 45, 145, 12 28 | 29 | // 底部链接栏 30 | CONTROL "", IDC_CREDITS, "Static", SS_NOTIFY | SS_CENTERIMAGE, 31 | 40, 65, 25, 12 32 | CONTROL "", IDC_BILIBILI_LINK, "Static", SS_NOTIFY | SS_CENTERIMAGE, 33 | 80, 65, 35, 12 34 | CONTROL "", IDC_GITHUB_LINK, "Static", SS_NOTIFY | SS_CENTERIMAGE, 35 | 125, 65, 32, 12 36 | CONTROL "", IDC_COPYRIGHT_LINK, "Static", SS_NOTIFY | SS_CENTERIMAGE, 37 | 165, 65, 36, 12 38 | CONTROL "", IDC_SUPPORT, "Static", SS_NOTIFY | SS_CENTERIMAGE, 39 | 215, 65, 25, 12 40 | END 41 | -------------------------------------------------------------------------------- /resource/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | Catime Application 10 | 11 | 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | PerMonitorV2, PerMonitor 46 | true 47 | 48 | 49 | -------------------------------------------------------------------------------- /resource/catime.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../resource/resource.h" 3 | 4 | // 版本信息 5 | VS_VERSION_INFO VERSIONINFO 6 | FILEVERSION CATIME_VERSION_MAJOR,CATIME_VERSION_MINOR,CATIME_VERSION_PATCH,CATIME_VERSION_BUILD 7 | PRODUCTVERSION CATIME_VERSION_MAJOR,CATIME_VERSION_MINOR,CATIME_VERSION_PATCH,CATIME_VERSION_BUILD 8 | FILEFLAGSMASK 0x3fL 9 | #ifdef _DEBUG 10 | FILEFLAGS 0x1L 11 | #else 12 | FILEFLAGS 0x0L 13 | #endif 14 | FILEOS 0x40004L 15 | FILETYPE 0x1L 16 | FILESUBTYPE 0x0L 17 | BEGIN 18 | BLOCK "StringFileInfo" 19 | BEGIN 20 | BLOCK "000004b0" 21 | BEGIN 22 | VALUE "CompanyName", "vladelaina" 23 | VALUE "FileDescription", "A very useful timer (Pomodoro Clock)" 24 | VALUE "FileVersion", CATIME_VERSION 25 | VALUE "InternalName", "Catime" 26 | VALUE "LegalCopyright", "Copyright (C) 2025 vladelaina. Apache License 2.0" 27 | VALUE "OriginalFilename", "Catime.exe" 28 | VALUE "ProductName", "Catime" 29 | VALUE "ProductVersion", CATIME_VERSION 30 | END 31 | END 32 | BLOCK "VarFileInfo" 33 | BEGIN 34 | VALUE "Translation", 0x0000, 1200 35 | END 36 | END -------------------------------------------------------------------------------- /resource/color_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 颜色值输入对话框 8 | CLOCK_IDD_COLOR_DIALOG DIALOGEX 0, 0, 200, 130 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "设置颜色值" 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "支持以下格式:\n\n1. HEX格式:#FFB6C1、FFB6C1\n2. RGB格式:255,182,193、255 182 193\n3. 颜色名:white、red、black、pink", CLOCK_IDC_STATIC, 10, 10, 180, 50 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 75, 180, 20, ES_AUTOHSCROLL | ES_MULTILINE 15 | PUSHBUTTON "确定", CLOCK_IDC_BUTTON_OK, 140, 105, 50, 14 16 | END -------------------------------------------------------------------------------- /resource/countdown_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 通用输入对话框 - 用于设置倒计时时间 8 | CLOCK_IDD_DIALOG1 DIALOGEX 0, 0, 200, 130 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "设置倒计时" 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "25=25分钟\n25h=25小时\n25s=25秒\n25 30=25分钟30秒\n25 30m=25小时30分钟\n1 30 20=1小时30分钟20秒\n17 20t=倒计时到17点20分\n9 9 9t=倒计时到9点9分9秒", CLOCK_IDC_STATIC, 10, 10, 180, 70 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 85, 180, 20, ES_AUTOHSCROLL | ES_MULTILINE 15 | PUSHBUTTON "确定", CLOCK_IDC_BUTTON_OK, 140, 108, 50, 14 16 | END -------------------------------------------------------------------------------- /resource/error_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 错误提示对话框资源定义 8 | IDD_ERROR_DIALOG DIALOGEX 0, 0, 160, 40 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | FONT 12, "Microsoft YaHei UI" 11 | BEGIN 12 | CTEXT "", IDC_ERROR_TEXT, 0, 10, 160, 20 13 | END -------------------------------------------------------------------------------- /resource/hotkey_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | #include 4 | 5 | // 设置 UTF-8 编码 6 | #pragma code_page(65001) 7 | 8 | // 热键设置对话框 9 | CLOCK_IDD_HOTKEY_DIALOG DIALOGEX 0, 0, 280, 300 10 | STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 11 | CAPTION "" 12 | FONT 9, "Segoe UI" 13 | BEGIN 14 | LTEXT "",IDC_HOTKEY_LABEL1,14,15,80,8 15 | CONTROL "",IDC_HOTKEY_EDIT1,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,13,160,14 16 | 17 | LTEXT "",IDC_HOTKEY_LABEL2,14,35,80,8 18 | CONTROL "",IDC_HOTKEY_EDIT2,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,33,160,14 19 | 20 | LTEXT "",IDC_HOTKEY_LABEL12,14,55,80,8 21 | CONTROL "",IDC_HOTKEY_EDIT12,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,53,160,14 22 | 23 | LTEXT "",IDC_HOTKEY_LABEL3,14,75,80,8 24 | CONTROL "",IDC_HOTKEY_EDIT3,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,73,160,14 25 | 26 | LTEXT "",IDC_HOTKEY_LABEL9,14,95,80,8 27 | CONTROL "",IDC_HOTKEY_EDIT9,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,93,160,14 28 | 29 | LTEXT "",IDC_HOTKEY_LABEL10,14,115,80,8 30 | CONTROL "",IDC_HOTKEY_EDIT10,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,113,160,14 31 | 32 | LTEXT "",IDC_HOTKEY_LABEL11,14,135,80,8 33 | CONTROL "",IDC_HOTKEY_EDIT11,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,133,160,14 34 | 35 | LTEXT "",IDC_HOTKEY_LABEL4,14,155,80,8 36 | CONTROL "",IDC_HOTKEY_EDIT4,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,153,160,14 37 | 38 | LTEXT "",IDC_HOTKEY_LABEL5,14,175,80,8 39 | CONTROL "",IDC_HOTKEY_EDIT5,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,173,160,14 40 | 41 | LTEXT "",IDC_HOTKEY_LABEL6,14,195,80,8 42 | CONTROL "",IDC_HOTKEY_EDIT6,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,193,160,14 43 | 44 | LTEXT "",IDC_HOTKEY_LABEL7,14,215,80,8 45 | CONTROL "",IDC_HOTKEY_EDIT7,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,213,160,14 46 | 47 | LTEXT "",IDC_HOTKEY_LABEL8,14,235,80,8 48 | CONTROL "",IDC_HOTKEY_EDIT8,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,105,233,160,14 49 | 50 | LTEXT "",IDC_HOTKEY_NOTE,15,265,200,8 51 | PUSHBUTTON "",IDCANCEL,170,280,50,14 52 | DEFPUSHBUTTON "",IDOK,225,280,50,14 53 | END -------------------------------------------------------------------------------- /resource/languages.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 语言资源ID 5 | #define LANG_EN_INI 1001 6 | #define LANG_ZH_CN_INI 1002 7 | #define LANG_ZH_TW_INI 1003 8 | #define LANG_ES_INI 1004 9 | #define LANG_FR_INI 1005 10 | #define LANG_DE_INI 1006 11 | #define LANG_RU_INI 1007 12 | #define LANG_PT_INI 1008 13 | #define LANG_JA_INI 1009 14 | #define LANG_KO_INI 1010 15 | 16 | // 语言资源数据 17 | LANG_EN_INI RCDATA "languages/en.ini" 18 | LANG_ZH_CN_INI RCDATA "languages/zh_CN.ini" 19 | LANG_ZH_TW_INI RCDATA "languages/zh-Hant.ini" 20 | LANG_ES_INI RCDATA "languages/es.ini" 21 | LANG_FR_INI RCDATA "languages/fr.ini" 22 | LANG_DE_INI RCDATA "languages/de.ini" 23 | LANG_RU_INI RCDATA "languages/ru.ini" 24 | LANG_PT_INI RCDATA "languages/pt.ini" 25 | LANG_JA_INI RCDATA "languages/ja.ini" 26 | LANG_KO_INI RCDATA "languages/ko.ini" -------------------------------------------------------------------------------- /resource/languages/de.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; Deutsche Übersetzung (German translation) 3 | ; Format: englischer Text=übersetzter Text 4 | 5 | "Set Countdown"="Countdown einstellen" 6 | "Set Time"="Zeit einstellen" 7 | "Time's up!"="Zeit ist abgelaufen!" 8 | "Show Current Time"="Aktuelle Zeit anzeigen" 9 | "24-Hour Format"="24-Stunden-Format" 10 | "Show Seconds"="Sekunden anzeigen" 11 | "Time Display"="Zeitanzeige" 12 | "Count Up"="Aufwärtszählen" 13 | "Countdown"="Countdown" 14 | "Start"="Start" 15 | "Pause"="Pause" 16 | "Resume"="Fortsetzen" 17 | "Start Over"="Neustart" 18 | "Restart"="Neu starten" 19 | "Edit Mode"="Bearbeitungsmodus" 20 | "Show Message"="Nachricht anzeigen" 21 | "Lock Screen"="Bildschirm sperren" 22 | "Shutdown"="Herunterfahren" 23 | "Timeout Action"="Timeout-Aktion" 24 | "Modify Time Options"="Zeitoptionen ändern" 25 | "Customize"="Anpassen" 26 | "Color"="Farbe" 27 | "Font"="Schriftart" 28 | "Version: %hs"="Version: %hs" 29 | "Feedback"="Feedback" 30 | "Check for Updates"="Nach Updates suchen" 31 | "About"="Über" 32 | "User Guide"="Benutzerhandbuch" 33 | "Reset"="Zurücksetzen" 34 | "Exit"="Beenden" 35 | "Settings"="Einstellungen" 36 | "Preset Manager"="Voreinstellungsmanager" 37 | "Startup Settings"="Starteinstellungen" 38 | "Start with Windows"="Mit Windows starten" 39 | "All Pomodoro cycles completed!"="Alle Pomodoro-Zyklen abgeschlossen!" 40 | "Break over! Time to focus again."="Pause vorbei! Zeit, sich wieder zu konzentrieren." 41 | "Error"="Fehler" 42 | "Failed to open file"="Datei konnte nicht geöffnet werden" 43 | "Timer Control"="Timer-Steuerung" 44 | "Pomodoro"="Pomodoro" 45 | "Loop Count: %d"="Schleifenzahl: %d" 46 | "Always on Top"="Immer im Vordergrund" 47 | "Save Preset"="Voreinstellung speichern" 48 | "Load Preset"="Voreinstellung laden" 49 | "Delete Preset"="Voreinstellung löschen" 50 | "Create New Preset"="Neue Voreinstellung erstellen" 51 | "Preset Name"="Voreinstellungsname" 52 | "Select Preset"="Voreinstellung auswählen" 53 | "Confirm Delete"="Löschen bestätigen" 54 | "Are you sure you want to delete this preset?"="Sind Sie sicher, dass Sie diese Voreinstellung löschen möchten?" 55 | "Open File/Software"="Datei/Software öffnen" 56 | "No Display"="Keine Anzeige" 57 | "Preset Management"="Voreinstellungsverwaltung" 58 | "Color Value"="Farbwert" 59 | "Color Panel"="Farbtafel" 60 | "More"="Mehr" 61 | "Help"="Hilfe" 62 | "Working: %d/%d"="Arbeiten: %d/%d" 63 | "Short Break: %d/%d"="Kurze Pause: %d/%d" 64 | "Long Break"="Lange Pause" 65 | "Time to focus!"="Zeit zum Konzentrieren!" 66 | "Time for a break!"="Zeit für eine Pause!" 67 | "Completed: %d/%d"="Abgeschlossen: %d/%d" 68 | "Browse..."="Durchsuchen..." 69 | "Open Website"="Website öffnen" 70 | "Combination"="Kombination" 71 | "Set to No Display on Startup"="Beim Start keine Anzeige" 72 | "Set to Stopwatch on Startup"="Beim Start Stoppuhr einstellen" 73 | "Set to Countdown on Startup"="Beim Start Countdown einstellen" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="Geben Sie Zahlen ein, durch Leerzeichen getrennt\nBeispiel: 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25 Minuten\n25h = 25 Stunden\n25s = 25 Sekunden\n25 30 = 25 Minuten 30 Sekunden\n25 30m = 25 Stunden 30 Minuten\n1 30 20 = 1 Stunde 30 Minuten 20 Sekunden" 76 | "Support"="Unterstützung" 77 | "Following actions are one-time only"="Folgende Aktionen sind einmalig" 78 | "Sleep"="Ruhezustand" 79 | "Stopwatch"="Stoppuhr" 80 | "Modify Quick Countdown Options"="Schnelle Countdown-Optionen ändern" 81 | "Notification Settings"="Benachrichtigungseinstellungen" 82 | "Hotkey Settings"="Tastenkürzel-Einstellungen" 83 | "CountdownDialogStaticText"="25=25 Minuten\n25h=25 Stunden\n25s=25 Sekunden\n25 30=25 Minuten 30 Sekunden\n25 30m=25 Stunden 30 Minuten\n1 30 20=1 Stunde 30 Minuten 20 Sekunden\n17 20t=Countdown bis 17:20\n9 9 9t=Countdown bis 09:09:09" 84 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Geben Sie die URL der Website ein, die am Ende des Countdowns geöffnet werden soll:\nBeispiel: https://github.com/vladelaina/Catime" 85 | 86 | ; 对话框相关翻译 87 | "Special thanks to Neko House Lili Official for the icon"="Besonderer Dank an Neko House Lili Official für das Symbol" 88 | "Build Date:"="Build-Datum:" 89 | "COPYRIGHT_TEXT"="Urheberrecht © 2025 vladelaina" 90 | "Credits"="Danksagungen" 91 | "BiliBili"="BiliBili" 92 | "GitHub"="GitHub" 93 | "Copyright Notice"="Urheberrechtshinweis" 94 | "Invalid input format, please try again."="Ungültiges Eingabeformat, bitte versuchen Sie es erneut." 95 | 96 | ; 热键对话框翻译 97 | "Show Current Time:"="Aktuelle Zeit anzeigen:" 98 | "Count Up:"="Aufwärtszählen:" 99 | "Countdown:"="Countdown:" 100 | "Default Countdown:"="Standard-Countdown:" 101 | "Quick Countdown 1:"="Schnell-Countdown 1:" 102 | "Quick Countdown 2:"="Schnell-Countdown 2:" 103 | "Quick Countdown 3:"="Schnell-Countdown 3:" 104 | "Start Pomodoro:"="Pomodoro starten:" 105 | "Hide/Show Window:"="Fenster ausblenden/anzeigen:" 106 | "Enter Edit Mode:"="Bearbeitungsmodus starten:" 107 | "Pause/Resume Timer:"="Timer pausieren/fortsetzen:" 108 | "Restart Timer:"="Timer neu starten:" 109 | "* Hotkeys will work globally"="* Tastenkürzel funktionieren global" 110 | 111 | ; 通知设置对话框翻译 112 | "Notification Settings"="Benachrichtigungseinstellungen" 113 | "Notification Content"="Benachrichtigungsinhalt" 114 | "Countdown timeout message:"="Countdown-Timeout-Nachricht:" 115 | "Pomodoro timeout message:"="Pomodoro-Timeout-Nachricht:" 116 | "Pomodoro cycle complete message:"="Pomodoro-Zyklus abgeschlossen-Nachricht:" 117 | "Notification Display"="Benachrichtigungsanzeige" 118 | "Notification display time:"="Benachrichtigungsanzeigezeit:" 119 | "Maximum notification opacity (1-100%):"="Maximale Benachrichtigungstransparenz (1-100%):" 120 | "Notification Method"="Benachrichtigungsmethode" 121 | "Catime notification window"="Catime-Benachrichtigungsfenster" 122 | "System notification"="Betriebssystembenachrichtigung" 123 | "System modal window"="Systemmodales Fenster" 124 | "Sound (supports .mp3/.wav/.flac):"="Ton (unterstützt .mp3/.wav/.flac):" 125 | "Test"="Test" 126 | "Stop"="Stopp" 127 | "Audio folder"="Audioordner" 128 | "Volume (0-100%):"="Lautstärke (0-100%):" 129 | "Cancel"="Abbrechen" 130 | "OK"="OK" 131 | "None"="Keine" 132 | "System Beep"="Systemton" 133 | 134 | ; 番茄钟循环设置对话框翻译 135 | "Set Pomodoro Loop Count"="Pomodoro-Zyklusanzahl einstellen" 136 | "Please enter loop count (1-10):"="Bitte geben Sie die Anzahl der Zyklen ein (1-10):" 137 | 138 | ; 为德语添加番茄钟组合对话框翻译 139 | "Set Pomodoro Time Combination"="Pomodoro-Zeitkombination einstellen" 140 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="Geben Sie die Pomodoro-Zeitsequenz ein, durch Leerzeichen getrennt:\n\n25m = 25 Minuten\n30s = 30 Sekunden\n1h30m = 1 Stunde 30 Minuten\nBeispiel: 25m 5m 25m 10m - Arbeit 25Min, kurze Pause 5Min, Arbeit 25Min, lange Pause 10Min" 141 | 142 | ; 番茄钟时间设置对话框翻译 143 | "Set Pomodoro Time"="Pomodoro-Zeit einstellen" 144 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25 Minuten\n25h=25 Stunden\n25s=25 Sekunden\n25 30=25 Minuten 30 Sekunden\n25 30m=25 Stunden 30 Minuten\n1 30 20=1 Stunde 30 Minuten 20 Sekunden" 145 | 146 | ; Countdown-Voreinstellungen 147 | "Countdown Presets"="Countdown-Voreinstellungen" 148 | "CountdownPresetDialogStaticText"="Geben Sie Zahlen (Minuten) ein, durch Leerzeichen getrennt\n\n25 10 5\n\nDies erstellt Optionen für 25 Minuten, 10 Minuten und 5 Minuten" 149 | -------------------------------------------------------------------------------- /resource/languages/en.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; 英语翻译(默认语言) 3 | ; 格式:英文原文=翻译文本 4 | 5 | "Set Countdown"="Set Countdown" 6 | "Set Time"="Set Time" 7 | "Time's up!"="Time's up!" 8 | "Show Current Time"="Show Current Time" 9 | "24-Hour Format"="24-Hour Format" 10 | "Show Seconds"="Show Seconds" 11 | "Time Display"="Time Display" 12 | "Count Up"="Count Up" 13 | "Countdown"="Countdown" 14 | "Start"="Start" 15 | "Pause"="Pause" 16 | "Resume"="Resume" 17 | "Start Over"="Start Over" 18 | "Restart"="Restart" 19 | "Edit Mode"="Edit Mode" 20 | "Show Message"="Show Message" 21 | "Lock Screen"="Lock Screen" 22 | "Shutdown"="Shutdown" 23 | "Timeout Action"="Timeout Action" 24 | "Modify Time Options"="Modify Time Options" 25 | "Customize"="Customize" 26 | "Color"="Color" 27 | "Font"="Font" 28 | "Version: %hs"="Version: %hs" 29 | "Feedback"="Feedback" 30 | "Check for Updates"="Check for Updates" 31 | "About"="About" 32 | "User Guide"="User Guide" 33 | "Reset"="Reset" 34 | "Exit"="Exit" 35 | "Settings"="Settings" 36 | "Preset Manager"="Preset Manager" 37 | "Startup Settings"="Startup Settings" 38 | "Start with Windows"="Start with Windows" 39 | "All Pomodoro cycles completed!"="All Pomodoro cycles completed!" 40 | "Break over! Time to focus again."="Break over! Time to focus again." 41 | "Error"="Error" 42 | "Failed to open file"="Failed to open file" 43 | "Timer Control"="Timer Control" 44 | "Pomodoro"="Pomodoro" 45 | "Loop Count: %d"="Loop Count: %d" 46 | "Always on Top"="Always on Top" 47 | "Save Preset"="Save Preset" 48 | "Load Preset"="Load Preset" 49 | "Delete Preset"="Delete Preset" 50 | "Create New Preset"="Create New Preset" 51 | "Preset Name"="Preset Name" 52 | "Select Preset"="Select Preset" 53 | "Confirm Delete"="Confirm Delete" 54 | "Are you sure you want to delete this preset?"="Are you sure you want to delete this preset?" 55 | "Open File/Software"="Open File/Software" 56 | "No Display"="No Display" 57 | "Preset Management"="Preset Management" 58 | "Color Value"="Color Value" 59 | "Color Panel"="Color Panel" 60 | "More"="More" 61 | "Help"="Help" 62 | "Working: %d/%d"="Working: %d/%d" 63 | "Short Break: %d/%d"="Short Break: %d/%d" 64 | "Long Break"="Long Break" 65 | "Time to focus!"="Time to focus!" 66 | "Time for a break!"="Time for a break!" 67 | "Completed: %d/%d"="Completed: %d/%d" 68 | "Browse..."="Browse..." 69 | "Open Website"="Open Website" 70 | "Combination"="Combination" 71 | "Set to No Display on Startup"="Set to No Display on Startup" 72 | "Set to Stopwatch on Startup"="Set to Stopwatch on Startup" 73 | "Set to Countdown on Startup"="Set to Countdown on Startup" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="Enter numbers separated by spaces\nExample: 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds" 76 | "Support"="Support" 77 | "Following actions are one-time only"="Following actions are one-time only" 78 | "Sleep"="Sleep" 79 | "Stopwatch"="Stopwatch" 80 | "Modify Quick Countdown Options"="Modify Quick Countdown Options" 81 | "Notification Settings"="Notification Settings" 82 | "Hotkey Settings"="Hotkey Settings" 83 | "CountdownDialogStaticText"="25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds\n17 20t=Countdown to 17:20\n9 9 9t=Countdown to 09:09:09" 84 | 85 | ; 对话框相关翻译 86 | "Special thanks to Neko House Lili Official for the icon"="Special thanks to Neko House Lili Official for the icon" 87 | "Build Date:"="Build Date:" 88 | "COPYRIGHT_TEXT"="Copyright © 2025 vladelaina" 89 | "Credits"="Credits" 90 | "BiliBili"="BiliBili" 91 | "GitHub"="GitHub" 92 | "Copyright Notice"="Copyright Notice" 93 | "Invalid input format, please try again."="Invalid input format, please try again." 94 | 95 | ; 番茄钟循环设置对话框翻译 96 | "Set Pomodoro Loop Count"="Set Pomodoro Loop Count" 97 | "Please enter loop count (1-10):"="Please enter loop count (1-10):" 98 | 99 | ; 热键对话框翻译 100 | "Show Current Time:"="Show Current Time:" 101 | "Count Up:"="Count Up:" 102 | "Countdown:"="Countdown:" 103 | "Default Countdown:"="Default Countdown:" 104 | "Quick Countdown 1:"="Quick Countdown 1:" 105 | "Quick Countdown 2:"="Quick Countdown 2:" 106 | "Quick Countdown 3:"="Quick Countdown 3:" 107 | "Start Pomodoro:"="Start Pomodoro:" 108 | "Hide/Show Window:"="Hide/Show Window:" 109 | "Enter Edit Mode:"="Enter Edit Mode:" 110 | "Pause/Resume Timer:"="Pause/Resume Timer:" 111 | "Restart Timer:"="Restart Timer:" 112 | "* Hotkeys will work globally"="* Hotkeys will work globally" 113 | 114 | ; 通知设置对话框翻译 115 | "Notification Settings"="Notification Settings" 116 | "Notification Content"="Notification Content" 117 | "Countdown timeout message:"="Countdown timeout message:" 118 | "Pomodoro timeout message:"="Pomodoro timeout message:" 119 | "Pomodoro cycle complete message:"="Pomodoro cycle complete message:" 120 | "Notification Display"="Notification Display" 121 | "Notification display time:"="Notification display time:" 122 | "Maximum notification opacity (1-100%):"="Maximum notification opacity (1-100%):" 123 | "Notification Method"="Notification Method" 124 | "Catime notification window"="Catime notification window" 125 | "System notification"="System notification" 126 | "System modal window"="System modal window" 127 | "Sound (supports .mp3/.wav/.flac):"="Sound (supports .mp3/.wav/.flac):" 128 | "Test"="Test" 129 | "Stop"="Stop" 130 | "Audio folder"="Audio folder" 131 | "Volume (0-100%):"="Volume (0-100%):" 132 | "Cancel"="Cancel" 133 | "OK"="OK" 134 | "None"="None" 135 | "System Beep"="System Beep" 136 | 137 | ; 番茄钟组合对话框翻译 138 | "Set Pomodoro Time Combination"="Set Pomodoro Time Combination" 139 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min" 140 | 141 | ; 番茄钟时间设置对话框翻译 142 | "Set Pomodoro Time"="Set Pomodoro Time" 143 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds" 144 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime" 145 | 146 | ; 快捷时间选项设置对话框翻译 147 | "Countdown Presets"="Countdown Presets" 148 | "CountdownPresetDialogStaticText"="Enter numbers (minutes), separated by spaces\n\n25 10 5\n\nThis will create options for 25 minutes, 10 minutes, and 5 minutes" 149 | -------------------------------------------------------------------------------- /resource/languages/es.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; 西班牙语翻译 3 | ; 格式:英文原文=翻译文本 4 | 5 | "Set Countdown"="Configurar cuenta regresiva" 6 | "Set Time"="Configurar tiempo" 7 | "Time's up!"="¡Se acabó el tiempo!" 8 | "Show Current Time"="Mostrar hora actual" 9 | "24-Hour Format"="Formato de 24 horas" 10 | "Show Seconds"="Mostrar segundos" 11 | "Time Display"="Visualización del tiempo" 12 | "Count Up"="Cuenta ascendente" 13 | "Countdown"="Cuenta regresiva" 14 | "Start"="Iniciar" 15 | "Pause"="Pausar" 16 | "Resume"="Reanudar" 17 | "Start Over"="Empezar de nuevo" 18 | "Restart"="Reiniciar" 19 | "Edit Mode"="Modo de edición" 20 | "Show Message"="Mostrar mensaje" 21 | "Lock Screen"="Bloquear pantalla" 22 | "Shutdown"="Apagar" 23 | "Timeout Action"="Acción al finalizar" 24 | "Modify Time Options"="Modificar opciones de tiempo" 25 | "Customize"="Personalizar" 26 | "Color"="Color" 27 | "Font"="Fuente" 28 | "Version: %hs"="Versión: %hs" 29 | "Feedback"="Comentarios" 30 | "Check for Updates"="Buscar actualizaciones" 31 | "About"="Acerca de" 32 | "User Guide"="Guía del usuario" 33 | "Reset"="Restablecer" 34 | "Exit"="Salir" 35 | "Settings"="Configuración" 36 | "Preset Manager"="Administrador de preajustes" 37 | "Startup Settings"="Configuración de inicio" 38 | "Start with Windows"="Iniciar con Windows" 39 | "All Pomodoro cycles completed!"="¡Todos los ciclos Pomodoro completados!" 40 | "Break over! Time to focus again."="¡Descanso terminado! Hora de concentrarse de nuevo." 41 | "Error"="Error" 42 | "Failed to open file"="No se pudo abrir el archivo" 43 | "Timer Control"="Control del temporizador" 44 | "Pomodoro"="Pomodoro" 45 | "Loop Count: %d"="Conteo de ciclos: %d" 46 | "Always on Top"="Siempre visible" 47 | "Save Preset"="Guardar preajuste" 48 | "Load Preset"="Cargar preajuste" 49 | "Delete Preset"="Eliminar preajuste" 50 | "Create New Preset"="Crear nuevo preajuste" 51 | "Preset Name"="Nombre del preajuste" 52 | "Select Preset"="Seleccionar preajuste" 53 | "Confirm Delete"="Confirmar eliminación" 54 | "Are you sure you want to delete this preset?"="¿Está seguro de que desea eliminar este preajuste?" 55 | "Open File/Software"="Abrir archivo/software" 56 | "No Display"="Sin visualización" 57 | "Preset Management"="Gestión de preajustes" 58 | "Color Value"="Valor de color" 59 | "Color Panel"="Panel de colores" 60 | "More"="Más" 61 | "Help"="Ayuda" 62 | "Working: %d/%d"="Trabajando: %d/%d" 63 | "Short Break: %d/%d"="Descanso corto: %d/%d" 64 | "Long Break"="Descanso largo" 65 | "Time to focus!"="¡Hora de concentrarse!" 66 | "Time for a break!"="¡Hora de descansar!" 67 | "Completed: %d/%d"="Completado: %d/%d" 68 | "Browse..."="Explorar..." 69 | "Open Website"="Abrir sitio web" 70 | "Combination"="Combinación" 71 | "Set to No Display on Startup"="Establecer sin visualización al inicio" 72 | "Set to Stopwatch on Startup"="Establecer cronómetro al inicio" 73 | "Set to Countdown on Startup"="Establecer cuenta regresiva al inicio" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="Ingrese números separados por espacios\nEjemplo: 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25 minutos\n25h = 25 horas\n25s = 25 segundos\n25 30 = 25 minutos 30 segundos\n25 30m = 25 horas 30 minutos\n1 30 20 = 1 hora 30 minutos 20 segundos" 76 | "Support"="Soporte" 77 | "Following actions are one-time only"="Las siguientes acciones son de una sola vez" 78 | "Sleep"="Suspender" 79 | "Stopwatch"="Cronómetro" 80 | "Modify Quick Countdown Options"="Modificar opciones de cuenta regresiva rápida" 81 | "Notification Settings"="Configuración de notificaciones" 82 | "Notification Content"="Contenido de notificación" 83 | "Countdown timeout message:"="Mensaje de cuenta regresiva finalizada:" 84 | "Pomodoro timeout message:"="Mensaje de Pomodoro finalizado:" 85 | "Pomodoro cycle complete message:"="Mensaje de ciclo Pomodoro completado:" 86 | "Notification Display"="Visualización de notificaciones" 87 | "Notification display time:"="Tiempo de visualización de notificación:" 88 | "Maximum notification opacity (1-100%):"="Opacidad máxima de notificación (1-100%):" 89 | "Notification Method"="Método de notificación" 90 | "Catime notification window"="Ventana de notificación de Catime" 91 | "System notification"="Notificación del sistema operativo" 92 | "System modal window"="Ventana modal del sistema" 93 | "Sound (supports .mp3/.wav/.flac):"="Sonido (soporta .mp3/.wav/.flac):" 94 | "Test"="Probar" 95 | "Stop"="Detener" 96 | "Audio folder"="Carpeta de audio" 97 | "Volume (0-100%):"="Volumen (0-100%):" 98 | "Cancel"="Cancelar" 99 | "OK"="Aceptar" 100 | "None"="Ninguno" 101 | "System Beep"="Sonido del sistema" 102 | "Set Pomodoro Loop Count"="Establecer número de ciclos Pomodoro" 103 | "Please enter loop count (1-10):"="Ingrese el número de ciclos (1-10):" 104 | "Set Pomodoro Time Combination"="Configurar combinación de tiempos Pomodoro" 105 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="Ingrese la secuencia de tiempos Pomodoro, separados por espacios:\n\n25m = 25 minutos\n30s = 30 segundos\n1h30m = 1 hora 30 minutos\nEjemplo: 25m 5m 25m 10m - trabajo 25min, descanso corto 5min, trabajo 25min, descanso largo 10min" 106 | "Set Pomodoro Time"="Configurar tiempo Pomodoro" 107 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25 minutos\n25h=25 horas\n25s=25 segundos\n25 30=25 minutos 30 segundos\n25 30m=25 horas 30 minutos\n1 30 20=1 hora 30 minutos 20 segundos" 108 | "* Hotkeys will work globally"="* Las teclas rápidas funcionarán globalmente" 109 | "CountdownDialogStaticText"="25=25 minutos\n25h=25 horas\n25s=25 segundos\n25 30=25 minutos 30 segundos\n25 30m=25 horas 30 minutos\n1 30 20=1 hora 30 minutos 20 segundos\n17 20t=Cuenta atrás hasta las 17:20\n9 9 9t=Cuenta atrás hasta las 09:09:09" 110 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Ingrese la URL del sitio web que se abrirá cuando finalice la cuenta regresiva:\nEjemplo: https://github.com/vladelaina/Catime" 111 | 112 | ; 对话框相关翻译 113 | "Special thanks to Neko House Lili Official for the icon"="Agradecimientos especiales a Neko House Lili Official por el ícono" 114 | "Build Date:"="Fecha de compilación:" 115 | "COPYRIGHT_TEXT"="Copyright © 2025 vladelaina" 116 | "Credits"="Créditos" 117 | "BiliBili"="BiliBili" 118 | "GitHub"="GitHub" 119 | "Copyright Notice"="Aviso de derechos de autor" 120 | "Invalid input format, please try again."="Formato de entrada inválido, inténtelo de nuevo." 121 | 122 | ; 热键对话框翻译 123 | "Show Current Time:"="Mostrar hora actual:" 124 | "Count Up:"="Cuenta ascendente:" 125 | "Countdown:"="Cuenta regresiva:" 126 | "Default Countdown:"="Cuenta regresiva predeterminada:" 127 | "Quick Countdown 1:"="Cuenta regresiva rápida 1:" 128 | "Quick Countdown 2:"="Cuenta regresiva rápida 2:" 129 | "Quick Countdown 3:"="Cuenta regresiva rápida 3:" 130 | "Start Pomodoro:"="Iniciar Pomodoro:" 131 | "Hide/Show Window:"="Ocultar/Mostrar ventana:" 132 | "Enter Edit Mode:"="Entrar en modo de edición:" 133 | "Pause/Resume Timer:"="Pausar/Reanudar temporizador:" 134 | "Restart Timer:"="Reiniciar temporizador:" 135 | 136 | ; Preajustes de cuenta regresiva 137 | "Countdown Presets"="Preajustes de cuenta regresiva" 138 | "CountdownPresetDialogStaticText"="Ingrese números (minutos), separados por espacios\n\n25 10 5\n\nEsto creará opciones para 25 minutos, 10 minutos y 5 minutos" 139 | -------------------------------------------------------------------------------- /resource/languages/fr.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; Traduction française (French translation) 3 | ; Format : texte anglais=texte traduit 4 | 5 | "Set Countdown"="Régler le compte à rebours" 6 | "Set Time"="Régler le temps" 7 | "Time's up!"="Temps écoulé !" 8 | "Show Current Time"="Afficher l'heure actuelle" 9 | "24-Hour Format"="Format 24 heures" 10 | "Show Seconds"="Afficher les secondes" 11 | "Time Display"="Affichage de l'heure" 12 | "Count Up"="Chronomètre" 13 | "Countdown"="Compte à rebours" 14 | "Start"="Démarrer" 15 | "Pause"="Pause" 16 | "Resume"="Reprendre" 17 | "Start Over"="Recommencer" 18 | "Restart"="Redémarrer" 19 | "Edit Mode"="Mode édition" 20 | "Show Message"="Afficher un message" 21 | "Lock Screen"="Verrouiller l'écran" 22 | "Shutdown"="Arrêter" 23 | "Timeout Action"="Action à la fin" 24 | "Modify Time Options"="Modifier les options de temps" 25 | "Customize"="Personnaliser" 26 | "Color"="Couleur" 27 | "Font"="Police" 28 | "Version: %hs"="Version : %hs" 29 | "Feedback"="Commentaires" 30 | "Check for Updates"="Vérifier les mises à jour" 31 | "About"="À propos" 32 | "User Guide"="Guide d'utilisation" 33 | "Reset"="Réinitialiser" 34 | "Exit"="Quitter" 35 | "Settings"="Paramètres" 36 | "Preset Manager"="Gestionnaire de préréglages" 37 | "Startup Settings"="Paramètres de démarrage" 38 | "Start with Windows"="Démarrer avec Windows" 39 | "All Pomodoro cycles completed!"="Tous les cycles Pomodoro sont terminés !" 40 | "Break over! Time to focus again."="Pause terminée ! Temps de se concentrer à nouveau." 41 | "Error"="Erreur" 42 | "Failed to open file"="Échec de l'ouverture du fichier" 43 | "Timer Control"="Contrôle du minuteur" 44 | "Pomodoro"="Pomodoro" 45 | "Loop Count: %d"="Nombre de cycles : %d" 46 | "Always on Top"="Toujours au premier plan" 47 | "Save Preset"="Enregistrer le préréglage" 48 | "Load Preset"="Charger le préréglage" 49 | "Delete Preset"="Supprimer le préréglage" 50 | "Create New Preset"="Créer un nouveau préréglage" 51 | "Preset Name"="Nom du préréglage" 52 | "Select Preset"="Sélectionner un préréglage" 53 | "Confirm Delete"="Confirmer la suppression" 54 | "Are you sure you want to delete this preset?"="Êtes-vous sûr de vouloir supprimer ce préréglage ?" 55 | "Open File/Software"="Ouvrir fichier/logiciel" 56 | "No Display"="Pas d'affichage" 57 | "Preset Management"="Gestion des préréglages" 58 | "Color Value"="Valeur de couleur" 59 | "Color Panel"="Panneau de couleurs" 60 | "More"="Plus" 61 | "Help"="Aide" 62 | "Working: %d/%d"="Travail : %d/%d" 63 | "Short Break: %d/%d"="Pause courte : %d/%d" 64 | "Long Break"="Pause longue" 65 | "Time to focus!"="Temps de se concentrer !" 66 | "Time for a break!"="Temps de faire une pause !" 67 | "Completed: %d/%d"="Terminé : %d/%d" 68 | "Browse..."="Parcourir..." 69 | "Open Website"="Ouvrir le site web" 70 | "Combination"="Combinaison" 71 | "Set to No Display on Startup"="Pas d'affichage au démarrage" 72 | "Set to Stopwatch on Startup"="Chronomètre au démarrage" 73 | "Set to Countdown on Startup"="Compte à rebours au démarrage" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="Entrez des nombres séparés par des espaces\nExemple : 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25 minutes\n25h = 25 heures\n25s = 25 secondes\n25 30 = 25 minutes 30 secondes\n25 30m = 25 heures 30 minutes\n1 30 20 = 1 heure 30 minutes 20 secondes" 76 | "Support"="Support" 77 | "Following actions are one-time only"="Les actions suivantes sont à usage unique" 78 | "Sleep"="Mise en veille" 79 | "Stopwatch"="Chronomètre" 80 | "Modify Quick Countdown Options"="Modifier les options de compte à rebours rapide" 81 | "Notification Settings"="Paramètres de notification" 82 | "Hotkey Settings"="Paramètres des raccourcis" 83 | "CountdownDialogStaticText"="25=25 minutes\n25h=25 heures\n25s=25 secondes\n25 30=25 minutes 30 secondes\n25 30m=25 heures 30 minutes\n1 30 20=1 heure 30 minutes 20 secondes\n17 20t=Compte à rebours jusqu'à 17h20\n9 9 9t=Compte à rebours jusqu'à 09h09m09s" 84 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Entrez l'URL du site web à ouvrir à la fin du compte à rebours :\nExemple : https://github.com/vladelaina/Catime" 85 | 86 | ; 对话框相关翻译 87 | "Special thanks to Neko House Lili Official for the icon"="Remerciements spéciaux à Neko House Lili Official pour l'icône" 88 | "Build Date:"="Date de compilation:" 89 | "COPYRIGHT_TEXT"="Droits d'auteur © 2025 vladelaina" 90 | "Credits"="Crédits" 91 | "BiliBili"="BiliBili" 92 | "GitHub"="GitHub" 93 | "Copyright Notice"="Avis de droit d'auteur" 94 | "Invalid input format, please try again."="Format d'entrée invalide, veuillez réessayer." 95 | 96 | ; 热键对话框翻译 97 | "Show Current Time:"="Afficher l'heure actuelle:" 98 | "Count Up:"="Chronomètre:" 99 | "Countdown:"="Compte à rebours:" 100 | "Default Countdown:"="Compte à rebours par défaut:" 101 | "Quick Countdown 1:"="Compte à rebours rapide 1:" 102 | "Quick Countdown 2:"="Compte à rebours rapide 2:" 103 | "Quick Countdown 3:"="Compte à rebours rapide 3:" 104 | "Start Pomodoro:"="Démarrer le Pomodoro:" 105 | "Hide/Show Window:"="Masquer/Afficher la fenêtre:" 106 | "Enter Edit Mode:"="Entrer en mode édition:" 107 | "Pause/Resume Timer:"="Pause/Reprendre le minuteur:" 108 | "Restart Timer:"="Redémarrer le minuteur:" 109 | "* Hotkeys will work globally"="* Les raccourcis fonctionneront globalement" 110 | 111 | ; 通知设置对话框翻译 112 | "Notification Settings"="Paramètres de notification" 113 | "Notification Content"="Contenu de notification" 114 | "Countdown timeout message:"="Message de fin de compte à rebours :" 115 | "Pomodoro timeout message:"="Message de fin de Pomodoro :" 116 | "Pomodoro cycle complete message:"="Message de fin de cycle Pomodoro :" 117 | "Notification Display"="Affichage des notifications" 118 | "Notification display time:"="Temps d'affichage de notification :" 119 | "Maximum notification opacity (1-100%):"="Opacité maximale de notification (1-100%) :" 120 | "Notification Method"="Méthode de notification" 121 | "Catime notification window"="Fenêtre de notification Catime" 122 | "System notification"="Notification du système d'exploitation" 123 | "System modal window"="Fenêtre modale système" 124 | "Sound (supports .mp3/.wav/.flac):"="Son (.mp3/.wav/.flac supportés) :" 125 | "Test"="Tester" 126 | "Stop"="Arrêter" 127 | "Audio folder"="Dossier audio" 128 | "Volume (0-100%):"="Volume (0-100%) :" 129 | "Cancel"="Annuler" 130 | "OK"="OK" 131 | "None"="Aucun" 132 | "System Beep"="Son système" 133 | 134 | ; 番茄钟循环设置对话框翻译 135 | "Set Pomodoro Loop Count"="Définir le nombre de cycles Pomodoro" 136 | "Please enter loop count (1-10):"="Veuillez entrer le nombre de cycles (1-10) :" 137 | 138 | ; 为法语添加番茄钟组合对话框翻译 139 | "Set Pomodoro Time Combination"="Définir la combinaison de temps Pomodoro" 140 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="Entrez la séquence de temps Pomodoro, séparée par des espaces :\n\n25m = 25 minutes\n30s = 30 secondes\n1h30m = 1 heure 30 minutes\nExemple : 25m 5m 25m 10m - travail 25min, pause courte 5min, travail 25min, pause longue 10min" 141 | 142 | ; 番茄钟时间设置对话框翻译 143 | "Set Pomodoro Time"="Régler le temps Pomodoro" 144 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25 minutes\n25h=25 heures\n25s=25 secondes\n25 30=25 minutes 30 secondes\n25 30m=25 heures 30 minutes\n1 30 20=1 heure 30 minutes 20 secondes" 145 | 146 | ; Paramètres de préréglage de compte à rebours 147 | "Countdown Presets"="Préréglages de compte à rebours" 148 | "CountdownPresetDialogStaticText"="Entrez des nombres (minutes), séparés par des espaces\n\n25 10 5\n\nCela créera des options pour 25 minutes, 10 minutes et 5 minutes" 149 | -------------------------------------------------------------------------------- /resource/languages/ja.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; 日本語翻訳 (Japanese translation) 3 | ; フォーマット:英語テキスト=翻訳テキスト 4 | 5 | "Set Countdown"="カウントダウン設定" 6 | "Set Time"="時間設定" 7 | "Time's up!"="時間切れ!" 8 | "Show Current Time"="現在時刻を表示" 9 | "24-Hour Format"="24時間表示" 10 | "Show Seconds"="秒を表示" 11 | "Time Display"="時間表示" 12 | "Count Up"="カウントアップ" 13 | "Countdown"="カウントダウン" 14 | "Start"="開始" 15 | "Pause"="一時停止" 16 | "Resume"="再開" 17 | "Start Over"="最初からやり直す" 18 | "Restart"="再起動" 19 | "Edit Mode"="編集モード" 20 | "Show Message"="メッセージを表示" 21 | "Lock Screen"="画面ロック" 22 | "Shutdown"="シャットダウン" 23 | "Timeout Action"="タイムアウト時の動作" 24 | "Modify Time Options"="時間オプションの変更" 25 | "Customize"="カスタマイズ" 26 | "Color"="色" 27 | "Font"="フォント" 28 | "Version: %hs"="バージョン:%hs" 29 | "Feedback"="フィードバック" 30 | "Check for Updates"="更新を確認" 31 | "About"="情報" 32 | "User Guide"="ユーザーガイド" 33 | "Reset"="リセット" 34 | "Exit"="終了" 35 | "Settings"="設定" 36 | "Preset Manager"="プリセット管理" 37 | "Startup Settings"="起動設定" 38 | "Start with Windows"="Windowsと同時に起動" 39 | "All Pomodoro cycles completed!"="すべてのポモドーロサイクルが完了しました!" 40 | "Break over! Time to focus again."="休憩終了!再び集中する時間です。" 41 | "Error"="エラー" 42 | "Failed to open file"="ファイルを開けませんでした" 43 | "Timer Control"="タイマー制御" 44 | "Pomodoro"="ポモドーロ" 45 | "Loop Count: %d"="ループ回数:%d" 46 | "Always on Top"="常に前面に表示" 47 | "Save Preset"="プリセットを保存" 48 | "Load Preset"="プリセットを読み込む" 49 | "Delete Preset"="プリセットを削除" 50 | "Create New Preset"="新しいプリセットを作成" 51 | "Preset Name"="プリセット名" 52 | "Select Preset"="プリセットを選択" 53 | "Confirm Delete"="削除の確認" 54 | "Are you sure you want to delete this preset?"="このプリセットを削除してもよろしいですか?" 55 | "Open File/Software"="ファイル/ソフトウェアを開く" 56 | "No Display"="表示なし" 57 | "Preset Management"="プリセット管理" 58 | "Color Value"="色の値" 59 | "Color Panel"="カラーパネル" 60 | "More"="その他" 61 | "Help"="ヘルプ" 62 | "Working: %d/%d"="作業中:%d/%d" 63 | "Short Break: %d/%d"="短い休憩:%d/%d" 64 | "Long Break"="長い休憩" 65 | "Time to focus!"="集中する時間です!" 66 | "Time for a break!"="休憩の時間です!" 67 | "Completed: %d/%d"="完了:%d/%d" 68 | "Browse..."="参照..." 69 | "Open Website"="ウェブサイトを開く" 70 | "Combination"="組み合わせ" 71 | "Set to No Display on Startup"="起動時に表示なし" 72 | "Set to Stopwatch on Startup"="起動時にストップウォッチ" 73 | "Set to Countdown on Startup"="起動時にカウントダウン" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="数字をスペースで区切って入力\n例:25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25分\n25h = 25時間\n25s = 25秒\n25 30 = 25分30秒\n25 30m = 25時間30分\n1 30 20 = 1時間30分20秒" 76 | "Support"="サポート" 77 | "Following actions are one-time only"="以下のアクションは一回限りです" 78 | "Sleep"="スリープ" 79 | "Stopwatch"="ストップウォッチ" 80 | "Modify Quick Countdown Options"="クイックカウントダウンオプションを変更" 81 | "Notification Settings"="通知設定" 82 | "Hotkey Settings"="ホットキー設定" 83 | "CountdownDialogStaticText"="25=25分\n25h=25時間\n25s=25秒\n25 30=25分30秒\n25 30m=25時間30分\n1 30 20=1時間30分20秒\n17 20t=17時20分までカウントダウン\n9 9 9t=9時9分9秒までカウントダウン" 84 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="カウントダウン終了時に開くウェブサイトのURLを入力してください:\n例:https://github.com/vladelaina/Catime" 85 | 86 | ; ダイアログ関連の翻訳 87 | "Special thanks to Neko House Lili Official for the icon"="アイコンを提供してくれた Neko House Lili Official に感謝します" 88 | "Build Date:"="ビルド日付:" 89 | "COPYRIGHT_TEXT"="著作権 © 2025 vladelaina" 90 | "Credits"="クレジット" 91 | "BiliBili"="BiliBili" 92 | "GitHub"="GitHub" 93 | "Copyright Notice"="著作権表示" 94 | "Invalid input format, please try again."="入力形式が無効です。もう一度お試しください。" 95 | 96 | ; ホットキー設定ダイアログの翻訳 97 | "Show Current Time:"="現在時刻を表示:" 98 | "Count Up:"="カウントアップ:" 99 | "Countdown:"="カウントダウン:" 100 | "Default Countdown:"="デフォルトカウントダウン:" 101 | "Quick Countdown 1:"="クイックカウントダウン1:" 102 | "Quick Countdown 2:"="クイックカウントダウン2:" 103 | "Quick Countdown 3:"="クイックカウントダウン3:" 104 | "Start Pomodoro:"="ポモドーロ開始:" 105 | "Hide/Show Window:"="ウィンドウ表示/非表示:" 106 | "Enter Edit Mode:"="編集モードに入る:" 107 | "Pause/Resume Timer:"="タイマー一時停止/再開:" 108 | "Restart Timer:"="タイマー再起動:" 109 | "* Hotkeys will work globally"="* ホットキーはグローバルに機能します" 110 | 111 | ; 通知设置对话框翻译 112 | "Notification Settings"="通知設定" 113 | "Notification Content"="通知内容" 114 | "Countdown timeout message:"="カウントダウンタイムアウト通知:" 115 | "Pomodoro timeout message:"="ポモドーロタイムアウト通知:" 116 | "Pomodoro cycle complete message:"="ポモドーロサイクル完了通知:" 117 | "Notification Display"="通知表示" 118 | "Notification display time:"="通知表示時間:" 119 | "Maximum notification opacity (1-100%):"="通知最大透明度(1-100%):" 120 | "Notification Method"="通知方法" 121 | "Catime notification window"="Catime通知ウィンドウ" 122 | "System notification"="OS通知" 123 | "System modal window"="システムモーダルウィンドウ" 124 | "Sound (supports .mp3/.wav/.flac):"="通知音(.mp3/.wav/.flacをサポート):" 125 | "Test"="テスト" 126 | "Stop"="停止" 127 | "Audio folder"="オーディオフォルダ" 128 | "Volume (0-100%):"="音量(0-100%):" 129 | "Cancel"="キャンセル" 130 | "OK"="OK" 131 | "None"="なし" 132 | "System Beep"="システム音" 133 | 134 | ; 番茄钟循环设置对话框翻译 135 | "Set Pomodoro Loop Count"="ポモドーロの繰り返し回数設定" 136 | "Please enter loop count (1-10):"="繰り返し回数を入力してください(1-10):" 137 | 138 | ; ポモドーロ時間設定ダイアログの翻訳 139 | "Set Pomodoro Time Combination"="ポモドーロ時間の組み合わせ設定" 140 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="ポモドーロ時間の組み合わせをスペースで区切って入力してください:\n\n25m = 25分\n30s = 30秒\n1h30m = 1時間30分\n例:25m 5m 25m 10m - 作業25分、短い休憩5分、作業25分、長い休憩10分" 141 | 142 | ; ポモドーロ時間設定ダイアログの翻訳 143 | "Set Pomodoro Time"="ポモドーロタイマーの設定" 144 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25分\n25h=25時間\n25s=25秒\n25 30=25分30秒\n25 30m=25時間30分\n1 30 20=1時間30分20秒" 145 | 146 | ; カウントダウンプリセットダイアログの翻訳 147 | "Countdown Presets"="カウントダウンプリセット" 148 | "CountdownPresetDialogStaticText"="数字(分)をスペースで区切って入力してください\n\n25 10 5\n\nこれにより、25分、10分、5分のオプションが作成されます" -------------------------------------------------------------------------------- /resource/languages/ko.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; 한국어 번역 (Korean translation) 3 | ; 형식: 영어 텍스트=번역된 텍스트 4 | 5 | "Set Countdown"="카운트다운 설정" 6 | "Set Time"="시간 설정" 7 | "Time's up!"="시간이 다 되었습니다!" 8 | "Show Current Time"="현재 시간 표시" 9 | "24-Hour Format"="24시간 형식" 10 | "Show Seconds"="초 표시" 11 | "Time Display"="시간 표시" 12 | "Count Up"="카운트업" 13 | "Countdown"="카운트다운" 14 | "Start"="시작" 15 | "Pause"="일시중지" 16 | "Resume"="재개" 17 | "Start Over"="다시 시작" 18 | "Restart"="재시작" 19 | "Edit Mode"="편집 모드" 20 | "Show Message"="메시지 표시" 21 | "Lock Screen"="화면 잠금" 22 | "Shutdown"="시스템 종료" 23 | "Timeout Action"="시간 초과 동작" 24 | "Modify Time Options"="시간 옵션 수정" 25 | "Customize"="사용자 정의" 26 | "Color"="색상" 27 | "Font"="글꼴" 28 | "Version: %hs"="버전: %hs" 29 | "Feedback"="피드백" 30 | "Check for Updates"="업데이트 확인" 31 | "About"="정보" 32 | "User Guide"="사용자 가이드" 33 | "Reset"="재설정" 34 | "Exit"="종료" 35 | "Settings"="설정" 36 | "Preset Manager"="프리셋 관리자" 37 | "Startup Settings"="시작 설정" 38 | "Start with Windows"="Windows와 함께 시작" 39 | "All Pomodoro cycles completed!"="모든 포모도로 사이클이 완료되었습니다!" 40 | "Break over! Time to focus again."="휴식 끝! 다시 집중할 시간입니다." 41 | "Error"="오류" 42 | "Failed to open file"="파일을 열지 못했습니다" 43 | "Timer Control"="타이머 제어" 44 | "Pomodoro"="포모도로" 45 | "Loop Count: %d"="반복 횟수: %d" 46 | "Always on Top"="항상 위에 표시" 47 | "Save Preset"="프리셋 저장" 48 | "Load Preset"="프리셋 불러오기" 49 | "Delete Preset"="프리셋 삭제" 50 | "Create New Preset"="새 프리셋 만들기" 51 | "Preset Name"="프리셋 이름" 52 | "Select Preset"="프리셋 선택" 53 | "Confirm Delete"="삭제 확인" 54 | "Are you sure you want to delete this preset?"="이 프리셋을 삭제하시겠습니까?" 55 | "Open File/Software"="파일/소프트웨어 열기" 56 | "No Display"="표시 안 함" 57 | "Preset Management"="프리셋 관리" 58 | "Color Value"="색상 값" 59 | "Color Panel"="색상 패널" 60 | "More"="더 보기" 61 | "Help"="도움말" 62 | "Working: %d/%d"="작업 중: %d/%d" 63 | "Short Break: %d/%d"="짧은 휴식: %d/%d" 64 | "Long Break"="긴 휴식" 65 | "Time to focus!"="집중할 시간입니다!" 66 | "Time for a break!"="휴식 시간입니다!" 67 | "Completed: %d/%d"="완료: %d/%d" 68 | "Browse..."="찾아보기..." 69 | "Open Website"="웹사이트 열기" 70 | "Combination"="조합" 71 | "Set to No Display on Startup"="시작 시 표시 안 함으로 설정" 72 | "Set to Stopwatch on Startup"="시작 시 스톱워치로 설정" 73 | "Set to Countdown on Startup"="시작 시 카운트다운으로 설정" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="공백으로 구분된 숫자 입력\n예: 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25분\n25h = 25시간\n25s = 25초\n25 30 = 25분 30초\n25 30m = 25시간 30분\n1 30 20 = 1시간 30분 20초" 76 | "Support"="지원" 77 | "Following actions are one-time only"="다음 작업은 일회성입니다" 78 | "Sleep"="절전 모드" 79 | "Stopwatch"="스톱워치" 80 | "Modify Quick Countdown Options"="빠른 카운트다운 옵션 수정" 81 | "Notification Settings"="알림 설정" 82 | "Hotkey Settings"="단축키 설정" 83 | "CountdownDialogStaticText"="25=25분\n25h=25시간\n25s=25초\n25 30=25분 30초\n25 30m=25시간 30분\n1 30 20=1시간 30분 20초\n17 20t=17시 20분까지 카운트다운\n9 9 9t=9시 9분 9초까지 카운트다운" 84 | "OK"="확인" 85 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="카운트다운이 끝나면 열 웹사이트 URL을 입력하세요:\n예시: https://github.com/vladelaina/Catime" 86 | 87 | ; 对话框相关翻译 88 | "Special thanks to Neko House Lili Official for the icon"="아이콘을 제공해 주신 Neko House Lili Official에게 특별한 감사를 드립니다" 89 | "Build Date:"="빌드 날짜:" 90 | "COPYRIGHT_TEXT"="저작권 © 2025 vladelaina" 91 | "Credits"="크레딧" 92 | "BiliBili"="BiliBili" 93 | "GitHub"="GitHub" 94 | "Copyright Notice"="저작권 고지" 95 | "Invalid input format, please try again."="잘못된 입력 형식입니다. 다시 시도하세요." 96 | 97 | ; 热键对话框翻译 98 | "Show Current Time:"="현재 시간 표시:" 99 | "Count Up:"="카운트업:" 100 | "Countdown:"="카운트다운:" 101 | "Default Countdown:"="기본 카운트다운:" 102 | "Quick Countdown 1:"="빠른 카운트다운 1:" 103 | "Quick Countdown 2:"="빠른 카운트다운 2:" 104 | "Quick Countdown 3:"="빠른 카운트다운 3:" 105 | "Start Pomodoro:"="포모도로 시작:" 106 | "Hide/Show Window:"="창 숨기기/표시:" 107 | "Enter Edit Mode:"="편집 모드 진입:" 108 | "Pause/Resume Timer:"="타이머 일시중지/재개:" 109 | "Restart Timer:"="타이머 재시작:" 110 | "* Hotkeys will work globally"="* 단축키는 전역적으로 작동합니다" 111 | 112 | ; 通知设置对话框翻译 113 | "Notification Settings"="알림 설정" 114 | "Notification Content"="알림 내용" 115 | "Countdown timeout message:"="카운트다운 시간 초과 메시지:" 116 | "Pomodoro timeout message:"="포모도로 시간 초과 메시지:" 117 | "Pomodoro cycle complete message:"="포모도로 사이클 완료 메시지:" 118 | "Notification Display"="알림 표시" 119 | "Notification display time:"="알림 표시 시간:" 120 | "Maximum notification opacity (1-100%):"="알림 최대 투명도(1-100%):" 121 | "Notification Method"="알림 방법" 122 | "Catime notification window"="Catime 알림 창" 123 | "System notification"="운영 체제 알림" 124 | "System modal window"="시스템 모달 창" 125 | "Sound (supports .mp3/.wav/.flac):"="알림음(.mp3/.wav/.flac 지원):" 126 | "Test"="테스트" 127 | "Stop"="중지" 128 | "Audio folder"="오디오 폴더" 129 | "Volume (0-100%):"="볼륨(0-100%):" 130 | "Cancel"="취소" 131 | "None"="없음" 132 | "System Beep"="시스템 알림음" 133 | 134 | ; 番茄钟循环设置对话框翻译 135 | "Set Pomodoro Loop Count"="뽀모도로 반복 횟수 설정" 136 | "Please enter loop count (1-10):"="반복 횟수를 입력하세요 (1-10):" 137 | 138 | ; 포모도로 시간 조합 대화 상자 번역 139 | "Set Pomodoro Time Combination"="포모도로 시간 조합 설정" 140 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="포모도로 시간 조합을 공백으로 구분하여 입력하세요:\n\n25m = 25분\n30s = 30초\n1h30m = 1시간 30분\n예시: 25m 5m 25m 10m - 작업 25분, 짧은 휴식 5분, 작업 25분, 긴 휴식 10분" 141 | 142 | ; 포모도로 시간 설정 대화 상자 번역 143 | "Set Pomodoro Time"="포모도로 타이머 설정" 144 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25분\n25h=25시간\n25s=25초\n25 30=25분 30초\n25 30m=25시간 30분\n1 30 20=1시간 30분 20초" 145 | "OK"="확인" 146 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime" 147 | 148 | ; 카운트다운 프리셋 대화 상자 번역 149 | "Countdown Presets"="카운트다운 프리셋" 150 | "CountdownPresetDialogStaticText"="숫자(분)를 공백으로 구분하여 입력하세요\n\n25 10 5\n\n이는 25분, 10분, 5분 옵션을 생성합니다" 151 | -------------------------------------------------------------------------------- /resource/languages/pt.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; Tradução em Português (Portuguese translation) 3 | ; Formato: texto em inglês=texto traduzido 4 | 5 | "Set Countdown"="Definir Contagem Regressiva" 6 | "Set Time"="Definir Tempo" 7 | "Time's up!"="Tempo esgotado!" 8 | "Show Current Time"="Mostrar Hora Atual" 9 | "24-Hour Format"="Formato 24 horas" 10 | "Show Seconds"="Mostrar Segundos" 11 | "Time Display"="Exibição do Tempo" 12 | "Count Up"="Contagem Progressiva" 13 | "Countdown"="Contagem Regressiva" 14 | "Start"="Iniciar" 15 | "Pause"="Pausar" 16 | "Resume"="Retomar" 17 | "Start Over"="Recomeçar" 18 | "Restart"="Reiniciar" 19 | "Edit Mode"="Modo de Edição" 20 | "Show Message"="Mostrar Mensagem" 21 | "Lock Screen"="Bloquear Tela" 22 | "Shutdown"="Desligar" 23 | "Timeout Action"="Ação ao Término" 24 | "Modify Time Options"="Modificar Opções de Tempo" 25 | "Customize"="Personalizar" 26 | "Color"="Cor" 27 | "Font"="Fonte" 28 | "Version: %hs"="Versão: %hs" 29 | "Feedback"="Feedback" 30 | "Check for Updates"="Verificar Atualizações" 31 | "About"="Sobre" 32 | "User Guide"="Guia do Usuário" 33 | "Reset"="Redefinir" 34 | "Exit"="Sair" 35 | "Settings"="Configurações" 36 | "Preset Manager"="Gerenciador de Predefinições" 37 | "Startup Settings"="Configurações de Inicialização" 38 | "Start with Windows"="Iniciar com o Windows" 39 | "All Pomodoro cycles completed!"="Todos os ciclos Pomodoro concluídos!" 40 | "Break over! Time to focus again."="Intervalo terminado! Hora de focar novamente." 41 | "Error"="Erro" 42 | "Failed to open file"="Falha ao abrir arquivo" 43 | "Timer Control"="Controle do Temporizador" 44 | "Pomodoro"="Pomodoro" 45 | "Loop Count: %d"="Contagem de Ciclos: %d" 46 | "Always on Top"="Sempre no Topo" 47 | "Save Preset"="Salvar Predefinição" 48 | "Load Preset"="Carregar Predefinição" 49 | "Delete Preset"="Excluir Predefinição" 50 | "Create New Preset"="Criar Nova Predefinição" 51 | "Preset Name"="Nome da Predefinição" 52 | "Select Preset"="Selecionar Predefinição" 53 | "Confirm Delete"="Confirmar Exclusão" 54 | "Are you sure you want to delete this preset?"="Tem certeza de que deseja excluir esta predefinição?" 55 | "Open File/Software"="Abrir Arquivo/Software" 56 | "No Display"="Sem Exibição" 57 | "Preset Management"="Gerenciamento de Predefinições" 58 | "Color Value"="Valor da Cor" 59 | "Color Panel"="Painel de Cores" 60 | "More"="Mais" 61 | "Help"="Ajuda" 62 | "Working: %d/%d"="Trabalhando: %d/%d" 63 | "Short Break: %d/%d"="Pausa Curta: %d/%d" 64 | "Long Break"="Pausa Longa" 65 | "Time to focus!"="Hora de focar!" 66 | "Time for a break!"="Hora de fazer uma pausa!" 67 | "Completed: %d/%d"="Concluído: %d/%d" 68 | "Browse..."="Navegar..." 69 | "Open Website"="Abrir Site" 70 | "Combination"="Combinação" 71 | "Set to No Display on Startup"="Definir para Sem Exibição na Inicialização" 72 | "Set to Stopwatch on Startup"="Definir para Cronômetro na Inicialização" 73 | "Set to Countdown on Startup"="Definir para Contagem Regressiva na Inicialização" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="Digite números separados por espaços\nExemplo: 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25 minutos\n25h = 25 horas\n25s = 25 segundos\n25 30 = 25 minutos 30 segundos\n25 30m = 25 horas 30 minutos\n1 30 20 = 1 hora 30 minutos 20 segundos" 76 | "Support"="Suporte" 77 | "Following actions are one-time only"="As seguintes ações são apenas de uso único" 78 | "Sleep"="Suspender" 79 | "Stopwatch"="Cronômetro" 80 | "Modify Quick Countdown Options"="Modificar Opções de Contagem Regressiva Rápida" 81 | "Notification Settings"="Configurações de Notificação" 82 | "Hotkey Settings"="Configurações de Teclas de Atalho" 83 | "CountdownDialogStaticText"="25=25 minutos\n25h=25 horas\n25s=25 segundos\n25 30=25 minutos 30 segundos\n25 30m=25 horas 30 minutos\n1 30 20=1 hora 30 minutos 20 segundos\n17 20t=Contagem regressiva para 17:20\n9 9 9t=Contagem regressiva para 09:09:09" 84 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Digite a URL do site para abrir quando a contagem regressiva terminar:\nExemplo: https://github.com/vladelaina/Catime" 85 | 86 | ; 对话框相关翻译 87 | "Special thanks to Neko House Lili Official for the icon"="Agradecimentos especiais a Neko House Lili Official pelo ícone" 88 | "Build Date:"="Data de compilação:" 89 | "COPYRIGHT_TEXT"="Direitos autorais © 2025 vladelaina" 90 | "Credits"="Créditos" 91 | "BiliBili"="BiliBili" 92 | "GitHub"="GitHub" 93 | "Copyright Notice"="Aviso de Direitos Autorais" 94 | "Invalid input format, please try again."="Formato de entrada inválido, tente novamente." 95 | 96 | ; 热键对话框翻译 97 | "Show Current Time:"="Mostrar Hora Atual:" 98 | "Count Up:"="Contagem Progressiva:" 99 | "Countdown:"="Contagem Regressiva:" 100 | "Default Countdown:"="Contagem Regressiva Padrão:" 101 | "Quick Countdown 1:"="Contagem Regressiva Rápida 1:" 102 | "Quick Countdown 2:"="Contagem Regressiva Rápida 2:" 103 | "Quick Countdown 3:"="Contagem Regressiva Rápida 3:" 104 | "Start Pomodoro:"="Iniciar Pomodoro:" 105 | "Hide/Show Window:"="Ocultar/Mostrar Janela:" 106 | "Enter Edit Mode:"="Entrar no Modo de Edição:" 107 | "Pause/Resume Timer:"="Pausar/Retomar Temporizador:" 108 | "Restart Timer:"="Reiniciar Temporizador:" 109 | "* Hotkeys will work globally"="* As teclas de atalho funcionarão globalmente" 110 | 111 | ; 通知设置对话框翻译 112 | "Notification Settings"="Configurações de Notificação" 113 | "Notification Content"="Conteúdo da Notificação" 114 | "Countdown timeout message:"="Mensagem de Término da Contagem Regressiva:" 115 | "Pomodoro timeout message:"="Mensagem de Término do Pomodoro:" 116 | "Pomodoro cycle complete message:"="Mensagem de Conclusão do Ciclo Pomodoro:" 117 | "Notification Display"="Exibição da Notificação" 118 | "Notification display time:"="Tempo de Exibição da Notificação:" 119 | "Maximum notification opacity (1-100%):"="Opacidade Máxima da Notificação (1-100%):" 120 | "Notification Method"="Método de Notificação" 121 | "Catime notification window"="Janela de Notificação do Catime" 122 | "System notification"="Notificação do Sistema Operacional" 123 | "System modal window"="Janela Modal do Sistema" 124 | "Sound (supports .mp3/.wav/.flac):"="Som (suporta .mp3/.wav/.flac):" 125 | "Test"="Testar" 126 | "Stop"="Parar" 127 | "Audio folder"="Pasta de Áudio" 128 | "Volume (0-100%):"="Volume (0-100%):" 129 | "Cancel"="Cancelar" 130 | "OK"="OK" 131 | "None"="Nenhum" 132 | "System Beep"="Som do Sistema" 133 | 134 | ; 番茄钟循环设置对话框翻译 135 | "Set Pomodoro Loop Count"="Definir Número de Ciclos Pomodoro" 136 | "Please enter loop count (1-10):"="Digite o número de ciclos (1-10):" 137 | 138 | ; 番茄钟组合对话框翻译 139 | "Set Pomodoro Time Combination"="Configurar Combinação de Tempos Pomodoro" 140 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="Digite a sequência de tempos Pomodoro, separados por espaços:\n\n25m = 25 minutos\n30s = 30 segundos\n1h30m = 1 hora e 30 minutos\nExemplo: 25m 5m 25m 10m - trabalho 25min, pausa curta 5min, trabalho 25min, pausa longa 10min" 141 | 142 | ; 番茄钟时间设置对话框翻译 143 | "Set Pomodoro Time"="Definir tempo do Pomodoro" 144 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25 minutos\n25h=25 horas\n25s=25 segundos\n25 30=25 minutos 30 segundos\n25 30m=25 horas 30 minutos\n1 30 20=1 hora 30 minutos 20 segundos" 145 | 146 | ; Predefinições de contagem regressiva 147 | "Countdown Presets"="Predefinições de Contagem Regressiva" 148 | "CountdownPresetDialogStaticText"="Digite números (minutos), separados por espaços\n\n25 10 5\n\nIsso criará opções para 25 minutos, 10 minutos e 5 minutos" -------------------------------------------------------------------------------- /resource/languages/ru.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; Русский перевод (Russian translation) 3 | ; Формат: английский текст=переведенный текст 4 | 5 | "Set Countdown"="Установить обратный отсчет" 6 | "Set Time"="Установить время" 7 | "Time's up!"="Время вышло!" 8 | "Show Current Time"="Показать текущее время" 9 | "24-Hour Format"="24-часовой формат" 10 | "Show Seconds"="Показывать секунды" 11 | "Time Display"="Отображение времени" 12 | "Count Up"="Прямой отсчет" 13 | "Countdown"="Обратный отсчет" 14 | "Start"="Старт" 15 | "Pause"="Пауза" 16 | "Resume"="Продолжить" 17 | "Start Over"="Начать сначала" 18 | "Restart"="Перезапустить" 19 | "Edit Mode"="Режим редактирования" 20 | "Show Message"="Показать сообщение" 21 | "Lock Screen"="Заблокировать экран" 22 | "Shutdown"="Выключить" 23 | "Timeout Action"="Действие по истечении времени" 24 | "Modify Time Options"="Изменить настройки времени" 25 | "Customize"="Настроить" 26 | "Color"="Цвет" 27 | "Font"="Шрифт" 28 | "Version: %hs"="Версия: %hs" 29 | "Feedback"="Обратная связь" 30 | "Check for Updates"="Проверить обновления" 31 | "About"="О программе" 32 | "User Guide"="Руководство пользователя" 33 | "Reset"="Сброс" 34 | "Exit"="Выход" 35 | "Settings"="Настройки" 36 | "Preset Manager"="Менеджер пресетов" 37 | "Startup Settings"="Настройки запуска" 38 | "Start with Windows"="Запускать вместе с Windows" 39 | "All Pomodoro cycles completed!"="Все циклы Pomodoro завершены!" 40 | "Break over! Time to focus again."="Перерыв окончен! Пора снова сосредоточиться." 41 | "Error"="Ошибка" 42 | "Failed to open file"="Не удалось открыть файл" 43 | "Timer Control"="Управление таймером" 44 | "Pomodoro"="Помодоро" 45 | "Loop Count: %d"="Количество циклов: %d" 46 | "Always on Top"="Поверх всех окон" 47 | "Save Preset"="Сохранить пресет" 48 | "Load Preset"="Загрузить пресет" 49 | "Delete Preset"="Удалить пресет" 50 | "Create New Preset"="Создать новый пресет" 51 | "Preset Name"="Название пресета" 52 | "Select Preset"="Выбрать пресет" 53 | "Confirm Delete"="Подтвердить удаление" 54 | "Are you sure you want to delete this preset?"="Вы уверены, что хотите удалить этот пресет?" 55 | "Open File/Software"="Открыть файл/программу" 56 | "No Display"="Не отображать" 57 | "Preset Management"="Управление пресетами" 58 | "Color Value"="Значение цвета" 59 | "Color Panel"="Цветовая панель" 60 | "More"="Еще" 61 | "Help"="Помощь" 62 | "Working: %d/%d"="Работа: %d/%d" 63 | "Short Break: %d/%d"="Короткий перерыв: %d/%d" 64 | "Long Break"="Длинный перерыв" 65 | "Time to focus!"="Время сосредоточиться!" 66 | "Time for a break!"="Время для перерыва!" 67 | "Completed: %d/%d"="Завершено: %d/%d" 68 | "Browse..."="Обзор..." 69 | "Open Website"="Открыть веб-сайт" 70 | "Combination"="Комбинация" 71 | "Set to No Display on Startup"="Не отображать при запуске" 72 | "Set to Stopwatch on Startup"="Установить секундомер при запуске" 73 | "Set to Countdown on Startup"="Установить обратный отсчет при запуске" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="Введите числа, разделенные пробелами\nПример: 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25 минут\n25h = 25 часов\n25s = 25 секунд\n25 30 = 25 минут 30 секунд\n25 30m = 25 часов 30 минут\n1 30 20 = 1 час 30 минут 20 секунд" 76 | "Support"="Поддержка" 77 | "Following actions are one-time only"="Следующие действия выполняются только один раз" 78 | "Sleep"="Спящий режим" 79 | "Stopwatch"="Секундомер" 80 | "Modify Quick Countdown Options"="Изменить параметры быстрого обратного отсчета" 81 | "Notification Settings"="Настройки уведомлений" 82 | "Hotkey Settings"="Настройки горячих клавиш" 83 | "CountdownDialogStaticText"="25=25 минут\n25h=25 часов\n25s=25 секунд\n25 30=25 минут 30 секунд\n25 30m=25 часов 30 минут\n1 30 20=1 час 30 минут 20 секунд\n17 20t=Обратный отсчет до 17:20\n9 9 9t=Обратный отсчет до 09:09:09" 84 | "OK"="ОК" 85 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Введите URL-адрес веб-сайта, который нужно открыть по окончании обратного отсчета:\nПример: https://github.com/vladelaina/Catime" 86 | 87 | ; 对话框相关翻译 88 | "Special thanks to Neko House Lili Official for the icon"="Особая благодарность Neko House Lili Official за иконку" 89 | "Build Date:"="Дата сборки:" 90 | "COPYRIGHT_TEXT"="Авторские права © 2025 vladelaina" 91 | "Credits"="Авторы" 92 | "BiliBili"="BiliBili" 93 | "GitHub"="GitHub" 94 | "Copyright Notice"="Уведомление об авторских правах" 95 | "Invalid input format, please try again."="Неверный формат ввода, попробуйте снова." 96 | 97 | ; 热键对话框翻译 98 | "Show Current Time:"="Показать текущее время:" 99 | "Count Up:"="Прямой отсчет:" 100 | "Countdown:"="Обратный отсчет:" 101 | "Default Countdown:"="Обратный отсчет по умолчанию:" 102 | "Quick Countdown 1:"="Быстрый обратный отсчет 1:" 103 | "Quick Countdown 2:"="Быстрый обратный отсчет 2:" 104 | "Quick Countdown 3:"="Быстрый обратный отсчет 3:" 105 | "Start Pomodoro:"="Запустить Помодоро:" 106 | "Hide/Show Window:"="Скрыть/Показать окно:" 107 | "Enter Edit Mode:"="Войти в режим редактирования:" 108 | "Pause/Resume Timer:"="Приостановить/Продолжить таймер:" 109 | "Restart Timer:"="Перезапустить таймер:" 110 | "* Hotkeys will work globally"="* Горячие клавиши будут работать глобально" 111 | 112 | ; 通知设置对话框翻译 113 | "Notification Settings"="Настройки уведомлений" 114 | "Notification Content"="Содержание уведомления" 115 | "Countdown timeout message:"="Сообщение о завершении обратного отсчета:" 116 | "Pomodoro timeout message:"="Сообщение о завершении Помодоро:" 117 | "Pomodoro cycle complete message:"="Сообщение о завершении цикла Помодоро:" 118 | "Notification Display"="Отображение уведомлений" 119 | "Notification display time:"="Время отображения уведомления:" 120 | "Maximum notification opacity (1-100%):"="Максимальная прозрачность уведомления (1-100%):" 121 | "Notification Method"="Способ уведомления" 122 | "Catime notification window"="Окно уведомления Catime" 123 | "System notification"="Уведомление операционной системы" 124 | "System modal window"="Модальное окно системы" 125 | "Sound (supports .mp3/.wav/.flac):"="Звуковой сигнал (поддерживает .mp3/.wav/.flac):" 126 | "Test"="Тест" 127 | "Stop"="Стоп" 128 | "Audio folder"="Аудио-папка" 129 | "Volume (0-100%):"="Громкость (0-100%):" 130 | "Cancel"="Отмена" 131 | "None"="Нет" 132 | "System Beep"="Системный звук" 133 | 134 | ; 番茄钟循环设置对话框翻译 135 | "Set Pomodoro Loop Count"="Установить количество циклов Помодоро" 136 | "Please enter loop count (1-10):"="Введите количество циклов (1-10):" 137 | 138 | ; 为俄语添加番茄钟组合对话框翻译 139 | "Set Pomodoro Time Combination"="Настройка комбинации времени Pomodoro" 140 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="Введите последовательность времени Pomodoro, разделяя пробелами:\n\n25m = 25 минут\n30s = 30 секунд\n1h30m = 1 час 30 минут\nПример: 25m 5m 25m 10m - работа 25 мин, короткий перерыв 5 мин, работа 25 мин, длинный перерыв 10 мин" 141 | 142 | ; 番茄钟时间设置对话框翻译 143 | "Set Pomodoro Time"="Установить время Помодоро" 144 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25 минут\n25h=25 часов\n25s=25 секунд\n25 30=25 минут 30 секунд\n25 30m=25 часов 30 минут\n1 30 20=1 час 30 минут 20 секунд" 145 | "OK"="ОК" 146 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime" 147 | 148 | ; Настройка пресетов обратного отсчета 149 | "Countdown Presets"="Пресеты обратного отсчета" 150 | "CountdownPresetDialogStaticText"="Введите числа (минуты), разделенные пробелами\n\n25 10 5\n\nЭто создаст опции для 25 минут, 10 минут и 5 минут" 151 | -------------------------------------------------------------------------------- /resource/languages/zh-Hant.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; 繁体中文翻译 3 | ; 格式:英文原文=翻译文本 4 | 5 | "Set Countdown"="倒計時" 6 | "Set Time"="倒計時" 7 | "Time's up!"="時間到了!" 8 | "Show Current Time"="顯示目前時間" 9 | "24-Hour Format"="24小時制" 10 | "Show Seconds"="顯示秒數" 11 | "Time Display"="時間顯示" 12 | "Count Up"="正計時" 13 | "Countdown"="倒計時" 14 | "Start"="開始" 15 | "Pause"="暫停" 16 | "Resume"="繼續" 17 | "Start Over"="重新開始" 18 | "Restart"="重新啟動" 19 | "Edit Mode"="編輯模式" 20 | "Show Message"="顯示訊息" 21 | "Lock Screen"="鎖定螢幕" 22 | "Shutdown"="關機" 23 | "Timeout Action"="逾時動作" 24 | "Modify Time Options"="倒計時預設" 25 | "Customize"="自訂" 26 | "Color"="顏色" 27 | "Font"="字型" 28 | "Version: %hs"="版本: %hs" 29 | "Feedback"="意見回饋" 30 | "Check for Updates"="檢查更新" 31 | "About"="關於" 32 | "User Guide"="使用指南" 33 | "Reset"="重設" 34 | "Exit"="結束" 35 | "Settings"="設定" 36 | "Preset Manager"="預設管理" 37 | "Startup Settings"="啟動設定" 38 | "Start with Windows"="開機時啟動" 39 | "All Pomodoro cycles completed!"="所有番茄鐘循環已完成!" 40 | "Break over! Time to focus again."="休息結束!該專注了!" 41 | "Error"="錯誤" 42 | "Failed to open file"="無法開啟檔案" 43 | "Timer Control"="計時器控制" 44 | "Pomodoro"="番茄鐘" 45 | "Loop Count: %d"="循環次數: %d" 46 | "Always on Top"="視窗置頂" 47 | "Save Preset"="儲存預設" 48 | "Load Preset"="載入預設" 49 | "Delete Preset"="刪除預設" 50 | "Create New Preset"="建立新預設" 51 | "Preset Name"="預設名稱" 52 | "Select Preset"="選擇預設" 53 | "Confirm Delete"="確認刪除" 54 | "Are you sure you want to delete this preset?"="確定要刪除此預設嗎?" 55 | "Open File/Software"="開啟檔案/軟體" 56 | "No Display"="不顯示" 57 | "Preset Management"="預設管理" 58 | "Color Value"="顏色數值" 59 | "Color Panel"="顏色面板" 60 | "More"="更多" 61 | "Help"="說明" 62 | "Working: %d/%d"="工作中: %d/%d" 63 | "Short Break: %d/%d"="短休息: %d/%d" 64 | "Long Break"="長休息" 65 | "Time to focus!"="該專注了!" 66 | "Time for a break!"="該休息了!" 67 | "Completed: %d/%d"="已完成: %d/%d" 68 | "Browse..."="瀏覽..." 69 | "Open Website"="開啟網站" 70 | "Combination"="組合" 71 | "Set to No Display on Startup"="設定為啟動時不顯示" 72 | "Set to Stopwatch on Startup"="設定為啟動時正計時" 73 | "Set to Countdown on Startup"="設定為啟動時倒計時" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="請輸入以空格分隔的數字\n範例: 25 10 5" 75 | "25 = 25 minutes\n25h = 25 hours\n25s = 25 seconds\n25 30 = 25 minutes 30 seconds\n25 30m = 25 hours 30 minutes\n1 30 20 = 1 hour 30 minutes 20 seconds"="25 = 25分鐘\n25h = 25小時\n25s = 25秒\n25 30 = 25分鐘30秒\n25 30m = 25小時30分鐘\n1 30 20 = 1小時30分鐘20秒" 76 | "Support"="支援" 77 | "Following actions are one-time only"="以下逾時動作為一次性" 78 | "Sleep"="睡眠" 79 | "Stopwatch"="正計時" 80 | "Modify Quick Countdown Options"="修改倒計時選項" 81 | "Notification Settings"="通知設定" 82 | "Hotkey Settings"="快速鍵設定" 83 | "CountdownDialogStaticText"="25=25分鐘\n25h=25小時\n25s=25秒\n25 30=25分鐘30秒\n25 30m=25小時30分鐘\n1 30 20=1小時30分鐘20秒\n17 20t=倒數到17點20分\n9 9 9t=倒數到9點9分9秒" 84 | 85 | ; 对话框相关翻译 86 | "Special thanks to Neko House Lili Official for the icon"="特別感謝 Neko House Lili Official 提供的圖標" 87 | "Build Date:"="構建日期:" 88 | "COPYRIGHT_TEXT"="版權所有 © 2025 vladelaina" 89 | "Credits"="鳴謝" 90 | "BiliBili"="嗶哩嗶哩" 91 | "GitHub"="GitHub" 92 | "Copyright Notice"="版權聲明" 93 | "Invalid input format, please try again."="輸入格式無效,請重新輸入。" 94 | 95 | ; 热键对话框翻译 96 | "Show Current Time:"="顯示目前時間:" 97 | "Count Up:"="正計時:" 98 | "Countdown:"="倒計時:" 99 | "Default Countdown:"="預設倒計時:" 100 | "Quick Countdown 1:"="快速倒計時1:" 101 | "Quick Countdown 2:"="快速倒計時2:" 102 | "Quick Countdown 3:"="快速倒計時3:" 103 | "Start Pomodoro:"="開始番茄鐘:" 104 | "Hide/Show Window:"="隱藏/顯示視窗:" 105 | "Enter Edit Mode:"="進入編輯模式:" 106 | "Pause/Resume Timer:"="暫停/繼續計時:" 107 | "Restart Timer:"="重新開始計時:" 108 | "* Hotkeys will work globally"="* 快速鍵將全局生效" 109 | 110 | ; 通知设置对话框翻译 111 | "Notification Settings"="通知設定" 112 | "Notification Content"="通知內容" 113 | "Countdown timeout message:"="倒計時逾時提示:" 114 | "Pomodoro timeout message:"="番茄鐘逾時提示:" 115 | "Pomodoro cycle complete message:"="番茄鐘循環完成提示:" 116 | "Notification Display"="通知顯示" 117 | "Notification display time:"="通知顯示時間:" 118 | "Maximum notification opacity (1-100%):"="通知最大透明度(1-100%):" 119 | "Notification Method"="通知方式" 120 | "Catime notification window"="Catime通知視窗" 121 | "System notification"="作業系統通知" 122 | "System modal window"="系統模態視窗" 123 | "Sound (supports .mp3/.wav/.flac):"="提示音(支援.mp3/.wav/.flac):" 124 | "Test"="測試" 125 | "Stop"="停止" 126 | "Audio folder"="音訊資料夾" 127 | "Volume (0-100%):"="音量(0-100%):" 128 | "Cancel"="取消" 129 | "OK"="確定" 130 | "None"="無" 131 | "System Beep"="系統提示音" 132 | 133 | ; 番茄钟循环设置对话框翻译 134 | "Set Pomodoro Loop Count"="設置番茄鐘循環次數" 135 | "Please enter loop count (1-10):"="請輸入循環次數(1-10):" 136 | 137 | ; 為繁體中文添加番茄鐘組合對話框翻譯 138 | "Set Pomodoro Time Combination"="設置番茄鐘時間組合" 139 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="輸入番茄鐘時間組合,用空格分隔:\n\n25m = 25分鐘\n30s = 30秒\n1h30m = 1小時30分鐘\n例如: 25m 5m 25m 10m - 工作25分鐘,短休息5分鐘,工作25分鐘,長休息10分鐘" 140 | 141 | ; 番茄鐘時間設置對話框翻譯 142 | "Set Pomodoro Time"="設置番茄鐘時間" 143 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25分鐘\n25h=25小時\n25s=25秒\n25 30=25分鐘30秒\n25 30m=25小時30分鐘\n1 30 20=1小時30分鐘20秒" 144 | "OK"="確定" 145 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="請輸入要在倒數計時結束時開啟的網站URL:\n例如:https://github.com/vladelaina/Catime" 146 | 147 | ; 快捷時間選項設置對話框翻譯 148 | "Countdown Presets"="倒計時預設" 149 | "CountdownPresetDialogStaticText"="輸入數字(分鐘),用空格分隔\n\n25 10 5\n\n表示創建 25分鐘、10分鐘、5分鐘三個選項" 150 | -------------------------------------------------------------------------------- /resource/languages/zh_CN.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | ; 简体中文翻译 3 | ; 格式:英文原文=翻译文本 4 | 5 | "Set Countdown"="倒计时" 6 | "Set Time"="倒计时" 7 | "Time's up!"="时间到啦!" 8 | "Show Current Time"="显示当前时间" 9 | "24-Hour Format"="24小时制" 10 | "Show Seconds"="显示秒数" 11 | "Time Display"="时间显示" 12 | "Count Up"="正计时" 13 | "Countdown"="倒计时" 14 | "Start"="开始" 15 | "Pause"="暂停" 16 | "Resume"="继续" 17 | "Start Over"="重新开始" 18 | "Restart"="重启" 19 | "Edit Mode"="编辑模式" 20 | "Show Message"="显示消息" 21 | "Lock Screen"="锁定屏幕" 22 | "Shutdown"="关机" 23 | "Timeout Action"="超时动作" 24 | "Modify Time Options"="倒计时预设" 25 | "Customize"="自定义" 26 | "Color"="颜色" 27 | "Font"="字体" 28 | "Version: %hs"="版本: %hs" 29 | "Feedback"="反馈" 30 | "Check for Updates"="检查更新" 31 | "About"="关于" 32 | "User Guide"="使用指南" 33 | "Reset"="重置" 34 | "Exit"="退出" 35 | "Settings"="设置" 36 | "Preset Manager"="预设管理" 37 | "Startup Settings"="启动设置" 38 | "Start with Windows"="开机自启动" 39 | "All Pomodoro cycles completed!"="所有番茄钟循环完成!" 40 | "Break over! Time to focus again."="休息结束!重新开始工作!" 41 | "Error"="错误" 42 | "Failed to open file"="无法打开文件" 43 | "Timer Control"="计时管理" 44 | "Pomodoro"="番茄时钟" 45 | "Loop Count: %d"="循环次数: %d" 46 | "Always on Top"="置顶" 47 | "Save Preset"="保存预设" 48 | "Load Preset"="加载预设" 49 | "Delete Preset"="删除预设" 50 | "Create New Preset"="创建新预设" 51 | "Preset Name"="预设名称" 52 | "Select Preset"="选择预设" 53 | "Confirm Delete"="确认删除" 54 | "Are you sure you want to delete this preset?"="确定要删除这个预设吗?" 55 | "Open File/Software"="打开文件/软件" 56 | "No Display"="不显示" 57 | "Preset Management"="预设管理" 58 | "Color Value"="颜色值" 59 | "Color Panel"="颜色面板" 60 | "More"="更多" 61 | "Help"="帮助" 62 | "Working: %d/%d"="工作中: %d/%d" 63 | "Short Break: %d/%d"="短休息: %d/%d" 64 | "Long Break"="长休息" 65 | "Time to focus!"="专注时间到了!" 66 | "Time for a break!"="休息时间到了!" 67 | "Completed: %d/%d"="已完成: %d/%d" 68 | "Browse..."="浏览..." 69 | "Open Website"="打开网站" 70 | "Combination"="组合" 71 | "Set to No Display on Startup"="设定为启动时不显示" 72 | "Set to Stopwatch on Startup"="设定为启动时正计时" 73 | "Set to Countdown on Startup"="设定为启动时倒计时" 74 | "Enter numbers separated by spaces\nExample: 25 10 5"="请输入以空格分隔的数字\n范例: 25 10 5" 75 | "25 = 25 minutes\n25h = 25小時\n25s = 25秒\n25 30 = 25分钟30秒\n25 30m = 25小时30分钟\n1 30 20 = 1小时30分钟20秒"="25 = 25分钟\n25h = 25小时\n25s = 25秒\n25 30 = 25分钟30秒\n25 30m = 25小时30分钟\n1 30 20 = 1小时30分钟20秒" 76 | "Support"="支持" 77 | "Following actions are one-time only"="以下超时动作为一次性" 78 | "Sleep"="睡眠" 79 | "Stopwatch"="正计时" 80 | "Modify Quick Countdown Options"="修改倒计时选项" 81 | "Notification Settings"="通知设置" 82 | "Hotkey Settings"="热键设置" 83 | "CountdownDialogStaticText"="25=25分钟\n25h=25小时\n25s=25秒\n25 30=25分钟30秒\n25 30m=25小时30分钟\n1 30 20=1小时30分钟20秒\n17 20t=倒计时到17点20分\n9 9 9t=倒计时到9点9分9秒" 84 | 85 | ; 对话框相关翻译 86 | "Special thanks to Neko House Lili Official for the icon"="特别感谢 Neko House Lili Official 提供的图标" 87 | "Build Date:"="构建日期:" 88 | "COPYRIGHT_TEXT"="版权所有 © 2025 vladelaina" 89 | "Credits"="鸣谢" 90 | "BiliBili"="哔哩哔哩" 91 | "GitHub"="GitHub" 92 | "Copyright Notice"="版权声明" 93 | "Invalid input format, please try again."="输入格式无效,请重新输入。" 94 | 95 | ; 番茄钟循环设置对话框翻译 96 | "Set Pomodoro Loop Count"="设置番茄钟循环次数" 97 | "Please enter loop count (1-10):"="请输入循环次数(1-10):" 98 | 99 | ; 热键对话框翻译 100 | "Show Current Time:"="显示当前时间:" 101 | "Count Up:"="正计时:" 102 | "Countdown:"="倒计时:" 103 | "Default Countdown:"="默认倒计时:" 104 | "Quick Countdown 1:"="快捷倒计时1:" 105 | "Quick Countdown 2:"="快捷倒计时2:" 106 | "Quick Countdown 3:"="快捷倒计时3:" 107 | "Start Pomodoro:"="开始番茄钟:" 108 | "Hide/Show Window:"="隐藏/显示窗口:" 109 | "Enter Edit Mode:"="进入编辑模式:" 110 | "Pause/Resume Timer:"="暂停/继续计时:" 111 | "Restart Timer:"="重新开始计时:" 112 | "* Hotkeys will work globally"="* 热键将全局生效" 113 | 114 | ; 通知设置对话框翻译 115 | "Notification Settings"="通知设置" 116 | "Notification Content"="通知内容" 117 | "Countdown timeout message:"="倒计时超时提示:" 118 | "Pomodoro timeout message:"="番茄钟超时提示:" 119 | "Pomodoro cycle complete message:"="番茄钟循环完成提示:" 120 | "Notification Display"="通知显示" 121 | "Notification display time:"="通知显示时间:" 122 | "Maximum notification opacity (1-100%):"="通知最大透明度(1-100%):" 123 | "Notification Method"="通知方式" 124 | "Catime notification window"="Catime通知窗口" 125 | "System notification"="操作系统通知" 126 | "System modal window"="系统模态窗口" 127 | "Sound (supports .mp3/.wav/.flac):"="提示音(支持.mp3/.wav/.flac):" 128 | "Test"="测试" 129 | "Stop"="结束" 130 | "Audio folder"="音频目录" 131 | "Volume (0-100%):"="音量(0-100%):" 132 | "Cancel"="取消" 133 | "OK"="确定" 134 | "None"="无" 135 | "System Beep"="系统提示音" 136 | 137 | ; 番茄钟组合对话框翻译 138 | "Set Pomodoro Time Combination"="设置番茄钟时间组合" 139 | "Enter pomodoro time sequence, separated by spaces:\n\n25m = 25 minutes\n30s = 30 seconds\n1h30m = 1 hour 30 minutes\nExample: 25m 5m 25m 10m - work 25min, short break 5min, work 25min, long break 10min"="输入番茄钟时间组合,用空格分隔:\n\n25m = 25分钟\n30s = 30秒\n1h30m = 1小时30分钟\n例如: 25m 5m 25m 10m - 工作25分钟,短休息5分钟,工作25分钟,长休息10分钟" 140 | 141 | ; 番茄钟时间设置对话框翻译 142 | "Set Pomodoro Time"="设置番茄钟时间" 143 | "25=25 minutes\n25h=25 hours\n25s=25 seconds\n25 30=25 minutes 30 seconds\n25 30m=25 hours 30 minutes\n1 30 20=1 hour 30 minutes 20 seconds"="25=25分钟\n25h=25小时\n25s=25秒\n25 30=25分钟30秒\n25 30m=25小时30分钟\n1 30 20=1小时30分钟20秒" 144 | "Enter the website URL to open when the countdown ends:\nExample: https://github.com/vladelaina/Catime"="请输入要在倒计时结束时打开的网站URL:\n例如:https://github.com/vladelaina/Catime" 145 | 146 | ; 快捷时间选项设置对话框翻译 147 | "Countdown Presets"="倒计时预设" 148 | "CountdownPresetDialogStaticText"="输入数字(分钟),用空格分隔\n\n25 10 5\n\n表示创建 25分钟、10分钟、5分钟三个选项" 149 | -------------------------------------------------------------------------------- /resource/notification_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "resource.h" 4 | 5 | // 设置 UTF-8 编码 6 | #pragma code_page(65001) 7 | 8 | // 整合后的通知设置对话框 9 | CLOCK_IDD_NOTIFICATION_SETTINGS_DIALOG DIALOGEX 0, 0, 350, 410 10 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 11 | CAPTION "通知设置" 12 | FONT 9, "Segoe UI" 13 | BEGIN 14 | // 通知内容部分 15 | GROUPBOX "通知内容", IDC_NOTIFICATION_CONTENT_GROUP, 10, 10, 330, 160 16 | 17 | LTEXT "倒计时超时提示:", IDC_NOTIFICATION_LABEL1, 20, 30, 80, 15 18 | EDITTEXT IDC_NOTIFICATION_EDIT1, 20, 45, 310, 20, ES_AUTOHSCROLL 19 | 20 | LTEXT "番茄钟超时提示:", IDC_NOTIFICATION_LABEL2, 20, 75, 80, 15 21 | EDITTEXT IDC_NOTIFICATION_EDIT2, 20, 90, 310, 20, ES_AUTOHSCROLL 22 | 23 | LTEXT "番茄钟循环完成提示:", IDC_NOTIFICATION_LABEL3, 20, 120, 100, 15 24 | EDITTEXT IDC_NOTIFICATION_EDIT3, 20, 135, 310, 20, ES_AUTOHSCROLL 25 | 26 | // 通知显示部分 27 | GROUPBOX "通知显示", IDC_NOTIFICATION_DISPLAY_GROUP, 10, 180, 330, 70 28 | 29 | LTEXT "通知显示时间:", IDC_NOTIFICATION_TIME_LABEL, 20, 200, 100, 15 30 | CONTROL "", IDC_NOTIFICATION_TIME_EDIT, "SysDateTimePick32", DTS_TIMEFORMAT | DTS_UPDOWN | WS_TABSTOP, 130, 198, 100, 20 31 | 32 | LTEXT "通知最大透明度(1-100%):", IDC_NOTIFICATION_OPACITY_LABEL, 20, 225, 110, 15 33 | CONTROL "", IDC_NOTIFICATION_OPACITY_EDIT, "msctls_trackbar32", TBS_BOTH | TBS_NOTICKS | WS_TABSTOP, 130, 223, 180, 15 34 | LTEXT "100%", IDC_NOTIFICATION_OPACITY_TEXT, 315, 225, 35, 15 35 | 36 | // 通知方式选择部分 37 | GROUPBOX "通知方式", IDC_NOTIFICATION_METHOD_GROUP, 10, 260, 330, 110 38 | AUTORADIOBUTTON "Catime通知窗口", IDC_NOTIFICATION_TYPE_CATIME, 20, 280, 90, 15 39 | AUTORADIOBUTTON "操作系统通知", IDC_NOTIFICATION_TYPE_OS, 120, 280, 90, 15 40 | AUTORADIOBUTTON "系统模态窗口", IDC_NOTIFICATION_TYPE_SYSTEM_MODAL, 220, 280, 90, 15 41 | 42 | LTEXT "提示音(支持.mp3/.wav/.flac):", IDC_NOTIFICATION_SOUND_LABEL, 20, 305, 150, 15 43 | COMBOBOX IDC_NOTIFICATION_SOUND_COMBO, 170, 303, 80, 100, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP 44 | PUSHBUTTON "测试", IDC_TEST_SOUND_BUTTON, 255, 303, 35, 20 45 | PUSHBUTTON "音频目录", IDC_OPEN_SOUND_DIR_BUTTON, 295, 303, 45, 20 46 | 47 | LTEXT "音量(0-100%):", IDC_VOLUME_LABEL, 20, 335, 70, 15 48 | CONTROL "", IDC_VOLUME_SLIDER, "msctls_trackbar32", TBS_BOTH | TBS_NOTICKS | WS_TABSTOP, 90, 335, 180, 15 49 | LTEXT "100%", IDC_VOLUME_TEXT, 275, 335, 35, 15 50 | 51 | // 确定和取消按钮 52 | PUSHBUTTON "取消", IDCANCEL, 235, 380, 50, 15 53 | PUSHBUTTON "确定", IDOK, 290, 380, 50, 15 54 | END -------------------------------------------------------------------------------- /resource/pomodoro_combo_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 番茄钟时间组合设置对话框 8 | CLOCK_IDD_POMODORO_COMBO_DIALOG DIALOGEX 0, 0, 200, 130 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "" 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "", CLOCK_IDC_STATIC, 10, 10, 180, 60 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 75, 180, 20, ES_AUTOHSCROLL | ES_MULTILINE 15 | PUSHBUTTON "", CLOCK_IDC_BUTTON_OK, 140, 100, 50, 14 16 | END -------------------------------------------------------------------------------- /resource/pomodoro_loop_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 番茄钟循环次数设置对话框 8 | CLOCK_IDD_POMODORO_LOOP_DIALOG DIALOGEX 0, 0, 200, 130 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "" // 通过代码设置本地化标题 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "", CLOCK_IDC_STATIC, 10, 10, 180, 60 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 75, 180, 20, ES_AUTOHSCROLL 15 | PUSHBUTTON "OK", CLOCK_IDC_BUTTON_OK, 140, 100, 50, 14 16 | END -------------------------------------------------------------------------------- /resource/pomodoro_time_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 番茄钟时间设置对话框 8 | CLOCK_IDD_POMODORO_TIME_DIALOG DIALOGEX 0, 0, 200, 130 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "" 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "", CLOCK_IDC_STATIC, 10, 10, 180, 60 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 75, 180, 20, ES_AUTOHSCROLL | ES_MULTILINE 15 | PUSHBUTTON "", CLOCK_IDC_BUTTON_OK, 140, 100, 50, 14 16 | END -------------------------------------------------------------------------------- /resource/resource.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | //----------------------------------------------------------------------------- 5 | // Program Icon 6 | //----------------------------------------------------------------------------- 7 | // Copyright notice: catime.ico is created by 猫屋敷梨梨Official 8 | // (https://space.bilibili.com/26087398) with all rights reserved. 9 | // Not for commercial use without explicit permission. 10 | IDI_CATIME ICON "../asset/icon/catime.ico" 11 | 12 | //----------------------------------------------------------------------------- 13 | // Fonts - CC BY-SA 4.0 License 14 | //----------------------------------------------------------------------------- 15 | 16 | //----------------------------------------------------------------------------- 17 | // Fonts - MIT License 18 | //----------------------------------------------------------------------------- 19 | IDR_FONT_PROFONT FONT "../asset/font/MIT/ProFont IIx Nerd Font Essence.ttf" 20 | 21 | //----------------------------------------------------------------------------- 22 | // Fonts - SIL Open Font License 23 | //----------------------------------------------------------------------------- 24 | IDR_FONT_DEPARTURE FONT "../asset/font/SIL/DepartureMono Nerd Font Propo Essence.ttf" 25 | IDR_FONT_DADDYTIME FONT "../asset/font/SIL/DaddyTimeMono Nerd Font Propo Essence.ttf" 26 | IDR_FONT_RECMONO FONT "../asset/font/SIL/RecMonoCasual Nerd Font Mono Essence.ttf" 27 | IDR_FONT_TERMINESS FONT "../asset/font/SIL/Terminess Nerd Font Propo Essence.ttf" 28 | 29 | //----------------------------------------------------------------------------- 30 | // Fonts - WTFPL License 31 | //----------------------------------------------------------------------------- 32 | 33 | //----------------------------------------------------------------------------- 34 | // Fonts - SIL Open Font License (OFL) 35 | //----------------------------------------------------------------------------- 36 | IDR_FONT_ARBUTUS FONT "../asset/font/OFL/Arbutus Essence.ttf" 37 | IDR_FONT_BERKSHIRE FONT "../asset/font/OFL/Berkshire Swash Essence.ttf" 38 | IDR_FONT_CAVEAT FONT "../asset/font/OFL/Caveat Brush Essence.ttf" 39 | IDR_FONT_CREEPSTER FONT "../asset/font/OFL/Creepster Essence.ttf" 40 | IDR_FONT_DOTGOTHIC FONT "../asset/font/OFL/DotGothic16 Essence.ttf" 41 | IDR_FONT_DOTO FONT "../asset/font/OFL/Doto ExtraBold Essence.ttf" 42 | // IDR_FONT_FLAVORS FONT "font/OFL/Flavors.ttf" 43 | IDR_FONT_FOLDIT FONT "../asset/font/OFL/Foldit SemiBold Essence.ttf" 44 | IDR_FONT_FREDERICKA FONT "../asset/font/OFL/Fredericka the Great Essence.ttf" 45 | IDR_FONT_FRIJOLE FONT "../asset/font/OFL/Frijole Essence.ttf" 46 | // IDR_FONT_GRIFFY FONT "font/OFL/Griffy.ttf" 47 | IDR_FONT_GWENDOLYN FONT "../asset/font/OFL/Gwendolyn Essence.ttf" 48 | IDR_FONT_HANDJET FONT "../asset/font/OFL/Handjet Essence.ttf" 49 | IDR_FONT_INKNUT FONT "../asset/font/OFL/Inknut Antiqua Medium Essence.ttf" 50 | IDR_FONT_JACQUARD FONT "../asset/font/OFL/Jacquard 12 Essence.ttf" 51 | IDR_FONT_JACQUARDA FONT "../asset/font/OFL/Jacquarda Bastarda 9 Essence.ttf" 52 | IDR_FONT_KAVOON FONT "../asset/font/OFL/Kavoon Essence.ttf" 53 | IDR_FONT_KUMAR_ONE_OUTLINE FONT "../asset/font/OFL/Kumar One Outline Essence.ttf" 54 | IDR_FONT_KUMAR_ONE FONT "../asset/font/OFL/Kumar One Essence.ttf" 55 | IDR_FONT_LAKKI_REDDY FONT "../asset/font/OFL/Lakki Reddy Essence.ttf" 56 | IDR_FONT_LICORICE FONT "../asset/font/OFL/Licorice Essence.ttf" 57 | IDR_FONT_MA_SHAN_ZHENG FONT "../asset/font/OFL/Ma Shan Zheng Essence.ttf" 58 | IDR_FONT_MOIRAI_ONE FONT "../asset/font/OFL/Moirai One Essence.ttf" 59 | IDR_FONT_MYSTERY_QUEST FONT "../asset/font/OFL/Mystery Quest Essence.ttf" 60 | IDR_FONT_NOTO_NASTALIQ FONT "../asset/font/OFL/Noto Nastaliq Urdu Medium Essence.ttf" 61 | IDR_FONT_PIEDRA FONT "../asset/font/OFL/Piedra Essence.ttf" 62 | IDR_FONT_PINYON_SCRIPT FONT "../asset/font/OFL/Pinyon Script Essence.ttf" 63 | IDR_FONT_PIXELIFY FONT "../asset/font/OFL/Pixelify Sans Medium Essence.ttf" 64 | IDR_FONT_PRESS_START FONT "../asset/font/OFL/Press Start 2P Essence.ttf" 65 | // IDR_FONT_RUBIK_BEASTLY FONT "font/OFL/Rubik Beastly.ttf" 66 | IDR_FONT_RUBIK_BUBBLES FONT "../asset/font/OFL/Rubik Bubbles Essence.ttf" 67 | IDR_FONT_RUBIK_BURNED FONT "../asset/font/OFL/Rubik Burned Essence.ttf" 68 | IDR_FONT_RUBIK_GLITCH FONT "../asset/font/OFL/Rubik Glitch Essence.ttf" 69 | IDR_FONT_RUBIK_MARKER_HATCH FONT "../asset/font/OFL/Rubik Marker Hatch Essence.ttf" 70 | IDR_FONT_RUBIK_PUDDLES FONT "../asset/font/OFL/Rubik Puddles Essence.ttf" 71 | IDR_FONT_RUBIK_VINYL FONT "../asset/font/OFL/Rubik Vinyl Essence.ttf" 72 | IDR_FONT_RUBIK_WET_PAINT FONT "../asset/font/OFL/Rubik Wet Paint Essence.ttf" 73 | IDR_FONT_RUGE_BOOGIE FONT "../asset/font/OFL/Ruge Boogie Essence.ttf" 74 | IDR_FONT_SEVILLANA FONT "../asset/font/OFL/Sevillana Essence.ttf" 75 | IDR_FONT_SILKSCREEN FONT "../asset/font/OFL/Silkscreen Essence.ttf" 76 | IDR_FONT_STICK FONT "../asset/font/OFL/Stick Essence.ttf" 77 | IDR_FONT_UNDERDOG FONT "../asset/font/OFL/Underdog Essence.ttf" 78 | IDR_FONT_WALLPOET FONT "../asset/font/OFL/Wallpoet Essence.ttf" 79 | IDR_FONT_YESTERYEAR FONT "../asset/font/OFL/Yesteryear Essence.ttf" 80 | IDR_FONT_ZCOOL_KUAILE FONT "../asset/font/OFL/ZCOOL KuaiLe Essence.ttf" 81 | 82 | //----------------------------------------------------------------------------- 83 | // Dialog Resources 84 | //----------------------------------------------------------------------------- 85 | // 输入框对话框 86 | IDD_INPUTBOX DIALOGEX 0, 0, 240, 90 87 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 88 | CAPTION "输入" 89 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 90 | BEGIN 91 | LTEXT "请输入:", IDC_STATIC_PROMPT, 7, 7, 226, 14 92 | EDITTEXT IDC_EDIT_INPUT, 7, 24, 226, 14, ES_AUTOHSCROLL 93 | DEFPUSHBUTTON "确定", IDOK, 123, 69, 50, 14 94 | PUSHBUTTON "取消", IDCANCEL, 183, 69, 50, 14 95 | END 96 | 97 | #include "countdown_dialog.rc" 98 | #include "color_dialog.rc" 99 | #include "startup_dialog.rc" 100 | #include "shortcut_dialog.rc" 101 | #include "about_dialog.rc" 102 | #include "error_dialog.rc" 103 | #include "pomodoro_time_dialog.rc" 104 | #include "pomodoro_loop_dialog.rc" 105 | #include "pomodoro_combo_dialog.rc" 106 | #include "website_dialog.rc" 107 | #include "notification_dialog.rc" 108 | #include "update_dialog.rc" 109 | #include "hotkey_dialog.rc" 110 | 111 | 1 RT_MANIFEST "app.manifest" 112 | -------------------------------------------------------------------------------- /resource/shortcut_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 快捷时间选项设置对话框 8 | CLOCK_IDD_SHORTCUT_DIALOG DIALOGEX 0, 0, 200, 130 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "Countdown Presets" 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "", CLOCK_IDC_STATIC, 10, 10, 180, 50 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 75, 180, 20, ES_AUTOHSCROLL | ES_MULTILINE 15 | PUSHBUTTON "", CLOCK_IDC_BUTTON_OK, 140, 105, 50, 14 16 | END -------------------------------------------------------------------------------- /resource/startup_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 启动设置对话框 8 | CLOCK_IDD_STARTUP_DIALOG DIALOGEX 0, 0, 200, 130 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "启动设置 - 倒计时" 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "设置启动时的默认倒计时时间\n格式同倒计时时间设置", CLOCK_IDC_STATIC, 10, 10, 180, 30 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 55, 180, 20, ES_AUTOHSCROLL | ES_MULTILINE 15 | PUSHBUTTON "确定", CLOCK_IDC_BUTTON_OK, 140, 105, 50, 14 16 | END -------------------------------------------------------------------------------- /resource/update_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 更新提示对话框资源定义 8 | IDD_UPDATE_DIALOG DIALOGEX 0, 0, 160, 100 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | FONT 12, "Microsoft YaHei UI" 11 | BEGIN 12 | CTEXT "当前版本: %s\n新版本: %s", IDC_UPDATE_TEXT, 0, 10, 160, 40 13 | CTEXT "即将退出程序", IDC_UPDATE_EXIT_TEXT, 0, 50, 160, 20 14 | PUSHBUTTON "是(&Y)", IDYES, 30, 75, 40, 15 15 | PUSHBUTTON "否(&N)", IDNO, 90, 75, 40, 15 16 | DEFPUSHBUTTON "确定", IDOK, 60, 75, 40, 15, NOT WS_VISIBLE 17 | END 18 | 19 | // 无需更新对话框资源定义 20 | IDD_NO_UPDATE_DIALOG DIALOGEX 0, 0, 160, 60 21 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 22 | FONT 12, "Microsoft YaHei UI" 23 | BEGIN 24 | CTEXT "您已经使用的是最新版本!", IDC_NO_UPDATE_TEXT, 0, 10, 160, 25 25 | DEFPUSHBUTTON "确定", IDOK, 60, 40, 40, 15 26 | END -------------------------------------------------------------------------------- /resource/website_dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | // 设置 UTF-8 编码 5 | #pragma code_page(65001) 6 | 7 | // 网站URL输入对话框 8 | CLOCK_IDD_WEBSITE_DIALOG DIALOGEX 0, 0, 280, 100 9 | STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 10 | CAPTION "Open Website" 11 | FONT 9, "Segoe UI" 12 | BEGIN 13 | LTEXT "", CLOCK_IDC_STATIC, 10, 10, 260, 30 14 | EDITTEXT CLOCK_IDC_EDIT, 10, 45, 260, 20, ES_AUTOHSCROLL | ES_MULTILINE 15 | PUSHBUTTON "", CLOCK_IDC_BUTTON_OK, 220, 75, 50, 14 16 | END -------------------------------------------------------------------------------- /src/async_update_checker.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file async_update_checker.c 3 | * @brief 简化的异步应用程序更新检查功能实现 4 | * 5 | * 本文件实现了应用程序异步检查更新的功能,确保更新检查不会阻塞主线程。 6 | */ 7 | 8 | #include 9 | #include 10 | #include "../include/async_update_checker.h" 11 | #include "../include/update_checker.h" 12 | #include "../include/log.h" 13 | 14 | // 线程参数结构体 15 | typedef struct { 16 | HWND hwnd; 17 | BOOL silentCheck; 18 | } UpdateThreadParams; 19 | 20 | // 正在运行的更新检查线程句柄 21 | static HANDLE g_hUpdateThread = NULL; 22 | static BOOL g_bUpdateThreadRunning = FALSE; 23 | 24 | /** 25 | * @brief 清理更新检查线程资源 26 | * 27 | * 关闭线程句柄并释放相关资源。 28 | */ 29 | void CleanupUpdateThread() { 30 | LOG_INFO("清理更新检查线程资源"); 31 | if (g_hUpdateThread != NULL) { 32 | LOG_INFO("等待更新检查线程结束,超时设为1秒"); 33 | // 等待线程结束,但最多等待1秒 34 | DWORD waitResult = WaitForSingleObject(g_hUpdateThread, 1000); 35 | if (waitResult == WAIT_TIMEOUT) { 36 | LOG_WARNING("等待线程结束超时,强制关闭线程句柄"); 37 | } else if (waitResult == WAIT_OBJECT_0) { 38 | LOG_INFO("线程已正常结束"); 39 | } else { 40 | LOG_WARNING("等待线程返回意外结果:%lu", waitResult); 41 | } 42 | 43 | CloseHandle(g_hUpdateThread); 44 | g_hUpdateThread = NULL; 45 | g_bUpdateThreadRunning = FALSE; 46 | LOG_INFO("线程资源已清理完毕"); 47 | } else { 48 | LOG_INFO("更新检查线程未运行,无需清理"); 49 | } 50 | } 51 | 52 | /** 53 | * @brief 更新检查线程函数 54 | * @param param 线程参数(窗口句柄) 55 | * 56 | * 在单独的线程中执行更新检查,不会阻塞主线程。 57 | */ 58 | unsigned __stdcall UpdateCheckThreadProc(void* param) { 59 | LOG_INFO("更新检查线程已启动"); 60 | 61 | // 解析线程参数 62 | UpdateThreadParams* threadParams = (UpdateThreadParams*)param; 63 | if (!threadParams) { 64 | LOG_ERROR("线程参数为空,无法执行更新检查"); 65 | g_bUpdateThreadRunning = FALSE; 66 | _endthreadex(1); 67 | return 1; 68 | } 69 | 70 | HWND hwnd = threadParams->hwnd; 71 | BOOL silentCheck = threadParams->silentCheck; 72 | 73 | LOG_INFO("解析线程参数成功,窗口句柄:0x%p,静默检查模式:%s", 74 | hwnd, silentCheck ? "是" : "否"); 75 | 76 | // 释放线程参数内存 77 | free(threadParams); 78 | LOG_INFO("释放线程参数内存"); 79 | 80 | // 调用原始的更新检查函数,传入静默检查参数 81 | LOG_INFO("开始执行更新检查"); 82 | CheckForUpdateSilent(hwnd, silentCheck); 83 | LOG_INFO("更新检查完成"); 84 | 85 | // 标记线程已结束 86 | g_bUpdateThreadRunning = FALSE; 87 | 88 | // 线程结束 89 | _endthreadex(0); 90 | return 0; 91 | } 92 | 93 | /** 94 | * @brief 异步检查应用程序更新 95 | * @param hwnd 窗口句柄 96 | * @param silentCheck 是否为静默检查(仅在有更新时显示提示) 97 | * 98 | * 在单独的线程中连接到GitHub检查是否有新版本。 99 | * 如果有,会提示用户是否在浏览器中下载。 100 | * 此函数立即返回,不会阻塞主线程。 101 | */ 102 | void CheckForUpdateAsync(HWND hwnd, BOOL silentCheck) { 103 | LOG_INFO("异步更新检查请求,窗口句柄:0x%p,静默模式:%s", 104 | hwnd, silentCheck ? "是" : "否"); 105 | 106 | // 如果已经有更新检查线程在运行,不要启动新线程 107 | if (g_bUpdateThreadRunning) { 108 | LOG_INFO("已有更新检查线程正在运行,跳过本次检查请求"); 109 | return; 110 | } 111 | 112 | // 清理之前的线程句柄(如果有) 113 | if (g_hUpdateThread != NULL) { 114 | LOG_INFO("发现旧的线程句柄,清理中..."); 115 | CloseHandle(g_hUpdateThread); 116 | g_hUpdateThread = NULL; 117 | LOG_INFO("旧线程句柄已关闭"); 118 | } 119 | 120 | // 分配线程参数内存 121 | LOG_INFO("为线程参数分配内存"); 122 | UpdateThreadParams* threadParams = (UpdateThreadParams*)malloc(sizeof(UpdateThreadParams)); 123 | if (!threadParams) { 124 | // 内存分配失败 125 | LOG_ERROR("线程参数内存分配失败,无法启动更新检查线程"); 126 | return; 127 | } 128 | 129 | // 设置线程参数 130 | threadParams->hwnd = hwnd; 131 | threadParams->silentCheck = silentCheck; 132 | LOG_INFO("线程参数设置完成"); 133 | 134 | // 标记线程即将运行 135 | g_bUpdateThreadRunning = TRUE; 136 | 137 | LOG_INFO("准备创建更新检查线程"); 138 | // 创建线程执行更新检查 139 | HANDLE hThread = (HANDLE)_beginthreadex( 140 | NULL, // 默认安全属性 141 | 0, // 默认栈大小 142 | UpdateCheckThreadProc, // 线程函数 143 | threadParams, // 线程参数 144 | 0, // 立即运行线程 145 | NULL // 不需要线程ID 146 | ); 147 | 148 | if (hThread) { 149 | // 保存线程句柄以便后续检查 150 | LOG_INFO("更新检查线程创建成功,线程句柄:0x%p", hThread); 151 | g_hUpdateThread = hThread; 152 | } else { 153 | // 线程创建失败,释放参数内存 154 | DWORD errorCode = GetLastError(); 155 | char errorMsg[256] = {0}; 156 | GetLastErrorDescription(errorCode, errorMsg, sizeof(errorMsg)); 157 | LOG_ERROR("更新检查线程创建失败,错误码:%lu,错误信息:%s", errorCode, errorMsg); 158 | 159 | free(threadParams); 160 | g_bUpdateThreadRunning = FALSE; 161 | } 162 | } -------------------------------------------------------------------------------- /src/drag_scale.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file drag_scale.c 3 | * @brief 窗口拖动和缩放功能实现 4 | * 5 | * 本文件实现了应用程序窗口的拖动和缩放功能, 6 | * 包括鼠标拖动窗口和滚轮缩放窗口的功能。 7 | */ 8 | 9 | #include 10 | #include "../include/window.h" 11 | #include "../include/config.h" 12 | #include "../include/drag_scale.h" 13 | 14 | // 添加变量来记录编辑模式前的置顶状态 15 | BOOL PREVIOUS_TOPMOST_STATE = FALSE; 16 | 17 | /** 18 | * @brief 开始拖动窗口 19 | * @param hwnd 窗口句柄 20 | * 21 | * 在编辑模式下,开始拖动窗口操作。 22 | * 记录初始鼠标位置并设置捕获。 23 | */ 24 | void StartDragWindow(HWND hwnd) { 25 | if (CLOCK_EDIT_MODE) { 26 | CLOCK_IS_DRAGGING = TRUE; 27 | SetCapture(hwnd); 28 | GetCursorPos(&CLOCK_LAST_MOUSE_POS); 29 | } 30 | } 31 | 32 | /** 33 | * @brief 开始编辑模式 34 | * @param hwnd 窗口句柄 35 | * 36 | * 启用编辑模式前,确保窗口为置顶状态, 37 | * 记录原始置顶状态以便退出编辑模式时恢复。 38 | */ 39 | void StartEditMode(HWND hwnd) { 40 | // 记录当前的置顶状态 41 | PREVIOUS_TOPMOST_STATE = CLOCK_WINDOW_TOPMOST; 42 | 43 | // 如果当前不是置顶状态,先设为置顶 44 | if (!CLOCK_WINDOW_TOPMOST) { 45 | SetWindowTopmost(hwnd, TRUE); 46 | } 47 | 48 | // 然后启用编辑模式 49 | CLOCK_EDIT_MODE = TRUE; 50 | 51 | // 应用模糊效果 52 | SetBlurBehind(hwnd, TRUE); 53 | 54 | // 禁用点击穿透 55 | SetClickThrough(hwnd, FALSE); 56 | 57 | // 确保鼠标光标为默认箭头 58 | SetCursor(LoadCursor(NULL, IDC_ARROW)); 59 | 60 | // 刷新窗口,添加立即更新 61 | InvalidateRect(hwnd, NULL, TRUE); 62 | UpdateWindow(hwnd); // 确保立即刷新 63 | } 64 | 65 | /** 66 | * @brief 结束编辑模式 67 | * @param hwnd 窗口句柄 68 | * 69 | * 退出编辑模式,恢复窗口原始置顶状态, 70 | * 清除模糊效果并更新相关设置。 71 | */ 72 | void EndEditMode(HWND hwnd) { 73 | if (CLOCK_EDIT_MODE) { 74 | CLOCK_EDIT_MODE = FALSE; 75 | 76 | // 移除模糊效果 77 | SetBlurBehind(hwnd, FALSE); 78 | SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 255, LWA_COLORKEY); 79 | 80 | // 恢复点击穿透 81 | SetClickThrough(hwnd, !CLOCK_EDIT_MODE); 82 | 83 | // 如果之前不是置顶状态,恢复为非置顶 84 | if (!PREVIOUS_TOPMOST_STATE) { 85 | SetWindowTopmost(hwnd, FALSE); 86 | } 87 | 88 | // 刷新窗口,添加立即更新 89 | InvalidateRect(hwnd, NULL, TRUE); 90 | UpdateWindow(hwnd); // 确保立即刷新 91 | } 92 | } 93 | 94 | /** 95 | * @brief 结束拖动窗口 96 | * @param hwnd 窗口句柄 97 | * 98 | * 结束拖动窗口操作。 99 | * 释放鼠标捕获并调整窗口位置。 100 | */ 101 | void EndDragWindow(HWND hwnd) { 102 | if (CLOCK_EDIT_MODE && CLOCK_IS_DRAGGING) { 103 | CLOCK_IS_DRAGGING = FALSE; 104 | ReleaseCapture(); 105 | // 编辑模式下不强制窗口在屏幕内,允许拖出 106 | AdjustWindowPosition(hwnd, FALSE); 107 | InvalidateRect(hwnd, NULL, TRUE); 108 | } 109 | } 110 | 111 | /** 112 | * @brief 处理窗口拖动事件 113 | * @param hwnd 窗口句柄 114 | * @return BOOL 是否处理了事件 115 | * 116 | * 在编辑模式下,处理鼠标拖动窗口的事件。 117 | * 根据鼠标移动距离更新窗口位置。 118 | */ 119 | BOOL HandleDragWindow(HWND hwnd) { 120 | if (CLOCK_EDIT_MODE && CLOCK_IS_DRAGGING) { 121 | POINT currentPos; 122 | GetCursorPos(¤tPos); 123 | 124 | int deltaX = currentPos.x - CLOCK_LAST_MOUSE_POS.x; 125 | int deltaY = currentPos.y - CLOCK_LAST_MOUSE_POS.y; 126 | 127 | RECT windowRect; 128 | GetWindowRect(hwnd, &windowRect); 129 | 130 | SetWindowPos(hwnd, NULL, 131 | windowRect.left + deltaX, 132 | windowRect.top + deltaY, 133 | windowRect.right - windowRect.left, 134 | windowRect.bottom - windowRect.top, 135 | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW 136 | ); 137 | 138 | CLOCK_LAST_MOUSE_POS = currentPos; 139 | 140 | UpdateWindow(hwnd); 141 | 142 | // 更新位置变量并保存设置 143 | CLOCK_WINDOW_POS_X = windowRect.left + deltaX; 144 | CLOCK_WINDOW_POS_Y = windowRect.top + deltaY; 145 | SaveWindowSettings(hwnd); 146 | 147 | return TRUE; 148 | } 149 | return FALSE; 150 | } 151 | 152 | /** 153 | * @brief 处理窗口缩放事件 154 | * @param hwnd 窗口句柄 155 | * @param delta 鼠标滚轮增量 156 | * @return BOOL 是否处理了事件 157 | * 158 | * 在编辑模式下,处理鼠标滚轮缩放窗口的事件。 159 | * 根据滚轮方向调整窗口和字体大小。 160 | */ 161 | BOOL HandleScaleWindow(HWND hwnd, int delta) { 162 | if (CLOCK_EDIT_MODE) { 163 | float old_scale = CLOCK_FONT_SCALE_FACTOR; 164 | 165 | RECT windowRect; 166 | GetWindowRect(hwnd, &windowRect); 167 | int oldWidth = windowRect.right - windowRect.left; 168 | int oldHeight = windowRect.bottom - windowRect.top; 169 | 170 | float scaleFactor = 1.1f; 171 | if (delta > 0) { 172 | CLOCK_FONT_SCALE_FACTOR *= scaleFactor; 173 | CLOCK_WINDOW_SCALE = CLOCK_FONT_SCALE_FACTOR; 174 | } else { 175 | CLOCK_FONT_SCALE_FACTOR /= scaleFactor; 176 | CLOCK_WINDOW_SCALE = CLOCK_FONT_SCALE_FACTOR; 177 | } 178 | 179 | // 保持缩放范围限制 180 | if (CLOCK_FONT_SCALE_FACTOR < MIN_SCALE_FACTOR) { 181 | CLOCK_FONT_SCALE_FACTOR = MIN_SCALE_FACTOR; 182 | CLOCK_WINDOW_SCALE = MIN_SCALE_FACTOR; 183 | } 184 | if (CLOCK_FONT_SCALE_FACTOR > MAX_SCALE_FACTOR) { 185 | CLOCK_FONT_SCALE_FACTOR = MAX_SCALE_FACTOR; 186 | CLOCK_WINDOW_SCALE = MAX_SCALE_FACTOR; 187 | } 188 | 189 | if (old_scale != CLOCK_FONT_SCALE_FACTOR) { 190 | // 计算新尺寸 191 | int newWidth = (int)(oldWidth * (CLOCK_FONT_SCALE_FACTOR / old_scale)); 192 | int newHeight = (int)(oldHeight * (CLOCK_FONT_SCALE_FACTOR / old_scale)); 193 | 194 | // 保持窗口中心位置不变 195 | int newX = windowRect.left + (oldWidth - newWidth)/2; 196 | int newY = windowRect.top + (oldHeight - newHeight)/2; 197 | 198 | SetWindowPos(hwnd, NULL, 199 | newX, newY, 200 | newWidth, newHeight, 201 | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW); 202 | 203 | // 触发重绘 204 | InvalidateRect(hwnd, NULL, FALSE); 205 | UpdateWindow(hwnd); 206 | 207 | // 保存设置 208 | SaveWindowSettings(hwnd); 209 | return TRUE; 210 | } 211 | } 212 | return FALSE; 213 | } -------------------------------------------------------------------------------- /src/drawing.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file drawing.c 3 | * @brief 窗口绘图功能实现 4 | * 5 | * 本文件实现了应用程序窗口绘图相关的功能, 6 | * 包括文本渲染、颜色设置和窗口内容绘制等功能。 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "../include/drawing.h" 14 | #include "../include/font.h" 15 | #include "../include/color.h" 16 | #include "../include/timer.h" 17 | #include "../include/config.h" 18 | 19 | // 从window_procedure.c引入的变量 20 | extern int elapsed_time; 21 | 22 | // 使用resource.h中定义的窗口绘制相关常量 23 | 24 | /** 25 | * @brief 处理窗口绘制 26 | * @param hwnd 窗口句柄 27 | * @param ps 绘制结构体 28 | * 29 | * 处理窗口的WM_PAINT消息,执行以下操作: 30 | * 1. 创建内存DC双缓冲防止闪烁 31 | * 2. 根据模式计算剩余时间/获取当前时间 32 | * 3. 动态加载字体资源(支持实时预览) 33 | * 4. 解析颜色配置(支持HEX/RGB格式) 34 | * 5. 使用双缓冲机制绘制文本 35 | * 6. 自动调整窗口尺寸适应文本内容 36 | */ 37 | void HandleWindowPaint(HWND hwnd, PAINTSTRUCT *ps) { 38 | static char time_text[50]; 39 | HDC hdc = ps->hdc; 40 | RECT rect; 41 | GetClientRect(hwnd, &rect); 42 | 43 | HDC memDC = CreateCompatibleDC(hdc); 44 | HBITMAP memBitmap = CreateCompatibleBitmap(hdc, rect.right, rect.bottom); 45 | HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap); 46 | 47 | SetGraphicsMode(memDC, GM_ADVANCED); 48 | SetBkMode(memDC, TRANSPARENT); 49 | SetStretchBltMode(memDC, HALFTONE); 50 | SetBrushOrgEx(memDC, 0, 0, NULL); 51 | 52 | // 根据不同模式生成显示文本 53 | if (CLOCK_SHOW_CURRENT_TIME) { 54 | time_t now = time(NULL); 55 | struct tm *tm_info = localtime(&now); 56 | int hour = tm_info->tm_hour; 57 | 58 | if (!CLOCK_USE_24HOUR) { 59 | if (hour == 0) { 60 | hour = 12; 61 | } else if (hour > 12) { 62 | hour -= 12; 63 | } 64 | } 65 | 66 | if (CLOCK_SHOW_SECONDS) { 67 | sprintf(time_text, "%d:%02d:%02d", 68 | hour, tm_info->tm_min, tm_info->tm_sec); 69 | } else { 70 | sprintf(time_text, "%d:%02d", 71 | hour, tm_info->tm_min); 72 | } 73 | } else if (CLOCK_COUNT_UP) { 74 | // 正计时模式 75 | int hours = countup_elapsed_time / 3600; 76 | int minutes = (countup_elapsed_time % 3600) / 60; 77 | int seconds = countup_elapsed_time % 60; 78 | 79 | if (hours > 0) { 80 | sprintf(time_text, "%d:%02d:%02d", hours, minutes, seconds); 81 | } else if (minutes > 0) { 82 | sprintf(time_text, "%d:%02d", minutes, seconds); 83 | } else { 84 | sprintf(time_text, "%d", seconds); 85 | } 86 | } else { 87 | // 倒计时模式 88 | int remaining_time = CLOCK_TOTAL_TIME - countdown_elapsed_time; 89 | if (remaining_time <= 0) { 90 | // 超时到达,根据情况决定是否显示内容 91 | if (CLOCK_TOTAL_TIME == 0 && countdown_elapsed_time == 0) { 92 | // 这是睡眠操作后的情况,不显示任何内容 93 | time_text[0] = '\0'; 94 | } else if (strcmp(CLOCK_TIMEOUT_TEXT, "0") == 0) { 95 | time_text[0] = '\0'; 96 | } else if (strlen(CLOCK_TIMEOUT_TEXT) > 0) { 97 | strncpy(time_text, CLOCK_TIMEOUT_TEXT, sizeof(time_text) - 1); 98 | time_text[sizeof(time_text) - 1] = '\0'; 99 | } else { 100 | time_text[0] = '\0'; 101 | } 102 | } else { 103 | int hours = remaining_time / 3600; 104 | int minutes = (remaining_time % 3600) / 60; 105 | int seconds = remaining_time % 60; 106 | 107 | if (hours > 0) { 108 | sprintf(time_text, "%d:%02d:%02d", hours, minutes, seconds); 109 | } else if (minutes > 0) { 110 | sprintf(time_text, "%d:%02d", minutes, seconds); 111 | } else { 112 | sprintf(time_text, "%d", seconds); 113 | } 114 | } 115 | } 116 | 117 | const char* fontToUse = IS_PREVIEWING ? PREVIEW_FONT_NAME : FONT_FILE_NAME; 118 | HFONT hFont = CreateFont( 119 | -CLOCK_BASE_FONT_SIZE * CLOCK_FONT_SCALE_FACTOR, 120 | 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, 121 | DEFAULT_CHARSET, OUT_TT_PRECIS, 122 | CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, 123 | VARIABLE_PITCH | FF_SWISS, 124 | IS_PREVIEWING ? PREVIEW_INTERNAL_NAME : FONT_INTERNAL_NAME 125 | ); 126 | HFONT oldFont = (HFONT)SelectObject(memDC, hFont); 127 | 128 | SetTextAlign(memDC, TA_LEFT | TA_TOP); 129 | SetTextCharacterExtra(memDC, 0); 130 | SetMapMode(memDC, MM_TEXT); 131 | 132 | DWORD quality = SetICMMode(memDC, ICM_ON); 133 | SetLayout(memDC, 0); 134 | 135 | int r = 255, g = 255, b = 255; 136 | const char* colorToUse = IS_COLOR_PREVIEWING ? PREVIEW_COLOR : CLOCK_TEXT_COLOR; 137 | 138 | if (strlen(colorToUse) > 0) { 139 | if (colorToUse[0] == '#') { 140 | if (strlen(colorToUse) == 7) { 141 | sscanf(colorToUse + 1, "%02x%02x%02x", &r, &g, &b); 142 | } 143 | } else { 144 | sscanf(colorToUse, "%d,%d,%d", &r, &g, &b); 145 | } 146 | } 147 | SetTextColor(memDC, RGB(r, g, b)); 148 | 149 | if (CLOCK_EDIT_MODE) { 150 | HBRUSH hBrush = CreateSolidBrush(RGB(20, 20, 20)); // 深灰色背景 151 | FillRect(memDC, &rect, hBrush); 152 | DeleteObject(hBrush); 153 | } else { 154 | HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0)); 155 | FillRect(memDC, &rect, hBrush); 156 | DeleteObject(hBrush); 157 | } 158 | 159 | if (strlen(time_text) > 0) { 160 | SIZE textSize; 161 | GetTextExtentPoint32(memDC, time_text, strlen(time_text), &textSize); 162 | 163 | if (textSize.cx != (rect.right - rect.left) || 164 | textSize.cy != (rect.bottom - rect.top)) { 165 | RECT windowRect; 166 | GetWindowRect(hwnd, &windowRect); 167 | 168 | SetWindowPos(hwnd, NULL, 169 | windowRect.left, windowRect.top, 170 | textSize.cx + WINDOW_HORIZONTAL_PADDING, 171 | textSize.cy + WINDOW_VERTICAL_PADDING, 172 | SWP_NOZORDER | SWP_NOACTIVATE); 173 | GetClientRect(hwnd, &rect); 174 | } 175 | 176 | 177 | int x = (rect.right - textSize.cx) / 2; 178 | int y = (rect.bottom - textSize.cy) / 2; 179 | 180 | // 如果处于编辑模式,强制使用白色文字并添加描边效果 181 | if (CLOCK_EDIT_MODE) { 182 | SetTextColor(memDC, RGB(255, 255, 255)); 183 | 184 | // 添加黑色描边效果 185 | SetTextColor(memDC, RGB(0, 0, 0)); 186 | TextOutA(memDC, x-1, y, time_text, strlen(time_text)); 187 | TextOutA(memDC, x+1, y, time_text, strlen(time_text)); 188 | TextOutA(memDC, x, y-1, time_text, strlen(time_text)); 189 | TextOutA(memDC, x, y+1, time_text, strlen(time_text)); 190 | 191 | // 设置回白色绘制文本 192 | SetTextColor(memDC, RGB(255, 255, 255)); 193 | TextOutA(memDC, x, y, time_text, strlen(time_text)); 194 | } else { 195 | SetTextColor(memDC, RGB(r, g, b)); 196 | 197 | for (int i = 0; i < 8; i++) { 198 | TextOutA(memDC, x, y, time_text, strlen(time_text)); 199 | } 200 | } 201 | } 202 | 203 | BitBlt(hdc, 0, 0, rect.right, rect.bottom, memDC, 0, 0, SRCCOPY); 204 | 205 | SelectObject(memDC, oldFont); 206 | DeleteObject(hFont); 207 | SelectObject(memDC, oldBitmap); 208 | DeleteObject(memBitmap); 209 | DeleteDC(memDC); 210 | } -------------------------------------------------------------------------------- /src/media.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file media.c 3 | * @brief 媒体控制功能实现 4 | * 5 | * 本文件实现了应用程序的媒体控制相关功能, 6 | * 包括暂停、播放等媒体控制操作。 7 | */ 8 | 9 | #include 10 | #include "../include/media.h" 11 | 12 | /** 13 | * @brief 暂停媒体播放 14 | * 15 | * 通过模拟媒体控制键的按键事件来暂停当前正在播放的媒体。 16 | * 包括停止和暂停/播放的组合操作,以确保媒体被正确暂停。 17 | */ 18 | void PauseMediaPlayback(void) { 19 | keybd_event(VK_MEDIA_STOP, 0, 0, 0); 20 | Sleep(50); 21 | keybd_event(VK_MEDIA_STOP, 0, KEYEVENTF_KEYUP, 0); 22 | Sleep(50); 23 | 24 | keybd_event(VK_MEDIA_PLAY_PAUSE, 0, 0, 0); 25 | Sleep(50); 26 | keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_KEYUP, 0); 27 | Sleep(50); 28 | 29 | keybd_event(VK_MEDIA_PLAY_PAUSE, 0, 0, 0); 30 | Sleep(50); 31 | keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_KEYUP, 0); 32 | Sleep(100); 33 | } -------------------------------------------------------------------------------- /src/startup.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file startup.c 3 | * @brief 开机自启动功能实现 4 | * 5 | * 本文件实现了应用程序开机自启动相关的功能, 6 | * 包括检查是否已启用自启动、创建和删除自启动快捷方式。 7 | */ 8 | 9 | #include "../include/startup.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "../include/config.h" 18 | #include "../include/timer.h" 19 | 20 | #ifndef CSIDL_STARTUP 21 | #define CSIDL_STARTUP 0x0007 22 | #endif 23 | 24 | #ifndef CLSID_ShellLink 25 | EXTERN_C const CLSID CLSID_ShellLink; 26 | #endif 27 | 28 | #ifndef IID_IShellLinkW 29 | EXTERN_C const IID IID_IShellLinkW; 30 | #endif 31 | 32 | /// @name 外部变量声明 33 | /// @{ 34 | extern BOOL CLOCK_SHOW_CURRENT_TIME; 35 | extern BOOL CLOCK_COUNT_UP; 36 | extern BOOL CLOCK_IS_PAUSED; 37 | extern int CLOCK_TOTAL_TIME; 38 | extern int countdown_elapsed_time; 39 | extern int countup_elapsed_time; 40 | extern int CLOCK_DEFAULT_START_TIME; 41 | extern char CLOCK_STARTUP_MODE[20]; 42 | /// @} 43 | 44 | /** 45 | * @brief 检查应用程序是否已设置为开机自启动 46 | * @return BOOL 如果已启用开机自启动则返回TRUE,否则返回FALSE 47 | */ 48 | BOOL IsAutoStartEnabled(void) { 49 | wchar_t startupPath[MAX_PATH]; 50 | 51 | if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, startupPath))) { 52 | wcscat(startupPath, L"\\Catime.lnk"); 53 | return GetFileAttributesW(startupPath) != INVALID_FILE_ATTRIBUTES; 54 | } 55 | return FALSE; 56 | } 57 | 58 | /** 59 | * @brief 创建开机自启动快捷方式 60 | * @return BOOL 如果创建成功则返回TRUE,否则返回FALSE 61 | */ 62 | BOOL CreateShortcut(void) { 63 | wchar_t startupPath[MAX_PATH]; 64 | wchar_t exePath[MAX_PATH]; 65 | IShellLinkW* pShellLink = NULL; 66 | IPersistFile* pPersistFile = NULL; 67 | BOOL success = FALSE; 68 | 69 | GetModuleFileNameW(NULL, exePath, MAX_PATH); 70 | 71 | if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, startupPath))) { 72 | wcscat(startupPath, L"\\Catime.lnk"); 73 | 74 | HRESULT hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, 75 | &IID_IShellLinkW, (void**)&pShellLink); 76 | if (SUCCEEDED(hr)) { 77 | hr = pShellLink->lpVtbl->SetPath(pShellLink, exePath); 78 | if (SUCCEEDED(hr)) { 79 | hr = pShellLink->lpVtbl->QueryInterface(pShellLink, 80 | &IID_IPersistFile, 81 | (void**)&pPersistFile); 82 | if (SUCCEEDED(hr)) { 83 | hr = pPersistFile->lpVtbl->Save(pPersistFile, startupPath, TRUE); 84 | if (SUCCEEDED(hr)) { 85 | success = TRUE; 86 | } 87 | pPersistFile->lpVtbl->Release(pPersistFile); 88 | } 89 | } 90 | pShellLink->lpVtbl->Release(pShellLink); 91 | } 92 | } 93 | 94 | return success; 95 | } 96 | 97 | /** 98 | * @brief 删除开机自启动快捷方式 99 | * @return BOOL 如果删除成功则返回TRUE,否则返回FALSE 100 | */ 101 | BOOL RemoveShortcut(void) { 102 | wchar_t startupPath[MAX_PATH]; 103 | 104 | if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, startupPath))) { 105 | wcscat(startupPath, L"\\Catime.lnk"); 106 | 107 | return DeleteFileW(startupPath); 108 | } 109 | return FALSE; 110 | } 111 | 112 | /** 113 | * @brief 更新开机自启动快捷方式 114 | * 115 | * 检查是否已启用自启动,如果已启用,则删除旧的快捷方式并创建新的, 116 | * 确保即使应用程序位置发生变化,自启动功能也能正常工作。 117 | * 118 | * @return BOOL 如果更新成功则返回TRUE,否则返回FALSE 119 | */ 120 | BOOL UpdateStartupShortcut(void) { 121 | // 如果已经启用了自启动 122 | if (IsAutoStartEnabled()) { 123 | // 先删除现有的快捷方式 124 | RemoveShortcut(); 125 | // 创建新的快捷方式 126 | return CreateShortcut(); 127 | } 128 | return TRUE; // 未启用自启动,视为成功 129 | } 130 | 131 | /** 132 | * @brief 应用启动模式设置 133 | * @param hwnd 窗口句柄 134 | * 135 | * 根据配置文件中的启动模式设置,初始化应用程序的显示状态 136 | */ 137 | void ApplyStartupMode(HWND hwnd) { 138 | // 从配置文件读取启动模式 139 | char configPath[MAX_PATH]; 140 | GetConfigPath(configPath, MAX_PATH); 141 | 142 | FILE *configFile = fopen(configPath, "r"); 143 | if (configFile) { 144 | char line[256]; 145 | while (fgets(line, sizeof(line), configFile)) { 146 | if (strncmp(line, "STARTUP_MODE=", 13) == 0) { 147 | sscanf(line, "STARTUP_MODE=%19s", CLOCK_STARTUP_MODE); 148 | break; 149 | } 150 | } 151 | fclose(configFile); 152 | 153 | // 应用启动模式 154 | if (strcmp(CLOCK_STARTUP_MODE, "COUNT_UP") == 0) { 155 | // 设置为正计时模式 156 | CLOCK_COUNT_UP = TRUE; 157 | CLOCK_SHOW_CURRENT_TIME = FALSE; 158 | 159 | // 启动计时器 160 | KillTimer(hwnd, 1); 161 | SetTimer(hwnd, 1, 1000, NULL); 162 | 163 | CLOCK_TOTAL_TIME = 0; 164 | countdown_elapsed_time = 0; 165 | countup_elapsed_time = 0; 166 | 167 | } else if (strcmp(CLOCK_STARTUP_MODE, "SHOW_TIME") == 0) { 168 | // 设置为显示当前时间模式 169 | CLOCK_SHOW_CURRENT_TIME = TRUE; 170 | CLOCK_COUNT_UP = FALSE; 171 | 172 | // 启动计时器 173 | KillTimer(hwnd, 1); 174 | SetTimer(hwnd, 1, 1000, NULL); 175 | 176 | } else if (strcmp(CLOCK_STARTUP_MODE, "NO_DISPLAY") == 0) { 177 | // 设置为不显示模式 178 | CLOCK_SHOW_CURRENT_TIME = FALSE; 179 | CLOCK_COUNT_UP = FALSE; 180 | CLOCK_TOTAL_TIME = 0; 181 | countdown_elapsed_time = 0; 182 | 183 | // 停止计时器 184 | KillTimer(hwnd, 1); 185 | 186 | } else { // 默认为倒计时模式 "COUNTDOWN" 187 | // 设置为倒计时模式 188 | CLOCK_SHOW_CURRENT_TIME = FALSE; 189 | CLOCK_COUNT_UP = FALSE; 190 | 191 | // 读取默认倒计时时间 192 | CLOCK_TOTAL_TIME = CLOCK_DEFAULT_START_TIME; 193 | countdown_elapsed_time = 0; 194 | 195 | // 如果有设置倒计时,则启动计时器 196 | if (CLOCK_TOTAL_TIME > 0) { 197 | KillTimer(hwnd, 1); 198 | SetTimer(hwnd, 1, 1000, NULL); 199 | } 200 | } 201 | 202 | // 刷新显示 203 | InvalidateRect(hwnd, NULL, TRUE); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/tray.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tray.c 3 | * @brief 系统托盘功能实现 4 | * 5 | * 本文件实现了应用程序的系统托盘操作,包括初始化、移除和通知显示功能, 6 | * 以及处理Windows资源管理器重启时托盘图标自动恢复的机制。 7 | */ 8 | 9 | #include 10 | #include 11 | #include "../include/language.h" 12 | #include "../resource/resource.h" 13 | #include "../include/tray.h" 14 | 15 | /// 全局通知图标数据结构 16 | NOTIFYICONDATAW nid; 17 | 18 | /// 记录TaskbarCreated消息的ID 19 | UINT WM_TASKBARCREATED = 0; 20 | 21 | /** 22 | * @brief 注册TaskbarCreated消息 23 | * 24 | * 注册系统发送的TaskbarCreated消息,用于在Windows资源管理器重启后 25 | * 能够接收到消息并重新创建托盘图标。此机制确保程序在系统托盘刷新后 26 | * 仍然正常显示图标。 27 | */ 28 | void RegisterTaskbarCreatedMessage() { 29 | // 注册接收资源管理器重启后发送的消息 30 | WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated")); 31 | } 32 | 33 | /** 34 | * @brief 初始化系统托盘图标 35 | * @param hwnd 与托盘图标关联的窗口句柄 36 | * @param hInstance 应用程序实例句柄 37 | * 38 | * 创建并显示带有默认设置的系统托盘图标。 39 | * 该图标将通过CLOCK_WM_TRAYICON回调接收消息。 40 | * 同时确保已注册TaskbarCreated消息,以支持托盘图标的自动恢复。 41 | */ 42 | void InitTrayIcon(HWND hwnd, HINSTANCE hInstance) { 43 | memset(&nid, 0, sizeof(nid)); 44 | nid.cbSize = sizeof(nid); 45 | nid.uID = CLOCK_ID_TRAY_APP_ICON; 46 | nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; 47 | nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CATIME)); 48 | nid.hWnd = hwnd; 49 | nid.uCallbackMessage = CLOCK_WM_TRAYICON; 50 | 51 | // 创建包含应用名称和版本号的提示文本 52 | wchar_t versionText[128] = {0}; 53 | // 将版本号从UTF-8转换为Unicode 54 | wchar_t versionWide[64] = {0}; 55 | MultiByteToWideChar(CP_UTF8, 0, CATIME_VERSION, -1, versionWide, _countof(versionWide)); 56 | swprintf_s(versionText, _countof(versionText), L"Catime %s", versionWide); 57 | wcscpy_s(nid.szTip, _countof(nid.szTip), versionText); 58 | 59 | Shell_NotifyIconW(NIM_ADD, &nid); 60 | 61 | // 确保已注册TaskbarCreated消息 62 | if (WM_TASKBARCREATED == 0) { 63 | RegisterTaskbarCreatedMessage(); 64 | } 65 | } 66 | 67 | /** 68 | * @brief 删除系统托盘图标 69 | * 70 | * 从系统托盘中移除应用程序的图标。 71 | * 应在应用程序关闭时调用,确保系统资源的正确释放。 72 | */ 73 | void RemoveTrayIcon(void) { 74 | Shell_NotifyIconW(NIM_DELETE, &nid); 75 | } 76 | 77 | /** 78 | * @brief 在系统托盘中显示通知 79 | * @param hwnd 与通知关联的窗口句柄 80 | * @param message 要在通知中显示的文本消息 81 | * 82 | * 从系统托盘图标显示气球提示通知。 83 | * 通知使用NIIF_NONE样式(无图标)并在3秒后超时。 84 | * 85 | * @note 消息文本从UTF-8转换为Unicode以正确显示各种语言字符。 86 | */ 87 | void ShowTrayNotification(HWND hwnd, const char* message) { 88 | NOTIFYICONDATAW nid_notify = {0}; 89 | nid_notify.cbSize = sizeof(NOTIFYICONDATAW); 90 | nid_notify.hWnd = hwnd; 91 | nid_notify.uID = CLOCK_ID_TRAY_APP_ICON; 92 | nid_notify.uFlags = NIF_INFO; 93 | nid_notify.dwInfoFlags = NIIF_NONE; // 不显示图标 94 | nid_notify.uTimeout = 3000; 95 | 96 | // 将UTF-8字符串转换为Unicode 97 | MultiByteToWideChar(CP_UTF8, 0, message, -1, nid_notify.szInfo, sizeof(nid_notify.szInfo)/sizeof(WCHAR)); 98 | // 保持标题为空 99 | nid_notify.szInfoTitle[0] = L'\0'; 100 | 101 | Shell_NotifyIconW(NIM_MODIFY, &nid_notify); 102 | } 103 | 104 | /** 105 | * @brief 重新创建托盘图标 106 | * @param hwnd 窗口句柄 107 | * @param hInstance 实例句柄 108 | * 109 | * 在Windows资源管理器重启后重新创建托盘图标。 110 | * 应在收到TaskbarCreated消息时调用此函数,确保托盘图标自动恢复, 111 | * 避免出现程序运行但托盘图标消失的情况。 112 | */ 113 | void RecreateTaskbarIcon(HWND hwnd, HINSTANCE hInstance) { 114 | // 首先尝试删除可能存在的旧图标 115 | RemoveTrayIcon(); 116 | 117 | // 重新创建托盘图标 118 | InitTrayIcon(hwnd, hInstance); 119 | } 120 | 121 | /** 122 | * @brief 更新托盘图标和菜单 123 | * @param hwnd 窗口句柄 124 | * 125 | * 在应用程序语言或设置更改后更新托盘图标和菜单。 126 | * 此函数先移除当前的托盘图标,然后重新创建它, 127 | * 确保托盘菜单显示的文本与当前语言设置一致。 128 | */ 129 | void UpdateTrayIcon(HWND hwnd) { 130 | // 获取实例句柄 131 | HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE); 132 | 133 | // 使用重新创建托盘图标函数来完成更新 134 | RecreateTaskbarIcon(hwnd, hInstance); 135 | } -------------------------------------------------------------------------------- /src/tray_events.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tray_events.c 3 | * @brief 系统托盘事件处理模块实现 4 | * 5 | * 本模块实现了应用程序系统托盘的事件处理相关功能, 6 | * 包括托盘图标的各类鼠标事件响应、菜单显示与控制, 7 | * 以及与计时器相关的暂停/继续、重启等托盘操作。 8 | * 提供了用户通过托盘图标快速控制应用的核心功能。 9 | */ 10 | 11 | #include 12 | #include 13 | #include "../include/tray_events.h" 14 | #include "../include/tray_menu.h" 15 | #include "../include/color.h" 16 | #include "../include/timer.h" 17 | #include "../include/language.h" 18 | #include "../include/window_events.h" 19 | #include "../resource/resource.h" 20 | 21 | // 声明从配置文件读取超时动作的函数 22 | extern void ReadTimeoutActionFromConfig(void); 23 | 24 | /** 25 | * @brief 处理系统托盘消息 26 | * @param hwnd 窗口句柄 27 | * @param uID 托盘图标ID 28 | * @param uMouseMsg 鼠标消息类型 29 | * 30 | * 处理系统托盘的鼠标事件,根据事件类型显示不同的上下文菜单: 31 | * - 左键点击:显示主功能上下文菜单,包含计时器控制等功能 32 | * - 右键点击:显示颜色选择菜单,用于快速更改显示颜色 33 | * 34 | * 所有菜单项的命令处理在对应的菜单显示模块中实现。 35 | */ 36 | void HandleTrayIconMessage(HWND hwnd, UINT uID, UINT uMouseMsg) { 37 | // 设置默认光标,防止显示等待光标 38 | SetCursor(LoadCursor(NULL, IDC_ARROW)); 39 | 40 | if (uMouseMsg == WM_RBUTTONUP) { 41 | ShowColorMenu(hwnd); 42 | } 43 | else if (uMouseMsg == WM_LBUTTONUP) { 44 | ShowContextMenu(hwnd); 45 | } 46 | } 47 | 48 | /** 49 | * @brief 暂停或继续计时器 50 | * @param hwnd 窗口句柄 51 | * 52 | * 根据当前状态切换计时器的暂停/继续状态: 53 | * 1. 检查当前是否有计时进行中(倒计时或正计时) 54 | * 2. 若计时正在进行,则切换暂停/继续状态 55 | * 3. 暂停时记录当前时间点并停止计时器 56 | * 4. 继续时重新启动计时器 57 | * 5. 刷新窗口以反映新状态 58 | * 59 | * 注意:仅当显示计时器(而非当前时间)且计时器活动时才能操作 60 | */ 61 | void PauseResumeTimer(HWND hwnd) { 62 | // 检查当前是否有计时进行中 63 | if (!CLOCK_SHOW_CURRENT_TIME && (CLOCK_COUNT_UP || CLOCK_TOTAL_TIME > 0)) { 64 | 65 | // 切换暂停/继续状态 66 | CLOCK_IS_PAUSED = !CLOCK_IS_PAUSED; 67 | 68 | if (CLOCK_IS_PAUSED) { 69 | // 如果暂停,记录当前时间点 70 | CLOCK_LAST_TIME_UPDATE = time(NULL); 71 | // 停止计时器 72 | KillTimer(hwnd, 1); 73 | 74 | // 暂停正在播放的通知音频(新增) 75 | extern BOOL PauseNotificationSound(void); 76 | PauseNotificationSound(); 77 | } else { 78 | // 如果继续,重新启动计时器 79 | SetTimer(hwnd, 1, 1000, NULL); 80 | 81 | // 继续播放通知音频(新增) 82 | extern BOOL ResumeNotificationSound(void); 83 | ResumeNotificationSound(); 84 | } 85 | 86 | // 更新窗口以反映新状态 87 | InvalidateRect(hwnd, NULL, TRUE); 88 | } 89 | } 90 | 91 | /** 92 | * @brief 重新开始计时器 93 | * @param hwnd 窗口句柄 94 | * 95 | * 重置计时器到初始状态并继续运行,保持当前计时器类型不变: 96 | * 1. 读取当前的超时动作设置 97 | * 2. 根据当前模式(倒计时/正计时)重置计时进度 98 | * 3. 重置所有相关的计时器状态变量 99 | * 4. 取消暂停状态,确保计时器正在运行 100 | * 5. 刷新窗口并确保重置后窗口置顶 101 | * 102 | * 此操作不会改变计时模式或总时长,只会将进度重置为初始状态。 103 | */ 104 | void RestartTimer(HWND hwnd) { 105 | // 停止任何可能正在播放的通知音频 106 | extern void StopNotificationSound(void); 107 | StopNotificationSound(); 108 | 109 | // 根据当前模式判断操作 110 | if (!CLOCK_COUNT_UP) { 111 | // 倒计时模式 112 | if (CLOCK_TOTAL_TIME > 0) { 113 | countdown_elapsed_time = 0; 114 | countdown_message_shown = FALSE; 115 | CLOCK_IS_PAUSED = FALSE; 116 | KillTimer(hwnd, 1); 117 | SetTimer(hwnd, 1, 1000, NULL); 118 | } 119 | } else { 120 | // 正计时模式 121 | countup_elapsed_time = 0; 122 | CLOCK_IS_PAUSED = FALSE; 123 | KillTimer(hwnd, 1); 124 | SetTimer(hwnd, 1, 1000, NULL); 125 | } 126 | 127 | // 更新窗口 128 | InvalidateRect(hwnd, NULL, TRUE); 129 | 130 | // 确保窗口置顶可见 131 | HandleWindowReset(hwnd); 132 | } 133 | 134 | /** 135 | * @brief 设置启动模式 136 | * @param hwnd 窗口句柄 137 | * @param mode 启动模式("COUNTDOWN"/"COUNT_UP"/"SHOW_TIME"/"NO_DISPLAY") 138 | * 139 | * 设置应用程序的默认启动模式,并将其保存到配置文件: 140 | * 1. 将选择的模式保存到配置文件 141 | * 2. 更新菜单项的选中状态以反映当前设置 142 | * 3. 刷新窗口显示 143 | * 144 | * 启动模式决定了应用启动时的默认行为,例如是显示当前时间还是开始计时。 145 | * 设置后将在下次启动程序时生效。 146 | */ 147 | void SetStartupMode(HWND hwnd, const char* mode) { 148 | // 保存启动模式到配置文件 149 | WriteConfigStartupMode(mode); 150 | 151 | // 更新菜单项的选中状态 152 | HMENU hMenu = GetMenu(hwnd); 153 | if (hMenu) { 154 | InvalidateRect(hwnd, NULL, TRUE); 155 | } 156 | } 157 | 158 | /** 159 | * @brief 打开使用指南网页 160 | * 161 | * 使用ShellExecute打开Catime的使用指南网页, 162 | * 为用户提供详细的软件使用说明和帮助文档。 163 | * 网址为:https://vladelaina.github.io/Catime/guide 164 | */ 165 | void OpenUserGuide(void) { 166 | ShellExecuteW(NULL, L"open", L"https://vladelaina.github.io/Catime/guide", NULL, NULL, SW_SHOWNORMAL); 167 | } 168 | 169 | /** 170 | * @brief 打开支持页面 171 | * 172 | * 使用ShellExecute打开Catime的支持页面, 173 | * 为用户提供支持开发者的渠道。 174 | * 网址为:https://vladelaina.github.io/Catime/support 175 | */ 176 | void OpenSupportPage(void) { 177 | ShellExecuteW(NULL, L"open", L"https://vladelaina.github.io/Catime/support", NULL, NULL, SW_SHOWNORMAL); 178 | } 179 | 180 | /** 181 | * @brief 打开反馈页面 182 | * 183 | * 根据当前语言设置打开不同的反馈渠道: 184 | * - 简体中文:打开bilibili私信页面 185 | * - 其他语言:打开GitHub Issues页面 186 | */ 187 | void OpenFeedbackPage(void) { 188 | extern AppLanguage CURRENT_LANGUAGE; // 声明外部变量 189 | 190 | // 根据语言选择不同的反馈链接 191 | if (CURRENT_LANGUAGE == APP_LANG_CHINESE_SIMP) { 192 | // 简体中文用户打开bilibili私信 193 | ShellExecuteW(NULL, L"open", URL_FEEDBACK, NULL, NULL, SW_SHOWNORMAL); 194 | } else { 195 | // 其他语言用户打开GitHub Issues 196 | ShellExecuteW(NULL, L"open", L"https://github.com/vladelaina/Catime/issues", NULL, NULL, SW_SHOWNORMAL); 197 | } 198 | } -------------------------------------------------------------------------------- /src/window_events.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file window_events.c 3 | * @brief 基本窗口事件处理实现 4 | * 5 | * 本文件实现了应用程序窗口的基本事件处理功能, 6 | * 包括窗口创建、销毁、大小调整和位置调整等基本功能。 7 | */ 8 | 9 | #include 10 | #include "../include/window.h" 11 | #include "../include/tray.h" 12 | #include "../include/config.h" 13 | #include "../include/drag_scale.h" 14 | #include "../include/window_events.h" 15 | 16 | /** 17 | * @brief 处理窗口创建事件 18 | * @param hwnd 窗口句柄 19 | * @return BOOL 处理结果 20 | */ 21 | BOOL HandleWindowCreate(HWND hwnd) { 22 | HWND hwndParent = GetParent(hwnd); 23 | if (hwndParent != NULL) { 24 | EnableWindow(hwndParent, TRUE); 25 | } 26 | 27 | // 加载窗口设置 28 | LoadWindowSettings(hwnd); 29 | 30 | // 设置点击穿透 31 | SetClickThrough(hwnd, !CLOCK_EDIT_MODE); 32 | 33 | // 确保窗口处于置顶状态 34 | SetWindowTopmost(hwnd, CLOCK_WINDOW_TOPMOST); 35 | 36 | return TRUE; 37 | } 38 | 39 | /** 40 | * @brief 处理窗口销毁事件 41 | * @param hwnd 窗口句柄 42 | */ 43 | void HandleWindowDestroy(HWND hwnd) { 44 | SaveWindowSettings(hwnd); // 保存窗口设置 45 | KillTimer(hwnd, 1); 46 | RemoveTrayIcon(); 47 | 48 | // 清理更新检查线程 49 | extern void CleanupUpdateThread(void); 50 | CleanupUpdateThread(); 51 | 52 | PostQuitMessage(0); 53 | } 54 | 55 | /** 56 | * @brief 处理窗口重置事件 57 | * @param hwnd 窗口句柄 58 | */ 59 | void HandleWindowReset(HWND hwnd) { 60 | // 无条件应用配置中的置顶设置 61 | // 不管CLOCK_WINDOW_TOPMOST当前值是什么,都强制设为TRUE并应用 62 | CLOCK_WINDOW_TOPMOST = TRUE; 63 | SetWindowTopmost(hwnd, TRUE); 64 | WriteConfigTopmost("TRUE"); 65 | 66 | // 确保窗口总是可见的 - 解决计时器重置后不可见的问题 67 | ShowWindow(hwnd, SW_SHOW); 68 | } 69 | 70 | // 该函数已移至drag_scale.c 71 | BOOL HandleWindowResize(HWND hwnd, int delta) { 72 | return HandleScaleWindow(hwnd, delta); 73 | } 74 | 75 | // 该函数已移至drag_scale.c 76 | BOOL HandleWindowMove(HWND hwnd) { 77 | return HandleDragWindow(hwnd); 78 | } 79 | -------------------------------------------------------------------------------- /xmake.lua: -------------------------------------------------------------------------------- 1 | -- 定义项目信息 2 | set_project("Catime") 3 | set_version("1.0.0") 4 | 5 | -- 设置xmake最低版本要求 6 | set_xmakever("2.5.0") 7 | 8 | -- 设置默认编译模式 9 | set_defaultmode("release") 10 | 11 | -- 允许使用平台API 12 | add_rules("mode.debug", "mode.release") 13 | 14 | -- 强制设定平台为Windows 15 | set_plat("mingw") 16 | 17 | -- 设置默认架构 18 | set_arch("x86_64") 19 | 20 | -- 设置MinGW工具链 21 | set_toolchains("mingw") 22 | 23 | -- 定义ASCII艺术标志 24 | local catime_logo = [[ 25 | 26 | ██████╗ █████╗ ████████╗██╗███╗ ███╗███████╗ 27 | ██╔════╝ ██╔══██╗╚══██╔══╝██║████╗ ████║██╔════╝ 28 | ██║ ███████║ ██║ ██║██╔████╔██║█████╗ 29 | ██║ ██╔══██║ ██║ ██║██║╚██╔╝██║██╔══╝ 30 | ╚██████╗ ██║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗ 31 | ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ 32 | 33 | ]] 34 | 35 | -- 定义目标 36 | target("catime") 37 | -- 设置为可执行程序 38 | set_kind("binary") 39 | 40 | -- 在构建开始前显示标志 41 | before_build(function (target) 42 | -- 显示ASCII艺术标志 43 | print("") 44 | print("\x1b[36m" .. "██████╗ █████╗ ████████╗██╗███╗ ███╗███████╗" .. "\x1b[0m") 45 | print("\x1b[36m" .. "██╔════╝ ██╔══██╗╚══██╔══╝██║████╗ ████║██╔════╝" .. "\x1b[0m") 46 | print("\x1b[36m" .. "██║ ███████║ ██║ ██║██╔████╔██║█████╗ " .. "\x1b[0m") 47 | print("\x1b[36m" .. "██║ ██╔══██║ ██║ ██║██║╚██╔╝██║██╔══╝ " .. "\x1b[0m") 48 | print("\x1b[36m" .. "╚██████╗ ██║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗" .. "\x1b[0m") 49 | print("\x1b[36m" .. " ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝" .. "\x1b[0m") 50 | print("") 51 | end) 52 | 53 | -- 添加Windows特有设置 54 | add_defines("_WINDOWS") 55 | add_ldflags("-mwindows", {force = true}) 56 | add_links("ole32", "shell32", "comdlg32", "uuid", "wininet", "winmm", "comctl32", "dwmapi", "user32", "gdi32", "shlwapi", "advapi32") 57 | 58 | -- 添加资源文件 59 | add_files("resource/resource.rc") 60 | add_files("resource/languages.rc") 61 | add_files("resource/catime.rc") 62 | 63 | -- 添加源文件 64 | add_files("src/*.c") 65 | 66 | -- 添加头文件搜索路径 67 | add_includedirs("include", "libs/miniaudio") 68 | 69 | -- 禁用某些警告选项 70 | add_cxflags("-Wno-unknown-warning-option", {force = false}) -- 禁用未知警告的警告 71 | 72 | -- 添加编译选项 73 | if is_mode("release") then 74 | -- 基本优化选项 75 | add_cflags("-O3", "-mtune=generic", "-ffunction-sections", "-fdata-sections", "-fno-strict-aliasing") 76 | 77 | -- 添加LTO(链接时优化)支持 78 | add_cflags("-flto") 79 | add_ldflags("-flto") 80 | 81 | -- 更多的优化标志 82 | add_cflags("-fno-exceptions", "-fomit-frame-pointer", "-fmerge-all-constants") 83 | add_cflags("-fno-math-errno", "-fno-trapping-math", "-ffast-math") 84 | 85 | -- 去除不必要的部分 86 | add_ldflags("-Wl,--gc-sections", "-s", "-Wl,--strip-all") 87 | 88 | -- 使用更小的运行时库 89 | add_cflags("-Os", {force = true}) -- 更倾向于体积优化而非速度优化 90 | 91 | add_defines("NDEBUG") 92 | end 93 | 94 | -- 设置输出目录 95 | set_targetdir("$(buildir)") 96 | set_objectdir("build") 97 | 98 | -- 添加miniaudio实现定义 99 | add_defines("MINIAUDIO_IMPLEMENTATION") 100 | 101 | -- 配置自定义构建事件 102 | after_build(function (target) 103 | -- 显示构建信息 104 | print("\x1b[38;2;0;255;0m[" .. " 99%]:\x1b[0m " .. "Output directory: " .. target:targetdir()) 105 | 106 | -- 获取并显示编译后的文件大小 107 | local targetfile = target:targetfile() 108 | local filesize = os.filesize(targetfile) 109 | 110 | -- 格式化文件大小显示 111 | local size_text = "" 112 | if filesize < 1024 then 113 | size_text = string.format("%.2f B", filesize) 114 | elseif filesize < 1024 * 1024 then 115 | size_text = string.format("%.2f KB", filesize / 1024) 116 | else 117 | size_text = string.format("%.2f MB", filesize / (1024 * 1024)) 118 | end 119 | 120 | print("\x1b[38;2;0;255;0m[" .. " 99%]:\x1b[0m " .. "Size: " .. size_text) 121 | end) 122 | 123 | -- 自定义菜单 124 | option("debug") 125 | set_default(false) 126 | set_showmenu(true) 127 | set_category("选项") 128 | set_description("启用调试模式") 129 | --------------------------------------------------------------------------------