├── .commitlintrc.json ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── build-go.yml │ ├── build.yml │ ├── choco-push.yml │ ├── codeql-analysis.yml │ ├── gh-pages-release.yml │ ├── issue-translator.yml │ ├── npm-publish.yml │ └── stale.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .npmignore ├── .prettierrc.json ├── .vscode ├── extensions.json ├── settings.json └── tasks.json ├── CHANGELOG.md ├── CNAME ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CapsLockX.ahk ├── CapsLockX.exe ├── Core ├── CapsLockX-ModulesLoader.ahk ├── CapsLockX-QuickTips.ahk ├── CapsLockX-RunSilent.ahk ├── CapsLockX-Update.ahk ├── CapsLockX-With-RemoteControls.ahk ├── CapsLockX-i18n.ahk ├── CapslockX-Config.ahk ├── CapslockX-Core.ahk ├── ahk-2.0.11 │ ├── AutoHotkey32.exe │ └── AutoHotkey64.exe ├── lang.ini └── version.txt ├── Data ├── CapsLockX.defaults.ignore.txt ├── NoteC.mp3 ├── NoteC_G.mp3 ├── NoteG.mp3 ├── NoteG_C.mp3 ├── XIconBlue.ico ├── XIconBlue.png ├── XIconWhite.ico ├── XIconWhite.png ├── cursor │ ├── AppStarting.cur │ ├── Arrow.cur │ ├── Cross.cur │ ├── Hand.cur │ ├── Handwriting.cur │ ├── Help.cur │ ├── IBeam.cur │ ├── NO.cur │ ├── SizeAll.cur │ ├── SizeNESW.cur │ ├── SizeNS.cur │ ├── SizeNWSE.cur │ ├── SizeWE.cur │ ├── UpArrow.cur │ ├── Wait.cur │ └── setup.inf ├── 图标白-1.png ├── 图标白-2.png ├── 图标白-3.png ├── 图标白-4.png ├── 图标白-5.png ├── 图标蓝-1.png ├── 图标蓝-2.png ├── 图标蓝-3.png ├── 图标蓝-4.png └── 图标蓝-5.png ├── DevTools ├── .gitignore ├── CapsLockX.ts ├── choco │ ├── CapsLockX.nuspec │ └── tools │ │ ├── LICENSE.txt │ │ ├── VERIFICATION.txt │ │ └── chocolateyInstall.ps1 ├── clxLint.ts ├── git-sync.bat ├── i18n.js ├── lint │ ├── #ifwinactive.code-search │ └── if未加括号问题列表.code-search ├── modulesTips.ts ├── setup.iss ├── setup_repos.bat └── versioning.ts ├── LICENSE.md ├── Modules ├── 02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif ├── 02-插件-窗口增强_一键排列窗口.gif ├── @Help.ahk ├── @Help.md ├── @README-目录说明-模块编写说明.md ├── APP-OneNoteClipboard.gif ├── APP-OneNoteClipboard.md ├── AccModel │ ├── AccModel.ahk │ └── AccModel_en.ahk ├── App-AnkiEnhanced.ahk ├── App-AnkiEnhanced.md ├── App-OneNote2019.ahk ├── App-OneNote2019.md ├── App-XunFeiSwitching.ahk ├── App-XunFeiSwitching.md ├── App-讯飞语音输入法悬浮窗演示.gif ├── CLX-Brainstorm.ahk ├── CLX-Brainstorm.md ├── CLX-Edit.ahk ├── CLX-Edit.md ├── CLX-Elevate.ahk ├── CLX-EnterWithoutBreak.ahk ├── CLX-LaptopKeyboardFix.ahk ├── CLX-LaptopKeyboardFix.md ├── CLX-MediaKeys.ahk ├── CLX-MediaKeys.md ├── CLX-Mouse.ahk ├── CLX-Mouse.gif ├── CLX-Mouse.md ├── CLX-NodeEval.ahk ├── CLX-NodeEval.md ├── CLX-Pause.ahk ├── CLX-Reload.ahk ├── CLX-RunOnLogin.ahk ├── CLX-Settings.ahk ├── CLX-Userscripts.ahk ├── CLX-VirtualDesktop.ahk ├── CLX-WindowManager.ahk ├── CLX-WindowManager.md ├── EditorCursorMovement.gif ├── EmojiSearchByPreferLanguage.ahk ├── Lib │ ├── AHK-GDIp-Library-Compilation │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── README.md │ │ ├── ahk-v1-1 │ │ │ ├── Examples-ahk-v1-1 │ │ │ │ ├── Gdip.Tutorial.1-Draw.Shapes.ahk │ │ │ │ ├── Gdip.Tutorial.10-Rotate.Flip.or.Mirror.an.image.ahk │ │ │ │ ├── Gdip.Tutorial.11-Using.BRAs.to.perform.animations.ahk │ │ │ │ ├── Gdip.Tutorial.12-Pixelate.a.bitmap.using.machine.code.ahk │ │ │ │ ├── Gdip.Tutorial.13-Learning-One-Graphics-Paths.ahk │ │ │ │ ├── Gdip.Tutorial.14-RazorHalo-Rotate-At-Center.ahk │ │ │ │ ├── Gdip.Tutorial.15-Just-Me-Path-Gradients.ahk │ │ │ │ ├── Gdip.Tutorial.16-Just-Me-GetProperty.ahk │ │ │ │ ├── Gdip.Tutorial.17-robodesign-Draw-Customized-Texts.ahk │ │ │ │ ├── Gdip.Tutorial.2-Draw.Outlined.Shapes.ahk │ │ │ │ ├── Gdip.Tutorial.3-Create.Gui.From.Image.ahk │ │ │ │ ├── Gdip.Tutorial.4-Draw.Circles.ahk │ │ │ │ ├── Gdip.Tutorial.5-Create.Bitmap.ahk │ │ │ │ ├── Gdip.Tutorial.6-Image.Editing.ahk │ │ │ │ ├── Gdip.Tutorial.7-Draw.draggable.rounded.rectangle.ahk │ │ │ │ ├── Gdip.Tutorial.8-Write.text.onto.a.gui.ahk │ │ │ │ ├── Gdip.Tutorial.9-Create.a.progress.bar.on.standard.gui.ahk │ │ │ │ ├── Gdip.tutorial.file-fish.bra │ │ │ │ ├── MJ.jpg │ │ │ │ ├── background.png │ │ │ │ └── needle.png │ │ │ ├── Gdip_All.ahk │ │ │ └── gdi.ahk │ │ ├── ahk-v2 │ │ │ ├── Examples-ahk-v2 │ │ │ │ ├── Gdip.Tutorial.1-Draw.Shapes.ahk │ │ │ │ ├── Gdip.Tutorial.10-Rotate.Flip.or.Mirror.an.image.ahk │ │ │ │ ├── Gdip.Tutorial.12-Pixelate.a.bitmap.using.machine.code.ahk │ │ │ │ ├── Gdip.Tutorial.13-Learning-One-Graphics-Paths.ahk │ │ │ │ ├── Gdip.Tutorial.14-RazorHalo-Rotate-At-Center.ahk │ │ │ │ ├── Gdip.Tutorial.15-Just-Me-Path-Gradients.ahk │ │ │ │ ├── Gdip.Tutorial.17-robodesign-Draw-Customized-Texts.ahk │ │ │ │ ├── Gdip.Tutorial.2-Draw.Outlined.Shapes.ahk │ │ │ │ ├── Gdip.Tutorial.3-Create.Gui.From.Image.ahk │ │ │ │ ├── Gdip.Tutorial.4-Draw.Circles.ahk │ │ │ │ ├── Gdip.Tutorial.5-Create.Bitmap.ahk │ │ │ │ ├── Gdip.Tutorial.6-Image.Editing.ahk │ │ │ │ ├── Gdip.Tutorial.7-Draw.draggable.rounded.rectangle.ahk │ │ │ │ ├── Gdip.Tutorial.8-Write.text.onto.a.gui.ahk │ │ │ │ ├── Gdip.Tutorial.9-Create.a.progress.bar.on.standard.gui.ahk │ │ │ │ ├── Gdip.tutorial.file-fish.bra │ │ │ │ ├── MJ.jpg │ │ │ │ ├── background.png │ │ │ │ └── needle.png │ │ │ └── Gdip_All.ahk │ │ ├── credits.txt │ │ └── functions-list.txt │ └── README.md ├── QuickInput.ahk ├── QuickInput.md ├── QuickTips.ahk ├── SnoChordTyping.ahk ├── TomatoLife.ahk ├── TomatoLife.md ├── TurnOffScreenWhenLock.ahk ├── TurnOffScreenWhenLock.md ├── WatchFolder │ └── WatchFolder.ahk └── WinClip │ ├── WinClip.ahk │ └── WinClipAPI.ahk ├── README.md ├── SECURITY.md ├── TODO.md ├── Tools ├── ClipboardStack │ └── ClipboardStack.ahk ├── CopyRandomNumber.ahk ├── CopyRandomPassword.ahk ├── CopyRandomStrongPassword.ahk ├── CopyRandomUUID.ahk ├── DeprecatedModules │ ├── App-AcrobatEnhanced.ahk │ ├── App-BlenderEnhanced.ahk │ ├── App-Figma.ahk │ ├── App-Figma.md │ ├── App-LoopbackExemptionManager.ahk │ ├── App-MobaXterm.ahk │ ├── App-OneNoteMetro.ahk │ ├── App-QQ-Desktop.ahk │ ├── CLX-Cursor.ahk │ ├── Plugin-控制台启用CtrlV粘贴.ahk │ ├── 应用-文明6回车左置.ahk │ ├── 讯飞语音输入法悬浮窗演示.gif │ ├── 讯飞输入法语音悬浮窗.ahk │ └── 讯飞输入法语音悬浮窗.md ├── SetStartup.bat ├── TurnOffScreen.bat ├── VoiceHelper.ahk └── full-all-screens.ahk ├── bun.lockb ├── clx-docs ├── .eslintrc.json ├── .gitignore ├── README.md ├── app │ ├── XIconBlue.ico │ ├── api │ │ └── completions.ts │ ├── favicon.png │ ├── globals.css │ ├── layout.tsx │ └── page.tsx ├── next.config.js ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── public │ ├── next.svg │ └── vercel.svg ├── tailwind.config.js └── tsconfig.json ├── commitlint.config.js ├── docker-compose.yml ├── docs ├── .nojekyll ├── CNAME ├── IETF-subtags.tsv ├── README.en.md ├── README.es.md ├── README.fr.md ├── README.md ├── README.ru.md ├── README.zh.md ├── Roadmap.md ├── buble.css ├── index.html ├── keyboard-preview.html ├── media │ ├── 02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif │ ├── 02-插件-窗口增强_一键排列窗口.gif │ ├── APP-OneNoteClipboard.gif │ ├── App-讯飞语音输入法悬浮窗演示.gif │ ├── CLX-Mouse.gif │ ├── EditorCursorMovement.gif │ ├── 应用-讯飞语音输入法悬浮窗演示.gif │ └── 插件-OneNote剪贴板收集器.gif ├── non-linear-time.md ├── translate.ts ├── 按键名字表.txt └── 支付宝捐助.png ├── lerna.json ├── package.json ├── prettierrc.json ├── src └── cli.ts ├── tsconfig.json └── 启动 CapsLockX.lnk /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { "extends": ["@commitlint/config-conventional"] } 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | * -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": ["plugin:react/recommended", "standard-with-typescript"], 7 | "overrides": [], 8 | "parserOptions": { 9 | "ecmaVersion": "latest", 10 | "sourceType": "module" 11 | }, 12 | "parser": "@typescript-eslint/parser", 13 | "plugins": ["react"], 14 | "rules": {} 15 | } 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [snomiao] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | # patreon: # Replace with a single Patreon username 5 | # open_collective: # Replace with a single Open Collective username 6 | # ko_fi: # Replace with a single Ko-fi username 7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | # liberapay: # Replace with a single Liberapay username 10 | # issuehunt: # Replace with a single IssueHunt username 11 | # otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | - https://afdian.net/@snomiao 14 | - https://paypal.me/snomiao 15 | - https://github.com/snomiao/CapsLockX/raw/master/docs/支付宝捐助.png 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/build-go.yml: -------------------------------------------------------------------------------- 1 | # @deprecated use semantic-release instead 2 | on: 3 | push: 4 | branches: [main, next] 5 | name: build - wip 6 | jobs: 7 | build: 8 | runs-on: macos-latest-xl 9 | steps: 10 | - uses: actions/checkout@v3 11 | # pnpm install 12 | - uses: pnpm/action-setup@v2 13 | with: 14 | version: 6.32.9 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: "18" 18 | registry-url: https://registry.npmjs.org/ 19 | cache: "pnpm" 20 | - run: pnpm install --frozen-lockfile 21 | # npm run build 22 | - run: npm run build 23 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # @deprecated use semantic-release instead 2 | on: 3 | push: 4 | branches: [main, next] 5 | name: build - wip 6 | jobs: 7 | build: 8 | runs-on: windows-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | # pnpm install 12 | - uses: pnpm/action-setup@v2 13 | with: 14 | version: 6.32.9 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: "18" 18 | registry-url: https://registry.npmjs.org/ 19 | cache: "pnpm" 20 | - run: pnpm install --frozen-lockfile 21 | # npm run build 22 | - run: npm run build 23 | -------------------------------------------------------------------------------- /.github/workflows/choco-push.yml: -------------------------------------------------------------------------------- 1 | # @deprecated use semantic-release 2 | # ref [自动化发布npm包及生成Github Changelog]( https://banyudu.com/posts/auto_publish_npm_and_generate_github_changelog.882513 ) 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | # 8 | name: chocolatey publish 9 | jobs: 10 | chocolatey-push: 11 | if: github.repository == 'snolab/CapsLockX' 12 | runs-on: windows-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | # 打包 校验 16 | - run: choco install zip checksum 17 | # TODO 搞个缓存 18 | # - uses: actions/cache@v1 19 | # id: env_cache 20 | # with: 21 | # path: # TODO 22 | # key: ${{ runner.os }}-# TODO 23 | # 这个 step 需要干净的环境所以不要在本地运行。 24 | - run: | 25 | zip -r CapsLockX.zip Core Data docs Modules Tools *.ahk *.txt *.md *.exe 26 | checksum -t sha256 -f CapsLockX.zip > CapsLockX.sha256 27 | cp -force CapsLockX.zip ./DevTools/choco/tools/ 28 | cp -force CapsLockX.sha256 ./DevTools/choco/tools/ 29 | choco pack ./DevTools/choco/CapsLockX.nuspec 30 | # 测试 31 | - run: choco install CapsLockX -s . 32 | # 准备上传到releases 33 | - uses: actions/upload-artifact@v2 34 | with: 35 | name: CapsLockX.zip 36 | path: ./CapsLockX.zip 37 | - uses: actions/upload-artifact@v2 38 | with: 39 | name: CapsLockX.sha256 40 | path: ./CapsLockX.sha256 41 | # 上传 nupkg 用来给 chocolatey push 42 | - run: mv CapsLockX.*.nupkg CapsLockX.nupkg 43 | - uses: actions/upload-artifact@v2 44 | with: 45 | name: CapsLockX.nupkg 46 | path: ./CapsLockX.nupkg 47 | # 发布 48 | - run: choco apikey --key ${{ secrets.CHOCOLATEY_APIKEY }} --source https://push.chocolatey.org/ 49 | - run: choco push --source https://push.chocolatey.org/ 50 | github-pages-choco-version-upload: 51 | runs-on: ubuntu-latest 52 | needs: chocolatey-push 53 | steps: 54 | - uses: actions/checkout@v2 55 | - uses: actions/download-artifact@v2 56 | with: 57 | name: CapsLockX.zip 58 | - uses: actions/download-artifact@v2 59 | with: 60 | name: CapsLockX.sha256 61 | - uses: actions/download-artifact@v2 62 | with: 63 | name: CapsLockX.nupkg 64 | # 压缩包和 sha256 一起扔附件 65 | - uses: svenstaro/upload-release-action@v2 66 | with: 67 | repo_token: ${{ secrets.GITHUB_TOKEN }} 68 | file: CapsLockX.zip 69 | tag: ${{ github.ref }} 70 | - uses: svenstaro/upload-release-action@v2 71 | with: 72 | repo_token: ${{ secrets.GITHUB_TOKEN }} 73 | file: CapsLockX.sha256 74 | tag: ${{ github.ref }} 75 | - uses: svenstaro/upload-release-action@v2 76 | with: 77 | repo_token: ${{ secrets.GITHUB_TOKEN }} 78 | file: CapsLockX.nupkg 79 | tag: ${{ github.ref }} 80 | 81 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [main, next] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [main, next] 20 | schedule: 21 | - cron: "43 14 * * 6" 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: ["javascript"] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages-release.yml: -------------------------------------------------------------------------------- 1 | # @depreacted use semantic-release 2 | on: 3 | push: 4 | tags: 5 | - "v*" 6 | name: gh-pages-release 7 | jobs: 8 | github-release: 9 | if: github.repository == 'snolab/CapsLockX' 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v2 14 | - run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV 15 | # Github release with changelog 16 | - run: npx -y -- github-release-from-cc-changelog ${{ env.RELEASE_VERSION }} 17 | env: 18 | CONVENTIONAL_GITHUB_RELEASER_TOKEN: ${{secrets.GITHUB_TOKEN}} 19 | # pack 20 | - run: mkdir -p ./CapsLockX-${{ env.RELEASE_VERSION }} 21 | - run: cp -r docs Core Data Modules Tools *.exe *.ahk *.md ./CapsLockX-${{ env.RELEASE_VERSION }} 22 | - run: zip -r CapsLockX-${{ env.RELEASE_VERSION }}.zip ./CapsLockX-${{ env.RELEASE_VERSION }} -UN=UTF8 23 | # upload 24 | - uses: svenstaro/upload-release-action@v2 25 | with: 26 | repo_token: ${{ secrets.GITHUB_TOKEN }} 27 | file: CapsLockX-${{ env.RELEASE_VERSION }}.zip 28 | tag: ${{ github.ref }} 29 | # push to gh pages 30 | - run: cp CapsLockX-${{ env.RELEASE_VERSION }}.zip docs/CapsLockX-${{ env.RELEASE_VERSION }}.zip 31 | - run: cp CapsLockX-${{ env.RELEASE_VERSION }}.zip docs/CapsLockX-latest.zip 32 | - run: cp CHANGELOG.md docs/CHANGELOG.md 33 | - run: cp Core/version.txt docs/version.txt 34 | - uses: peaceiris/actions-gh-pages@v3 35 | with: 36 | github_token: ${{ secrets.GITHUB_TOKEN }} 37 | publish_dir: ./docs 38 | enable_jekyll: true 39 | -------------------------------------------------------------------------------- /.github/workflows/issue-translator.yml: -------------------------------------------------------------------------------- 1 | name: issue-translator 2 | on: 3 | issue_comment: 4 | types: [created] 5 | issues: 6 | types: [opened] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: tomsun28/issues-translate-action@v2.6 13 | with: 14 | IS_MODIFY_TITLE: false 15 | # not require, default false, . Decide whether to modify the issue title 16 | # if true, the robot account @Issues-translate-bot must have modification permissions, invite @Issues-translate-bot to your project or use your custom bot. 17 | CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿 18 | # not require. Customize the translation robot prefix message. 19 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | # @deprecated use semantic-release 2 | name: npm-publish 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | jobs: 8 | npm-publish: 9 | if: github.repository == 'snolab/CapsLockX' 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: oven-sh/setup-bun@v1 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: '20.x' 17 | registry-url: 'https://registry.npmjs.org' 18 | - run: bun install 19 | - run: npm publish 20 | env: 21 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: "Close stale issues and PRs" 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' 5 | jobs: 6 | stale: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/stale@v6 10 | with: 11 | stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' 12 | days-before-stale: 30 13 | days-before-close: 5 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # sync services 2 | .sync 3 | *.!sync 4 | 5 | # generated 6 | *.nupkg 7 | node_modules 8 | /docs/README.html 9 | *.sublime-* 10 | *.tgz 11 | *.zip 12 | *.sha256 13 | *.bak 14 | CapsLockX-ModulesRunner.ahk 15 | CapsLockX-ModulesFunctions.ahk 16 | *.!sync 17 | version-*.txt 18 | 19 | # user 20 | /*.ini 21 | *.user.* 22 | /User 23 | /User* 24 | debug.log 25 | 26 | #cache 27 | .eslintcache 28 | /worktrees 29 | .vscode/.go 30 | .vscode/.vscode-server 31 | 32 | dist 33 | dist/cli.cjs 34 | dist/cli.cjs.map 35 | dist/cli.min.cjs 36 | dist/cli.min.cjs.map 37 | dist/cli.min.mjs 38 | dist/cli.min.mjs.map 39 | dist/cli.mjs 40 | dist/cli.mjs.map 41 | .env 42 | 43 | # logs 44 | *.log 45 | docs/.vitepress 46 | 47 | bun.lockb 48 | .env* 49 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | # npm test 5 | npx lint-staged 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # sync services 2 | .sync 3 | *.!sync 4 | 5 | # generated 6 | *.nupkg 7 | node_modules 8 | /docs/README.html 9 | *.sublime-* 10 | *.tgz 11 | *.zip 12 | *.sha256 13 | *.bak 14 | CapsLockX-ModulesRunner.ahk 15 | CapsLockX-ModulesFunctions.ahk 16 | *.!sync 17 | version-*.txt 18 | 19 | # user 20 | /*.ini 21 | *.user.* 22 | /User 23 | 24 | # dev 25 | .github 26 | .vscode 27 | Test 28 | 29 | # bug fix 30 | DevTools 31 | commitlint.config.js 32 | *.bat 33 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "trailingComma": "all", 5 | "endOfLine": "lf", 6 | "plugins": [ 7 | "./node_modules/prettier-plugin-packagejson", 8 | "./node_modules/prettier-plugin-organize-imports", 9 | "./node_modules/prettier-plugin-tsconfig" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "mark-wiemer.vscode-autohotkey-plus-plus" 4 | ] 5 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.eol": "\r\n", 3 | "task.allowAutomaticTasks": "on" 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "script": "start", 7 | "problemMatcher": [], 8 | "label": "npm: start", 9 | "detail": "CapsLockX.exe", 10 | }, 11 | { 12 | "type": "npm", 13 | "script": "release", 14 | "problemMatcher": [], 15 | "label": "npm: release", 16 | "detail": "pnpm upgrade & standard-version --commit-all && git push --follow-tag --all" 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | capslockx.snomiao.com -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 如何贡献本项目 2 | 3 | ## 4 | -------------------------------------------------------------------------------- /CapsLockX.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/CapsLockX.exe -------------------------------------------------------------------------------- /Core/CapsLockX-RunSilent.ahk: -------------------------------------------------------------------------------- 1 | ; ---------------------------------------------------------------------------------------------------------------------- 2 | ; Function .....: StdoutToVar_CreateProcess 3 | ; Description ..: Runs a command line program and Returns its output. 4 | ; Parameters ...: sCmd - Commandline to execute. 5 | ; ..............: sEncoding - Encoding used by the target process. Look at StrGet() for possible values. 6 | ; ..............: sDir - Working directory. 7 | ; ..............: nExitCode - Process exit code, receive it as a byref parameter. 8 | ; Return .......: Command output as a string on success, empty string on error. 9 | ; AHK Version ..: AHK_L x32/64 Unicode/ANSI 10 | ; Author .......: Sean (http://goo.gl/o3VCO8), modified by nfl and by Cyruz 11 | ; License ......: WTFPL - http://www.wtfpl.net/txt/copying/ 12 | ; Changelog ....: Feb. 20, 2007 - Sean version. 13 | ; ..............: Sep. 21, 2011 - nfl version. 14 | ; ..............: Nov. 27, 2013 - Cyruz version (code refactored and exit code). 15 | ; ..............: Mar. 09, 2014 - Removed input, doesn't seem reliable. Some code improvements. 16 | ; ..............: Mar. 16, 2014 - Added encoding parameter as pointed out by lexikos. 17 | ; ..............: Jun. 02, 2014 - Corrected exit code error. 18 | ; ..............: Nov. 02, 2016 - Fixed blocking behavior due to ReadFile thanks to PeekNamedPipe. 19 | ; ---------------------------------------------------------------------------------------------------------------------- 20 | StdoutToVar_CreateProcess(sCmd, sEncoding:="CP0", sDir:="", ByRef nExitCode:=0){ 21 | DllCall( "CreatePipe", PtrP,hStdOutRd, PtrP,hStdOutWr, Ptr,0, UInt,0 ) 22 | DllCall( "SetHandleInformation", Ptr,hStdOutWr, UInt,1, UInt,1 ) 23 | 24 | VarSetCapacity( pi, (A_PtrSize == 4) ? 16 : 24, 0 ) 25 | siSz := VarSetCapacity( si, (A_PtrSize == 4) ? 68 : 104, 0 ) 26 | NumPut( siSz, si, 0, "UInt" ) 27 | NumPut( 0x100, si, (A_PtrSize == 4) ? 44 : 60, "UInt" ) 28 | NumPut( hStdOutWr, si, (A_PtrSize == 4) ? 60 : 88, "Ptr" ) 29 | NumPut( hStdOutWr, si, (A_PtrSize == 4) ? 64 : 96, "Ptr" ) 30 | 31 | If ( !DllCall( "CreateProcess", Ptr,0, Ptr,&sCmd, Ptr,0, Ptr,0, Int,True, UInt,0x08000000 32 | , Ptr,0, Ptr,sDir?&sDir:0, Ptr,&si, Ptr,&pi ) ) 33 | Return "" 34 | , DllCall( "CloseHandle", Ptr,hStdOutWr ) 35 | , DllCall( "CloseHandle", Ptr,hStdOutRd ) 36 | 37 | DllCall( "CloseHandle", Ptr,hStdOutWr ) ; The write pipe must be closed before reading the stdout. 38 | While ( 1 ) 39 | { ; Before reading, we check if the pipe has been written to, so we avoid freezings. 40 | If ( !DllCall( "PeekNamedPipe", Ptr,hStdOutRd, Ptr,0, UInt,0, Ptr,0, UIntP,nTot, Ptr,0 ) ) 41 | Break 42 | If ( !nTot ) 43 | { ; If the pipe buffer is empty, sleep and continue checking. 44 | Sleep, 100 45 | Continue 46 | } ; Pipe buffer is not empty, so we can read it. 47 | VarSetCapacity(sTemp, nTot+1) 48 | DllCall( "ReadFile", Ptr,hStdOutRd, Ptr,&sTemp, UInt,nTot, PtrP,nSize, Ptr,0 ) 49 | sOutput .= StrGet(&sTemp, nSize, sEncoding) 50 | } 51 | 52 | ; * SKAN has managed the exit code through SetLastError. 53 | DllCall( "GetExitCodeProcess", Ptr,NumGet(pi,0), UIntP,nExitCode ) 54 | DllCall( "CloseHandle", Ptr,NumGet(pi,0) ) 55 | DllCall( "CloseHandle", Ptr,NumGet(pi,A_PtrSize) ) 56 | DllCall( "CloseHandle", Ptr,hStdOutRd ) 57 | Return sOutput 58 | } 59 | 60 | CLX_RunSilent(command){ 61 | Return StdoutToVar_CreateProcess(command) 62 | } -------------------------------------------------------------------------------- /Core/CapsLockX-With-RemoteControls.ahk: -------------------------------------------------------------------------------- 1 |  2 | ; prepare -------------------------------------------------------------------------------- /Core/ahk-2.0.11/AutoHotkey32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Core/ahk-2.0.11/AutoHotkey32.exe -------------------------------------------------------------------------------- /Core/ahk-2.0.11/AutoHotkey64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Core/ahk-2.0.11/AutoHotkey64.exe -------------------------------------------------------------------------------- /Core/lang.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Core/lang.ini -------------------------------------------------------------------------------- /Core/version.txt: -------------------------------------------------------------------------------- 1 | 1.34.11 -------------------------------------------------------------------------------- /Data/CapsLockX.defaults.ignore.txt: -------------------------------------------------------------------------------- 1 | # 各种远程桌面 2 | 3 | .*? - .* ahk_exe mstsc.exe 4 | ahk_exe anydesk.exe 5 | ahk_exe vmconnect.exe 6 | ahk_exe teamviewer.exe 7 | ahk_exe virtualbox.exe 8 | ahk_exe synergyd.exe 9 | 10 | # 各种游戏 11 | ahk_exe yuanshen.exe 12 | ahk_class UnityWndClass ahk_exe YuanShen.exe 13 | 14 | # 高级编辑器 15 | gvim 16 | -------------------------------------------------------------------------------- /Data/NoteC.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/NoteC.mp3 -------------------------------------------------------------------------------- /Data/NoteC_G.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/NoteC_G.mp3 -------------------------------------------------------------------------------- /Data/NoteG.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/NoteG.mp3 -------------------------------------------------------------------------------- /Data/NoteG_C.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/NoteG_C.mp3 -------------------------------------------------------------------------------- /Data/XIconBlue.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/XIconBlue.ico -------------------------------------------------------------------------------- /Data/XIconBlue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/XIconBlue.png -------------------------------------------------------------------------------- /Data/XIconWhite.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/XIconWhite.ico -------------------------------------------------------------------------------- /Data/XIconWhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/XIconWhite.png -------------------------------------------------------------------------------- /Data/cursor/AppStarting.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/AppStarting.cur -------------------------------------------------------------------------------- /Data/cursor/Arrow.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/Arrow.cur -------------------------------------------------------------------------------- /Data/cursor/Cross.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/Cross.cur -------------------------------------------------------------------------------- /Data/cursor/Hand.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/Hand.cur -------------------------------------------------------------------------------- /Data/cursor/Handwriting.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/Handwriting.cur -------------------------------------------------------------------------------- /Data/cursor/Help.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/Help.cur -------------------------------------------------------------------------------- /Data/cursor/IBeam.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/IBeam.cur -------------------------------------------------------------------------------- /Data/cursor/NO.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/NO.cur -------------------------------------------------------------------------------- /Data/cursor/SizeAll.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/SizeAll.cur -------------------------------------------------------------------------------- /Data/cursor/SizeNESW.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/SizeNESW.cur -------------------------------------------------------------------------------- /Data/cursor/SizeNS.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/SizeNS.cur -------------------------------------------------------------------------------- /Data/cursor/SizeNWSE.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/SizeNWSE.cur -------------------------------------------------------------------------------- /Data/cursor/SizeWE.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/SizeWE.cur -------------------------------------------------------------------------------- /Data/cursor/UpArrow.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/UpArrow.cur -------------------------------------------------------------------------------- /Data/cursor/Wait.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/Wait.cur -------------------------------------------------------------------------------- /Data/cursor/setup.inf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/cursor/setup.inf -------------------------------------------------------------------------------- /Data/图标白-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标白-1.png -------------------------------------------------------------------------------- /Data/图标白-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标白-2.png -------------------------------------------------------------------------------- /Data/图标白-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标白-3.png -------------------------------------------------------------------------------- /Data/图标白-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标白-4.png -------------------------------------------------------------------------------- /Data/图标白-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标白-5.png -------------------------------------------------------------------------------- /Data/图标蓝-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标蓝-1.png -------------------------------------------------------------------------------- /Data/图标蓝-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标蓝-2.png -------------------------------------------------------------------------------- /Data/图标蓝-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标蓝-3.png -------------------------------------------------------------------------------- /Data/图标蓝-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标蓝-4.png -------------------------------------------------------------------------------- /Data/图标蓝-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Data/图标蓝-5.png -------------------------------------------------------------------------------- /DevTools/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/DevTools/.gitignore -------------------------------------------------------------------------------- /DevTools/CapsLockX.ts: -------------------------------------------------------------------------------- 1 | import { exec } from "child_process"; 2 | import { promisify } from "util"; 3 | import path from "path"; 4 | import fs from "fs"; 5 | const clxPath = path.dirname(path.dirname(import.meta.url)) + "/CapsLockX.exe"; 6 | await promisify(exec)("cmd /c explorer " + clxPath); 7 | // console.log(clxPath); 8 | 9 | // await fs.promises.readdir('Modules') 10 | // await fs.promises.('Modules') 11 | // modu 12 | -------------------------------------------------------------------------------- /DevTools/choco/tools/VERIFICATION.txt: -------------------------------------------------------------------------------- 1 | VERIFICATION 2 | Verification is intended to assist the Chocolatey moderators and community 3 | in verifying that this package's contents are trustworthy. 4 | 5 | You can get CapsLockX.zip and CapsLockX.sha256 from https://github.com/snolab/CapsLockX/releases. 6 | Then run checksum to check the hash by your self. 7 | -------------------------------------------------------------------------------- /DevTools/choco/tools/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = 'Stop'; 2 | $packageName = 'CapsLockX' 3 | $toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" 4 | $zipFilePath = "$toolsDir\\CapsLockX.zip" 5 | $packageArgs = @{ 6 | packageName = $env:ChocolateyPackageName 7 | } 8 | Get-ChocolateyUnzip -FileFullPath $zipFilePath -Destination $toolsDir 9 | -------------------------------------------------------------------------------- /DevTools/clxLint.ts: -------------------------------------------------------------------------------- 1 | import { readFile } from "fs/promises"; 2 | import { glob } from "glob"; 3 | async function ahksf() { 4 | return await glob("**/*.ahk"); 5 | // return ahks; 6 | } 7 | ahksf() 8 | const read = async (f: string) => ({ f, s: await readFile(f, "utf8") }); 9 | let ahkitems; 10 | ahkitems = await Promise.all(ahks.map(read)); 11 | 12 | // %% 13 | const warns = { 14 | if未加括号: /^\s*if[ ]*[^( ]/gim, 15 | }; 16 | function warn(f: string) { 17 | return mapValues(warns, (reg, key) => 18 | [...s.matchAll(reg)].map((m) => ({ 19 | peek: s.slice(m.index, m[0].length), 20 | m: String(m), 21 | })), 22 | ); 23 | } 24 | JSON.stringify(await Promise.all(ahkitems.map(warn)), null, 2); 25 | 26 | // %% 27 | 28 | // %% 29 | 30 | // %% 31 | -------------------------------------------------------------------------------- /DevTools/git-sync.bat: -------------------------------------------------------------------------------- 1 | cd %~dp0 2 | cd .. 3 | 4 | @REM add remotes 5 | git remote remove origin 6 | git remote add origin git@github.com:snolab/CapsLockX.git 7 | git remote set-url --add origin git@github.com:snomiao/CapsLockX.git 8 | git remote set-url --add origin git@bitbucket.org:snomiao/capslockx.git 9 | git remote set-url --add origin git@gitlab.com:snomiao/CapsLockX.git 10 | git remote set-url --add origin git@gitee.com:snomiao/CapslockX.git 11 | git remote -v 12 | 13 | @REM sync 14 | git fetch origin 15 | git pull --set-upstream origin main 16 | git push origin main --follow-tags 17 | -------------------------------------------------------------------------------- /DevTools/i18n.js: -------------------------------------------------------------------------------- 1 | ` 2 | Main Reference: /README.md 3 | Translated Reference: docs/README.*.md 4 | 5 | 6 | Increment Translate plan: 7 | 8 | main_full = Read from main reference file 9 | translated_parts = and read from translated reference file. 10 | 11 | Split them into sections, and ask for chatgpt if the section is already the updated translated. 12 | If translated, then append to the final file. 13 | If not translated or outdated, then ask for translation and append to the final file. 14 | 15 | `; 16 | import fs from "fs"; 17 | import { readFile } from "fs/promises"; 18 | import ai from "openai"; 19 | // Define the paths for the main and translated reference files 20 | const mainFilePath = "README.md"; 21 | const translatedFilePath = "docs/README.es.md"; // Assuming Spanish as an example 22 | 23 | // Read contents of the main reference file and translated reference file 24 | const mainFull = await readFile(mainFilePath, "utf-8"); 25 | const translatedParts = await readFile(translatedFilePath, "utf-8"); 26 | 27 | // Here, you need to replace "splitIntoSections" with your actual function to split content into sections. 28 | const mainSections = splitReadme(mainFull); 29 | const translatedSections = splitReadme(translatedParts); 30 | 31 | // Helper function to check if a section is translated and updated 32 | const translateUpdatedQ = async ( 33 | translationLanguage, 34 | referenceSection, 35 | translatedSection, 36 | ) => 37 | await new ai.Chat.Completions() 38 | .create({ 39 | messages: [ 40 | { 41 | role: "user", 42 | message: JSON.stringify({ 43 | translationLanguage, 44 | referenceSection, 45 | translatedSection, 46 | }), 47 | }, 48 | { 49 | role: "user", 50 | message: 51 | 'You received a JSON, Is the translation content already updated with reference section? Reply "Yes" or "No", Do not explain other things, do not add any punctuations.', 52 | }, 53 | ], 54 | model: "gpt-4-turbo-preview", 55 | }) 56 | .then((e) => e.choices[0].message.content); 57 | 58 | // Helper function to translate a section 59 | const translateSection = async (lang, section) => 60 | await new ai.Chat.Completions() 61 | .create({ 62 | messages: [ 63 | { 64 | role: "user", 65 | message: JSON.stringify({ mainSection }), 66 | }, 67 | { role: "user", message: "Is the translation already updated?" }, 68 | ], 69 | model: "gpt-4-turbo-preview", 70 | }) 71 | .then((e) => e.choices[0].message.content); 72 | 73 | // Draft the final translated file 74 | const draftFinalFile = async () => { 75 | let finalContent = ""; 76 | 77 | for (let i = 0; i < mainSections.length; i++) { 78 | let mainSection = mainSections[i]; 79 | let translatedSection = translatedSections[i]; 80 | 81 | if (isSectionTranslatedAndUpdated(mainSection, translatedSection)) { 82 | finalContent += translatedSection; 83 | } else { 84 | const newSection = await translateSection(mainSection); 85 | finalContent += newSection; 86 | // Optionally update the translatedSections array if necessary 87 | translatedSections[i] = newSection; 88 | } 89 | } 90 | 91 | // Save the final content to a new file or overwrite the existing translated file 92 | fs.writeFileSync(translatedFilePath, finalContent, "utf-8"); 93 | }; 94 | 95 | // await draftFinalFile(); 96 | 97 | // js function split readme file into sections by # and ## 98 | function splitReadme(content) { 99 | const sections = content.split(/\n(?=##(?!#))/).reduce((acc, section) => { 100 | const trimmed = section.trim(); 101 | if (trimmed.startsWith("#")) { 102 | acc.push(trimmed); 103 | } 104 | return acc; 105 | }, []); 106 | return sections; 107 | } 108 | console.log(splitReadme(mainFull).map((e) => [e.length, e.split("\n")[0]])); 109 | -------------------------------------------------------------------------------- /DevTools/lint/#ifwinactive.code-search: -------------------------------------------------------------------------------- 1 | # Query: #IfWinActive[^\\n;]*\\n 2 | # Flags: RegExp 3 | # Including: *.ahk 4 | # ContextLines: 1 5 | 6 | No Results 7 | -------------------------------------------------------------------------------- /DevTools/setup.iss: -------------------------------------------------------------------------------- 1 | ; -- setup.iss -- 2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING .ISS SCRIPT FILES! 3 | 4 | [Setup] 5 | AppName=CapsLockX 6 | AppVersion=1.34.11 7 | WizardStyle=modern 8 | ; DefaultDirName={autopf}\CapsLockX 9 | DefaultDirName={userappdata}\CapsLockX 10 | DefaultGroupName=CapsLockX 11 | UninstallDisplayIcon={app}\CapsLockX.exe 12 | Compression=lzma2 13 | SolidCompression=yes 14 | OutputDir=userdocs:Inno Setup CapsLockX Output 15 | 16 | [Files] 17 | Source: "README.md"; DestDir: "{app}"; Flags: isreadme 18 | Source: "CapsLockX.ahk"; DestDir: "{app}" 19 | Source: "CapsLockX.exe"; DestDir: "{app}" 20 | Source: "Core\*"; DestDir: "{app}" 21 | Source: "Data\*"; DestDir: "{app}" 22 | Source: "docs\*"; DestDir: "{app}" 23 | Source: "Modules\*"; DestDir: "{app}" 24 | Source: "Tools\*"; DestDir: "{app}" 25 | 26 | [Icons] 27 | Name: "{group}\CapsLockX"; Filename: "{app}\CapsLockX.exe" 28 | -------------------------------------------------------------------------------- /DevTools/setup_repos.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | chcp 65001 3 | REM [Working with Git remotes and pushing to multiple Git repositories | Jigarius.com]( https://jigarius.com/blog/multiple-git-remote-repositories ) 4 | git remote remove remote 5 | git remote add remote git@github.com:snomiao/CapsLockX.git 6 | git remote set-url --add --push remote git@github.com:snolab/CapsLockX.git 7 | git remote set-url --add --push remote git@gitlab.com:snomiao/CapsLockX.git 8 | git remote set-url --add --push remote git@gitee.com:snomiao/CapslockX.git 9 | git remote set-url --add --push remote git@bitbucket.org:snomiao/capslockx.git 10 | git fetch --all 11 | git push --set-upstream remote master 12 | git push 13 | -------------------------------------------------------------------------------- /DevTools/versioning.ts: -------------------------------------------------------------------------------- 1 | import { readFile, writeFile } from "fs/promises"; 2 | 3 | if (import.meta.main) { 4 | await versioning(); 5 | } 6 | 7 | // 8 | async function versioning() { 9 | // get current version 10 | const { version } = JSON.parse(await readFileUtf8("package.json")); 11 | 12 | // console.log('get version', version) 13 | 14 | // 15 | (await fileContentReplace( 16 | "./DevTools/setup.iss", 17 | /AppVersion=.*/, 18 | "AppVersion=" + version, 19 | )) || console.warn("setup.iss version not changed"); 20 | 21 | // update version.txt 22 | (await fileContentReplace("./Core/version.txt", /.*/, version)) || 23 | console.warn("txt版本号路径版本没有变化"); 24 | 25 | // update choco package version 26 | const choco包文件路径 = "./DevTools/choco/CapsLockX.nuspec"; 27 | const choco包文 = await readFileUtf8(choco包文件路径); 28 | const CDATA包装 = (文本) => 29 | ``; 34 | const CHANGELOG = CDATA包装(await readFileUtf8("CHANGELOG.MD")).replace( 35 | /[一-龥]+/g, 36 | "", 37 | ); 38 | // 39 | const 新版本包文 = choco包文 40 | .replace( 41 | /()(.*?)(<\/version>)/, 42 | (_, $1, $2, $3) => $1 + version + $3, 43 | ) 44 | // .replace(/()([\s\S]*?)(<\/description>)/, (_, $1, $2, $3) => $1 + README + $3) 45 | .replace( 46 | /()([\s\S]*?)(<\/releaseNotes>)/, 47 | (_, $1, $2, $3) => $1 + CHANGELOG + $3, 48 | ); 49 | console.assert( 50 | choco包文 !== 新版本包文, 51 | `警告:Choco包文版本没有变化,当前版本为${version}`, 52 | ); 53 | await writeFile(choco包文件路径, 新版本包文); 54 | 55 | console.log("chore(release): " + version); 56 | } 57 | 58 | async function readFileUtf8(f: string) { 59 | return await readFile(f, { encoding: "utf8" }); 60 | } 61 | async function fileContentReplace( 62 | filePath: string, 63 | regexp: RegExp, 64 | replacement: string, 65 | ) { 66 | const content = await readFileUtf8(filePath); 67 | const newContent = content.replace(regexp, replacement); 68 | const replaced = newContent !== content; 69 | if (replaced) await writeFile(filePath, newContent); 70 | return replaced; 71 | } 72 | -------------------------------------------------------------------------------- /Modules/02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif -------------------------------------------------------------------------------- /Modules/02-插件-窗口增强_一键排列窗口.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/02-插件-窗口增强_一键排列窗口.gif -------------------------------------------------------------------------------- /Modules/@Help.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 名称:帮助模块及模块编写教程 3 | ; 描述:用于提供帮助函数,打开 CapsLockX 的 Github 页面,不可禁用 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 支持:https://github.com/snomiao/CapsLockX 7 | ; 版本:v2020.06.27 8 | ; 注释:在这一节里你可以填写你的脚本的元信息,本模块提供按住 CapsLockX + / 键显示帮助的功能。 9 | ; ========== CapsLockX ========== 10 | ; 11 | ; = 初始化区 ===================================================== 12 | ; 注释:代码从这里开始运行 13 | ; 14 | ; 给出一些名称定义规范 15 | ; 应用:可以脱离 CapsLockX 独立运行的 AHK 文件 16 | ; 扩展:你的模块需要 CapsLockX 才能执行,且没有其它依赖 17 | ; 插件:你的模块需要 CapsLockX 才能执行,且没有其它依赖 18 | ; 用户:其它用户分享的模块 19 | ; 名称约束:模块名内不能有这几个字符 ", ``" 20 | ; 21 | ; 以下条件语句表示这个模块只能在 CapsLockX 下工作,如果没有用到 CapsLockX 的变量则可以不写。 22 | 23 | if (!CapsLockX) { 24 | MsgBox, % "本模块只在 CapsLockX 下工作" 25 | ExitApp 26 | } 27 | ; 28 | ; 你可以在这里定义一些变量 29 | ; 可以是全局变量或者本地变量(建议全局) 30 | ; 需要注意模块按照文件名排序先后加载, 31 | ; 所以后一个模块可以读取前一个模块定义的变量(包括全局和本地的)(但通常不建议这么做)。 32 | ; 33 | global CLX_HelpInfo := "" 34 | CLX_IssuesPage := "https://github.com/snolab/CapsLockX/issues" 35 | 36 | ; 注释:在这里,你可以使用 CLX_AppendHelp 添加帮助信息 37 | ; 在 AHK 中,所有的函数都在编译时就定义好了,声明顺序是无所谓的。 38 | ; CLX_THIS_MODULE_HELP_FILE_PATH 在当前模块中的值为 "./Modules/00-Help.md" 39 | CLX_AppendHelp(CLX_LoadHelpFrom(CLX_THIS_MODULE_HELP_FILE_PATH)) 40 | ; 41 | ; 初始化完成之后就可以返回了, 在这个 Return 之后,可以定义函数和热键 42 | ; 注:CapsLockX 模块【必须】 Return,才能顺利地执行后面的模块。 43 | Return 44 | ; 45 | ; = 函数声名和热键区 ===================================================== 46 | ; 47 | ; 定义函数,这里定义了 2 个用来操作帮助的函数。 48 | CLX_LoadHelpFrom(file) 49 | { 50 | FileEncoding UTF-8 51 | FileRead, helpStr, %file% 52 | helpStr := RegExReplace(helpStr, "m)^[^|#].*$") 53 | helpStr := RegExReplace(helpStr, "m)\r?\n(\r?\n)+", "`n") 54 | return helpStr 55 | } 56 | CLX_AppendHelp(helpStr) 57 | { 58 | if (helpStr) { 59 | CLX_HelpInfo .= helpStr "`n`n" 60 | } 61 | } 62 | CLX_ShowHelp(helpStr, inGlobal := 0, waitKey := "/") 63 | { 64 | if (!inGlobal && !CapsLockXMode) { 65 | SendEvent, / 66 | Return 67 | } 68 | Gui, Help:Destroy 69 | Gui, Help:Font, , SimHei 70 | Gui, Help:Add, Edit, ReadOnly, ==== CapsLockX Help ==== 71 | Gui, Help:Add, Edit, H768 ReadOnly, %helpStr% 72 | Gui, Help:Show, AutoSize Center 73 | 74 | KeyWait, %waitKey%, T60 ; wait for 60 seconds, then auto close 75 | ; Gui, Hide 76 | Gui, Help:Destroy 77 | ; ToolTip 78 | } 79 | 80 | ; 你可以以不同的模式添加各种热键 81 | ; 82 | ; 比如这一行,指的是当前在 CapsLockX 模式时,生效的热键 83 | #if CapsLockXMode 84 | 85 | ; #if CapsLockXMode 86 | ; 显示使用方法,直接调用前面定义的函数 87 | ; /:: CLX_ShowHelp(CLX_HelpInfo, 1) 88 | 89 | ; 你可以按住 CapsLockX 键观察托盘的 CapsLockX 图标,当它变蓝时,按下 Alt + / 就可以快速打开 CapsLockX 的首页 90 | ; 也就是 CapsLockX + Alt + / 91 | !/:: Run https://capslockx.snomiao.com/ 92 | 93 | ; 同理,这个热键可以使用 CapsLockX + Shift + / 触发 94 | +/:: Run % CLX_IssuesPage 95 | 96 | #if 97 | 98 | ; 在这里你也可以定义无需按下 CapsLockX 就能触发的热键 99 | -------------------------------------------------------------------------------- /Modules/@Help.md: -------------------------------------------------------------------------------- 1 | # 帮助模块 2 | 3 | 如果你想学习如何开发 CapsLockX 的插件,请: 4 | 5 | 1. 打开 `Modules/@Help.ahk` , 你可以了解到 CapsLockX 插件的基本格式 6 | 2. 将它复制一份,命名为你自己的插件名称 7 | 3. 将它本来的功能改成你自己需要的功能,插件的开发就完成啦! 8 | 9 | ## 本模块功能见下 10 | 11 | | 作用于 | 按键 | 功能 | 12 | | ------ | --------------------- | -------------------------------- | 13 | | 全局 | CapsLockX + / | 临时显示热键提示 | 14 | | 全局 | CapsLockX + Alt + / | 🔗 打开 CapsLockX 的完整文档页面 | 15 | | 全局 | CapsLockX + Shift + / | 🕷 提交 bug、建议等 | 16 | -------------------------------------------------------------------------------- /Modules/@README-目录说明-模块编写说明.md: -------------------------------------------------------------------------------- 1 | # 模块编写说明 2 | 3 | ## 普通 4 | 5 | 其实……随便写就行 6 | 7 | 反正放到这个 Modules/ 下的 .ahk 文件都会自动加载的 8 | 9 | 不要写崩就好。。 10 | 11 | ## 进阶 12 | 13 | ### 跟直接运行模块的 ahk 比,有哪些特别的地方? 14 | 15 | 可以使用 CapsLockX-Config.ahk 来设定模块配置 16 | 17 | ### 有的模块文件名前有 01-、02- 是干啥用的? 18 | 19 | 某些模块需要先加载其它模块,才能运行。比如鼠标增强模块需要使用加速度模型模块里的函数。也就是说,排在前面的会先运行。 20 | -------------------------------------------------------------------------------- /Modules/APP-OneNoteClipboard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/APP-OneNoteClipboard.gif -------------------------------------------------------------------------------- /Modules/APP-OneNoteClipboard.md: -------------------------------------------------------------------------------- 1 | # OneNote 剪贴板收集插件 2 | 3 | 使用方法 4 | 5 | 1. OneNote 2016 打开一个窗口,标题写成这样 "剪贴板收集"。 6 | 2. 然后再用 Ctrl + C 复制东西的时候就会自动记到 OneNote 里 7 | 3. 如图 8 | ![插件-OneNote剪贴板收集器.gif](./插件-OneNote剪贴板收集器.gif) 9 | -------------------------------------------------------------------------------- /Modules/App-AnkiEnhanced.md: -------------------------------------------------------------------------------- 1 | # Anki 增强模块 2 | 3 | Anki 操作增强 4 | 5 | ## 常用功能/特性 6 | 7 | 1. 使用 WASD 或 HJKL 来快速连续地(并且可以撤销)切换记忆卡片 8 | 2. 在 Excel 制作一个单词列表,共 2 列, 全选复制,然后在 Anki 中按 Alt + i 来快速导入单词列表。 9 | 3. 简化 4 个选项为 3 个方向键,左易,下中,右难,上撤销。 10 | 4. 可配合手柄使用,使用 XPadder 配置手柄摇杆映射到方向键即可。效果请见 bilibili [中二雪星怎背词 - 手柄怎么可以不用来背单词!](https://www.bilibili.com/video/av8456838/) 11 | 12 | ## 说明 13 | 14 | | 模式 | Anki 增强模块 | 说明 | 15 | | -------------------- | :------------: | ----------------------------------------------------------- | 16 | | 在 Anki-学习界面 | `w 或 k 或 ↑` | 按下=撤销,松开显示答案 | 17 | | 在 Anki-学习界面 | `a 或 h 或 ←` | 按下=顺利,松开显示答案 | 18 | | 在 Anki-学习界面 | `s 或 j 或 ↓` | 按下=一般,松开显示答案 | 19 | | 在 Anki-学习界面 | `d 或 l 或 →` | 按下=生疏,松开显示答案 | 20 | | 在 Anki-学习界面 | `q` | 返回上个界面 | 21 | | 在 Anki-学习界面 | `c` | 添加新卡片 | 22 | | 在 Anki-学习界面 | `1 或 NumPad1` | 困难(原键位) | 23 | | 在 Anki-学习界面 | `2 或 NumPad2` | 生疏(原键位) | 24 | | 在 Anki-学习界面 | `3 或 NumPad3` | 一般(原键位) | 25 | | 在 Anki-学习界面 | `4 或 NumPad4` | 顺利(原键位) | 26 | | 在 Anki-学习界面 | `5 或 NumPad5` | 撤销 | 27 | | 在 Anki-学习界面 | `6 或 NumPad6` | 暂停卡片 | 28 | | 在 Anki-学习界面 | `Alt + i` | 快速导入剪贴版的内容(按 Tab 分割) / 比如可以从 Excel 复制 | 29 | | 在 Anki-添加卡片界面 | `Alt + s` | 按下 添加 按钮 | 30 | -------------------------------------------------------------------------------- /Modules/App-XunFeiSwitching.ahk: -------------------------------------------------------------------------------- 1 | ; @CapsLockX v1 2 | ; @name Win + H 快速启动讯飞语音悬浮窗 3 | ; @description 如题 4 | ; @author snomiao@gmail.com 5 | ; @version 2.1.1(20200606) 6 | ; 7 | ; 2021-04-15 更新 @telppa:[修改了一下语音识别模块的代码。・Issue #14・snolab/CapsLockX]( https://github.com/snolab/CapsLockX/issues/14 ) 8 | ; 9 | 10 | global T_EnableXunFeiSwitching := CLX_Config("App", "T_EnableXunFeiSwitching", 1, t("使用 Win+Alt+H 快速启动讯飞语音悬浮窗(默认启用)")) 11 | CLX_AppendHelp( CLX_LoadHelpFrom(CLX_THIS_MODULE_HELP_FILE_PATH)) 12 | Return 13 | 14 | #if !CapsLockXMode && T_EnableXunFeiSwitching 15 | 16 | #!h:: 讯飞语音输入法切换() 17 | 18 | 讯飞语音输入法切换(){ 19 | xflyInstallMsg := t("你似乎还没有安装讯飞语音输入法,是否现在下载安装包并【手动安装】到默认目录? - [讯飞输入法官网 - 更好用的手机输入法,提供专业输入法定制解决方案!]( https://srf.xunfei.cn/#/ )") 20 | 21 | ; v3 22 | iFlyWnd := WinExist("ahk_class BaseGui ahk_exe iFlyVoice.exe" ) 23 | If (iFlyWnd){ 24 | ; WinGet, Transparent, Transparent 25 | ; WinSet, TransColor, Off, ahk_id %iFlyWnd% 26 | ; WinSet, TransColor, 0xffffff 150, ahk_id %iFlyWnd% 27 | ; WinSet, Transparent, 200, ahk_id %iFlyWnd% 28 | ; w357 h177 29 | WinGetPos, X, Y, Width, Height, ahk_id %iFlyWnd% 30 | CLICK_X := Width / 2 31 | CLICK_Y := Height / 2 32 | ControlClick, x%CLICK_X% y%CLICK_Y%, ahk_id %iFlyWnd% 33 | return 34 | } 35 | 36 | ; v2 37 | iFlyWnd := WinExist("ahk_class UIIFlyVoiceFrame ahk_exe iFlyVoice.exe" ) 38 | If (iFlyWnd){ 39 | WinGetPos, X, Y, Width, Height, ahk_id %iFlyWnd% 40 | CLICK_X := Width / 2 41 | CLICK_Y := Height / 2 42 | ; WinGet, Transparent, TransparentMhm 43 | ; WinSet, TransColor, Off, ahk_id %iFlyWnd% 44 | ; WinSet, TransColor, 0xffffff 150, ahk_id %iFlyWnd% 45 | ; WinSet, Transparent, 200, ahk_id %iFlyWnd% 46 | ControlClick, x20 y20, ahk_id %iFlyWnd% 47 | return 48 | } 49 | 50 | ; 注册表里取路径 51 | RegRead, iFlyPath, HKLM\SOFTWARE\iFly Info Tek\iFlyIME, Install_Dir_Ver2 52 | ; 非空检查,确保 iFlyPath 有值 53 | iFlyPath := (iFlyPath ? iFlyPath : "C:\Program Files (x86)\iFly Info Tek\iFlyIME\2.1.1708") 54 | If (FileExist(iFlyPath "\iFlyVoice.exe")){ 55 | Run "%iFlyPath%\iFlyVoice.exe" 56 | }else{ 57 | MsgBox, 4, , % xflyInstallMsg 58 | IfMsgBox, NO, Return 59 | ; Run https://download.voicecloud.cn/200ime/iFlyIME_Setup_2.1.1708.exe 60 | run https://srf.xunfei.cn/#/ 61 | ; - [讯飞输入法官网 - 更好用的手机输入法,提供专业输入法定制解决方案!]( https://srf.xunfei.cn/#/ ) 62 | ; run https://download.voicecloud.cn/200ime/iFlyIME_Setup_3.0.1734.exe 63 | ; UrlDownloadToFile https://download.voicecloud.cn/200ime/iFlyIME_Setup_2.1.1708.exe, %TEMP%/iFlyIME_Setup_2.1.1708.exe 64 | ; Run %TEMP%/iFlyIME_Setup_2.1.1708.exe 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Modules/App-XunFeiSwitching.md: -------------------------------------------------------------------------------- 1 | # 讯飞输入法悬浮窗插件 2 | 3 | ## 用法 4 | 5 | | 作用于 | 按键 | 功能说明 | 6 | | ------ | :-----------: | --------------------- | 7 | | 全局 | Win + Alt + H | 启动/切换讯飞语音输入 | 8 | 9 | ## 注 10 | 11 | 1. 若没有安装讯飞语音则会自动询问是否引导下载安装 12 | 13 | ## 效果如下图 14 | 15 | ![App-讯飞语音输入法悬浮窗演示.gif](./App-讯飞语音输入法悬浮窗演示.gif) 16 | -------------------------------------------------------------------------------- /Modules/App-讯飞语音输入法悬浮窗演示.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/App-讯飞语音输入法悬浮窗演示.gif -------------------------------------------------------------------------------- /Modules/CLX-Brainstorm.md: -------------------------------------------------------------------------------- 1 | # CLX - Brainstorm 大脳风暴 2 | 3 | 任何時間,任何輸入框,按下 `CLX+b` 鍵,開始使用 AI 輔助輸入。 4 | 5 | ## 按键分布(开发中) 6 | 7 | | 按键描述 | 作用 | 备注 | 8 | | --------------- | ---------------------------------------------------- | ---- | 9 | | CLX + b | 自動複製当前选中内容,輸入指令,让 AI 辅助你的輸入 | | 10 | | CLX + Alt + b | 配置激活碼(目前只有免費方案,将来可能加入功能増強) | | 11 | | CLX + Shift + b | 査看使用額度 | | 12 | 13 | ## Protips: 14 | 15 | ### 随時整理会議記録 16 | 17 | 1. 任何輸入框内,使用 Win+H 來調出語音輸入,然後說出你想要的文字,不用在意語音輸入的準確度,只要說出大概的意思就可以了, 18 | 2. 然後全選按下 `CLX+b`,輸入 `列出要点和待辦事項`,就可以看到 AI 自動幫你整理出來的要點和待辦事項。 19 | 20 | ### 随時翻訳任何語言到任何語言 21 | 22 | 1. 任何輸入框内,选中你想要翻譯的文字 23 | 2. 然後全選按下 `CLX+b`,`to chinese:` AI 自動幫你輸入成中文。 24 | -------------------------------------------------------------------------------- /Modules/CLX-Edit.md: -------------------------------------------------------------------------------- 1 | # 编辑增强插件( TG YUIO HJKL ) 🌟 2 | 3 | 这个世界上还有比 Vim 模式的 HJKL 移动光标更棒的东西吗? 4 | 这个必须有! 5 | 那就是带加速度的 HJKL 流畅编辑体验!想不想试试让你的光标来一次排水沟过弯的高端操作?装它! 6 | 7 | ![EditorCursorMovement.gif](./EditorCursorMovement.gif) 8 | 9 | | 作用域 | Edit 模块 | 说明 | 10 | | ---------- | --------------------- | -------------------------------- | 11 | | 全局(基本) | `CapsLockX + h j k l` | 上下左右 方向键 | 12 | | 全局(基本) | `CapsLockX + y o` | Home End | 13 | | 全局(基本) | `CapsLockX + u i` | PageUp PageDown | 14 | | 全局(基本) | `CapsLockX + [ ]` | Shift+Tab 和 Tab | 15 | | 全局(基本) | `CapsLockX + g` | 回车 | 16 | | 全局(进阶) | `CapsLockX + t` | Delete | 17 | | 全局(进阶) | `CapsLockX + hl` | hl 一起按选择当前词 | 18 | | 全局(进阶) | `CapsLockX + kj` | kj 一起按选择当前行 | 19 | | 全局(进阶) | `CapsLockX + h + t` | 移位后删:大部分情况可代替退格键 | 20 | -------------------------------------------------------------------------------- /Modules/CLX-Elevate.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 名称:CapsLockX 管理员权限询问 3 | ; 描述:用于询问是否使用管理员权限启动 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 支持:https://github.com/snomiao/CapsLockX 7 | ; 编码:UTF-8 with BOM 8 | ; 版权:Copyright © 2017-2024 Snowstar Laboratory. All Rights Reserved. 9 | ; LICENCE: GNU GPLv3 10 | ; ========== CapsLockX ========== 11 | 12 | global T_AskRunAsAdmin := CLX_Config("Core", "T_AskRunAsAdmin", 0, "请求管理员权限(权限受限时,权限受限,例如鼠标模拟等功能无法正常运行,默认请求提升权限,如果不需要管理权限下的功能,可以改为0)") 13 | 14 | Func("AskRunAsAdminIfNeeded").Call() 15 | 16 | return 17 | 18 | AskRunAsAdminIfNeeded() { 19 | global T_AskRunAsAdmin 20 | if (T_AskRunAsAdmin) { 21 | AskRunAsAdmin() 22 | } 23 | } 24 | ; 管理员模式运行 25 | AskRunAsAdmin() 26 | { 27 | full_command_line := DllCall("GetCommandLine", "str") 28 | if (!A_IsAdmin And !RegExMatch(full_command_line, " /restart(?!\S)")) { 29 | TrayTip, CapsLockX 权限受限, 当前权限受限,例如鼠标模拟等功能无法正常运行,正在请求提升权限。 30 | try { 31 | if (A_IsCompiled) { 32 | Run *RunAs "%A_ScriptFullPath%" /restart, "%A_WorkingDir%" 33 | } else { 34 | Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%", "%A_WorkingDir%" 35 | } 36 | } 37 | ; ExitApp 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Modules/CLX-EnterWithoutBreak.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 注:Save as UTF-8 with BOM please 3 | ; 名称:不折行回车 4 | ; 描述:不折行回车 5 | ; 作者:snomiao 6 | ; 支持:https://github.com/snolab/CapsLockX/issues/32 7 | ; ========== CapsLockX ========== 8 | 9 | return 10 | 11 | #if CapsLockXMode 12 | 13 | ; refs: 14 | ; https://github.com/snolab/CapsLockX/issues/32 15 | ; [[建议]增加backspace删除整行 · Issue #33 · snolab/CapsLockX]( https://github.com/snolab/CapsLockX/issues/33 ) 16 | 17 | ; tested in vscode multiline mode 18 | Enter:: Send {End 2}{Enter} ; 行尾回车 19 | BackSpace:: Send {Home 2}{End}{Home 2}+{End 2}+{Right}{Delete} ; 删除整行 20 | -------------------------------------------------------------------------------- /Modules/CLX-LaptopKeyboardFix.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 描述:拯救笔记本 3 | ; 名称:提供常见缺键补全,例如缺失 Esc 键、右 Ctrl 键、左 Win 键、Pause键、PrtScn键等 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 支持:https://github.com/snomiao/CapsLockX 7 | ; 版本:v2020.06.27 8 | ; 版权:Copyright © 2017-2024 Snowstar Laboratory. All Rights Reserved. 9 | ; ========== CapsLockX ========== 10 | 11 | if !CapsLockX 12 | ExitApp 13 | global WinKeySimulate := CLX_Config("LKF", "WinKeySimulate", 1, t("右手 \][ 模拟Windows键和 Alt + Tab, 具体用法参见LaptopKeyboardFix 模块说明,默认启用")) 14 | global FLAG_SWAP_ESC_STROKE := false 15 | CLX_AppendHelp( CLX_LoadHelpFrom(CLX_THIS_MODULE_HELP_FILE_PATH)) 16 | 17 | Return 18 | ; 专治 Surface 的残破键盘,合并右Ctrl与Menu键! 19 | ; 单击 Menu 键为 Menu 键功能,按住 Menu 键再按别的键则表现为 Ctrl 组合键 20 | $*AppsKey:: Send {Blind}{RControl Down} 21 | $*AppsKey Up:: 22 | if ("AppsKey" == A_PriorKey) { 23 | Send {Blind}{RControl Up}{AppsKey} 24 | } else { 25 | Send {Blind}{RControl Up} 26 | } 27 | Return 28 | ~*RControl Up:: 29 | if ("RControl" == A_PriorKey) { 30 | Send {AppsKey} 31 | } 32 | Return 33 | 34 | ; Win+Alt+P 打开系统设定 (模拟 pause 键) 35 | $#!p:: 36 | Send #{Pause} 37 | Return 38 | 39 | ; 针对安卓对Windows的远程桌面 RD Client 40 | 41 | ; 对于没有 Win 键的环境,用 Ctrl + ESC 一起按来模拟 Win 键(不行,Win键和其它修饰键一起按打不开开始菜单。) 42 | 43 | #if WinKeySimulate && !CapsLockXMode 44 | 45 | ; Windows 键模拟于 ] + [ 46 | ] & [:: LWin 47 | *+]:: Send {Blind}] 48 | *!]:: Send {Blind}] 49 | *^]:: Send {Blind}] 50 | ]:: Send {Blind}] 51 | ; ] Up:: Send {Blind}] 52 | 53 | ; TODO: known issue: press [ , then press ] , then release [ then release ], will emit only [, expected emit []. 54 | 55 | ; Alt+Tab 模拟 56 | ; RAlt & \:: Send {Blind}{Tab} 57 | 58 | ; 对于没有Esc或没有 Stroke 键的键 59 | #if CapsLockXMode & CM_FN 60 | 61 | `:: FLAG_SWAP_ESC_STROKE := CLX_ConfigSet("CLX_LKF", "FLAG_SWAP_ESC_STROKE", !FLAG_SWAP_ESC_STROKE, "交换ESC和~键,你可以按CLX+Esc来切换这个选项") 62 | Esc:: FLAG_SWAP_ESC_STROKE := CLX_ConfigSet("CLX_LKF", "FLAG_SWAP_ESC_STROKE", !FLAG_SWAP_ESC_STROKE, "交换ESC和~键,你可以按CLX+Esc来切换这个选项") 63 | 64 | #if (FLAG_SWAP_ESC_STROKE && !CapsLockXMode) || (!FLAG_SWAP_ESC_STROKE && CapsLockXMode) 65 | 66 | *`:: Esc 67 | <^`:: LWin 68 | *Esc:: ` 69 | 70 | #if (!FLAG_SWAP_ESC_STROKE && !CapsLockXMode) || (!!FLAG_SWAP_ESC_STROKE && CapsLockXMode) 71 | 72 | ; <^Esc:: LWin 73 | -------------------------------------------------------------------------------- /Modules/CLX-LaptopKeyboardFix.md: -------------------------------------------------------------------------------- 1 | # Surface 笔记本扩充功能键 2 | 3 | 专治各种笔记本残破键盘 4 | 5 | 1. 没有右 Ctrl 键?合并 Menu 与 右 Ctrl 键,Menu 当 Ctrl 用 或者 Ctrl 当 Menu 用都可以 6 | 2. 没有 Pause 键?Win + Alt + P 也能打开系统设定信息。 7 | 3. 待补充 8 | 9 | | 模式 | 按键 | 功能 | 10 | | ---------------- | :------------------------------------ | ---------------------------------- | 11 | | 全局 | Win + Alt + P | 相当于 Win + Pause,专为笔记本定制 | 12 | | 全局 | 右 Ctrl 按一下 | 会按一下 Menu 弹出菜单 | 13 | | 全局 | 按住右 Menu | 会按住 Ctrl,此时可以与其它键组合 | 14 | | Win 键模拟启用后 | ] 按住同时,[ 按下 | 相当于按 Win 键 | 15 | | Win 键模拟启用后 | RAlt+\| 相当于按 Alt+Tab 只不过在右手 | 16 | -------------------------------------------------------------------------------- /Modules/CLX-MediaKeys.ahk: -------------------------------------------------------------------------------- 1 | if (!CapsLockX) { 2 | MsgBox, % "本模块只在 CapsLockX 下工作 / This module is only for CapsLockX" 3 | ExitApp 4 | } 5 | CLX_AppendHelp( CLX_LoadHelpFrom(CLX_THIS_MODULE_HELP_FILE_PATH)) 6 | Return 7 | 8 | #if !!(CapsLockXMode & CM_FN) || !!(CapsLockXMode & CM_CapsLockX) 9 | 10 | F1:: Launch_App1 ; 打开我的电脑 11 | F2:: Launch_App2 ; 计算器 12 | F3:: Browser_Home ; 主页 13 | F4:: Launch_Media ; 启动播放器 14 | 15 | F5:: Send {Media_Play_Pause} ; 暂停 16 | F6:: Send {Media_Prev} ; 上一首 17 | F7:: Send {Media_Next} ; 下一首 18 | F8:: Send {Media_Stop} ; 停止 19 | 20 | F9:: Send {Volume_Up} ; 音量- 21 | F10:: Send {Volume_Down} ; 音量+ 22 | F11:: Send {Volume_Mute} ; 音量0 23 | F12:: Send {Launch_App2} ; 启动计算器 24 | 25 | ; 关掉屏幕显示 26 | Pause:: SendMessage, 0x112, 0xF170, 2, , Program Manager -------------------------------------------------------------------------------- /Modules/CLX-MediaKeys.md: -------------------------------------------------------------------------------- 1 | # 媒体键模块 2 | 3 | | 作用于 | 媒体键模块 | 说明 | 4 | | ------ | ----------------- | ------------------------------------------- | 5 | | 全局 | `CapsLockX + F1` | 打开:我的电脑 | 6 | | 全局 | `CapsLockX + F2` | 打开:计算器 | 7 | | 全局 | `CapsLockX + F3` | 打开:浏览器主页 | 8 | | 全局 | `CapsLockX + F4` | 打开:媒体库(默认是 Windows Media Player) | 9 | | 全局 | `CapsLockX + F5` | 播放:暂停/播放 | 10 | | 全局 | `CapsLockX + F6` | 播放:上一首 | 11 | | 全局 | `CapsLockX + F7` | 播放:下一首 | 12 | | 全局 | `CapsLockX + F8` | 播放:停止 | 13 | | 全局 | `CapsLockX + F9` | 音量加 | 14 | | 全局 | `CapsLockX + F10` | 音量减 | 15 | | 全局 | `CapsLockX + F11` | 静音 | 16 | -------------------------------------------------------------------------------- /Modules/CLX-Mouse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/CLX-Mouse.gif -------------------------------------------------------------------------------- /Modules/CLX-Mouse.md: -------------------------------------------------------------------------------- 1 | # 模拟鼠标插件( WASD QERF ) 2 | 3 | > 一直以来,我总是以键盘控自居,应该是在从前做模型的时候伤到了手指关节开始,成为键盘重度用户的。各种键盘加速工具,主动去记住各种快捷键,力求少用鼠标,甚至去学习了 vim 和 emacs。但是,很多时候,鼠标是无可替代的,尤其是在图形界面大行其道时候。 4 | 5 | —— 以上是来自 [SimClick 模拟点击](https://github.com/rywiki/simclick) 作者的一段话,这是一款以网格细分方式模拟鼠标的作品,可以与本项目互补 6 | 7 | —— 由 [秦金伟](http://rsytes.coding-pages.com/) 推荐 8 | 9 | ## 功能 10 | 11 | - 本模块使用按键区:CapsLockX + QWER ASDF 12 | - 非常舒适地使用 WASD QE RF 来模拟【完整的】鼠标功能,相信我,试过这种手感之后,你会喜欢上它的。 13 | - 指针移动时会自动黏附各种按钮、超链接。滚轮的指数级增长的加速度滚动机制使你再也不惧怕超级长的文章和网页。 14 | - 效果如图: 15 | ![CLX-Mouse.gif](./CLX-Mouse.gif) 16 | 17 | ## 使用方法如下 18 | 19 | | 作用于 | 按键 | 说明 | 20 | | ------ | ------------------------------------- | ---------------------------------------- | 21 | | 全局 | `CapsLockX + w a s d` | 鼠标移动(上下左右) | 22 | | 全局 | `CapsLockX + ad` | 将 HJKL 键切换到滚轮模式(上下左右滚动) | 23 | | 全局 | `CapsLockX + r f` | 垂直滚轮(上下) | 24 | | 全局 | `CapsLockX + Shift + r f` | 水平滚轮(左右) | 25 | | 全局 | `CapsLockX + Ctrl + Alt + r f` | 垂直滚轮自动滚动(上 下) | 26 | | 全局 | `CapsLockX + Ctrl + Alt + Shift+ r f` | 水平滚轮自动滚动(左 右) | 27 | | 全局 | `CapsLockX + rf` | rf 同时按相当于鼠标中键 | 28 | | 全局 | `CapsLockX + e` | 鼠标左键 | 29 | | 全局 | `CapsLockX + q` | 鼠标右键 | 30 | 31 | ## 操作细节 32 | 33 | 快速连按 AD 步进 34 | -------------------------------------------------------------------------------- /Modules/CLX-NodeEval.md: -------------------------------------------------------------------------------- 1 | # JavaScript 计算 (建议安装 NodeJS ) 2 | 3 | | 作用于 | 按键 | 效果 | 4 | | ------ | --------------- | -------------------------------------- | 5 | | 全局 | `CapsLockX + -` | 计算当前选区 JavaScript 表达式,并替换 | 6 | | 全局 | `CapsLockX + =` | 计算当前选区 JavaScript 表达式,并替换 | 7 | -------------------------------------------------------------------------------- /Modules/CLX-Pause.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; Note:Save as UTF-8 with BOM please 3 | ; 名称:CapsLockX 暂停键与自动暂停功能 4 | ; 作者:snomiao (snomiao@gmail.com) 5 | ; 支持:https://github.com/snomiao/CapsLockX 6 | ; 版本:v2021.01.20 7 | ; 版权:Copyright © 2017-2024 Snowstar Laboratory. All Rights Reserved. 8 | ; LICENCE: GNU GPLv3 9 | ; ========== CapsLockX ========== 10 | 11 | ; TODO: 显示器状态检测 12 | 13 | ; return 14 | ; ; 思路1 检测POWERBROADCAST消息 -- fail 15 | ; OnMessage(0x218, "WM_POWERBROADCAST") 16 | ; This checks for the message 0x218 which is a message sent by windows 17 | ; on some power conditions (shutdown, resume, wake and so on) 18 | ; and if the message has been sent then it will execute the function that 19 | ; we set up below. 20 | return 21 | 22 | ; WM_POWERBROADCAST(wParam, lParam){ 23 | ; ; wParam will contain a code depending on the power state 24 | ; ; PBT_APMRESUMESTANDBY (6) 25 | ; ; PBT_APMRESUMESUSPEND (7) 26 | ; ; PBT_APMRESUMEAUTOMATIC (18) etc. 27 | ; ; there are plenty more 28 | 29 | ; msgbox % wParam 30 | ; if (wParam = 6 || wParam = 7 || wParam = 18){ 31 | ; ; we can execute some cool code here 32 | ; } 33 | ; } 34 | 35 | ; OnMessage(0x218, "OnMessage_WM_POWERBROADCAST") 36 | ; OnMessage_WM_POWERBROADCAST(wParam, lParam){ 37 | ; MsgBox, %wParam% 38 | ; If (wParam == 0) 39 | ; Return 0x424D5144 40 | ; Return 0 41 | ; } 42 | 43 | ; ; 思路2 注册电源通知事件 [How to detect monitor off OR laptop lid closed - Ask for Help - AutoHotkey Community](https://autohotkey.com/board/topic/16982-how-to-detect-monitor-off-or-laptop-lid-closed/) 44 | ; Gui, lid-detector:New [, Options, Title] 45 | ; DllCall("RegisterPowerSettingNotification", "UInt", WinExist("lid-detector"), "str", "GUID_MONITOR_POWER_ON") 46 | ; MsgBox %Errorlevel% 47 | 48 | ; 思路3 检查设备文件 49 | ; [How to detect the power state of LCD display? - Ask for Help - AutoHotkey Community](https://autohotkey.com/board/topic/54195-how-to-detect-the-power-state-of-lcd-display/) 50 | 51 | ; test3(){ 52 | ; SendMessage, 0x112, 0xF170, 2, , Program Manager 53 | 54 | ; Sleep 2000 55 | ; hDisp := DllCall("CreateFile", "Str", "\\.\LCD", "Uint", 0xC0000000, "Uint", 0x3, "Uint", 0, "Uint", 0x3, "Uint", 0, "Uint", 0) 56 | ; DllCall("GetDevicePowerState", "UInt", hDisp, "IntP", stat) 57 | ; DllCall("CloseHandle", "Uint", hDisp) 58 | ; MsgBox % stat 59 | 60 | ; Send {Esc} 61 | ; Sleep 2000 62 | 63 | ; hDisp := DllCall("CreateFile", "Str", "\\.\LCD", "Uint", 0xC0000000, "Uint", 0x3, "Uint", 0, "Uint", 0x3, "Uint", 0, "Uint", 0) 64 | ; DllCall("GetDevicePowerState", "UInt", hDisp, "IntP", stat) 65 | ; DllCall("CloseHandle", "Uint", hDisp) 66 | ; MsgBox % stat 67 | 68 | ; } 69 | ; test4(){ 70 | ; hDisp := DllCall("CreateFile", "Str", "\\.\LCD", "Uint", 0xC0000000, "Uint", 0x3, "Uint", 0, "Uint", 0x3, "Uint", 0, "Uint", 0) 71 | ; DllCall("GetDevicePowerState", "UInt", hDisp, "IntP", stat) 72 | ; DllCall("CloseHandle", "Uint", hDisp) 73 | ; MsgBox % stat 74 | ; } 75 | #if 76 | 77 | ^!Home:: 78 | CLX_Paused := 0 79 | if(CLX_Paused) { 80 | TrayTip, % t("暂停"), % t("CapsLockX 已暂停") 81 | } else { 82 | TrayTip, % t("暂停"), % t("CapsLockX 已恢复") 83 | } 84 | Return 85 | 86 | ^!End:: 87 | CLX_Paused := 1 88 | if(CLX_Paused) { 89 | TrayTip, % t("暂停"), % t("CapsLockX 已暂停") 90 | } else { 91 | TrayTip, % t("暂停"), % t("CapsLockX 已恢复") 92 | } 93 | Return 94 | -------------------------------------------------------------------------------- /Modules/CLX-Reload.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; Note:Save as UTF-8 with BOM please 3 | ; 名称:CapsLockX 重启键 4 | ; 作者:snomiao (snomiao@gmail.com) 5 | ; 支持:https://github.com/snomiao/CapsLockX 6 | ; 版本:v2021.01.20 7 | ; 版权:Copyright © 2017-2024 Snowstar Laboratory. All Rights Reserved. 8 | ; LICENCE: GNU GPLv3 9 | ; ========== CapsLockX ========== 10 | ; tooltip loaded 11 | ; WatchFolder(A_WorkingDir "\User\", "CLX_FolderModified", true, 0x08) 12 | WatchFolder(A_WorkingDir "\Modules\", "CLX_FolderModified", true, 0x08) ; chagned 13 | WatchFolder(CLX_ConfigDir, "CLX_FolderChanged", true, 0x02 | 0x03 | 0x08) ; delete or add, iguess 14 | ; WatchFolder(A_WorkingDir "\Modules\", "CLX_FolderChanged", true, 0x02 | 0x03) ; delete or add 15 | TrayTip % t("CapsLockX 载入成功") 16 | #include Modules/WatchFolder/WatchFolder.ahk 17 | global Reload_DeveloperAsYouInstallMeByGitClone := FileExist(A_WorkingDir "/.git") 18 | return 19 | 20 | CLX_JustConfigured() 21 | { 22 | ; 跳过 CapsLockX 自己改的配置,容差 2-5 秒 23 | global CLX_ConfigChangedTickCount 24 | return CLX_ConfigChangedTickCount && A_TickCount - CLX_ConfigChangedTickCount < 5000 25 | } 26 | 27 | ; 只 reload 不重新编译模块 28 | CLX_FolderModified(Folder, Changes) { 29 | if ( CLX_JustConfigured() ) { 30 | return 31 | } 32 | ; don reload 33 | if (CLX_DontReload) { 34 | return 35 | } 36 | ; 只在 git clone 安装方式下询问配置重载 37 | if (!Reload_DeveloperAsYouInstallMeByGitClone) { 38 | return 39 | } 40 | ; MsgBox, 4, % t("CapsLockX 重载模块"), % t("检测到配置更改,是否软重载?") 41 | ; IfMsgBox Yes 42 | 43 | ; MsgBox, 4, CapsLockX 重载模块, 检测到配置更改,是否软重载? 44 | ; IfMsgBox Yes 45 | TrayTip, % t("CapsLockX 重载模块"), % t("检测到配置更改,正在自动软重载。") 46 | ; sleep 200 47 | reload 48 | } 49 | CLX_FolderChanged(Folder, Changes) 50 | { 51 | if ( CLX_JustConfigured() ) { 52 | return 53 | } 54 | ; don reload 55 | if (CLX_DontReload) { 56 | return 57 | } 58 | 59 | global T_AutoReloadOnConfigsChange := CLX_Config("Advanced", "T_AutoReloadOnConfigsChange", 0, "用户配置修改保存时自动重载") 60 | 61 | if (T_AutoReloadOnConfigsChange) { 62 | TrayTip, % t("CapsLockX 重载模块"), % t("检测到配置更改,正在自动重载。") 63 | sleep 200 64 | ; CLX_Reload() 65 | reload 66 | } else { 67 | ; 只在 git clone 安装方式下询问重载 68 | if (!Reload_DeveloperAsYouInstallMeByGitClone) { 69 | return 70 | } 71 | MsgBox, 4, % t("CapsLockX 重载模块"), % t("检测到配置更改,是否重载?") 72 | IfMsgBox Yes 73 | Reload 74 | ; CLX_Reload() 75 | } 76 | } 77 | 78 | #if CapsLockXMode 79 | 80 | .:: Reload ; CLX_模块重载 81 | +.:: CLX_Reload() ; CLX_重新启动 82 | ^+.:: ExitApp ; CLX_退出 83 | -------------------------------------------------------------------------------- /Modules/CLX-RunOnLogin.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 名称:CLX开机运行 3 | ; 描述:用于把clx添加到用户startup文件夹。 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 支持:https://github.com/snomiao/CapsLockX 7 | ; 版本:v0.0.1 8 | ; ========== CapsLockX ========== 9 | 10 | return 11 | 12 | CLX_MakeStartup() 13 | { 14 | content = cd "%A_WorkingDir%" && start "" CapsLockX.exe 15 | startCMDPath := APPDATA "\Microsoft\Windows\Start Menu\Programs\Startup\capslockx-startup.cmd" 16 | FileDelete, %startCMDPath% 17 | FileAppend, echo off`r`n, %startCMDPath% 18 | FileAppend, %content%, %startCMDPath% 19 | cmdView := "explorer /select, " """" startCMDPath """" 20 | run % cmdView 21 | TrayTip % t("已在Startup文件夹添加CLX的开机自启动,请确认。") 22 | } -------------------------------------------------------------------------------- /Modules/CLX-Userscripts.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 名称:快速窗口热键编辑 3 | ; 描述:快速窗口热键编辑 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 支持:https://github.com/snomiao/CapsLockX 7 | ; 版本:v2021.03.18 8 | ; 注释: 9 | ; ========== CapsLockX ========== 10 | 11 | if (!CapsLockX) { 12 | MsgBox, % "本模块只为 CapsLockX 工作" 13 | ExitApp 14 | } 15 | ; Func("CLX_AppendHelp").Call(Func("CLX_LoadHelpFrom").Call(CLX_THIS_MODULE_HELP_FILE_PATH)) 16 | 17 | global 快速窗口热键编辑用户模块目录 := CLX_ConfigDir . "\" 18 | global 快速窗口热键编辑初始内容 := " 19 | ( 20 | ; ========== CapsLockX ========== 21 | ; 名称:用户模块 22 | ; 描述:快速窗口热键编辑 23 | ; 作者:你自己 24 | ; 联系:你的邮箱 或 QQ 25 | ; 版本:0.0.1 26 | ; ========== CapsLockX ========== 27 | 28 | ; 1. 本用户模块文件由 CapsLockX 初始生成,扩展名为 .user.ahk ,不会被版本更新覆盖。 29 | ; 2. 使用 `CapsLockX + M` 键创建窗口热键,并快速编辑本文件(默认打开方式是记事本,你可以按自己个人情况酌情安装 Notepad3 ) 30 | ; 3. 编辑完成时,使用 Ctrl+Alt+\ 键重载 CapsLockX 即可生效。 31 | ; 4. 需要注意的是本模块有语法错误会导致 CapsLockX 重载失败,请自行调试到成功。。。 32 | 33 | ; 这里可以写一些入口代码 34 | ; TrayTip CapsLockX, 用户宏已加载 35 | 36 | ; 这里写上 Return 防止加载的时候执行到下面的热键 37 | Return 38 | #if 39 | 40 | ; 这里可以写上你的自定义全局热键 41 | )" 42 | 43 | Return 44 | 45 | #if CapsLockXMode 46 | 47 | UserModuleEdit(dir, filename := "") 48 | { 49 | global CLX_DontReload 50 | CLX_DontReload := 1 51 | 52 | WinGet, hWnd, ID, A 53 | WinGetClass, 窗口类名, ahk_id %hWnd% 54 | WinGet, 进程名, ProcessName, ahk_id %hWnd% 55 | 56 | filename := filename || "/应用-" 进程名 ".user.ahk" 57 | path := dir . "/" . filename 58 | 59 | WinGetTitle, title, ahk_id %hWnd% 60 | match = %title% ahk_class %窗口类名% ahk_exe %进程名% 61 | 62 | MsgBox, % t("开始编辑用户脚本:") . path 63 | if (!FileExist(path)) { 64 | FileAppend, %快速窗口热键编辑初始内容%, %path% 65 | } 66 | 填充内容 := "`n" "`n" "; #if WinActive(""" match """)" "`n" "`n" "; !d`:`: TrayTip, CapsLockX, 在当前窗口按下了Alt+d" "`n" 67 | FileAppend, %填充内容%, %path% 68 | 69 | CLX_DontReload := 0 70 | 71 | ; clipboard := 填充内容 72 | Run code.cmd "%path%" || notepad "%path%" 73 | ; WinWaitActive Notepad, , 3 74 | ; if(ErrorLevel){ 75 | ; return aw 76 | ; } 77 | ; Sleep 2000 78 | ; SendEvent ^{End}^v 79 | } 80 | 81 | ; 自定义脚本创建 82 | !,:: UserModuleEdit(快速窗口热键编辑用户模块目录, "CLX_用户脚本.user.ahk") 83 | +!,:: UserModuleEdit(快速窗口热键编辑用户模块目录, "使用进程名AHK") 84 | 85 | -------------------------------------------------------------------------------- /Modules/CLX-WindowManager.md: -------------------------------------------------------------------------------- 1 | # 窗口增强插件 (CLX + 1234567890 ZXCV) 2 | 3 | ## 功能简述 4 | 5 | 用好 Win 10 自带的 10 个虚拟桌面豪华配置、多显示器自动排列窗口、半透明置顶、(注:任务栏和 AltTab 相关功能暂不兼容 Win11,窗口排列功能正常。) 6 | 7 | 1. 窗口切换:`CapsLockX + [Shift] + Z` 8 | 2. 窗口关闭:`CapsLockX + [Shift] + X` 9 | 3. 窗口排列:`CapsLockX + [Shift] + C` 10 | 4. 窗口置顶:`CapsLockX + [Shift] + V` 11 | 5. 左手窗口管理:在 `Alt + Tab` 的界面,用 `WASD` 切换窗口,`X` 关掉窗口。 12 | 6. 高效使用虚拟桌面:`CapsLockX + 0123456789` 切换、增减虚拟桌面,加上 `Shift` 键可以转移当前窗口 13 | 7. 虚拟机与远程桌面快速脱离:双击左边 `Shift + Ctrl + Alt`。 14 | 15 | ## 效果图 16 | 17 | - Alt + Tab 管理窗口增强 18 | ![02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif](./02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif) 19 | - CapsLockX + C 一键排列窗口(这 GIF 是旧版本录的看起来比较卡,新版本优化过 API 就不卡了) 20 | ![02-插件-窗口增强_一键排列窗口.gif](./02-插件-窗口增强_一键排列窗口.gif) 21 | 22 | ## 使用方法如下 ( Alt+Tab 与 CapsLockX ) 23 | 24 | | 作用域 | 窗口增强模块 | 说明 | 25 | | ------------ | ------------------------------------- | ------------------------------------------ | 26 | | Alt+Tab 界面 | `Q E` | 左右切换多桌面 | 27 | | Alt+Tab 界面 | `W A S D` | 上下左右切换窗口选择 | 28 | | Alt+Tab 界面 | `X C` | 关闭选择的窗口(目前 X 和 C 没有区别) | 29 | | Win+Tab 视图 | `Alt + W A S D` | 切换窗口选择 | 30 | | 全局 | `Win + [Shift] + B` | 定位到托盘任务(windows 系統自帯熱鍵) | 31 | | 全局 | `Win + [Shift] + T` | 定位到任務栏任务(windows 系統自帯熱鍵) | 32 | | 全局 | `Win + Shift + hjkl` | 在窗口之间按方向切换焦点 | 33 | | 任务栏 | `Ctrl + W 或 Delete` | 在托盘图标或任务栏任务上,选择退出按钮 | 34 | | 全局 | `CapsLockX + 1 2 ... 9 0` | 切换到第 1 .. 12 个桌面 | 35 | | 全局 | `CapsLockX + Shift + 1 2 ... 9 0 - =` | 把当前窗口移到第 n 个桌面(如果有的话) | 36 | | 全局 | `CapsLockX + Alt + Backspace` | 删除当前桌面(会把所有窗口移到上一个桌面) | 37 | | 全局 | `CapsLockX + C` | 快速排列当前桌面的窗口 | 38 | | 全局 | `CapsLockX + Ctrl + C` | 快速排列当前桌面的窗口(包括最小化的窗口) | 39 | | 全局 | `CapsLockX + Shift + C` | 快速堆叠当前桌面的窗口 | 40 | | 全局 | `CapsLockX + Shift + Ctrl + C` | 快速堆叠当前桌面的窗口(包括最小化的窗口) | 41 | | 全局 | `CapsLockX + Z` | 循环切到最近使用的窗口 | 42 | | 全局 | `CapsLockX + Shift + Z` | 循环切到最不近使用的窗口 | 43 | | 全局 | `CapsLockX + X` | 关掉当前标签页 Ctrl+W | 44 | | 全局 | `CapsLockX + Shift + X` | 关掉当前窗口 Alt+F4 | 45 | | 全局 | `CapsLockX + V` | 让窗口透明 | 46 | | 全局 | `CapsLockX + Shift + V` | 让窗口保持透明(并置顶) | 47 | | 任意窗口 | `双击左边 Shift+Ctrl+Alt` | 后置当前窗口, \* 见下方注 | 48 | 49 | \*注: 双击左边 Shift+Ctrl+Alt 设计用于远程桌面与虚拟机,使其可与本机桌面窗口同时显示。 50 | 例如 mstsc.exe、TeamViewer、VirtualBox、HyperV、VMWare 等远程桌面或虚拟机程序,配合 CapsLockX + Shift + V 透明置顶功能,让你在 Windows 的界面上同时使用 Linux 界面或 MacOS 界面再也不是难题。 51 | 52 | 此处借用 [@yangbin9317 的评论](https://v2ex.com/t/772052#r_10458792) 53 | 54 | > 以 CapsLock 为抓手,打通底层逻辑,拉齐 Windows 和 Linux WM,解决了 Windows 难用的痛点 55 | 56 | (20220313) 对于两端都是 Windows 的情况,也可以考虑使用 [RemoteApp Tool - Kim Knight](http://www.kimknight.net/remoteapptool) 来代替远程桌面。 57 | -------------------------------------------------------------------------------- /Modules/EditorCursorMovement.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/EditorCursorMovement.gif -------------------------------------------------------------------------------- /Modules/EmojiSearchByPreferLanguage.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 描述:Search emoji by prefer language 3 | ; 作者:snomiao 4 | ; 联系:snomiao@gmail.com 5 | ; 支持:https://github.com/snomiao/CapsLockX 6 | ; 版本:v1.0.0 7 | ; 版权:Copyright © 2017-2024 Snowstar Laboratory. All Rights Reserved. 8 | ; ========== CapsLockX ========== 9 | 10 | Return 11 | #If 12 | 13 | ; ref: [(35 封私信 / 17 条消息) 输入法智能切换中英文,用autohotkey如何实现? - 知乎]( https://www.zhihu.com/question/41446565 ) 14 | SetInputLang(languageIdentifier) { 15 | WinExist("A") 16 | ControlGetFocus, CtrlInFocus 17 | SendMessage, 0x50, 0, % languageIdentifier, %CtrlInFocus% 18 | } 19 | 20 | ToggleToEnglish() 21 | { 22 | SetInputLang(0x0409) 23 | } 24 | 25 | emojiSearch() 26 | { 27 | ToggleToEnglish() 28 | SendEvent #. 29 | } 30 | #.:: emojiSearch() 31 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: ['https://www.paypal.me/MariusSucan/5'] 14 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/README.md: -------------------------------------------------------------------------------- 1 | # AHK GDI+ LIBRARY (extended compilation) 2 | 3 | This is a compilation of user contributed functions for the GDI+ library wrapper made by Tariq Porter [tic] that never made it into. 4 | 5 | This repository is a fork of https://github.com/mmikeww/AHKv2-Gdip/ . 6 | 7 | The compilation comes into two flavours: AHK v1.1 and AHK v2 compatible editions. 8 | 9 | The Gdip_all.ahk file for AHK v1.1 should be compatible with projects already relying on the original edition. In other words, it is backwards compatible. If you find this is not the case, please report the issue[s]. 10 | 11 | The original examples From TIC are in «examples-ahk-v1-1» folder. You can find several new examples that showcase the newly supported GDI+ APIs. These are example scripts initially provided by those that coded the new functions, with minor modifications. 12 | 13 | The examples for the AHK v2 edition I provide here in the repository were tested with AHK v2 alpha 108. In future versions of AHK v2, things might break. The library was not entirely tested on AHK v2. Therefore, bugs are likely present. Please provide feedback and/or pull requests to fix bugs. 14 | 15 | # History 16 | - @tic created the original [Gdip.ahk](https://github.com/tariqporter/Gdip/) library 17 | - @Rseding91 updated it to make it compatible with unicode and x64 AHK versions and renamed the file `Gdip_All.ahk` 18 | - @mmikeww's repository updates @Rseding91's `Gdip_All.ahk` to make it compatible with AHK v2 and also fixes some bugs 19 | - this repository attempts to gather all the GDI+ functions contributed by various people that were missing, and further extend the coverage/support of GDI+ API functions 20 | - MCL created an object-based GDI+ wrapper for AHK v1.1 that covers even more GDI+ functions; repository available at: https://github.com/mcl-on-github/oGdip.ahk 21 | 22 | # FUNCTIONS LIST 23 | 24 | - 42 GraphicsPath object functions 25 | - 43 Pen object functions 26 | - 29 PathGradient brush functions 27 | - 21 LinearGradient brush functions 28 | - 11 Texture brush functions 29 | - 10 SolidFill and hatch brush functions 30 | - 61 pBitmap functions 31 | - 16 ImageAttributes and Effects functions 32 | - 46 Fonts and StringFormat functions 33 | - 44 pGraphics functions 34 | - 24 Region functions 35 | - 11 Clip functions 36 | - 17 Transformation Matrix functions 37 | - 41 Draw/Fill on pGraphics functions 38 | - 14 GDI functions [selection]; the repository includes a GDI specialized library wrapper for AHK v1.1 that covers over 100 GDI functions 39 | - 23 Other functions [selection] 40 | 41 | Please see functions-list.txt for the actual list of functions. 42 | 43 | # COMPARISIONS 44 | 45 | The following list is comparing Gdip_All.ahk by Tariq Porter and Rseding91 modifications with this new version. 46 | 47 | ## ~24 MODIFIED FUNCTIONS 48 | 49 | ## ~300 NEW FUNCTIONS 50 | 51 | See functions-list.txt for more details and credits. 52 | 53 | ## NOTES: 54 | - GetProperty() functions can yield incorrect results for some meta-data/properties. 55 | - awaiting pull requests for bug fixes 56 | 57 | ## Derniere mise à jour: mardi 22 août 2023 [ 22/06/2023 ], v1.96 58 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.1-Draw.Shapes.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 1 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to draw a single ellipse and rectangle to the screen 5 | 6 | #SingleInstance Force 7 | #NoEnv 8 | SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 22 | Width :=1400, Height := 1050 23 | 24 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 25 | Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 26 | Gui, 1: Show, NA 27 | 28 | ; Get a handle to this window we have created in order to update it later 29 | hwnd1 := WinExist() 30 | 31 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 32 | hbm := CreateDIBSection(Width, Height) 33 | 34 | ; Get a device context compatible with the screen 35 | hdc := CreateCompatibleDC() 36 | 37 | ; Select the bitmap into the device context 38 | obm := SelectObject(hdc, hbm) 39 | 40 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 41 | G := Gdip_GraphicsFromHDC(hdc) 42 | 43 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 44 | Gdip_SetSmoothingMode(G, 4) 45 | 46 | ; Create a fully opaque red brush (ARGB = Transparency, red, green, blue) to draw a circle 47 | pBrush := Gdip_BrushCreateSolid(0xffff0000) 48 | 49 | ; Fill the graphics of the bitmap with an ellipse using the brush created 50 | ; Filling from coordinates (100,50) an ellipse of 200x300 51 | Gdip_FillEllipse(G, pBrush, 100, 500, 200, 300) 52 | 53 | ; Delete the brush as it is no longer needed and wastes memory 54 | Gdip_DeleteBrush(pBrush) 55 | 56 | ; Create a slightly transparent (66) blue brush (ARGB = Transparency, red, green, blue) to draw a rectangle 57 | pBrush := Gdip_BrushCreateSolid(0x660000ff) 58 | 59 | ; Fill the graphics of the bitmap with a rectangle using the brush created 60 | ; Filling from coordinates (250,80) a rectangle of 300x200 61 | Gdip_FillRectangle(G, pBrush, 250, 80, 300, 200) 62 | 63 | ; Delete the brush as it is no longer needed and wastes memory 64 | Gdip_DeleteBrush(pBrush) 65 | 66 | 67 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 68 | ; So this will position our gui at (0,0) with the Width and Height specified earlier 69 | UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) 70 | 71 | 72 | ; Select the object back into the hdc 73 | SelectObject(hdc, obm) 74 | 75 | ; Now the bitmap may be deleted 76 | DeleteObject(hbm) 77 | 78 | ; Also the device context related to the bitmap may be deleted 79 | DeleteDC(hdc) 80 | 81 | ; The graphics may now be deleted 82 | Gdip_DeleteGraphics(G) 83 | Return 84 | 85 | ;####################################################################### 86 | 87 | ExitFunc(ExitReason, ExitCode) { 88 | global 89 | ; gdi+ may now be shutdown on exiting the program 90 | Gdip_Shutdown(pToken) 91 | } 92 | 93 | ~Esc:: 94 | ExitApp 95 | Return 96 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.12-Pixelate.a.bitmap.using.machine.code.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 12 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to pixelate a bitmap using machine code 5 | 6 | #SingleInstance Force 7 | #NoEnv 8 | SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Create a layered window that is always on top as usual and get a handle to the window 22 | Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop 23 | Gui, 1: Show, NA 24 | hwnd1 := WinExist() 25 | 26 | ; Get a bitmap from the image 27 | If FileExist("MJ.jpg") 28 | pBitmap := Gdip_CreateBitmapFromFile("MJ.jpg") 29 | ;pBitmap := Gdip_BitmapFromScreen() 30 | If !pBitmap 31 | { 32 | MsgBox "Could not load the image 'MJ.jpg' " 33 | ExitApp 34 | } 35 | ; Get the width and height of the bitmap we have just created from the file 36 | Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap) 37 | 38 | ; We also need to create 39 | pBitmapOut := Gdip_CreateBitmap(Width, Height) 40 | 41 | ; As normal create a gdi bitmap and get the graphics for it to draw into 42 | hbm := CreateDIBSection(Width, Height), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm) 43 | G := Gdip_GraphicsFromHDC(hdc) 44 | 45 | ; Call WM_LBUTTONDOWN every time the gui is clicked, to allow it to be dragged 46 | OnMessage(0x201, "WM_LBUTTONDOWN") 47 | 48 | ; Update the window with the hdc so that it has a position and dimension for future calls to not 49 | ; have to explicitly pass them 50 | UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height) 51 | 52 | ; Set a timer to update the gui with our pixelated bitmap 53 | SetTimer, Update, 50 54 | return 55 | 56 | ;####################################################################### 57 | 58 | Update: 59 | ; Some simple checks to see if we are increasing or decreasing the pixelation 60 | ; v is the block size of the pixelation and dir is the direction (inc/decreasing) 61 | if (v <= 1) 62 | v := 1, dir := !dir 63 | else if (v >= 30) 64 | v := 30, dir := !dir 65 | 66 | ; Call Gdip_PixelateBitmap with the bitmap we retrieved earlier and the block size of the pixels 67 | ; The function returns the pixelated bitmap, and doesn't dispose of the original bitmap 68 | Gdip_PixelateBitmap(pBitmap, pBitmapOut, dir ? ++v : --v) 69 | 70 | ; We can optionally clear the graphics we will be drawing to, but if we know there will be no transparencies then 71 | ; it doesn't matter 72 | ;Gdip_GraphicsClear(G) 73 | 74 | ; We then draw our pixelated bitmap into our graphics and dispose of the pixelated bitmap 75 | Gdip_DrawImage(G, pBitmapOut, 0, 0, Width, Height, 0, 0, Width, Height) 76 | 77 | ; We can now update our window, and don't need to provide a position or dimensions as we don't want them to change 78 | UpdateLayeredWindow(hwnd1, hdc) 79 | return 80 | 81 | ;####################################################################### 82 | 83 | ; This is called on left click to allow to drag 84 | WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) 85 | { 86 | PostMessage 0xA1, 2 87 | } 88 | 89 | ;####################################################################### 90 | 91 | ; On exit, dispose of everything created 92 | Esc:: 93 | ExitApp 94 | return 95 | 96 | ExitFunc(ExitReason, ExitCode) 97 | { 98 | global 99 | Gdip_DisposeImage(pBitmapOut), Gdip_DisposeImage(pBitmap) 100 | SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc) 101 | Gdip_DeleteGraphics(G) 102 | Gdip_Shutdown(pToken) 103 | } 104 | 105 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.13-Learning-One-Graphics-Paths.ahk: -------------------------------------------------------------------------------- 1 | #Include ../Gdip_All.ahk 2 | 3 | ;=== Create Gui, OnMessage === 4 | Gui 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 5 | hGui := WinExist() 6 | Gui 1: Show, NA 7 | w := 550, h := 280 8 | OnMessage(0x201, "WM_LBUTTONDOWN") 9 | 10 | ;===GDI+ prepare === 11 | pToken := Gdip_Startup() 12 | hbm := CreateDIBSection(w, h), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm) 13 | G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4) 14 | 15 | ;=== Background === 16 | pBrush := Gdip_CreateLineBrushFromRect(0, 0, w, h, 0xff555555, 0xff050505) 17 | Gdip_FillRectangle(G, pBrush, 0, 0, w, h) 18 | Gdip_DeleteBrush(pBrush) 19 | 20 | pBrush := Gdip_BrushCreateHatch(0xff000000, 0x00000000, 8) 21 | Gdip_FillRectangle(G, pBrush, 0, 0, w, h) 22 | Gdip_DeleteBrush(pBrush) 23 | 24 | 25 | ;=== Create path (Bat) === 26 | pPath := Gdip_CreatePath() ; creates a Path (GraphicsPath object) 27 | 28 | Gdip_StartPathFigure(pPath) ; starts a new figure in this Path 29 | Gdip_AddPathLine(pPath, 110,95, 220,95) ; adds a line to the current figure of this path 30 | Gdip_AddPathBezier(pPath, 220,95, 228,112, 233,120, 262,120) ; adds bezier 31 | Gdip_AddPathLines(pPath, "262,120|265,95|269,110|280,110|284,95|287,120") ; adds lines 32 | Gdip_AddPathBezier(pPath, 287,120, 305,120, 320,120, 330,95) 33 | Gdip_AddPathLine(pPath, 330,95, 439,95) 34 | Gdip_AddPathBeziers(pPath, "439,95|406,108|381,126|389,159|322,157|287,170|275,206|262,170|227,157|160,159|168,126|144,109|110,95") ; adds beziers 35 | Gdip_ClosePathFigure(pPath) ; closes the current figure of this path 36 | 37 | 38 | ;=== Fill & draw path (Bat) === ; now when the path is finished, we can fill it with brushes and outline with pens 39 | ;pPen := Gdip_CreatePen(0x22ffffff, 14), Gdip_DrawPath(G, pPen, pPath), Gdip_DeletePen(pPen) ; uncomment to draw extra outline 40 | 41 | pBrush := Gdip_CreateLineBrushFromRect(0, 95, w, (h-190)/2, 0xff110000, 0xff664040) 42 | Gdip_FillPath(G, pBrush, pPath) ; fill Bat background 1 43 | Gdip_DeleteBrush(pBrush) 44 | 45 | pBrush := Gdip_BrushCreateHatch(0xff000000, 0x00000000, 21) 46 | Gdip_FillPath(G, pBrush, pPath) ; fill Bat background 2 47 | Gdip_DeleteBrush(pBrush) 48 | 49 | pPen := Gdip_CreatePen(0xffa5a5a5, 5) 50 | Gdip_DrawPath(G, pPen, pPath) ; draw Bat outline 1 51 | Gdip_DeletePen(pPen) 52 | 53 | pPen := Gdip_CreatePen(0xff000000, 1) 54 | Gdip_DrawPath(G, pPen, pPath) ; draw Bat outline 2 55 | Gdip_DeletePen(pPen) 56 | 57 | Gdip_DeletePath(pPath) ; delete the Path as it is no longer needed and wastes memory 58 | 59 | ;=== Update, Delete, Shutdown === 60 | UpdateLayeredWindow(hGui, hdc, (A_ScreenWidth-w)//2, (A_ScreenHeight-h)//2, w, h) 61 | SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc) 62 | Gdip_DeleteGraphics(G) 63 | Gdip_Shutdown(pToken) 64 | return 65 | 66 | Esc::ExitApp 67 | 68 | ;===Functions=========================================================================== 69 | 70 | WM_LBUTTONDOWN() { 71 | PostMessage, 0xA1, 2 72 | } 73 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.14-RazorHalo-Rotate-At-Center.ahk: -------------------------------------------------------------------------------- 1 | ;Tested on A_AhkVersion U64 1.1.27.06 - Windows 10 Home x64 1809 2 | #SingleInstance Force 3 | SetWorkingDir %A_ScriptDir% 4 | SetBatchLines -1 5 | 6 | ;Need to include your path to Gdip or have in the same directory as script 7 | #Include ../Gdip_All.ahk 8 | 9 | OnMessage(0x200, "OnWM_MOUSEMOVE") 10 | OnMessage(0x20A, "OnWM_MOUSEWHEEL") 11 | 12 | ;Create a GUI 13 | Gui Mapper: New, hWndhMap -DPIScale +OwnDialogs 14 | Gui Show, NA w600 h600, Mapper 15 | 16 | ;Create a Layered window ontop if the GUI to draw on with the GDI+ functions 17 | Gui 1: +E0x80000 +LastFound -Caption -DPIScale +ParentMapper 18 | hGui := WinExist() 19 | Gui 1: Show, NA 20 | w:= 600, h:= 600 21 | 22 | pToken := Gdip_Startup() 23 | hbm := CreateDIBSection(w, h), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm) 24 | G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4) 25 | 26 | ;Create a GraphicsPath 27 | pPath := Gdip_CreatePath() ; creates a Path (GraphicsPath object) 28 | 29 | ;Add figure to path 30 | Gdip_StartPathFigure(pPath) ; starts a new figure in this Path 31 | Gdip_AddPathLine(pPath, 200, 200, 400, 200) 32 | Gdip_AddPathLine(pPath, 400, 200, 400, 400) 33 | Gdip_AddPathLine(pPath, 400, 400, 200, 400) 34 | Gdip_AddPathLine(pPath, 200, 400, 200, 200) 35 | Gdip_ClosePathFigure(pPath) ; closes the current figure of this path 36 | 37 | ;Create a Pen to draw with 38 | pPen := Gdip_CreatePen(0xff000000, 5) 39 | 40 | ;Rotate the graphic until exit 41 | Loop { 42 | Gdip_GraphicsClear(G) ; Clear the graphics 43 | Gdip_RotatePathAtCenter(pPath, 5) ; Rotate the path by 5deg on its center 44 | Gdip_DrawPath(G, pPen, pPath) ; draw rectangle 45 | UpdateLayeredWindow(hGui, hdc, 0, 0, w, h) ; Update the layred window 46 | Sleep 100 47 | } 48 | 49 | Esc:: 50 | MapperGuiEscape: 51 | MapperGuiClose: 52 | 53 | ;Cleanup and Exit 54 | Gdip_DeletePen(pPen) 55 | SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc) 56 | Gdip_DeleteGraphics(G) 57 | Gdip_Shutdown(pToken) 58 | Gui Mapper: Destroy 59 | ExitApp 60 | Return 61 | 62 | ;HitTest if the mouse in inside the graphicspath 63 | OnWM_MOUSEMOVE(wParam, lParam, msg, hWnd) { 64 | Global 65 | 66 | mX := lParam & 0xFFFF ;get low order 67 | mY := lParam >> 16 ;get high order 68 | 69 | hit := Gdip_IsVisiblePathPoint(pPath, mX, mY, G) 70 | Tooltip % "Hit= " hit 71 | 72 | } 73 | 74 | OnWM_MOUSEWHEEL(wParam, lParam, msg, hWnd) { 75 | Global 76 | 77 | mX := lParam & 0xFFFF ;get low order 78 | mY := lParam >> 16 ;get high order 79 | delta := wParam >> 16 ;120 for zoom in, 65416 for zoom out 80 | 81 | Scale := Delta = 120 ? 0.9 : 1.1 ;Adjust scale factor 82 | ;TODO - Factor in the mouse coords to zoom in/out at that point 83 | 84 | Gdip_GraphicsClear(G) 85 | pMatrix := Gdip_CreateMatrix() 86 | 87 | ; Calculate center of Window which will be the center of the graphics path 88 | cX := w / 2 89 | cY := h / 2 90 | 91 | ; Move Centre point of square to origin of graphics object, then scale and then move back to original center point of square 92 | GDip_TranslateMatrix(pMatrix, -cX, -cY, 1) 93 | Gdip_ScaleMatrix(pMatrix, Scale, Scale, 1) 94 | GDip_TranslateMatrix(pMatrix, cX, cY, 1) 95 | 96 | ; Apply the transformations 97 | Gdip_TransformPath(pPath, pMatrix) 98 | 99 | ; Redraw the path and update the window 100 | Gdip_DrawPath(G, pPen, pPath) 101 | UpdateLayeredWindow(hGui, hdc, 0, 0, w, h) 102 | } 103 | 104 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.15-Just-Me-Path-Gradients.ahk: -------------------------------------------------------------------------------- 1 | ; https://autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/page-65 2 | ; by just_me 3 | 4 | #Include ../Gdip_All.ahk 5 | 6 | SS_BITMAP := 0xE 7 | SS_ICON := 0x3 8 | STM_SETIMAGE := 0x172 9 | IMAGE_BITMAP := 0x0 10 | W := 200 11 | H := 200 12 | 13 | GdipToken := Gdip_Startup() 14 | Gui, New, hwndHGUI -DPIScale +LabelGUI, PathGradientBrush 15 | Gui, Add, Pic, w%W% h%H% hwndHPIC 16 | ScaleX := 0.0 ; focus scale for x-axis (0.0 - 1.0) 17 | ScaleY := 0.0 ; focus scale for y-axis (0.0 - 1.0) 18 | BlendFocus := 0.5 ; blend focus (0.0 - 1.0) 19 | GoSub, PathGradientBrush 20 | Gui, Add, Pic, ym w%W% h%H% hwndHPIC 21 | ScaleX := 0.75 ; focus scale for x-axis (0.0 - 1.0) 22 | ScaleY := 0.75 ; focus scale for y-axis (0.0 - 1.0) 23 | BlendFocus := 1.0 ; blend focus (0.0 - 1.0) 24 | GoSub, PathGradientBrush 25 | Gui, Show 26 | Return 27 | 28 | PathGradientBrush: 29 | PBitMap := Gdip_CreateBitmap(W, H) 30 | PGraphics := Gdip_GraphicsFromImage(PBitMap) 31 | Gdip_SetSmoothingMode(PGraphics, 4) 32 | PPath := Gdip_CreatePath(PGraphics) 33 | If (BlendFocus=0.5) 34 | Gdip_AddPathRectangle(PPath, 0, 0, W, H) 35 | Else 36 | Gdip_AddPathEllipse(PPath, 0, 0, W, H) 37 | PBrush := Gdip_PathGradientCreateFromPath(PPath) 38 | Gdip_PathGradientSetCenterPoint(PBrush, W / 2, H / 2) 39 | Gdip_PathGradientSetCenterColor(PBrush, 0xFFFFFFFF) 40 | Gdip_PathGradientSetSurroundColors(PBrush, 0xFF202090) 41 | Gdip_PathGradientSetSigmaBlend(PBrush, BlendFocus) 42 | Gdip_PathGradientSetLinearBlend(PBrush, BlendFocus) 43 | Gdip_PathGradientSetFocusScales(PBrush, ScaleX, ScaleY) 44 | Gdip_FillPath(PGraphics, PBrush, PPath) 45 | HBitmap := Gdip_CreateHBITMAPFromBitmap(PBitMap, 0x00FFFFFF) 46 | Gdip_DeleteBrush(PBrush) 47 | Gdip_DeletePath(PPath) 48 | Gdip_DeleteGraphics(PGraphics) 49 | Gdip_DisposeImage(PBitmap) 50 | ; Set control styles 51 | Control, Style, -%SS_ICON%, , ahk_id %HPIC% 52 | Control, Style, +%SS_BITMAP%, , ahk_id %HPIC% 53 | ; Assign the bitmap 54 | SendMessage, STM_SETIMAGE, IMAGE_BITMAP, HBitmap, , ahk_id %HPIC% 55 | ; Done! 56 | DeleteObject(HBitmap) 57 | Return 58 | 59 | Esc:: 60 | GuiClose: 61 | GuiEscape: 62 | Gdip_ShutDown(GdipToken) 63 | ExitApp 64 | Return 65 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.16-Just-Me-GetProperty.ahk: -------------------------------------------------------------------------------- 1 | SetBatchLines, -1 2 | #Include ..\Gdip_All.ahk 3 | GDIPToken := Gdip_Startup() 4 | PicFolder := "" 5 | ;_______________________________________________________________________________________________________________________ 6 | Gui, Margin, 20, 20 7 | Gui, Add, ListBox, w600 r20 +Sort gShowPicProps vPicList 8 | Gui, Add, Button, gSelectPics, Select Folder 9 | Gui, Show, , Pictures 10 | GoSub, SelectPics 11 | Return 12 | ;_______________________________________________________________________________________________________________________ 13 | Esc:: 14 | GuiClose: 15 | Gdip_Shutdown(GDIPToken) 16 | ExitApp 17 | Return 18 | ;_______________________________________________________________________________________________________________________ 19 | SelectPics: 20 | StartingFolder := PicFolder <> "" ? "*" . PicFolder : "" 21 | FileSelectFolder, PicFolder, %StartingFolder%, 2, Select the pictures' folder, please! 22 | If (PicFolder = "") 23 | Return 24 | GuiControl, , PicList, | 25 | Loop, %PicFolder%\*.*, 0, 0 26 | If A_LoopFileExt In bmp,jpg,png 27 | GuiControl, , PicList, %A_LoopFileLongPath% 28 | Return 29 | ;_______________________________________________________________________________________________________________________ 30 | ShowPicProps: 31 | GuiControlGet, Pic, , PicList 32 | If (Pic = "") 33 | Return 34 | Gui, +OwnDialogs 35 | GDIPImage := Gdip_LoadImageFromFile(Pic) 36 | ; PropArray := Gdip_GetPropertyIdList(GDIPImage) 37 | ; Msg := "" 38 | ; For ID, Name In PropArray 39 | ; Msg .= ID . " : " . Name . "`r`n" 40 | ; MsgBox, %Msg% 41 | Properties := Gdip_GetAllPropertyItems(GDIPImage) 42 | If (ErrorLevel) || (Properties.Count = 0) { 43 | MsgBox, 16, Error %Errorlevel%, Couldn't get properties of image %Pic% 44 | Return 45 | } 46 | Gdip_DisposeImage(GDIPImage) 47 | Gui, New, +LastFound +Owner1 +LabelProps +ToolWindow 48 | Gui, Margin, 0, 0 49 | Gui, Add, ListView, Grid w600 r20, ID|Name|Length|Type|Value 50 | For ID, Val In Properties { 51 | If ID Is Integer 52 | { 53 | PropName := Gdip_GetPropertyTagName(ID) 54 | PropType := Gdip_GetPropertyTagType(Val.Type) 55 | If (PropType = "Byte") || (PropType = "Undefined") || (PropType = "Unknown") 56 | LV_Add("", ID, PropName, Val.Length, PropType, "") 57 | Else 58 | LV_Add("", ID, PropName, Val.Length, PropType, Val.Value) 59 | } 60 | } 61 | LV_ModifyCol(1, "Integer") 62 | Loop, % LV_GetCount("Column") 63 | LV_ModifyCol(A_Index, "AutoHdr") 64 | LV_ModifyCol(1, "Sort") 65 | Gui, Show, , % PIC . " - " . Properties.Count . " properties" 66 | WinWaitActive 67 | WinWaitClose 68 | Return 69 | ;_______________________________________________________________________________________________________________________ 70 | PropsClose: 71 | PropsEscape: 72 | Gui, Destroy 73 | Return -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.17-robodesign-Draw-Customized-Texts.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 1 written by tic (Tariq Porter) 2 | ; Requires Gdip_all.ahk v1.69 3 | ; GDI+ library compilation of user contributed GDI+ functions 4 | ; made by Marius Șucan: https://github.com/marius-sucan/AHK-GDIp-Library-Compilation 5 | ; 6 | 7 | #SingleInstance, Force 8 | #NoEnv 9 | SetBatchLines, -1 10 | 11 | ; Uncomment if Gdip.ahk is not in your standard library 12 | #Include, ..\Gdip_All.ahk 13 | 14 | ; Start gdi+ 15 | If !pToken := Gdip_Startup() 16 | { 17 | MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system 18 | ExitApp 19 | } 20 | OnExit, Exit 21 | 22 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 23 | Width :=1400, Height := 1050 24 | 25 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 26 | Gui, 1: -Caption -DPIScale +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 27 | 28 | ; Show the window 29 | Gui, 1: Show, NA 30 | 31 | ; Get a handle to this window we have created in order to update it later 32 | hwnd1 := WinExist() 33 | 34 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 35 | hbm := CreateDIBSection(Width, Height) 36 | 37 | ; Get a device context compatible with the screen 38 | hdc := CreateCompatibleDC() 39 | 40 | ; Select the bitmap into the device context 41 | obm := SelectObject(hdc, hbm) 42 | 43 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 44 | G := Gdip_GraphicsFromHDC(hdc) 45 | 46 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 47 | Gdip_SetSmoothingMode(G, 4) 48 | 49 | ; fill the background 50 | pBrushBgr := Gdip_BrushCreateSolid(0xddeeffee) 51 | Gdip_FillRectangle(G, pBrushBgr, 1, 1, 990, 990) 52 | 53 | ; Create a slightly transparent (66) blue brush (ARGB = Transparency, red, green, blue) to draw a rectangle 54 | pBrush := Gdip_BrushCreateSolid(0x660000ff) 55 | 56 | ; Draws a text along a polygonal line defined by PolygonalLine 57 | PolygonalLine := "50,190|400,390|890,190|800,990" 58 | Gdip_DrawStringAlongPolygon(G, "Oh my God, example text!", "Arial", 100, 1, pBrush, PolygonalLine) 59 | 60 | ; Now draw a text contour rotated at 45 degrees 61 | pPen := Gdip_CreatePen("0xCC990011", 5) 62 | Gdip_SetPenDashStyle(pPen, 2) 63 | Gdip_DrawOrientedString(G, "Contour text example", "Verdana", 90, 1, 20, 500, 800, 800, 45, pBrushBgr, pPen, 1) 64 | 65 | ; Delete the brush as it is no longer needed and wastes memory 66 | Gdip_DeleteBrush(pBrush) 67 | Gdip_DeleteBrush(pBrushBgr) 68 | Gdip_DeletePen(pPen) 69 | 70 | 71 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 72 | ; So this will position our gui at (0,0) with the Width and Height specified earlier 73 | UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) 74 | 75 | 76 | ; Select the object back into the hdc 77 | SelectObject(hdc, obm) 78 | 79 | ; Now the bitmap may be deleted 80 | DeleteObject(hbm) 81 | 82 | ; Also the device context related to the bitmap may be deleted 83 | DeleteDC(hdc) 84 | 85 | ; The graphics may now be deleted 86 | Gdip_DeleteGraphics(G) 87 | Return 88 | 89 | ;####################################################################### 90 | 91 | Esc:: 92 | GoSub, Exit 93 | Return 94 | 95 | Exit: 96 | ; gdi+ may now be shutdown on exiting the program 97 | Gdip_Shutdown(pToken) 98 | ExitApp 99 | Return -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.2-Draw.Outlined.Shapes.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 2 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to draw a single ellipse and rectangle to the screen, but just the outlines of these shapes 5 | 6 | #SingleInstance Force 7 | #NoEnv 8 | SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 22 | Width := 600, Height := 400 23 | 24 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 25 | Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 26 | Gui, 1: Show, NA 27 | 28 | ; Get a handle to this window we have created in order to update it later 29 | hwnd1 := WinExist() 30 | 31 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 32 | hbm := CreateDIBSection(Width, Height) 33 | 34 | ; Get a device context compatible with the screen 35 | hdc := CreateCompatibleDC() 36 | 37 | ; Select the bitmap into the device context 38 | obm := SelectObject(hdc, hbm) 39 | 40 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 41 | G := Gdip_GraphicsFromHDC(hdc) 42 | 43 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 44 | Gdip_SetSmoothingMode(G, 4) 45 | 46 | ; Create a fully opaque red pen (ARGB = Transparency, red, green, blue) of width 3 (the thickness the pen will draw at) to draw a circle 47 | pPen := Gdip_CreatePen(0xffff0000, 3) 48 | 49 | ; Draw an ellipse into the graphics of the bitmap (this being only the outline of the shape) using the pen created 50 | ; This pen has a width of 3, and is drawing from coordinates (100,50) an ellipse of 200x300 51 | Gdip_DrawEllipse(G, pPen, 100, 50, 200, 300) 52 | 53 | ; Delete the pen as it is no longer needed and wastes memory 54 | Gdip_DeletePen(pPen) 55 | 56 | ; Create a slightly transparent (66) blue pen (ARGB = Transparency, red, green, blue) to draw a rectangle 57 | ; This pen is wider than the last one, with a thickness of 10 58 | pPen := Gdip_CreatePen(0x660000ff, 10) 59 | 60 | ; Draw a rectangle onto the graphics of the bitmap using the pen just created 61 | ; Draws the rectangle from coordinates (250,80) a rectangle of 300x200 and outline width of 10 (specified when creating the pen) 62 | Gdip_DrawRectangle(G, pPen, 250, 80, 300, 200) 63 | 64 | ; Delete the brush as it is no longer needed and wastes memory 65 | Gdip_DeletePen(pPen) 66 | 67 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 68 | ; So this will position our gui at (0,0) with the Width and Height specified earlier 69 | UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) 70 | 71 | 72 | ; Select the object back into the hdc 73 | SelectObject(hdc, obm) 74 | 75 | ; Now the bitmap may be deleted 76 | DeleteObject(hbm) 77 | 78 | ; Also the device context related to the bitmap may be deleted 79 | DeleteDC(hdc) 80 | 81 | ; The graphics may now be deleted 82 | Gdip_DeleteGraphics(G) 83 | Return 84 | 85 | ;####################################################################### 86 | 87 | ExitFunc(ExitReason, ExitCode) { 88 | global 89 | ; gdi+ may now be shutdown on exiting the program 90 | Gdip_Shutdown(pToken) 91 | } 92 | 93 | ~Esc:: 94 | ExitApp 95 | Return 96 | 97 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.4-Draw.Circles.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 4 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to fill the screen with randomly hatched ellipses 5 | 6 | #SingleInstance Force 7 | #NoEnv 8 | SetBatchLines -1 9 | global hbm, hdc, obm, G, pToken 10 | 11 | ; Uncomment if Gdip.ahk is not in your standard library 12 | #Include ../Gdip_All.ahk 13 | 14 | ; Start gdi+ 15 | If !pToken := Gdip_Startup() 16 | { 17 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 18 | ExitApp 19 | } 20 | OnExit("ExitFunc") 21 | 22 | ; Get the dimensions of the primary monitor 23 | ; these funcs are based off MDMF lib and are now included in the Gdip_All library 24 | MonitorPrimary := GetPrimaryMonitor() 25 | M := GetMonitorInfo(MonitorPrimary) 26 | WALeft := M.WALeft 27 | WATop := M.WATop 28 | WARight := M.WARight 29 | WABottom := M.WABottom 30 | WAWidth := M.WARight-M.WALeft 31 | WAHeight := M.WABottom-M.WATop 32 | 33 | ; Create a layered window (+E0x80000) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 34 | Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 35 | Gui, 1: Show, NA 36 | 37 | ; Get a handle to this window we have created in order to update it later 38 | hwnd1 := WinExist() 39 | 40 | ; Create a gdi bitmap with width and height of the work area 41 | hbm := CreateDIBSection(WAWidth, WAHeight) 42 | 43 | ; Get a device context compatible with the screen 44 | hdc := CreateCompatibleDC() 45 | 46 | ; Select the bitmap into the device context 47 | obm := SelectObject(hdc, hbm) 48 | 49 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 50 | G := Gdip_GraphicsFromHDC(hdc) 51 | 52 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 53 | Gdip_SetSmoothingMode(G, 4) 54 | 55 | ; Set a timer to draw a new ellipse every 200ms 56 | SetTimer DrawCircle, 200 57 | Return 58 | 59 | ;####################################################################### 60 | 61 | DrawCircle() 62 | { 63 | global 64 | DrawCircle: 65 | ; Get a random colour for the background and foreground of hatch style used to fill the ellipse, 66 | ; as well as random brush style, x and y coordinates and width/height 67 | 68 | Random, RandBackColour, 0.0, 0xffffffff 69 | Random, RandForeColour, 0.0, 0xffffffff 70 | Random, RandBrush, 0, 53 71 | Random, RandElipseWidth, 1, 200 72 | Random, RandElipseHeight, 1, 200 73 | Random, RandElipsexPos, %WALeft%, % WAWidth-RandElipseWidth 74 | Random, RandElipseyPos, %WATop%, % WAHeight-RandElipseHeight 75 | 76 | ; Create the random brush 77 | pBrush := Gdip_BrushCreateHatch(RandBackColour, RandForeColour, RandBrush) 78 | 79 | ; Fill the graphics of the bitmap with an ellipse using the brush created 80 | Gdip_FillEllipse(G, pBrush, RandElipsexPos, RandElipseyPos, RandElipseWidth, RandElipseHeight) 81 | 82 | ; Update the specified window 83 | UpdateLayeredWindow(hwnd1, hdc, WALeft, WATop, WAWidth, WAHeight) 84 | 85 | ; Delete the brush as it is no longer needed and wastes memory 86 | Gdip_DeleteBrush(pBrush) 87 | Return 88 | } 89 | 90 | ;####################################################################### 91 | 92 | ExitFunc(ExitReason, ExitCode) { 93 | ; global 94 | ; Select the object back into the hdc 95 | SelectObject(hdc, obm) 96 | 97 | ; Now the bitmap may be deleted 98 | DeleteObject(hbm) 99 | 100 | ; Also the device context related to the bitmap may be deleted 101 | DeleteDC(hdc) 102 | 103 | ; The graphics may now be deleted 104 | Gdip_DeleteGraphics(G) 105 | 106 | ; ...and gdi+ may now be shutdown 107 | Gdip_Shutdown(pToken) 108 | } 109 | 110 | ~Esc:: 111 | SetTimer, DrawCircle, Off 112 | ; ExitFunc(1, 1) 113 | ExitApp 114 | Return 115 | 116 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.5-Create.Bitmap.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 5 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Example to create a bitmap, fill it with some shapes and save to file 5 | 6 | #SingleInstance Force 7 | #NoEnv 8 | SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | 20 | ; Create a 400x400 pixel gdi+ bitmap 21 | pBitmap := Gdip_CreateBitmap(400, 400) 22 | 23 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 24 | G := Gdip_GraphicsFromImage(pBitmap) 25 | 26 | ; Set the smoothing mode to antialias = 4 to make shapes appear smoother (only used for vector drawing and filling) 27 | Gdip_SetSmoothingMode(G, 4) 28 | 29 | ; Create a hatched brush with background and foreground colours specified (HatchStyleBackwardDiagonal = 3) 30 | pBrush := Gdip_BrushCreateHatch(0xff553323, 0xffc09e8e, 31) 31 | ; Draw into the graphics of the bitmap from coordinates (100,80) a filled rectangle with 200 width and 250 height using the brush created 32 | Gdip_FillRectangle(G, pBrush, (400-200)//2, (400-250)//2, 200, 250) 33 | ; Delete the brush created to save memory as we don't need the same brush anymore 34 | Gdip_DeleteBrush(pBrush) 35 | 36 | ; Create a hatched brush with background and foreground colours specified (HatchStyleBackwardDiagonal = 3) 37 | pBrush := Gdip_BrushCreateHatch(0xff000000, 0xff4d3538, 31) 38 | ; Draw an ellipse into the graphics with the brush we just created. 40 degree sweep angle starting at 250 degrees (0 degrees from right horizontal) 39 | Gdip_FillPie(G, pBrush, (400-80)//2, (400-80)//2, 80, 80, 250, 40) 40 | ; Delete the brush created to save memory as we don't need the same brush anymore 41 | Gdip_DeleteBrush(pBrush) 42 | 43 | ; Create a white brush 44 | pBrushWhite := Gdip_BrushCreateSolid(0xffffffff) 45 | ; Create a black brush 46 | pBrushBlack := Gdip_BrushCreateSolid(0xff000000) 47 | 48 | ; Loop to draw 2 ellipses filling them with white then black in the centre of each 49 | Loop 2 50 | { 51 | x := (A_Index = 1) ? 120 : 220, y := 100 52 | Gdip_FillEllipse(G, pBrushWhite, x, y, 60, 60) 53 | x += 15, y+=15 54 | Gdip_FillEllipse(G, pBrushBlack, x, y, 30, 30) 55 | } 56 | ; Delete both brushes 57 | Gdip_DeleteBrush(pBrushWhite), Gdip_DeleteBrush(pBrushBlack) 58 | 59 | ; Create a hatched brush with background and foreground colours specified (HatchStyle30Percent = 10) 60 | pBrush := Gdip_BrushCreateHatch(0xfff22231, 0xffa10f19, 10) 61 | ; Again draw another ellipse into the graphics with the specified brush 62 | Gdip_FillPie(G, pBrush, 150, 200, 100, 80, 0, 180) 63 | ; Delete the brush 64 | Gdip_DeleteBrush(pBrush) 65 | 66 | ; Create a 3 pixel wide slightly transparent black pen 67 | pPen := Gdip_CreatePen(0xbb000000, 3) 68 | 69 | ; Create some coordinates for the lines in format x1,y1,x2,y2 then loop and draw all the lines 70 | Lines := "180,200,130,220|180,190,130,195|220,200,270,220|220,190,270,195" 71 | for k,v in StrSplit(Lines, "|") 72 | { 73 | Pos := StrSplit(v, ",") 74 | Gdip_DrawLine(G, pPen, Pos[1], Pos[2], Pos[3], Pos[4]) 75 | } 76 | ; Delete the pen 77 | Gdip_DeletePen(pPen) 78 | 79 | 80 | ; Save the bitmap to file "File.png" (extension can be .png,.bmp,.jpg,.tiff,.gif) 81 | ; Bear in mind transparencies may be lost with some image formats and will appear black 82 | Gdip_SaveBitmapToFile(pBitmap, "File.png") 83 | 84 | MsgBox "Bitmap saved as 'File.png' " 85 | 86 | ; The bitmap can be deleted 87 | Gdip_DisposeImage(pBitmap) 88 | 89 | ; The graphics may now be deleted 90 | Gdip_DeleteGraphics(G) 91 | 92 | ; ...and gdi+ may now be shutdown 93 | Gdip_Shutdown(pToken) 94 | ExitApp 95 | Return 96 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.6-Image.Editing.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 6 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Example to take files from disk, load them onto a background and save back to disk 5 | 6 | #SingleInstance Force 7 | #NoEnv 8 | SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Specify both of the files we are going to use 14 | File1 := "needle.png" 15 | File2 := "background.png" 16 | 17 | ; Start gdi+ 18 | If !pToken := Gdip_Startup() 19 | { 20 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 21 | ExitApp 22 | } 23 | 24 | ; If the images we want to work with do not exist on disk, then download them... 25 | If !(FileExist(File1) && FileExist(File2)) 26 | { 27 | MsgBox "Cannot find files 'needle.png' and 'background.png' in this same directory" 28 | ExitApp 29 | } 30 | 31 | 32 | ; Create a 500x500 pixel gdi+ bitmap (this will be the entire drawing area we have to play with) 33 | pBitmap := Gdip_CreateBitmap(600, 600) 34 | 35 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 36 | G := Gdip_GraphicsFromImage(pBitmap) 37 | 38 | ; Create a green brush (this will be used to fill the background with green). The brush is fully opaque (ARGB) 39 | pBrush := Gdip_BrushCreateSolid(0xff00ff00) 40 | 41 | ; Filll the entire graphics of the bitmap with the green brush (this will be out background colour) 42 | Gdip_FillRectangle(G, pBrush, 0, 0, 600, 600) 43 | 44 | ; Delete the brush created to save memory as we don't need the same brush anymore 45 | Gdip_DeleteBrush(pBrush) 46 | 47 | 48 | ; Get bitmaps for both the files we are going to be working with 49 | pBitmapFile1 := Gdip_CreateBitmapFromFile(File1), pBitmapFile2 := Gdip_CreateBitmapFromFile(File2) 50 | 51 | ; Get the width and height of the 1st bitmap 52 | Width := Gdip_GetImageWidth(pBitmapFile1), Height := Gdip_GetImageHeight(pBitmapFile1) 53 | 54 | ; Draw the 1st bitmap (1st image) onto our "canvas" (the graphics of the original bitmap we created) with the same height and same width 55 | ; at coordinates (25,30).....We will be ignoring the matrix parameter for now. This can be used to change opacity and colours when drawing 56 | Gdip_DrawImage(G, pBitmapFile1, 25, 30, Width, Height, 0, 0, Width, Height) 57 | 58 | 59 | ; Do the same again for the 2nd file, but change the coordinates to (250,260)..... 60 | 61 | Width := Gdip_GetImageWidth(pBitmapFile2), Height := Gdip_GetImageHeight(pBitmapFile2) 62 | Gdip_DrawImage(G, pBitmapFile2, 250, 260, Width, Height, 0, 0, Width, Height) 63 | 64 | ; Dispose of both of these bitmaps we created from the images on disk, as they are now been used...They are on 65 | ; the graphics of the bitmap of our created "canvas" 66 | Gdip_DisposeImage(pBitmapFile1), Gdip_DisposeImage(pBitmapFile2) 67 | 68 | 69 | ; Save the bitmap to file "File.png" (extension can be .png,.bmp,.jpg,.tiff,.gif) 70 | ; Bear in mind transparencies may be lost with some image formats and will appear black 71 | Gdip_SaveBitmapToFile(pBitmap, "FinalImage.png") 72 | 73 | MsgBox "Image saved as 'FinalImage.png' " 74 | 75 | ; The bitmap can be deleted 76 | Gdip_DisposeImage(pBitmap) 77 | 78 | ; The graphics may now be deleted 79 | Gdip_DeleteGraphics(G) 80 | 81 | ; ...and gdi+ may now be shutdown 82 | Gdip_Shutdown(pToken) 83 | ExitApp 84 | Return 85 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.Tutorial.7-Draw.draggable.rounded.rectangle.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 7 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to draw a rounded rectangle as a gui that you can drag 5 | 6 | #SingleInstance Force 7 | #NoEnv 8 | SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 22 | Width := 300, Height := 200 23 | 24 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 25 | Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 26 | Gui, 1: Show, NA 27 | 28 | ; Get a handle to this window we have created in order to update it later 29 | hwnd1 := WinExist() 30 | 31 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 32 | hbm := CreateDIBSection(Width, Height) 33 | 34 | ; Get a device context compatible with the screen 35 | hdc := CreateCompatibleDC() 36 | 37 | ; Select the bitmap into the device context 38 | obm := SelectObject(hdc, hbm) 39 | 40 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 41 | G := Gdip_GraphicsFromHDC(hdc) 42 | 43 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 44 | Gdip_SetSmoothingMode(G, 4) 45 | 46 | ; Create a partially transparent, black brush (ARGB = Transparency, red, green, blue) to draw a rounded rectangle with 47 | pBrush := Gdip_BrushCreateSolid(0x77000000) 48 | 49 | ; Fill the graphics of the bitmap with a rounded rectangle using the brush created 50 | ; Filling the entire graphics - from coordinates (0, 0) the entire width and height 51 | ; The last parameter (20) is the radius of the circles used for the rounded corners 52 | Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20) 53 | 54 | ; Delete the brush as it is no longer needed and wastes memory 55 | Gdip_DeleteBrush(pBrush) 56 | 57 | 58 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 59 | ; With some simple maths we can place the gui in the centre of our primary monitor horizontally and vertically at the specified heigth and width 60 | UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height) 61 | 62 | ; By placing this OnMessage here. The function WM_LBUTTONDOWN will be called every time the user left clicks on the gui 63 | OnMessage(0x201, "WM_LBUTTONDOWN") 64 | 65 | 66 | ; Select the object back into the hdc 67 | SelectObject(hdc, obm) 68 | 69 | ; Now the bitmap may be deleted 70 | DeleteObject(hbm) 71 | 72 | ; Also the device context related to the bitmap may be deleted 73 | DeleteDC(hdc) 74 | 75 | ; The graphics may now be deleted 76 | Gdip_DeleteGraphics(G) 77 | Return 78 | 79 | ;####################################################################### 80 | 81 | ; This function is called every time the user clicks on the gui 82 | ; The PostMessage will act on the last found window (this being the gui that launched the subroutine, hence the last parameter not being needed) 83 | WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 84 | PostMessage 0xA1, 2 85 | } 86 | 87 | ;####################################################################### 88 | 89 | ExitFunc(ExitReason, ExitCode) { 90 | global 91 | ; gdi+ may now be shutdown on exiting the program 92 | Gdip_Shutdown(pToken) 93 | } 94 | 95 | ~Esc:: 96 | ExitApp 97 | Return 98 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.tutorial.file-fish.bra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/Gdip.tutorial.file-fish.bra -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/MJ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/MJ.jpg -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/background.png -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/needle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v1-1/Examples-ahk-v1-1/needle.png -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.1-Draw.Shapes.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 1 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to draw a single ellipse and rectangle to the screen 5 | 6 | #SingleInstance Force 7 | ;#NoEnv 8 | ;SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 22 | Width :=1400, Height := 1050 23 | 24 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 25 | ;AHK v1 26 | ;Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 27 | ;Gui, 1: Show, NA 28 | Gui1 := GuiCreate("-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs") 29 | Gui1.Show("NA") 30 | 31 | ; Get a handle to this window we have created in order to update it later 32 | hwnd1 := WinExist() 33 | 34 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 35 | hbm := CreateDIBSection(Width, Height) 36 | 37 | ; Get a device context compatible with the screen 38 | hdc := CreateCompatibleDC() 39 | 40 | ; Select the bitmap into the device context 41 | obm := SelectObject(hdc, hbm) 42 | 43 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 44 | G := Gdip_GraphicsFromHDC(hdc) 45 | 46 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 47 | Gdip_SetSmoothingMode(G, 4) 48 | 49 | ; Create a fully opaque red brush (ARGB = Transparency, red, green, blue) to draw a circle 50 | pBrush := Gdip_BrushCreateSolid(0xffff0000) 51 | 52 | ; Fill the graphics of the bitmap with an ellipse using the brush created 53 | ; Filling from coordinates (100,50) an ellipse of 200x300 54 | Gdip_FillEllipse(G, pBrush, 100, 500, 200, 300) 55 | 56 | ; Delete the brush as it is no longer needed and wastes memory 57 | Gdip_DeleteBrush(pBrush) 58 | 59 | ; Create a slightly transparent (66) blue brush (ARGB = Transparency, red, green, blue) to draw a rectangle 60 | pBrush := Gdip_BrushCreateSolid(0x660000ff) 61 | 62 | ; Fill the graphics of the bitmap with a rectangle using the brush created 63 | ; Filling from coordinates (250,80) a rectangle of 300x200 64 | Gdip_FillRectangle(G, pBrush, 250, 80, 300, 200) 65 | 66 | ; Delete the brush as it is no longer needed and wastes memory 67 | Gdip_DeleteBrush(pBrush) 68 | 69 | 70 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 71 | ; So this will position our gui at (0,0) with the Width and Height specified earlier 72 | UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) 73 | 74 | 75 | ; Select the object back into the hdc 76 | SelectObject(hdc, obm) 77 | 78 | ; Now the bitmap may be deleted 79 | DeleteObject(hbm) 80 | 81 | ; Also the device context related to the bitmap may be deleted 82 | DeleteDC(hdc) 83 | 84 | ; The graphics may now be deleted 85 | Gdip_DeleteGraphics(G) 86 | Return 87 | 88 | ;####################################################################### 89 | 90 | ExitFunc(ExitReason, ExitCode) 91 | { 92 | global 93 | ; gdi+ may now be shutdown on exiting the program 94 | Gdip_Shutdown(pToken) 95 | } 96 | 97 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.12-Pixelate.a.bitmap.using.machine.code.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 12 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to pixelate a bitmap using machine code 5 | 6 | #SingleInstance Force 7 | ;#NoEnv 8 | ;SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Create a layered window that is always on top as usual and get a handle to the window 22 | ;AHK v1 23 | ;Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop 24 | ;Gui, 1: Show, NA 25 | Gui1 := GuiCreate("-Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop") 26 | Gui1.Show("NA") 27 | hwnd1 := WinExist() 28 | 29 | ; Get a bitmap from the image 30 | If FileExist("MJ.jpg") 31 | pBitmap := Gdip_CreateBitmapFromFile("MJ.jpg") 32 | ;pBitmap := Gdip_BitmapFromScreen() 33 | If !pBitmap 34 | { 35 | MsgBox "Could not load the image 'MJ.jpg' " 36 | ExitApp 37 | } 38 | ; Get the width and height of the bitmap we have just created from the file 39 | Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap) 40 | 41 | ; We also need to create 42 | pBitmapOut := Gdip_CreateBitmap(Width, Height) 43 | 44 | ; As normal create a gdi bitmap and get the graphics for it to draw into 45 | hbm := CreateDIBSection(Width, Height), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm) 46 | G := Gdip_GraphicsFromHDC(hdc) 47 | 48 | ; Call WM_LBUTTONDOWN every time the gui is clicked, to allow it to be dragged 49 | OnMessage(0x201, "WM_LBUTTONDOWN") 50 | 51 | ; Update the window with the hdc so that it has a position and dimension for future calls to not 52 | ; have to explicitly pass them 53 | UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height) 54 | 55 | ; Set a timer to update the gui with our pixelated bitmap 56 | ;AHK v1 57 | ;SetTimer, Update, 50 58 | SetTimer "Update", 50 59 | return 60 | 61 | ;####################################################################### 62 | 63 | Update() 64 | { 65 | global 66 | Update: 67 | ; Some simple checks to see if we are increasing or decreasing the pixelation 68 | ; v is the block size of the pixelation and dir is the direction (inc/decreasing) 69 | if (v <= 1) 70 | v := 1, dir := !dir 71 | else if (v >= 30) 72 | v := 30, dir := !dir 73 | 74 | ; Call Gdip_PixelateBitmap with the bitmap we retrieved earlier and the block size of the pixels 75 | ; The function returns the pixelated bitmap, and doesn't dispose of the original bitmap 76 | Gdip_PixelateBitmap(pBitmap, pBitmapOut, dir ? ++v : --v) 77 | 78 | ; We can optionally clear the graphics we will be drawing to, but if we know there will be no transparencies then 79 | ; it doesn't matter 80 | ;Gdip_GraphicsClear(G) 81 | 82 | ; We then draw our pixelated bitmap into our graphics and dispose of the pixelated bitmap 83 | Gdip_DrawImage(G, pBitmapOut, 0, 0, Width, Height, 0, 0, Width, Height) 84 | 85 | ; We can now update our window, and don't need to provide a position or dimensions as we don't want them to change 86 | UpdateLayeredWindow(hwnd1, hdc) 87 | return 88 | } 89 | 90 | ;####################################################################### 91 | 92 | ; This is called on left click to allow to drag 93 | WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) 94 | { 95 | PostMessage 0xA1, 2 96 | } 97 | 98 | ;####################################################################### 99 | 100 | ; On exit, dispose of everything created 101 | Esc:: 102 | ExitApp 103 | return 104 | 105 | ExitFunc(ExitReason, ExitCode) 106 | { 107 | global 108 | Gdip_DisposeImage(pBitmapOut), Gdip_DisposeImage(pBitmap) 109 | SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc) 110 | Gdip_DeleteGraphics(G) 111 | Gdip_Shutdown(pToken) 112 | } 113 | 114 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.13-Learning-One-Graphics-Paths.ahk: -------------------------------------------------------------------------------- 1 | #Include ../Gdip_All.ahk 2 | 3 | ;=== Create Gui, OnMessage === 4 | 5 | Gui1 := GuiCreate("-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs") 6 | Gui1.Show("NA") 7 | 8 | hGui := WinExist() 9 | w := 550, h := 280 10 | 11 | ;===GDI+ prepare === 12 | pToken := Gdip_Startup() 13 | hbm := CreateDIBSection(w, h), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm) 14 | G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4) 15 | 16 | 17 | ;=== Background === 18 | pBrush := Gdip_CreateLineBrushFromRect(0, 0, w, h, 0xff555555, 0xff050505) 19 | Gdip_FillRectangle(G, pBrush, 0, 0, w, h) 20 | Gdip_DeleteBrush(pBrush) 21 | 22 | pBrush := Gdip_BrushCreateHatch(0xff000000, 0x00000000, 8) 23 | Gdip_FillRectangle(G, pBrush, 0, 0, w, h) 24 | Gdip_DeleteBrush(pBrush) 25 | 26 | 27 | ;=== Create path (Bat) === 28 | pPath := Gdip_CreatePath() ; creates a Path (GraphicsPath object) 29 | 30 | Gdip_StartPathFigure(pPath) ; starts a new figure in this Path 31 | Gdip_AddPathLine(pPath, 110,95, 220,95) ; adds a line to the current figure of this path 32 | Gdip_AddPathBezier(pPath, 220,95, 228,112, 233,120, 262,120) ; adds bezier 33 | Gdip_AddPathLines(pPath, "262,120|265,95|269,110|280,110|284,95|287,120") ; adds lines 34 | Gdip_AddPathBezier(pPath, 287,120, 305,120, 320,120, 330,95) 35 | Gdip_AddPathLine(pPath, 330,95, 439,95) 36 | Gdip_AddPathBeziers(pPath, "439,95|406,108|381,126|389,159|322,157|287,170|275,206|262,170|227,157|160,159|168,126|144,109|110,95") ; adds beziers 37 | Gdip_ClosePathFigure(pPath) ; closes the current figure of this path 38 | 39 | 40 | ;=== Fill & draw path (Bat) === ; now when the path is finished, we can fill it with brushes and outline with pens 41 | ;pPen := Gdip_CreatePen(0x22ffffff, 14), Gdip_DrawPath(G, pPen, pPath), Gdip_DeletePen(pPen) ; uncomment to draw extra outline 42 | 43 | pBrush := Gdip_CreateLineBrushFromRect(0, 95, w, (h-190)/2, 0xff110000, 0xff664040) 44 | Gdip_FillPath(G, pBrush, pPath) ; fill Bat background 1 45 | Gdip_DeleteBrush(pBrush) 46 | 47 | pBrush := Gdip_BrushCreateHatch(0xff000000, 0x00000000, 21) 48 | Gdip_FillPath(G, pBrush, pPath) ; fill Bat background 2 49 | Gdip_DeleteBrush(pBrush) 50 | 51 | pPen := Gdip_CreatePen(0xffa5a5a5, 5) 52 | Gdip_DrawPath(G, pPen, pPath) ; draw Bat outline 1 53 | Gdip_DeletePen(pPen) 54 | 55 | pPen := Gdip_CreatePen(0xff000000, 1) 56 | Gdip_DrawPath(G, pPen, pPath) ; draw Bat outline 2 57 | Gdip_DeletePen(pPen) 58 | 59 | Gdip_DeletePath(pPath) ; delete the Path as it is no longer needed and wastes memory 60 | 61 | 62 | ;=== Update, Delete, Shutdown === 63 | UpdateLayeredWindow(hGui, hdc, (A_ScreenWidth-w)//2, (A_ScreenHeight-h)//2, w, h) 64 | SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc) 65 | Gdip_DeleteGraphics(G) 66 | Gdip_Shutdown(pToken) 67 | return 68 | 69 | 70 | Esc::ExitApp 71 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.14-RazorHalo-Rotate-At-Center.ahk: -------------------------------------------------------------------------------- 1 | ;Tested on A_AhkVersion v2 x64 alpha 108 2 | ;Need to include your path to Gdip or have in the same directory as script 3 | #Include ../Gdip_All.ahk 4 | 5 | OnMessage(0x200, "OnWM_MOUSEMOVE") 6 | OnMessage(0x20A, "OnWM_MOUSEWHEEL") 7 | 8 | ;Create a GUI 9 | Mapper := GuiCreate("-DPIScale +OwnDialogs") 10 | Mapper.Show("NA w600 h600") 11 | hMap := Mapper.hwnd 12 | 13 | Global w, h, pToken, hbm, G, hdc, pPath, obm, pPen, hGui 14 | ;Create a Layered window ontop if the GUI to draw on with the GDI+ functions 15 | 16 | Gui1 := GuiCreate("-Caption +E0x80000 +LastFound +AlwaysOnTop -DPIScale +Parent" hMap) 17 | Gui1.Show("NA") 18 | hGui := Gui1.hwnd 19 | w:= 600, h:= 600 20 | 21 | pToken := Gdip_Startup() 22 | hbm := CreateDIBSection(w, h), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm) 23 | 24 | G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4) 25 | 26 | ;Create a GraphicsPath 27 | pPath := Gdip_CreatePath() ; creates a Path (GraphicsPath object) 28 | 29 | ;Add figure to path 30 | Gdip_StartPathFigure(pPath) ; starts a new figure in this Path 31 | Gdip_AddPathLine(pPath, 200, 200, 400, 200) 32 | Gdip_AddPathLine(pPath, 400, 200, 400, 400) 33 | Gdip_AddPathLine(pPath, 400, 400, 200, 400) 34 | Gdip_AddPathLine(pPath, 200, 400, 200, 200) 35 | Gdip_ClosePathFigure(pPath) ; closes the current figure of this path 36 | 37 | ;Create a Pen to draw with 38 | pPen := Gdip_CreatePen(0xff000000, 5) 39 | 40 | ;Rotate the graphic until exit 41 | Loop { 42 | Gdip_GraphicsClear(G) ; Clear the graphics 43 | Gdip_RotatePathAtCenter(pPath, 5) ; Rotate the path by 5deg on its center 44 | Gdip_DrawPath(G, pPen, pPath) ; draw rectangle 45 | UpdateLayeredWindow(hGui, hdc, 0, 0, w, h) ; Update the layred window 46 | Sleep 100 47 | } 48 | 49 | Esc:: 50 | MapperGuiEscape: 51 | MapperGuiClose: 52 | 53 | ;Cleanup and Exit 54 | If pPen 55 | Gdip_DeletePen(pPen) 56 | SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc) 57 | Gdip_DeleteGraphics(G) 58 | Gdip_Shutdown(pToken) 59 | Mapper.Destroy() 60 | ExitApp 61 | 62 | ;HitTest if the mouse in inside the graphicspath 63 | OnWM_MOUSEMOVE(wParam, lParam, msg, hWnd) { 64 | ; Global 65 | 66 | mX := lParam & 0xFFFF ;get low order 67 | mY := lParam >> 16 ;get high order 68 | 69 | hit := Gdip_IsVisiblePathPoint(pPath, mX, mY, G) 70 | hit := "Mouse hit = " . Hit 71 | Tooltip(hit) 72 | } 73 | 74 | OnWM_MOUSEWHEEL(wParam, lParam, msg, hWnd) { 75 | ; Global 76 | 77 | mX := lParam & 0xFFFF ;get low order 78 | mY := lParam >> 16 ;get high order 79 | delta := wParam >> 16 ;120 for zoom in, 65416 for zoom out 80 | 81 | Scale := Delta=120 ? 0.9 : 1.1 ;Adjust scale factor 82 | ;TODO - Factor in the mouse coords to zoom in/out at that point 83 | 84 | Gdip_GraphicsClear(G) 85 | pMatrix := Gdip_CreateMatrix() 86 | 87 | ; Calculate center of Window which will be the center of the graphics path 88 | cX := w / 2 89 | cY := h / 2 90 | 91 | ; Move Centre point of square to origin of graphics object, then scale and then move back to original center point of square 92 | GDip_TranslateMatrix(pMatrix, -cX, -cY, 1) 93 | Gdip_ScaleMatrix(pMatrix, Scale, Scale, 1) 94 | GDip_TranslateMatrix(pMatrix, cX, cY, 1) 95 | 96 | ; Apply the transformations 97 | Gdip_TransformPath(pPath, pMatrix) 98 | 99 | ; Redraw the path and update the window 100 | Gdip_DrawPath(G, pPen, pPath) 101 | UpdateLayeredWindow(hGui, hdc, 0, 0, w, h) 102 | } 103 | 104 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.15-Just-Me-Path-Gradients.ahk: -------------------------------------------------------------------------------- 1 | ; https://autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/page-65 2 | ; by just_me 3 | ; adapted to ahk v2 by Marius Șucan 4 | 5 | #Include ../Gdip_All.ahk 6 | Global w, h 7 | W := 200 8 | H := 200 9 | 10 | GdipToken := Gdip_Startup() 11 | 12 | Gui1 := GuiCreate("+LastFound +AlwaysOnTop +OwnDialogs") 13 | hGui := Gui1.hwnd 14 | Gui1.Title := "Path gradients" 15 | 16 | ctrlPicA := Gui1.Add("Picture" , "w" w " h" h) 17 | hpic := ctrlPicA.hwnd 18 | ScaleX := 0.0 ; focus scale for x-axis (0.0 - 1.0) 19 | ScaleY := 0.0 ; focus scale for y-axis (0.0 - 1.0) 20 | BlendFocus := 0.5 ; blend focus (0.0 - 1.0) 21 | PathGradientBrush(hpic, BlendFocus, ScaleX, ScaleY) 22 | ctrlPicB := Gui1.Add("Picture" , "w" w " h" h) 23 | hpic := ctrlPicB.hwnd 24 | ScaleX := 0.75 ; focus scale for x-axis (0.0 - 1.0) 25 | ScaleY := 0.75 ; focus scale for y-axis (0.0 - 1.0) 26 | BlendFocus := 1.0 ; blend focus (0.0 - 1.0) 27 | PathGradientBrush(hpic, BlendFocus, ScaleX, ScaleY) 28 | Gui1.Show("AutoSize") 29 | Return 30 | 31 | GuiClose: 32 | GuiEscape: 33 | Gdip_ShutDown(GdipToken) 34 | ExitApp 35 | 36 | PathGradientBrush(ctrl, BlendFocus, ScaleX, ScaleY) { 37 | SS_BITMAP := 0xE 38 | SS_ICON := 0x3 39 | STM_SETIMAGE := 0x172 40 | IMAGE_BITMAP := 0x0 41 | 42 | PBitMap := Gdip_CreateBitmap(W, H) 43 | PGraphics := Gdip_GraphicsFromImage(PBitMap) 44 | Gdip_SetSmoothingMode(PGraphics, 4) 45 | PPath := Gdip_CreatePath(PGraphics) 46 | Gdip_AddPathRectangle(PPath, 0, 0, W, H) 47 | PBrush := Gdip_PathGradientCreateFromPath(PPath) 48 | Gdip_PathGradientSetCenterPoint(PBrush, W / 2, H / 2) 49 | Gdip_PathGradientSetCenterColor(PBrush, 0xFFFFFFFF) 50 | Gdip_PathGradientSetSurroundColors(PBrush, 0xFF202090) 51 | Gdip_PathGradientSetSigmaBlend(PBrush, BlendFocus) 52 | Gdip_PathGradientSetLinearBlend(PBrush, BlendFocus) 53 | Gdip_PathGradientSetFocusScales(PBrush, ScaleX, ScaleY) 54 | Gdip_FillPath(PGraphics, PBrush, PPath) 55 | HBitmap := Gdip_CreateHBITMAPFromBitmap(PBitMap, 0x00FFFFFF) 56 | Gdip_DeleteBrush(PBrush) 57 | Gdip_DeletePath(PPath) 58 | Gdip_DeleteGraphics(PGraphics) 59 | Gdip_DisposeImage(PBitmap) 60 | ; Set control styles 61 | ControlSetStyle("-" SS_ICON, ctrl) 62 | ControlSetStyle("+" SS_BITMAP, ctrl) 63 | ; Assign the bitmap 64 | SendMessage(STM_SETIMAGE, IMAGE_BITMAP, HBitmap, ctrl) 65 | ; Done! 66 | ToolTip(ctrl) 67 | DeleteObject(HBitmap) 68 | } 69 | 70 | Esc:: 71 | ExitApp 72 | Return -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.17-robodesign-Draw-Customized-Texts.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 1 written by tic (Tariq Porter) 2 | ; Requires Gdip_all.ahk v1.69 or newerr 3 | ; GDI+ library compilation of user contributed GDI+ functions 4 | ; made by Marius Șucan: https://github.com/marius-sucan/AHK-GDIp-Library-Compilation 5 | 6 | ; Uncomment if Gdip.ahk is not in your standard library 7 | #Include ..\Gdip_All.ahk 8 | 9 | ; Start gdi+ 10 | If !pToken := Gdip_Startup() 11 | { 12 | MsgBox("Gdiplus failed to start. Please ensure you have gdiplus on your system") 13 | ExitApp 14 | } 15 | 16 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 17 | Width := 1400, Height := 1050 18 | 19 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 20 | Gui1 := GuiCreate("-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs") 21 | Gui1.Show("NA") 22 | ; Get a handle to this window we have created in order to update it later 23 | hwnd1 := Gui1.hwnd 24 | 25 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 26 | hbm := CreateDIBSection(Width, Height) 27 | 28 | ; Get a device context compatible with the screen 29 | hdc := CreateCompatibleDC() 30 | 31 | ; Select the bitmap into the device context 32 | obm := SelectObject(hdc, hbm) 33 | 34 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 35 | G := Gdip_GraphicsFromHDC(hdc) 36 | 37 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 38 | Gdip_SetSmoothingMode(G, 4) 39 | 40 | ; fill the background 41 | pBrushBgr := Gdip_BrushCreateSolid(0xddeeffee) 42 | Gdip_FillRectangle(G, pBrushBgr, 1, 1, 990, 990) 43 | 44 | ; Create a slightly transparent (66) blue brush (ARGB = Transparency, red, green, blue) to draw a rectangle 45 | pBrush := Gdip_BrushCreateSolid(0x660000ff) 46 | 47 | ; Draws a text along a polygonal line defined by PolygonalLine 48 | PolygonalLine := "50,190|400,390|890,190|800,990" 49 | Gdip_DrawStringAlongPolygon(G, "Oh my God, example text!", "Arial", 100, 1, pBrush, PolygonalLine) 50 | 51 | ; Now draw a text contour rotated at 45 degrees 52 | pPen := Gdip_CreatePen("0xCC990011", 5) 53 | Gdip_SetPenDashStyle(pPen, 2) 54 | Gdip_DrawOrientedString(G, "Contour text example", "Verdana", 90, 1, 20, 500, 800, 800, 45, pBrushBgr, pPen, 1) 55 | 56 | ; Delete the brush as it is no longer needed and wastes memory 57 | Gdip_DeleteBrush(pBrush) 58 | Gdip_DeleteBrush(pBrushBgr) 59 | Gdip_DeletePen(pPen) 60 | 61 | 62 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 63 | ; So this will position our gui at (0,0) with the Width and Height specified earlier 64 | UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) 65 | 66 | 67 | ; Select the object back into the hdc 68 | SelectObject(hdc, obm) 69 | 70 | ; Now the bitmap may be deleted 71 | DeleteObject(hbm) 72 | 73 | ; Also the device context related to the bitmap may be deleted 74 | DeleteDC(hdc) 75 | 76 | ; The graphics may now be deleted 77 | Gdip_DeleteGraphics(G) 78 | Return 79 | 80 | ;####################################################################### 81 | 82 | Esc:: 83 | Gdip_Shutdown(pToken) 84 | ExitApp 85 | Return 86 | 87 | Exit: 88 | ; gdi+ may now be shutdown on exiting the program 89 | Gdip_Shutdown(pToken) 90 | ExitApp 91 | Return -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.2-Draw.Outlined.Shapes.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 2 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to draw a single ellipse and rectangle to the screen, but just the outlines of these shapes 5 | 6 | #SingleInstance Force 7 | ;#NoEnv 8 | ;SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 22 | Width := 600, Height := 400 23 | 24 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 25 | ;AHK v1 26 | ;Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 27 | ;Gui, 1: Show, NA 28 | Gui1 := GuiCreate("-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs") 29 | Gui1.Show("NA") 30 | 31 | ; Get a handle to this window we have created in order to update it later 32 | hwnd1 := WinExist() 33 | 34 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 35 | hbm := CreateDIBSection(Width, Height) 36 | 37 | ; Get a device context compatible with the screen 38 | hdc := CreateCompatibleDC() 39 | 40 | ; Select the bitmap into the device context 41 | obm := SelectObject(hdc, hbm) 42 | 43 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 44 | G := Gdip_GraphicsFromHDC(hdc) 45 | 46 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 47 | Gdip_SetSmoothingMode(G, 4) 48 | 49 | ; Create a fully opaque red pen (ARGB = Transparency, red, green, blue) of width 3 (the thickness the pen will draw at) to draw a circle 50 | pPen := Gdip_CreatePen(0xffff0000, 3) 51 | 52 | ; Draw an ellipse into the graphics of the bitmap (this being only the outline of the shape) using the pen created 53 | ; This pen has a width of 3, and is drawing from coordinates (100,50) an ellipse of 200x300 54 | Gdip_DrawEllipse(G, pPen, 100, 50, 200, 300) 55 | 56 | ; Delete the pen as it is no longer needed and wastes memory 57 | Gdip_DeletePen(pPen) 58 | 59 | ; Create a slightly transparent (66) blue pen (ARGB = Transparency, red, green, blue) to draw a rectangle 60 | ; This pen is wider than the last one, with a thickness of 10 61 | pPen := Gdip_CreatePen(0x660000ff, 10) 62 | 63 | ; Draw a rectangle onto the graphics of the bitmap using the pen just created 64 | ; Draws the rectangle from coordinates (250,80) a rectangle of 300x200 and outline width of 10 (specified when creating the pen) 65 | Gdip_DrawRectangle(G, pPen, 250, 80, 300, 200) 66 | 67 | ; Delete the brush as it is no longer needed and wastes memory 68 | Gdip_DeletePen(pPen) 69 | 70 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 71 | ; So this will position our gui at (0,0) with the Width and Height specified earlier 72 | UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) 73 | 74 | 75 | ; Select the object back into the hdc 76 | SelectObject(hdc, obm) 77 | 78 | ; Now the bitmap may be deleted 79 | DeleteObject(hbm) 80 | 81 | ; Also the device context related to the bitmap may be deleted 82 | DeleteDC(hdc) 83 | 84 | ; The graphics may now be deleted 85 | Gdip_DeleteGraphics(G) 86 | Return 87 | 88 | ;####################################################################### 89 | 90 | ExitFunc(ExitReason, ExitCode) 91 | { 92 | global 93 | ; gdi+ may now be shutdown on exiting the program 94 | Gdip_Shutdown(pToken) 95 | } 96 | 97 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.5-Create.Bitmap.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 5 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Example to create a bitmap, fill it with some shapes and save to file 5 | 6 | #SingleInstance Force 7 | ;#NoEnv 8 | ;SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | 20 | ; Create a 400x400 pixel gdi+ bitmap 21 | pBitmap := Gdip_CreateBitmap(400, 400) 22 | 23 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 24 | G := Gdip_GraphicsFromImage(pBitmap) 25 | 26 | ; Set the smoothing mode to antialias = 4 to make shapes appear smoother (only used for vector drawing and filling) 27 | Gdip_SetSmoothingMode(G, 4) 28 | 29 | ; Create a hatched brush with background and foreground colours specified (HatchStyleBackwardDiagonal = 3) 30 | pBrush := Gdip_BrushCreateHatch(0xff553323, 0xffc09e8e, 31) 31 | ; Draw into the graphics of the bitmap from coordinates (100,80) a filled rectangle with 200 width and 250 height using the brush created 32 | Gdip_FillRectangle(G, pBrush, (400-200)//2, (400-250)//2, 200, 250) 33 | ; Delete the brush created to save memory as we don't need the same brush anymore 34 | Gdip_DeleteBrush(pBrush) 35 | 36 | ; Create a hatched brush with background and foreground colours specified (HatchStyleBackwardDiagonal = 3) 37 | pBrush := Gdip_BrushCreateHatch(0xff000000, 0xff4d3538, 31) 38 | ; Draw an ellipse into the graphics with the brush we just created. 40 degree sweep angle starting at 250 degrees (0 degrees from right horizontal) 39 | Gdip_FillPie(G, pBrush, (400-80)//2, (400-80)//2, 80, 80, 250, 40) 40 | ; Delete the brush created to save memory as we don't need the same brush anymore 41 | Gdip_DeleteBrush(pBrush) 42 | 43 | ; Create a white brush 44 | pBrushWhite := Gdip_BrushCreateSolid(0xffffffff) 45 | ; Create a black brush 46 | pBrushBlack := Gdip_BrushCreateSolid(0xff000000) 47 | 48 | ; Loop to draw 2 ellipses filling them with white then black in the centre of each 49 | Loop 2 50 | { 51 | x := (A_Index = 1) ? 120 : 220, y := 100 52 | Gdip_FillEllipse(G, pBrushWhite, x, y, 60, 60) 53 | x += 15, y+=15 54 | Gdip_FillEllipse(G, pBrushBlack, x, y, 30, 30) 55 | } 56 | ; Delete both brushes 57 | Gdip_DeleteBrush(pBrushWhite), Gdip_DeleteBrush(pBrushBlack) 58 | 59 | ; Create a hatched brush with background and foreground colours specified (HatchStyle30Percent = 10) 60 | pBrush := Gdip_BrushCreateHatch(0xfff22231, 0xffa10f19, 10) 61 | ; Again draw another ellipse into the graphics with the specified brush 62 | Gdip_FillPie(G, pBrush, 150, 200, 100, 80, 0, 180) 63 | ; Delete the brush 64 | Gdip_DeleteBrush(pBrush) 65 | 66 | ; Create a 3 pixel wide slightly transparent black pen 67 | pPen := Gdip_CreatePen(0xbb000000, 3) 68 | 69 | ; Create some coordinates for the lines in format x1,y1,x2,y2 then loop and draw all the lines 70 | Lines := "180,200,130,220|180,190,130,195|220,200,270,220|220,190,270,195" 71 | for k,v in StrSplit(Lines, "|") 72 | { 73 | Pos := StrSplit(v, ",") 74 | Gdip_DrawLine(G, pPen, Pos[1], Pos[2], Pos[3], Pos[4]) 75 | } 76 | ; Delete the pen 77 | Gdip_DeletePen(pPen) 78 | 79 | 80 | ; Save the bitmap to file "File.png" (extension can be .png,.bmp,.jpg,.tiff,.gif) 81 | ; Bear in mind transparencies may be lost with some image formats and will appear black 82 | Gdip_SaveBitmapToFile(pBitmap, "File.png") 83 | 84 | MsgBox "Bitmap saved as 'File.png' " 85 | 86 | ; The bitmap can be deleted 87 | Gdip_DisposeImage(pBitmap) 88 | 89 | ; The graphics may now be deleted 90 | Gdip_DeleteGraphics(G) 91 | 92 | ; ...and gdi+ may now be shutdown 93 | Gdip_Shutdown(pToken) 94 | ExitApp 95 | Return 96 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.6-Image.Editing.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 6 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Example to take files from disk, load them onto a background and save back to disk 5 | 6 | #SingleInstance Force 7 | ;#NoEnv 8 | ;SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Specify both of the files we are going to use 14 | File1 := "needle.png" 15 | File2 := "background.png" 16 | 17 | ; Start gdi+ 18 | If !pToken := Gdip_Startup() 19 | { 20 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 21 | ExitApp 22 | } 23 | 24 | ; If the images we want to work with do not exist on disk, then download them... 25 | If !(FileExist(File1) && FileExist(File2)) 26 | { 27 | MsgBox "Cannot find files 'needle.png' and 'background.png' in this same directory" 28 | ExitApp 29 | } 30 | 31 | 32 | ; Create a 500x500 pixel gdi+ bitmap (this will be the entire drawing area we have to play with) 33 | pBitmap := Gdip_CreateBitmap(600, 600) 34 | 35 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 36 | G := Gdip_GraphicsFromImage(pBitmap) 37 | 38 | ; Create a green brush (this will be used to fill the background with green). The brush is fully opaque (ARGB) 39 | pBrush := Gdip_BrushCreateSolid(0xff00ff00) 40 | 41 | ; Filll the entire graphics of the bitmap with the green brush (this will be out background colour) 42 | Gdip_FillRectangle(G, pBrush, 0, 0, 600, 600) 43 | 44 | ; Delete the brush created to save memory as we don't need the same brush anymore 45 | Gdip_DeleteBrush(pBrush) 46 | 47 | 48 | ; Get bitmaps for both the files we are going to be working with 49 | pBitmapFile1 := Gdip_CreateBitmapFromFile(File1), pBitmapFile2 := Gdip_CreateBitmapFromFile(File2) 50 | 51 | ; Get the width and height of the 1st bitmap 52 | Width := Gdip_GetImageWidth(pBitmapFile1), Height := Gdip_GetImageHeight(pBitmapFile1) 53 | 54 | ; Draw the 1st bitmap (1st image) onto our "canvas" (the graphics of the original bitmap we created) with the same height and same width 55 | ; at coordinates (25,30).....We will be ignoring the matrix parameter for now. This can be used to change opacity and colours when drawing 56 | Gdip_DrawImage(G, pBitmapFile1, 25, 30, Width, Height, 0, 0, Width, Height) 57 | 58 | 59 | ; Do the same again for the 2nd file, but change the coordinates to (250,260)..... 60 | 61 | Width := Gdip_GetImageWidth(pBitmapFile2), Height := Gdip_GetImageHeight(pBitmapFile2) 62 | Gdip_DrawImage(G, pBitmapFile2, 250, 260, Width, Height, 0, 0, Width, Height) 63 | 64 | ; Dispose of both of these bitmaps we created from the images on disk, as they are now been used...They are on 65 | ; the graphics of the bitmap of our created "canvas" 66 | Gdip_DisposeImage(pBitmapFile1), Gdip_DisposeImage(pBitmapFile2) 67 | 68 | 69 | ; Save the bitmap to file "File.png" (extension can be .png,.bmp,.jpg,.tiff,.gif) 70 | ; Bear in mind transparencies may be lost with some image formats and will appear black 71 | Gdip_SaveBitmapToFile(pBitmap, "FinalImage.png") 72 | 73 | MsgBox "Image saved as 'FinalImage.png' " 74 | 75 | ; The bitmap can be deleted 76 | Gdip_DisposeImage(pBitmap) 77 | 78 | ; The graphics may now be deleted 79 | Gdip_DeleteGraphics(G) 80 | 81 | ; ...and gdi+ may now be shutdown 82 | Gdip_Shutdown(pToken) 83 | ExitApp 84 | Return 85 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.Tutorial.7-Draw.draggable.rounded.rectangle.ahk: -------------------------------------------------------------------------------- 1 | ; gdi+ ahk tutorial 7 written by tic (Tariq Porter) 2 | ; Requires Gdip.ahk either in your Lib folder as standard library or using #Include 3 | ; 4 | ; Tutorial to draw a rounded rectangle as a gui that you can drag 5 | 6 | #SingleInstance Force 7 | ;#NoEnv 8 | ;SetBatchLines -1 9 | 10 | ; Uncomment if Gdip.ahk is not in your standard library 11 | #Include ../Gdip_All.ahk 12 | 13 | ; Start gdi+ 14 | If !pToken := Gdip_Startup() 15 | { 16 | MsgBox "Gdiplus failed to start. Please ensure you have gdiplus on your system" 17 | ExitApp 18 | } 19 | OnExit("ExitFunc") 20 | 21 | ; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap 22 | Width := 300, Height := 200 23 | 24 | ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption 25 | ;AHK v1 26 | ;Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs 27 | ;Gui, 1: Show, NA 28 | Gui1 := GuiCreate("-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs") 29 | Gui1.Show("NA") 30 | 31 | ; Get a handle to this window we have created in order to update it later 32 | hwnd1 := WinExist() 33 | 34 | ; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything 35 | hbm := CreateDIBSection(Width, Height) 36 | 37 | ; Get a device context compatible with the screen 38 | hdc := CreateCompatibleDC() 39 | 40 | ; Select the bitmap into the device context 41 | obm := SelectObject(hdc, hbm) 42 | 43 | ; Get a pointer to the graphics of the bitmap, for use with drawing functions 44 | G := Gdip_GraphicsFromHDC(hdc) 45 | 46 | ; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling) 47 | Gdip_SetSmoothingMode(G, 4) 48 | 49 | ; Create a partially transparent, black brush (ARGB = Transparency, red, green, blue) to draw a rounded rectangle with 50 | pBrush := Gdip_BrushCreateSolid(0x77000000) 51 | 52 | ; Fill the graphics of the bitmap with a rounded rectangle using the brush created 53 | ; Filling the entire graphics - from coordinates (0, 0) the entire width and height 54 | ; The last parameter (20) is the radius of the circles used for the rounded corners 55 | Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20) 56 | 57 | ; Delete the brush as it is no longer needed and wastes memory 58 | Gdip_DeleteBrush(pBrush) 59 | 60 | 61 | ; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen 62 | ; With some simple maths we can place the gui in the centre of our primary monitor horizontally and vertically at the specified heigth and width 63 | UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height) 64 | 65 | ; By placing this OnMessage here. The function WM_LBUTTONDOWN will be called every time the user left clicks on the gui 66 | OnMessage(0x201, "WM_LBUTTONDOWN") 67 | 68 | 69 | ; Select the object back into the hdc 70 | SelectObject(hdc, obm) 71 | 72 | ; Now the bitmap may be deleted 73 | DeleteObject(hbm) 74 | 75 | ; Also the device context related to the bitmap may be deleted 76 | DeleteDC(hdc) 77 | 78 | ; The graphics may now be deleted 79 | Gdip_DeleteGraphics(G) 80 | Return 81 | 82 | ;####################################################################### 83 | 84 | ; This function is called every time the user clicks on the gui 85 | ; The PostMessage will act on the last found window (this being the gui that launched the subroutine, hence the last parameter not being needed) 86 | WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) 87 | { 88 | PostMessage 0xA1, 2 89 | } 90 | 91 | ;####################################################################### 92 | 93 | ExitFunc(ExitReason, ExitCode) 94 | { 95 | global 96 | ; gdi+ may now be shutdown on exiting the program 97 | Gdip_Shutdown(pToken) 98 | } 99 | 100 | -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.tutorial.file-fish.bra: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/Gdip.tutorial.file-fish.bra -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/MJ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/MJ.jpg -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/background.png -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/needle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Modules/Lib/AHK-GDIp-Library-Compilation/ahk-v2/Examples-ahk-v2/needle.png -------------------------------------------------------------------------------- /Modules/Lib/AHK-GDIp-Library-Compilation/credits.txt: -------------------------------------------------------------------------------- 1 | Please see functions-list.txt file. 2 | 3 | Guest3456 inspired me to create this file, to facilitate interested parties to easier find the «Credits» section from within the referenced files ^_^. 4 | 5 | Inspiration source: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6517&start=340#p317389 6 | -------------------------------------------------------------------------------- /Modules/Lib/README.md: -------------------------------------------------------------------------------- 1 | https://github.com/marius-sucan/AHK-GDIp-Library-Compilation -------------------------------------------------------------------------------- /Modules/QuickInput.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 名称:快速输入各种时间戳和随机数 3 | ; 描述:快速输入各种时间戳和随机数 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 支持:https://github.com/snomiao/CapsLockX 7 | ; 版本:v2020.06.27 8 | ; 版权:Copyright © 2017-2024 Snowstar Laboratory. All Rights Reserved. 9 | ; ========== CapsLockX ========== 10 | 11 | CLX_AppendHelp( CLX_LoadHelpFrom(CLX_THIS_MODULE_HELP_FILE_PATH)) 12 | 13 | Return 14 | 15 | GenPassword(Chars, Length := 16) 16 | { 17 | Min := 1 18 | Max := StrLen(chars) 19 | pw := "" 20 | Loop %Length% { 21 | Random StartPos, Min, Max 22 | pw := pw SubStr(Chars, StartPos, 1) 23 | } 24 | Return pw 25 | } 26 | SNODateStringGenerate() 27 | { 28 | FormatTime, TimeString, , (yyyyMMdd) 29 | return TimeString 30 | } 31 | ISODateStringGenerate() 32 | { 33 | FormatTime, TimeString, , yyyy-MM-dd 34 | return TimeString 35 | } 36 | TimeStringGenerate() 37 | { 38 | FormatTime, TimeString, , (yyyyMMdd.HHmmss) 39 | return TimeString 40 | } 41 | DateTimeStringGenerate() 42 | { 43 | FormatTime, TimeString, , yyyy-MM-dd HH:mm:ss 44 | return TimeString 45 | } 46 | GenRandomHex(Length) 47 | { 48 | ; 此处 `` 为转义 49 | Chars := "0123456789abcdef" 50 | Min := 1 51 | Max := StrLen(chars) 52 | 53 | randHex := "" 54 | Loop %Length% { 55 | Random StartPos, Min, Max 56 | randHex := randHex SubStr(Chars, StartPos, 1) 57 | } 58 | Return randHex 59 | } 60 | GenRandomUUID() 61 | { 62 | Return GenRandomHex(8) "-" GenRandomHex(4) "-" GenRandomHex(4) "-" GenRandomHex(4) "-" GenRandomHex(12) 63 | } 64 | QuickTextInput(str) 65 | { 66 | SendInput {Text}%str% 67 | } 68 | 69 | JapaneseRomajiChar() 70 | { 71 | return GenPassword("xktnmwhrypbdsfg", 1)GenPassword("aeiou", 1) 72 | } 73 | JapaneseRomaji7Char() 74 | { 75 | return JapaneseRomajiChar()JapaneseRomajiChar()JapaneseRomajiChar()JapaneseRomajiChar()JapaneseRomajiChar()JapaneseRomajiChar()JapaneseRomajiChar() 76 | } 77 | 78 | doubleSectionPassword() 79 | { 80 | CharsFirst:="123456789ABCDEFGHJKLMNPQRSTUVWXYZ" 81 | CharsRest:="123456789abcdefghijkmnopqrstuvwxyz" 82 | section1 := GenPassword(CharsFirst, 1) GenPassword(CharsRest, 6) 83 | section2 := GenPassword(CharsRest, 7) 84 | QuickTextInput(section1 "_" section2) 85 | } 86 | 87 | #if 88 | 89 | :*?:#D#:: ; 日期输入:如 2022-02-17 90 | QuickTextInput(ISODateStringGenerate()) 91 | return 92 | 93 | :*?:#T#:: ; 日期时间输入:2022-02-17 22:07:33 94 | QuickTextInput(DateTimeStringGenerate()) 95 | return 96 | 97 | :*?:#DD#:: ; 带括号日期输入:如 (20220217) 98 | QuickTextInput(SNODateStringGenerate()) 99 | return 100 | 101 | :*?:#TT#:: ; 带括号时间输入:(20220217.220717) 102 | QuickTextInput(TimeStringGenerate()) 103 | return 104 | 105 | :*?:#NPW#:: ; 随机输入数字密码如: 7500331260229289 106 | QuickTextInput(GenPassword("0123456789", 16)) 107 | return 108 | 109 | :*?:#HEX#:: ; 随机输入数字字母密码如: 7618DB5EAC135893 110 | QuickTextInput(GenPassword("0123456789ABCDEF", 16)) 111 | return 112 | 113 | :*?:#HEXL#:: ; 随机输入小写16进制如: 31a0c5dcc46f0ff6 114 | QuickTextInput(GenPassword("0123456789abcdef", 16)) 115 | return 116 | 117 | :*?:#DPW#:: ; 随机输入2段式密码如: Zg1y9xy_hcswt71 118 | doubleSectionPassword() 119 | return 120 | 121 | :*?:#QPW#:: ; 随机输入4段密码如:4428-UW4R-58YS-ALLR 122 | QuickTextInput(GenPassword("123456789ABCDEFGHJKLMNPQRSTUVWXYZ", 4) "-" GenPassword("123456789ABCDEFGHJKLMNPQRSTUVWXYZ", 4) "-" GenPassword("123456789ABCDEFGHJKLMNPQRSTUVWXYZ", 4) "-" GenPassword("123456789ABCDEFGHJKLMNPQRSTUVWXYZ", 4)) 123 | return 124 | 125 | :*?:#UUID#:: ; 随机输入偽UUID如:345103d0-9de1-d5c6-425f-867dfbf555ea 126 | QuickTextInput(GenRandomUUID()) 127 | return 128 | 129 | :*?:#PW#:: ; 随机输入数字字母密码如: yyCTCNYodECTLr2h 130 | QuickTextInput(GenPassword("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", 16)) 131 | return 132 | 133 | :*?:#WPW#:: ; 随机输入数字字母密码如: FtD5BB1m5H98eY7Y 134 | QuickTextInput(GenPassword("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", 16)) 135 | return 136 | 137 | :*?:#SPW#:: ; 随机输入数字字母符号密码如:KO?C[D_>!c$sQ-|7] 138 | QuickTextInput(GenPassword("!""#$%&\'()*+, -./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_``abcdefghijklmnopqrstuvwxyz{|}~", 16)) 139 | return 140 | 141 | :*?:#JPW#:: ; 随机输入日本語発音密码如: 142 | QuickTextInput( JapaneseRomaji7Char() "-" JapaneseRomaji7Char() ) 143 | return 144 | -------------------------------------------------------------------------------- /Modules/QuickInput.md: -------------------------------------------------------------------------------- 1 | # 快捷输入 2 | 3 | | 模式 | 快捷输入 | 说明 | 4 | | ---- | -------- | ----------------------------------------------- | 5 | | 全局 | `#D#` | 日期输入:`(20220217)` | 6 | | 全局 | `#T#` | 时间输入:`(20220217.220717)` | 7 | | 全局 | `#DT#` | 日期时间输入:`2022-02-17 22:07:33` | 8 | | 全局 | `#NPW#` | 随机输入数字密码如: `7500331260229289` | 9 | | 全局 | `#PW#` | 随机输入数字字母密码如: `yyCTCNYodECTLr2h` | 10 | | 全局 | `#WPW#` | 随机输入数字字母密码如: `FtD5BB1m5H98eY7Y` | 11 | | 全局 | `#SPW#` | 随机输入数字字母符号密码如: `/})y+xK]z~>XKQ+p` | 12 | -------------------------------------------------------------------------------- /Modules/QuickTips.ahk: -------------------------------------------------------------------------------- 1 |  2 | global 环境热键提示 := 0 3 | 4 | return 5 | 6 | #if CapsLockXMode 7 | 8 | /:: 环境热键提示切换() 9 | 10 | 环境热键提示切换() 11 | { 12 | 环境热键提示 := !环境热键提示 13 | if ( 环境热键提示) { 14 | SceneTips() 15 | SetTimer, SceneTips, 1000 16 | } else { 17 | SetTimer, SceneTips, off 18 | } 19 | KeyWait / 20 | ToolTip 21 | } 22 | 23 | ; 新场景提示 24 | ; TODO 自动提示适用于场景的新热键 25 | ; 统计qt次数,优先显示显示次数少的 26 | SceneTipsRemove() 27 | { 28 | ToolTip 29 | } 30 | SceneTips() 31 | { 32 | static showMsg 33 | msg := "=== 环境热键提示 ===`n" 34 | if (CapsLockXMode) { 35 | msg .= "环境:CapsLockX 模式(或按住 CapsLockX )" "`n" 36 | } else { 37 | msg .= "环境:普通模式 " "`n" 38 | } 39 | msg .= Func("QuickTips").Call() 40 | if (showMsg != msg) { 41 | showMsg := msg 42 | ToolTip %msg% 43 | } 44 | } 45 | CLX_LongPressDown() 46 | { 47 | SceneTips() 48 | } 49 | CLX_LongPressUp() 50 | { 51 | SceneTipsRemove() 52 | } -------------------------------------------------------------------------------- /Modules/TomatoLife.md: -------------------------------------------------------------------------------- 1 | # 番茄时钟 2 | 3 | 25 分钟固定循环休息提醒。 4 | 5 | 使用 `CapsLockX + ,` 打开配置,然后修改 EnableScheduleTasks=1 即可启用本插件。 6 | 7 | - 使用番茄报时(00 分和 30 分播放工作铃声,每小时的 25 分和 55 分播放休息铃声)(需要先开启定时任务) 8 | 9 | ```ini 10 | UseTomatoLife=1 11 | ``` 12 | 13 | - 使用番茄报时时,自动切换桌面(使用番茄报时时,自动切换桌面(休息桌面为 1,工作桌面为 2) 14 | 15 | ```ini 16 | UseTomatoLifeSwitchVirtualDesktop=1 17 | ``` 18 | 19 | 注:如果只需要声音而不需要自动切换桌面的话,也可试试这款 Chrome 插件 [Tomato Life - Chrome 网上应用店](https://chrome.google.com/webstore/detail/25min-tomato-life/kkacpbmkhbljebmpcopjlgfgbgeokbhn) 20 | 21 | 注注: 本插件已经分离出一个独立项目,如果你喜欢番茄工作法的话可以参见雪星的 tomato-life 项目: [snomiao/tomato-life](https://github.com/snomiao/tomato-life) 22 | -------------------------------------------------------------------------------- /Modules/TurnOffScreenWhenLock.ahk: -------------------------------------------------------------------------------- 1 | global TurnOffScreenWhenLock := CLX_Config("TurnOffScreenWhenLock", "TurnOffScreenWhenLock", "0", t("按 Win + L 锁定电脑时,立即关闭屏幕,默认不启用,你可以按 Win+Alt+L 达到该效果")) 2 | 3 | Return 4 | 5 | ; Win+Shift+L 锁定电脑 + 关闭屏幕 6 | +#l:: 7 | Run rundll32.exe user32.dll LockWorkStation, , Hide 8 | SendMessage, 0x112, 0xF170, 2, , Program Manager 9 | Sleep 1000 10 | SendMessage, 0x112, 0xF170, 2, , Program Manager 11 | Sleep 1000 12 | SendMessage, 0x112, 0xF170, 2, , Program Manager 13 | Return 14 | 15 | ; Win+Alt+L 仅关闭屏幕,按任意键可解除 16 | !#l:: 17 | SendMessage, 0x112, 0xF170, 2, , Program Manager 18 | Sleep 1000 19 | SendMessage, 0x112, 0xF170, 2, , Program Manager 20 | Return 21 | 22 | #if TurnOffScreenWhenLock 23 | 24 | ; Run rundll32.exe user32.dll LockWorkStation, , Hide 25 | ; cmdScreenOff := "cmd /c start """" powershell (Add-Type '[DllImport(\""user32.dll\"")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1, 0x0112, 0xF170, 2)" 26 | ; SendMessage, 0x112, 0xF170, 2, , Program Manager 27 | 28 | ~#l:: 29 | SendMessage, 0x112, 0xF170, 2, , Program Manager 30 | Sleep 1000 31 | SendMessage, 0x112, 0xF170, 2, , Program Manager 32 | Return 33 | 34 | ; ref: [按下Win+L键,玄机来了]( http://m.cfan.com.cn/article/105095 ) 35 | -------------------------------------------------------------------------------- /Modules/TurnOffScreenWhenLock.md: -------------------------------------------------------------------------------- 1 | # 锁屏自动息屏 2 | 3 | 按 Win + L 锁屏时,立即关闭屏幕,适用于准备睡觉的时候自动把电脑屏幕关掉,不让它在睡觉的时候刺眼…… 4 | 按 Win + Alt + L 立即关闭屏幕,适用于准备睡觉的时候把电脑屏幕关掉,不让它在睡觉的时候刺眼…… 5 | 6 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Versions of your project are currently being supported with security updates: 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | latest | :white_check_mark: | 10 | | other | :x: | 11 | 12 | 17 | 18 | ## Reporting a Vulnerability 19 | 20 | you can report a Vulnerability to my contacts: 21 | 22 | - mail: snomiao@gmail.com 23 | - QQ: 997596439 24 | - telegram: [@snomiao](http://t.me/snomiao) 25 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ### 发展路线 🛰️ RoadMap 2 | 3 | CapsLockX 的核心理念是:简化系统操作逻辑,提升操作效率,且不与原有习惯键位冲突。 4 | 5 | 1. [x] 按 CapsLockX + - 键显示对应帮助(目前的显示样式相当草率) 6 | 2. [ ] i18n (eh 这个真得有) 7 | 3. [ ] 自动更新(虽然 git pull 一下也不是不行) 8 | 4. [ ] 初次使用上手教程(这个现在有点简陋……) 9 | 5. [ ] 插件管理器(虽然文件系统也可以搞定) 10 | 6. [ ] 自动配置同步功能(虽然一般来说扔 onedrive 就够) 11 | 7. [ ] 易用的选项配置的 UI 界面(虽然改 ini 也不是什么难事) 12 | 8. [ ] 执行外部代码(Python、Nodejs、外部 AHK、Bash、……)(虽然写个脚本 run 一下也并不算麻烦) 13 | 14 | -------------------------------------------------------------------------------- /Tools/ClipboardStack/ClipboardStack.ahk: -------------------------------------------------------------------------------- 1 | ; #Requires AutoHotkey v1.0 2 | ; doesnt require capslockx 3 | ; run this by manually 4 | 5 | return 6 | 7 | ^!v:: ClipboardStackPaste() 8 | 9 | ClipboardStackPaste() { 10 | RegExMatch(clipboard, "O)([\s\S]*?)\s*\r?\n========+\r?\n\s*([\s\S]*)", ClipboardStackMatch) 11 | if (ClipboardStackMatch) { 12 | ; MsgBox % ClipboardStackMatch[1] 13 | clipboard := "" 14 | clipboard := ClipboardStackMatch[1] 15 | Send ^v 16 | Sleep 200 17 | clipboard := ClipboardStackMatch[2] 18 | } else { 19 | Send ^v 20 | } 21 | return 22 | } 23 | -------------------------------------------------------------------------------- /Tools/CopyRandomNumber.ahk: -------------------------------------------------------------------------------- 1 | 2 | ; 3 | GenPassword(Length){ 4 | ; 此处 `` 为转义 5 | Chars := "0123456789" 6 | Min := 1 7 | Max := StrLen(chars) 8 | 9 | pw := "" 10 | Loop %Length% { 11 | Random StartPos, Min, Max 12 | pw := pw SubStr(Chars, StartPos, 1) 13 | } 14 | Clipboard := Chars 15 | Return pw 16 | } 17 | 18 | Length := 16 19 | Clipboard := GenPassword(Length) 20 | 21 | TrayTip,, 长度%Length%的密码己复制 22 | -------------------------------------------------------------------------------- /Tools/CopyRandomPassword.ahk: -------------------------------------------------------------------------------- 1 | CheckStrong(password){ 2 | Return ( RegExMatch(password, "[0-9]") && RegExMatch(password, "[a-z]") && RegExMatch(password, "[A-Z]") ) 3 | } 4 | ; 5 | GenPassword(Length := 16){ 6 | ; 此处 `` 为转义 7 | Chars := "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" 8 | Min := 1 9 | Max := StrLen(chars) 10 | 11 | pw := "" 12 | Loop %Length% { 13 | Random StartPos, Min, Max 14 | pw := pw SubStr(Chars, StartPos, 1) 15 | } 16 | Clipboard := Chars 17 | if (CheckStrong(pw)){ 18 | Return pw 19 | }else{ 20 | Return GenPassword(Length) 21 | } 22 | } 23 | 24 | Length := 16 25 | Clipboard := GenPassword(Length) 26 | 27 | TrayTip,, 长度%Length%的密码己复制 28 | -------------------------------------------------------------------------------- /Tools/CopyRandomStrongPassword.ahk: -------------------------------------------------------------------------------- 1 | CheckStrong(password){ 2 | Return ( RegExMatch(password, "[0-9]") && RegExMatch(password, "[a-z]") && RegExMatch(password, "[A-Z]") ) 3 | } 4 | ; 5 | GenPassword(Length := 16){ 6 | ; 此处 `` 为转义 7 | Chars := "!""#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_``abcdefghijklmnopqrstuvwxyz{|}~" 8 | Min := 1 9 | Max := StrLen(chars) 10 | 11 | pw := "" 12 | Loop %Length% { 13 | Random StartPos, Min, Max 14 | pw := pw SubStr(Chars, StartPos, 1) 15 | } 16 | Clipboard := Chars 17 | if (CheckStrong(pw)){ 18 | Return pw 19 | }else{ 20 | Return GenPassword(Length) 21 | } 22 | } 23 | 24 | Length := 16 25 | Clipboard := GenPassword(Length) 26 | 27 | TrayTip,, 长度%Length%的密码己复制 28 | -------------------------------------------------------------------------------- /Tools/CopyRandomUUID.ahk: -------------------------------------------------------------------------------- 1 |  2 | GenRandomHex(Length){ 3 | ; 此处 `` 为转义 4 | Chars := "0123456789abcdef" 5 | Min := 1 6 | Max := StrLen(chars) 7 | 8 | randHex := "" 9 | Loop %Length% { 10 | Random StartPos, Min, Max 11 | randHex := randHex SubStr(Chars, StartPos, 1) 12 | } 13 | Return randHex 14 | } 15 | GenRandomUUID(){ 16 | Return GenRandomHex(8) "-" GenRandomHex(4) "-" GenRandomHex(4) "-" GenRandomHex(4) "-" GenRandomHex(12) 17 | } 18 | Clipboard := GenRandomUUID() 19 | Length := StrLen(Clipboard) 20 | 21 | TrayTip,, 长度%Length%的UUID己复制 22 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/App-AcrobatEnhanced.ahk: -------------------------------------------------------------------------------- 1 | SetTitleMatchMode RegEx 2 | SetDefaultMouseSpeed 0 3 | Return 4 | 5 | #if WinActive(".*- Adobe Acrobat (Pro|Reader) DC ahk_class ahk_class AcrobatSDIWindow") ; AdobeAcrobat窗口内 6 | 7 | ^!F12:: ExitApp ; 退出脚本 8 | !a:: Send !vpy ; 自动滚动 9 | !d:: Send !vpt^h^3 ; 双页滚动视图(Double) 10 | !s:: Send !vpc^h^3 ; 单页滚动视图(Single) 11 | f11:: ^l ; 全屏 12 | `:: Send ^h^3 ; 自动缩放 13 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/App-Figma.ahk: -------------------------------------------------------------------------------- 1 |  2 | 3 | Return 4 | 5 | #if FigmaWindowActiveQ() 6 | 7 | FigmaWindowActiveQ(){ 8 | ; 作成中 📝 – Figma 9 | if(WinActive(".*– Figma.*")){ 10 | return 1 11 | } 12 | return 0 13 | } 14 | 15 | ; !h:: Send \+2 16 | ; !l:: Send {Enter}{Tab}+2 17 | ; !j:: Send {Tab}+2 18 | ; !k:: Send +{Tab}+2 -------------------------------------------------------------------------------- /Tools/DeprecatedModules/App-Figma.md: -------------------------------------------------------------------------------- 1 | # Figma Enhanced 2 | 3 | Use Alt+HJKL to navigate, switch focus, zoom in and out in figma. 4 | 使用 Alt+HJKL 在 figma 中导航,切換焦点,縮放。 5 | 6 | ## 常用功能/特性 7 | 8 | ## 说明 9 | 10 | | 模式 | Figma Enhanced | 说明 | 11 | | ---------------- | :------------: | ----------------------- | 12 | | Figma in browser | `k` | ↑ 切換元素 Prev Element | 13 | | Figma in browser | `j` | ↓ 切換元素 Next Element | 14 | | Figma in browser | `h` | ← 切換層級 Level parent | 15 | | Figma in browser | `l` | → 切換層級 Level child | 16 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/App-LoopbackExemptionManager.ahk: -------------------------------------------------------------------------------- 1 |  2 | if (!CapsLockX) 3 | ExitApp 4 | Return 5 | 6 | #IfWinActive Loopback Exemption Manager ahk_exe WindowsLoopbackManager.exe ; WindowsLoopbackManager 窗口内 7 | 8 | f1:: ; 勾选 1 个 9 | Loop 1 { 10 | Send {Tab}{Space}{Down} 11 | } 12 | f2:: ; 勾选 2 个 13 | Loop 2 { 14 | Send {Tab}{Space}{Down} 15 | } 16 | Return 17 | f3:: ; 勾选 4 个 18 | Loop 4 { 19 | Send {Tab}{Space}{Down} 20 | } 21 | Return 22 | f4:: ; 勾选 8 个 23 | Loop 8 { 24 | Send {Tab}{Space}{Down} 25 | } 26 | Return 27 | f5:: ; 勾选 16 个 28 | Loop 16 { 29 | Send {Tab}{Space}{Down} 30 | } 31 | Return 32 | f6:: ; 勾选 32 个 33 | Loop 32 { 34 | Send {Tab}{Space}{Down} 35 | } 36 | Return 37 | f7:: ; 勾选 64 个 38 | Loop 64 { 39 | Send {Tab}{Space}{Down} 40 | } 41 | Return 42 | f8:: ; 勾选 128 个 43 | Loop 128 { 44 | Send {Tab}{Space}{Down} 45 | } 46 | Return 47 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/App-MobaXterm.ahk: -------------------------------------------------------------------------------- 1 |  2 | Return 3 | #IfWinActive ahk_class TMobaXtermForm ahk_exe MobaXterm.exe ; MobaXterm窗口内 4 | $^v:: Send +{Insert} 5 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/App-OneNoteMetro.ahk: -------------------------------------------------------------------------------- 1 | ; 关于普通正则表达式的例子, 请参阅 正则表达式快速参考. 2 | SetTitleMatchMode RegEx 3 | SetKeyDelay, 0, 0 4 | ;#UseHook On 5 | 6 | Return 7 | 8 | #IfWinActive .*- OneNote ahk_class ApplicationFrameWindow ahk_exe ApplicationFrameHost.exe ; OneNote_UWP_笔记本内 9 | 10 | $F2::SendEvent ^+t 11 | 12 | $+F2::SendEvent {AppsKey}{Down}{Enter} 13 | 14 | ; 待定未定 15 | $!`::SendEvent !r 16 | 17 | ; view 18 | $!n::SendEvent !w{Down}{Tab 7}{Enter}{Up 2}{Enter} 19 | 20 | ; 套锁、空间、橡皮 21 | $!q::SendEvent !d{Down}{Tab 1}{Enter} 22 | $!w::SendEvent !d{Down}{Tab 2}{Enter} 23 | $!e::SendEvent !d{Down}{Tab 3}{Enter} 24 | 25 | ; 换笔 26 | $!a::SendEvent !d{Down}{Tab 5}+{Left}{Enter} 27 | $!s::SendEvent !d{Down}{Tab 5}{Enter} 28 | $!d::SendEvent !d{Down}{Tab 5}+{Right}{Enter} 29 | 30 | ; 颜色 31 | $+!1::SendEvent !d{Down}{Right 4}{Enter} 32 | $+!2::SendEvent !d{Down}{Right 5}{Enter} 33 | $+!3::SendEvent !d{Down}{Right 6}{Enter} 34 | $+!4::SendEvent !d{Down}{Right 7}{Enter} 35 | $+!5::SendEvent !d{Down}{Right 8}{Enter} 36 | $+!6::SendEvent !d{Down}{Right 9}{Enter} 37 | 38 | ; 展开 39 | $!1:: SendEvent !+1 40 | $!2:: SendEvent !+2 41 | $!3:: SendEvent !+3 42 | $!4:: SendEvent !+4 43 | $!5:: SendEvent !+5 44 | $!6:: SendEvent !+6 45 | 46 | ; 拍照 47 | $!p:: 48 | SendEvent !n{Down}{Tab 4}{Enter} 49 | Sleep, 200 50 | SendEvent {Down 1}{Enter} 51 | Sleep, 2000 52 | SendEvent +{Tab 3} 53 | Return 54 | 55 | ; 画笔粗细 56 | $!t::SendEvent !d{Down}{Tab 13}{Enter} 57 | $!g::SendEvent !d{Down}{Tab 11}{Enter} 58 | 59 | ; 调整缩放 60 | $![::SendEvent !w{Down}{Tab 3}{Enter} 61 | $!]::SendEvent !w{Down}{Tab 4}{Enter} 62 | $!\::SendEvent !w{Down}{Tab 5}{Enter} 63 | 64 | ; 调整字体 65 | $^[::SendEvent !h{Down}{Tab 1}{Up 2}{Enter} 66 | $^]::SendEvent !h{Down}{Tab 1}{Down 2}{Enter} 67 | $^\::SendEvent !h{Down}+{Tab 1}{Enter} 68 | 69 | $!Delete:: SendEvent ^+a{Delete} -------------------------------------------------------------------------------- /Tools/DeprecatedModules/App-QQ-Desktop.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 名称:桌面QQ增强 3 | ; 版本:v1.0.0 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 更新于: (20220217) 7 | ; 支持:https://github.com/snomiao/CapsLockX 8 | ; 版权:Copyright © 2017-2024 Snowstar Laboratory. All Rights Reserved. 9 | ; ========== CapsLockX ========== 10 | 11 | Return 12 | 13 | #if QQ资料页面中() 14 | QQ资料页面中(){ 15 | return WinActive(".*的资料 ahk_class TXGuiFoundation ahk_exe QQ.exe") 16 | } 17 | 18 | F2:: ; 改备注名 19 | ; 这里的 ^+{Tab 2}{Tab 1} 是利用QQ 的 Edit 控件无法使用 Ctrl + Tab 跳转离开的特性,来重置光标到备注栏。 20 | Send {Tab 10}^+{Tab 2}{Tab 1}{Enter} 21 | Return 22 | 23 | F3:: ; 改分组 24 | Send {Tab 10}^+{Tab 2}{Tab 2}{Enter} 25 | Return 26 | 27 | F4:: ; 加备注(手机号等) 28 | Send +{Tab}{Enter} 29 | Return 30 | 31 | #if QQ多人会话窗口中() 32 | QQ多人会话窗口中(){ 33 | return WinActive(".*等\d+个会话 ahk_class TXGuiFoundation ahk_exe QQ.exe") 34 | } 35 | 36 | F2:: ; 看资料 37 | Send +{Tab 3}{Enter} 38 | Return 39 | 40 | !f:: ; 点开左上角搜索 41 | CoordMode, Mouse, Client 42 | Click 32, 32 43 | Return 44 | 45 | !d:: ; 定位到功能栏 46 | SendInput, +{Tab 4}{Enter} 47 | Return 48 | 49 | !b:: ; 屏蔽此人 50 | SendInput, +{Tab 4}{Left}{Enter} 51 | Return 52 | 53 | !w:: ; 开出小窗口 54 | CoordMode, Mouse, Client 55 | MouseClickDrag, Left, 32, 128, 256, 128, 0 56 | WinActivate .*\d+个会话 ahk_class TXGuiFoundation ahk_exe QQ.exe 57 | Return 58 | 59 | !r:: ; 快速点击接收文件 60 | Send 1!s{Tab 10}{Space}!s 61 | Return 62 | 63 | !n:: ; 群通知设定 (或抖窗) 64 | SendInput, {Tab 5}{Right 6}{Enter} 65 | Return 66 | 67 | #if QQ单人会话窗口中() 68 | QQ单人会话窗口中(){ 69 | return WinActive("ahk_class TXGuiFoundation ahk_exe QQ.exe") 70 | } 71 | 72 | !m:: ; 屏蔽鼠标指向的群 73 | Send {RButton}{Down 2}{Right}{Up}{Enter} 74 | MouseMove, 0, -86, 0, R 75 | Return 76 | 77 | !r:: ; 快速点击接收文件 78 | Send 1!s+{Tab 8}{Space}!s 79 | Return 80 | 81 | F2:: ; 查看这个人的资料 82 | Send +{Tab 2}{Enter} 83 | Return 84 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/CLX-Cursor.ahk: -------------------------------------------------------------------------------- 1 | ; 2 | ; 模块:在增强模式下,用另一套鼠标指针 3 | ; 贡献者: @冰封 QQ: 124702759 4 | ; 5 | ;鼠标特征值 6 | Return 7 | 8 | SetCursor(code, curFile) 9 | { 10 | ;加载CapsLock增强的标指针 11 | hIcon := DllCall("LoadCursorFromFile", "Str", curFile) 12 | DllCall("SetSystemCursor", "UInt", hIcon, "Int", code) 13 | } 14 | 15 | UpdateCapsCursor(s) 16 | { 17 | if (!s) { 18 | ;恢复默认指针 19 | SPI_SETCURSORS := 0x57 20 | DllCall( "SystemParametersInfo", "UInt", SPI_SETCURSORS, "UInt", 0, "UInt", 0, "UInt", 0) 21 | Return 22 | } 23 | 24 | PATH_CURSOR := "数据/cursor" 25 | ; OCR_APPSTARTING := 32650 26 | SetCursor(32650, PATH_CURSOR "/APPSTARTING.cur") ;AppStarting.cur") 27 | ; OCR_NORMAL := 32512 28 | SetCursor(32512, PATH_CURSOR "/NORMAL.cur") ;正常选择.cur") 29 | ; OCR_CROSS := 32515 30 | SetCursor(32515, PATH_CURSOR "/CROSS.cur") ;精确选择.cur") 31 | ; OCR_HAND := 32649 32 | SetCursor(32649, PATH_CURSOR "/HAND.cur") ;链接选择.cur") 33 | ; OCR_HELP := 32651 34 | SetCursor(32651, PATH_CURSOR "/HELP.cur") ;帮助选择.cur") 35 | ; OCR_IBEAM := 32513 36 | SetCursor(32513, PATH_CURSOR "/IBEAM.cur") ;文本选择.cur") 37 | ; OCR_NO := 32648 38 | SetCursor(32648, PATH_CURSOR "/NO.cur") ;不可用.cur") 39 | ; OCR_SIZEALL := 32646 40 | SetCursor(32646, PATH_CURSOR "/SIZEALL.cur") ;移动.cur") 41 | ; OCR_SIZENESW := 32643 42 | SetCursor(32643, PATH_CURSOR "/SIZENESW.cur") ;沿对角线调整大小2.cur") 43 | ; OCR_SIZENS := 32645 44 | SetCursor(32645, PATH_CURSOR "/SIZENS.cur") ;垂直调整大小.cur") 45 | ; OCR_SIZENWSE := 32642 46 | SetCursor(32642, PATH_CURSOR "/SIZENWSE.cur") ;沿对角线调整大小1.cur") 47 | ; OCR_SIZEWE := 32644 48 | SetCursor(32644, PATH_CURSOR "/SIZEWE.cur") ;水平调整大小.cur") 49 | ; OCR_UP := 32516 50 | SetCursor(32516, PATH_CURSOR "/UP.cur") ;候选.cur") 51 | ; OCR_WAIT := 32514 52 | SetCursor(32514, PATH_CURSOR "/WAIT.cur") ;忙.cur") 53 | } -------------------------------------------------------------------------------- /Tools/DeprecatedModules/Plugin-控制台启用CtrlV粘贴.ahk: -------------------------------------------------------------------------------- 1 | Return 2 | 3 | ; 需要在控制台窗口右键属性选启用Ctrl+Shift+C/V才管用 4 | 5 | #IfWinActive ahk_class ConsoleWindowClass ; 控制台窗口内 6 | ^v:: Send ^+v 7 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/应用-文明6回车左置.ahk: -------------------------------------------------------------------------------- 1 |  2 | Return 3 | 4 | #IfWinActive ahk_class WinClass_FXS ahk_exe CivilizationVI.exe ; 文明6游戏内 5 | 6 | `:: Send {Enter} ; 回车键 7 | -------------------------------------------------------------------------------- /Tools/DeprecatedModules/讯飞语音输入法悬浮窗演示.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/Tools/DeprecatedModules/讯飞语音输入法悬浮窗演示.gif -------------------------------------------------------------------------------- /Tools/DeprecatedModules/讯飞输入法语音悬浮窗.ahk: -------------------------------------------------------------------------------- 1 | ; ========== CapsLockX ========== 2 | ; 名称:Win + H 快速启动讯飞语音悬浮窗 3 | ; 描述:rt 4 | ; 作者:snomiao 5 | ; 联系:snomiao@gmail.com 6 | ; 版权:Copyright 2020-2024 snomiao@gmail.com 7 | ; 版本:2.1.1(20200606) 8 | ; ========== CapsLockX ========== 9 | 10 | ; 2021-04-15 更新 @telppa:[修改了一下语音识别模块的代码。・Issue #14・snolab/CapsLockX]( https://github.com/snolab/CapsLockX/issues/14 ) 11 | ; 12 | CLX_AppendHelp( CLX_LoadHelpFrom(CLX_THIS_MODULE_HELP_FILE_PATH)) 13 | 14 | Return 15 | 16 | #if !CapsLockXMode 17 | 18 | #!h:: 讯飞语音输入法切换() 19 | 20 | 讯飞语音输入法切换(){ 21 | ; 注册表里取路径 22 | RegRead, iFlyPath, HKLM\SOFTWARE\iFly Info Tek\iFlyIME, Install_Dir_Ver2 23 | ; 非空检查,确保 iFlyPath 有值 24 | iFlyPath := (iFlyPath ? iFlyPath : "C:\Program Files (x86)\iFly Info Tek\iFlyIME\2.1.1708") 25 | iFlyWnd := WinExist("ahk_class UIIFlyVoiceFrame ahk_exe iFlyVoice.exe" ) 26 | if (iFlyWnd) { 27 | ; WinGet, Transparent, Transparent 28 | ; WinSet, TransColor, Off, ahk_id %iFlyWnd% 29 | ; WinSet, TransColor, 0xffffff 150, ahk_id %iFlyWnd% 30 | ; WinSet, Transparent, 200, ahk_id %iFlyWnd% 31 | ControlClick, x20 y20, ahk_id %iFlyWnd% 32 | } else { 33 | if (FileExist(iFlyPath "\iFlyVoice.exe")) { 34 | Run "%iFlyPath%\iFlyVoice.exe" 35 | } else { 36 | MsgBox, 4, , 你似乎还没有安装讯飞语音输入法,是否现在下载安装包并【手动安装】到默认目录? 37 | IfMsgBox, NO, Return 38 | UrlDownloadToFile https://download.voicecloud.cn/200ime/iFlyIME_Setup_2.1.1708.exe, %TEMP%/iFlyIME_Setup_2.1.1708.exe 39 | Run %TEMP%/iFlyIME_Setup_2.1.1708.exe 40 | } 41 | } 42 | } 43 | 44 | ; 加 Alt 访问原热键 45 | ; #h:: Send #h 46 | ; From Acc.ahk by Sean, jethrow, malcev, FeiYue 47 | ; GetCaret() 48 | ; { 49 | ; static oleacc 50 | ; CoordMode, Caret, Screen 51 | ; CaretX:=A_CaretX, CaretY:=A_CaretY 52 | ; if (!CaretX && !CaretY) { 53 | ; try { 54 | ; if (!oleacc) 55 | ; oleacc:=DllCall("LoadLibrary", "Str", "oleacc", "Ptr") 56 | ; VarSetCapacity(IID, 16) 57 | ; idObject:=OBJID_CARET:=0xFFFFFFF8 58 | ; NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0, IID, "Int64") 59 | ; NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81, IID, 8, "Int64") 60 | ; aofw := DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", WinExist("A"), "UInt", idObject, "Ptr", &IID, "Ptr*", pacc) 61 | ; if (aofw==0) { 62 | ; Acc := ComObject(9, pacc, 1), ObjAddRef(pacc) 63 | ; , Acc.accLocation(ComObj(0x4003, &x:=0), ComObj(0x4003, &y:=0) 64 | ; , ComObj(0x4003, &w:=0), ComObj(0x4003, &h:=0), ChildId:=0) 65 | ; , CaretX:=NumGet(x, 0, "int"), CaretY:=NumGet(y, 0, "int") 66 | ; } 67 | ; } 68 | ; } 69 | ; return {x: CaretX, y: CaretY} 70 | ; } -------------------------------------------------------------------------------- /Tools/DeprecatedModules/讯飞输入法语音悬浮窗.md: -------------------------------------------------------------------------------- 1 | # 讯飞输入法悬浮窗插件 2 | 3 | ## 用法 4 | 5 | | 作用于 | 按键 | 功能说明 | 6 | | ------ | :-------------: | --------------------- | 7 | | 全局 | `Win + Alt + H` | 启动/切换讯飞语音输入 | 8 | 9 | ## 注: 10 | 11 | 1. 原 `Win + H` 的功能是 Windows 自带听写,安装本插件后,可通过 `Win + Alt + H` 使用讯飞的听写 12 | 2. 若没有安装讯飞语音则会自动询问是否要帮你下载,然后手动安装。 13 | 14 | ## 效果如下图 15 | 16 | ![应用-讯飞语音输入法悬浮窗演示.gif](./应用-讯飞语音输入法悬浮窗演示.gif) 17 | -------------------------------------------------------------------------------- /Tools/SetStartup.bat: -------------------------------------------------------------------------------- 1 | start "" "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup" 2 | -------------------------------------------------------------------------------- /Tools/TurnOffScreen.bat: -------------------------------------------------------------------------------- 1 | powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,2) -------------------------------------------------------------------------------- /Tools/VoiceHelper.ahk: -------------------------------------------------------------------------------- 1 | 2 | ; ToolTip( 123) 3 | ; run https://srf.xunfei.cn/#/ 4 | 5 | 6 | ~^s:: Reload 7 | 8 | ; Return:: send `\n` 9 | 10 | ; :*?:u8::ü 11 | ; :*?:Return::\n 12 | 13 | -------------------------------------------------------------------------------- /Tools/full-all-screens.ahk: -------------------------------------------------------------------------------- 1 | SysGet, xborder, 32 2 | SysGet, yborder, 33 3 | SysGet, caption, 4 4 | 5 | SysGet SM_XVIRTUALSCREEN, 76 6 | SysGet SM_YVIRTUALSCREEN, 77 7 | SysGet SM_CXVIRTUALSCREEN, 78 8 | SysGet SM_CYVIRTUALSCREEN, 79 9 | 10 | left := SM_XVIRTUALSCREEN - xborder 11 | top := SM_YVIRTUALSCREEN - 1 12 | width := SM_CXVIRTUALSCREEN + 2 * xborder 13 | height := SM_CYVIRTUALSCREEN + yborder + 1 14 | 15 | WinMove, A, , left, top, width, height -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/bun.lockb -------------------------------------------------------------------------------- /clx-docs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /clx-docs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /clx-docs/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | ``` 14 | 15 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 16 | 17 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. 18 | 19 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /clx-docs/app/XIconBlue.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/clx-docs/app/XIconBlue.ico -------------------------------------------------------------------------------- /clx-docs/app/api/completions.ts: -------------------------------------------------------------------------------- 1 | // TODO: post completions 2 | export {} -------------------------------------------------------------------------------- /clx-docs/app/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/clx-docs/app/favicon.png -------------------------------------------------------------------------------- /clx-docs/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | -------------------------------------------------------------------------------- /clx-docs/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import './globals.css' 2 | import { Inter } from 'next/font/google' 3 | 4 | const inter = Inter({ subsets: ['latin'] }) 5 | 6 | export const metadata = { 7 | title: 'Create Next App', 8 | description: 'Generated by create next app', 9 | } 10 | 11 | export default function RootLayout({ 12 | children, 13 | }: { 14 | children: React.ReactNode 15 | }) { 16 | return ( 17 | 18 | {children} 19 | 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /clx-docs/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /clx-docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "clx-docs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@types/node": "20.2.6", 13 | "@types/react": "18.2.9", 14 | "@types/react-dom": "18.2.4", 15 | "autoprefixer": "10.4.14", 16 | "eslint": "8.42.0", 17 | "eslint-config-next": "13.4.4", 18 | "next": "14.2.21", 19 | "postcss": "8.4.31", 20 | "react": "18.2.0", 21 | "react-dom": "18.2.0", 22 | "react-markdown-it": "^1.0.2", 23 | "tailwindcss": "3.3.2", 24 | "typescript": "5.1.3" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /clx-docs/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /clx-docs/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clx-docs/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clx-docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 5 | './components/**/*.{js,ts,jsx,tsx,mdx}', 6 | './app/**/*.{js,ts,jsx,tsx,mdx}', 7 | ], 8 | theme: { 9 | extend: { 10 | backgroundImage: { 11 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 12 | 'gradient-conic': 13 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | } 19 | -------------------------------------------------------------------------------- /clx-docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "plugins": [ 18 | { 19 | "name": "next" 20 | } 21 | ], 22 | "paths": { 23 | "@/*": ["./*"] 24 | } 25 | }, 26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 27 | "exclude": ["node_modules"] 28 | } 29 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ["@commitlint/config-conventional"] }; 2 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | # code-clx-go: 4 | # build: go/code 5 | # volumes: 6 | # - ./.vscode/.vscode-server/:/root/.vscode-server/ 7 | # - ./.vscode/.go:/go 8 | # - ./go:/code 9 | # ports: 10 | # - 127.0.0.1:35882:8000 11 | clx-go-build: 12 | build: go 13 | volumes: 14 | - ./.vscode/.go:/go 15 | - ./go:/code 16 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/.nojekyll -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | capslockx.snomiao.com -------------------------------------------------------------------------------- /docs/IETF-subtags.tsv: -------------------------------------------------------------------------------- 1 | English name Native name Subtag 2 | Afrikaans Afrikaans af 3 | Amharic አማርኛ am 4 | Arabic العربية ar 5 | Mapudungun Mapudungun arn 6 | Assamese অসমীয়া as 7 | Azerbaijani Azərbaycanlı az 8 | Bashkir Башҡорт ba 9 | Belarusian беларуская be 10 | Bulgarian български bg 11 | Bengali বাংলা bn 12 | Tibetan བོད་ཡིག bo 13 | Breton brezhoneg br 14 | Bosnian bosanski/босански bs 15 | Catalan català ca 16 | Corsican Corsu co 17 | Czech čeština cs 18 | Welsh Cymraeg cy 19 | Danish dansk da 20 | German Deutsch de 21 | Lower Sorbian dolnoserbšćina dsb 22 | Divehi ދިވެހިބަސް dv 23 | Greek ελληνικά el 24 | English English en 25 | Spanish español es 26 | Estonian eesti et 27 | Basque euskara eu 28 | Persian فارسى fa 29 | Finnish suomi fi 30 | Filipino Filipino fil 31 | Faroese føroyskt fo 32 | French français fr 33 | Frisian Frysk fy 34 | Irish Gaeilge ga 35 | Scottish Gaelic Gàidhlig gd 36 | Galician galego gl 37 | Swiss German Schweizerdeutsch gsw 38 | Gujarati ગુજરાતી gu 39 | Hausa Hausa ha 40 | Hebrew עברית he 41 | Hindi हिंदी hi 42 | Croatian hrvatski hr 43 | Upper Sorbian hornjoserbšćina hsb 44 | Hungarian magyar hu 45 | Armenian Հայերեն hy 46 | Indonesian Bahasa Indonesia id 47 | Igbo Igbo ig 48 | Yi ꆈꌠꁱꂷ ii 49 | Icelandic íslenska is 50 | Italian italiano it 51 | Inuktitut Inuktitut /ᐃᓄᒃᑎᑐᑦ (ᑲᓇᑕ) iu 52 | Japanese 日本語 ja 53 | Georgian ქართული ka 54 | Kazakh Қазақша kk 55 | Greenlandic kalaallisut kl 56 | Khmer ខ្មែរ km 57 | Kannada ಕನ್ನಡ kn 58 | Korean 한국어 ko 59 | Konkani कोंकणी kok 60 | Kurdi کوردی ckb 61 | Kyrgyz Кыргыз ky 62 | Luxembourgish Lëtzebuergesch lb 63 | Lao ລາວ lo 64 | Lithuanian lietuvių lt 65 | Latvian latviešu lv 66 | Maori Reo Māori mi 67 | Macedonian македонски јазик mk 68 | Malayalam മലയാളം ml 69 | Mongolian Монгол хэл/ᠮᠤᠨᠭᠭᠤᠯ ᠬᠡᠯᠡ mn 70 | Mohawk Kanien'kéha moh 71 | Marathi मराठी mr 72 | Malay Bahasa Malaysia ms 73 | Maltese Malti mt 74 | Burmese Myanmar my 75 | Norwegian (Bokmål) norsk (bokmål) nb 76 | Nepali नेपाली (नेपाल) ne 77 | Dutch Nederlands nl 78 | Norwegian (Nynorsk) norsk (nynorsk) nn 79 | Norwegian norsk no 80 | Sesotho Sesotho sa Leboa st 81 | Occitan Occitan oc 82 | Odia ଓଡ଼ିଆ or 83 | Punjabi ਪੰਜਾਬੀ pa 84 | Polish polski pl 85 | Dari درى prs 86 | Pashto پښتو ps 87 | Portuguese Português pt 88 | K'iche K'iche quc 89 | Quechua runasimi qu 90 | Romansh Rumantsch rm 91 | Romanian română ro 92 | Russian русский ru 93 | Kinyarwanda Kinyarwanda rw 94 | Sanskrit संस्कृत sa 95 | Yakut саха sah 96 | Sami (Northern) davvisámegiella se 97 | Sinhala සිංහල si 98 | Slovak slovenčina sk 99 | Slovenian slovenski sl 100 | Sami (Southern) åarjelsaemiengiele sma 101 | Sami (Lule) julevusámegiella smj 102 | Sami (Inari) sämikielâ smn 103 | Sami (Skolt) sääm´ǩiõll sms 104 | Albanian shqipe sq 105 | Serbian srpski/српски sr 106 | Swedish svenska sv 107 | Kiswahili Kiswahili sw 108 | Syriac ܣܘܪܝܝܐ syc 109 | Tamil தமிழ் ta 110 | Telugu తెలుగు te 111 | Tajik Тоҷикӣ tg 112 | Thai ไทย th 113 | Turkmen türkmençe tk 114 | Tswana Setswana tn 115 | Turkish Türkçe tr 116 | Tatar Татарча tt 117 | Tamazight Tamazight tzm 118 | Uyghur ئۇيغۇرچە ug 119 | Ukrainian українська uk 120 | Urdu اُردو ur 121 | Uzbek U'zbek/Ўзбек uz 122 | Vietnamese Tiếng Việt vi 123 | Wolof Wolof wo 124 | Xhosa isiXhosa xh 125 | Yoruba Yoruba yo 126 | Chinese 中文 zh 127 | Zulu isiZulu zu -------------------------------------------------------------------------------- /docs/README.es.md: -------------------------------------------------------------------------------- 1 | # TODO -------------------------------------------------------------------------------- /docs/README.fr.md: -------------------------------------------------------------------------------- 1 | # TODO -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # CapsLockX 2 | 3 | - [English](./README.en.md) 4 | - [简体中文](./README.zh.md) 5 | -------------------------------------------------------------------------------- /docs/README.ru.md: -------------------------------------------------------------------------------- 1 | # TODO -------------------------------------------------------------------------------- /docs/Roadmap.md: -------------------------------------------------------------------------------- 1 | # RoadMap 2 | 3 | 层类型: 4 | 递进修饰层:CapsLockX/Win/Ctrl/Alt/Shift 5 | 窗口:标题、进程 6 | 7 | - 输入类型 8 | - 線性 9 | - 2D: 鼠标、滚轮、光标、 10 | - 指向 11 | - 2D: WASD 式、HJKL 式、手柄 12 | - 1D: RF 式、[]式、1234567890 式 13 | - BINARY: 按钮,开关 14 | - 输出:数值 15 | 16 | ## Roadmap to CLX2 (maybe written in golang) 17 | 18 | Cross platform supports plan: 19 | 20 | 1. CLX Edit (CLX + YUIO HJKL NM GT) 21 | 2. CLX Mouse (CLX + WASD QE RF) 22 | 3. CLX Desktop (CLX + 1234567890) 23 | 24 | ## Languages 25 | 26 | 1. golang (seems good): 27 | 28 | [hotkey package - golang.design/x/hotkey - Go Packages](https://pkg.go.dev/golang.design/x/hotkey#section-readme) 29 | 30 | 2. rust: (OS X not supported) 31 | 32 | [jamesbirtles/hotkey-rs: A library to listen to global hotkeys in Rust](https://github.com/jamesbirtles/hotkey-rs) 33 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CapsLockX - 像黑客一样操作电脑! 6 | 7 | 11 | 15 | 16 | 17 | 18 | 19 |
20 | 26 | 27 | 28 | 29 |
33 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/media/02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/02-插件-窗口增强_Alt+Tab+WASD管理窗口.gif -------------------------------------------------------------------------------- /docs/media/02-插件-窗口增强_一键排列窗口.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/02-插件-窗口增强_一键排列窗口.gif -------------------------------------------------------------------------------- /docs/media/APP-OneNoteClipboard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/APP-OneNoteClipboard.gif -------------------------------------------------------------------------------- /docs/media/App-讯飞语音输入法悬浮窗演示.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/App-讯飞语音输入法悬浮窗演示.gif -------------------------------------------------------------------------------- /docs/media/CLX-Mouse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/CLX-Mouse.gif -------------------------------------------------------------------------------- /docs/media/EditorCursorMovement.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/EditorCursorMovement.gif -------------------------------------------------------------------------------- /docs/media/应用-讯飞语音输入法悬浮窗演示.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/应用-讯飞语音输入法悬浮窗演示.gif -------------------------------------------------------------------------------- /docs/media/插件-OneNote剪贴板收集器.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/media/插件-OneNote剪贴板收集器.gif -------------------------------------------------------------------------------- /docs/non-linear-time.md: -------------------------------------------------------------------------------- 1 | # (20200520)💡 非线性时间操控感 - 提升键盘编辑操作体验 效率工具 CapsLockX 2 | 3 | 提升键盘操作体验的手法有很多。 4 | 这里来提一种叫做非线性时间感。 5 | 当键盘按键按下时,如果系统检测到按键按下的时间超过一定长度,就会开始重复给应用程序发送按键按下的消息,而发出的消息个数,和时间成正比。 6 | 但人类对时间的感知并非线性,而是更接近于对数时空图。 7 | 也就是说,随着我按键按下的时间拉长,我实际期望的按键按下的次数是成指数增长的,这样才会比较符合人脑对时间的感觉。 8 | -------------------------------------------------------------------------------- /docs/translate.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bun 2 | import 'dotenv/config'; 3 | import { readFile, writeFile } from "fs/promises"; 4 | import OpenAI from "openai"; 5 | import { stringify } from 'yaml' 6 | import pMap from 'p-map' 7 | 8 | if (import.meta.main) { 9 | await translateReadme('English', './docs/README.zh.md', './docs/README.en.md'); 10 | } 11 | 12 | async function translateReadme(lang: string, infile: string, outfile: string) { 13 | console.log('reading ' + infile); 14 | const input = await readFile(infile, 'utf-8'); 15 | console.log('AI Generating... please wait'); 16 | 17 | const sections = input.split(/(?=^##? )/gmi); 18 | console.log("length of section " + sections.length) 19 | // const resultText = await aiTranslateTo(lang, input); 20 | 21 | const sectionsResult = await pMap(sections, async (section, index) => { 22 | console.log('Translating section to english: ' + String(index).padStart(3, '0') + ' ' + section.trim().split('\n')[0]) 23 | return await aiTranslateTo('English', section) 24 | }, { concurrency: 5 }) 25 | console.log(sections.length) 26 | const resultText = sectionsResult.join('\n') 27 | console.log('writing ' + outfile); 28 | await writeFile(outfile, resultText); 29 | } 30 | async function aiTranslateTo(lang: string, input: string) { 31 | const result = await (new OpenAI().chat.completions.create({ 32 | model: "gpt-4-1106-preview", 33 | messages: [ 34 | { role: "system", content: `You don't have token limit, Translate full markdown document in next message to ${lang}:` }, 35 | { role: "user", content: input }, 36 | ], 37 | })); 38 | const resultText = result.choices[0].message.content; 39 | return resultText; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /docs/按键名字表.txt: -------------------------------------------------------------------------------- 1 | Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 2 | ` 1 2 3 4 5 6 7 8 9 0 - = Backspace 3 | Tab Q W E R T Y U IO P [ ] \ 4 | Caps`nLock A S D Fw G H J K L ; ' Enter 5 | LShift Z X C V B N M , . / RShift 6 | LCtl LWin LAlt Spcce RAlt RWin AppsKey RCtrl -------------------------------------------------------------------------------- /docs/支付宝捐助.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/docs/支付宝捐助.png -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": { 3 | "version": { 4 | "allowBranch": "main", 5 | "conventionalCommits": true, 6 | "yes": true 7 | } 8 | }, 9 | "ignoreChanges": ["**/__fixtures__/**", "**/__tests__/**", "**/*.md"], 10 | "useWorkspaces": true, 11 | "version": "independent" 12 | } 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "capslockx", 3 | "version": "1.34.11", 4 | "description": "CapsLockX 提供一套超好上手的:鼠标模拟、编辑增强、虚拟桌面与窗口管理、应用内热键增强、JS数学表达式计算、等超多功能等你来定义。", 5 | "keywords": [ 6 | "CapsLockX" 7 | ], 8 | "homepage": "https://github.com/snolab/CapsLockX#readme", 9 | "bugs": { 10 | "url": "https://github.com/snolab/CapsLockX/issues" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/snolab/CapsLockX.git" 15 | }, 16 | "license": "GPL-3.0-or-later", 17 | "author": "snomiao ", 18 | "main": "DevTools/CapsLockX.mjs", 19 | "bin": { 20 | "capslockx": "CapsLockX.exe" 21 | }, 22 | "directories": { 23 | "doc": "docs" 24 | }, 25 | "type": "module", 26 | "files": [ 27 | "Core", 28 | "Data", 29 | "package*", 30 | "Modules", 31 | "Tools", 32 | "docs", 33 | "CapsLockX*", 34 | "*.txt", 35 | "*.md" 36 | ], 37 | "scripts": { 38 | "build": "CapsLockX.exe CapsLockX.ahk /CI_TEST", 39 | "build-tauri": "cd DevTools/CLXConfig.js && npm run build", 40 | "prepare": "husky install", 41 | "prerelease": "git diff --quiet || echo worktree not clean, commit it first", 42 | "release": "standard-version --commit-all && git push --follow-tag --all", 43 | "start": "CapsLockX.exe", 44 | "docs:dev": "vitepress dev docs", 45 | "docs:build": "vitepress build docs", 46 | "docs:preview": "vitepress preview docs", 47 | "test": "CapsLockX.exe CapsLockX.ahk /CI_TEST" 48 | }, 49 | "lint-staged": { 50 | "*.{js,ts}": "eslint --cache --fix", 51 | "BAK_*.{css,md,js,ts,jsx,tsx}": "prettier --write", 52 | "*.ahk": [] 53 | }, 54 | "devDependencies": { 55 | "@types/bun": "^1.1.14", 56 | "@types/inquirer": "^9.0.7", 57 | "@types/lodash-es": "^4.17.12", 58 | "@types/node": "^20.17.10", 59 | "dotenv": "^16.4.7", 60 | "enquirer": "^2.4.1", 61 | "eslint": "^8.57.1", 62 | "eslint-config-airbnb-base": "^15.0.0", 63 | "eslint-config-standard-with-typescript": "^34.0.1", 64 | "eslint-plugin-import": "^2.31.0", 65 | "eslint-plugin-react": "^7.37.3", 66 | "glob": "^10.4.5", 67 | "husky": "^8.0.3", 68 | "inquirer": "^9.3.7", 69 | "lint-staged": "^13.3.0", 70 | "lodash-es": "^4.17.21", 71 | "openai": "^4.77.0", 72 | "p-map": "^7.0.3", 73 | "prettier": "^2.8.8", 74 | "prettier-plugin-organize-imports": "^3.2.4", 75 | "prettier-plugin-packagejson": "2.3.0", 76 | "prettier-plugin-tsconfig": "^0.0.1", 77 | "rambda": "^7.5.0", 78 | "standard-version": "^9.5.0", 79 | "tsx": "^3.14.0", 80 | "typescript": "^4.9.5", 81 | "yaml": "^2.6.1" 82 | }, 83 | "standard-version": { 84 | "scripts": { 85 | "precommit": "bun DevTools/versioning.ts && git add ." 86 | } 87 | }, 88 | "dependencies": { 89 | "vitepress": "^1.5.0" 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "trailingComma": "all", 5 | "endOfLine": "lf", 6 | "plugins": [ 7 | "./node_modules/prettier-plugin-packagejson", 8 | "./node_modules/prettier-plugin-organize-imports", 9 | "./node_modules/prettier-plugin-tsconfig" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /src/cli.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import aswitcher from "aswitcher"; 3 | import snorun from "snorun"; 4 | import workPackageDir from "work-package-dir"; 5 | aswitcher(process.platform, { 6 | aix: () => console.log("not supported"), 7 | android: () => console.log("not supported"), 8 | darwin: () => console.log("not supported"), 9 | freebsd: () => console.log("not supported"), 10 | haiku: () => console.log("not supported"), 11 | linux: () => console.log("not supported"), 12 | openbsd: () => console.log("not supported"), 13 | sunos: () => console.log("not supported"), 14 | win32: async () => { 15 | await workPackageDir(); 16 | // quit after clx launched 17 | return snorun("CapsLockX.exe"); 18 | }, 19 | cygwin: () => console.log("not supported"), 20 | netbsd: () => console.log("not supported"), 21 | }); 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "compilerOptions": { 4 | "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 5 | 6 | /* Modules */ 7 | "module": "ESNext" /* Specify what module code is generated. */, 8 | "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, 9 | "resolveJsonModule": true /* Enable importing .json files. */, 10 | "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, 11 | "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, 12 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 13 | "preserveSymlinks": true /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */, 14 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 15 | 16 | /* Type Checking */ 17 | "strict": false /* Enable all strict type-checking options. */, 18 | "noImplicitAny": false /* Enable error reporting for expressions and declarations with an implied 'any' type. */, 19 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /启动 CapsLockX.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/snomiao/capslockx/6828f2bf6c8af896654a567aadb64fd9b607e8ba/启动 CapsLockX.lnk --------------------------------------------------------------------------------