Compare commits

..

336 Commits

Author SHA1 Message Date
CJKmkp f67b4db4ba alpha 2025-08-23 21:39:21 +08:00
PrefacedCorg 7bac32e3c4 Update MainWindow.xaml 2025-08-01 02:56:53 +08:00
PrefacedCorg 880ca08571 fix time 2025-08-01 02:56:24 +08:00
PrefacedCorg 85d4d8a71e 修复二级菜单移位
修复二级菜单移位(和优化江陵写的屎山)
2025-07-31 20:38:30 +08:00
CJKmkp abb8ed0bcc fix:插入图片 2025-07-31 16:49:53 +08:00
CJKmkp bea0d10a6c Merge branch 'beta' of https://github.com/InkCanvasForClass/community into beta 2025-07-31 16:36:42 +08:00
CJK_mkp 80d943af23 Merge pull request #123 from InkCanvasForClass/beta-PrefacedCorg
合并分支
2025-07-31 15:22:18 +08:00
PrefacedCorg 90b85e469d Update MainWindow.xaml 2025-07-31 15:07:39 +08:00
PrefacedCorg 0d419c1323 fix 二级菜单移位 2025-07-31 14:52:44 +08:00
PrefacedCorg f7a2ecc2e0 给二级菜单加了个x :( 2025-07-31 14:12:49 +08:00
PrefacedCorg 5fdbf83f32 新增图片选择选项 2025-07-31 13:23:33 +08:00
CJKmkp c513ad9291 improve:插入图片 2025-07-31 10:55:01 +08:00
CJKmkp a2dfa55dbd improve:插入图片 2025-07-31 10:27:19 +08:00
CJKmkp 78f8d9a271 fix:退出确认按钮 2025-07-31 10:03:29 +08:00
CJK_mkp b25a5aac8c Merge pull request #122 from MKStoler1024/beta
fix: gitignore
2025-07-31 09:46:24 +08:00
MKStoler1024 25cc70035e fix: gitignore 2025-07-31 09:39:46 +08:00
MKStoler1024 e5d70d5a0e del: unneeded files 2025-07-31 09:38:07 +08:00
MKStoler1024 066b0d1f8a fix: gitignore 2025-07-31 09:35:00 +08:00
CJKmkp 71b2e56187 improve:截图功能 2025-07-30 20:06:43 +08:00
CJKmkp 457832fbbe improve:截图功能 2025-07-30 20:06:29 +08:00
CJKmkp 00554e066b add:截图功能 2025-07-30 19:56:22 +08:00
CJKmkp 9f9775e585 fix:图片插入 2025-07-30 14:18:45 +08:00
CJKmkp 9cf70ae74e fix:图片插入 2025-07-30 14:12:10 +08:00
CJKmkp 4f046987c6 fix:线擦切换至批注的面板弹出及高光显示问题 2025-07-30 13:24:52 +08:00
CJKmkp 699666c23b fix:issue #120 2025-07-29 23:14:20 +08:00
CJKmkp 6a8cdd0155 fix:issue #118 2025-07-29 19:07:59 +08:00
CJKmkp ce61f0e2b7 improve:IACore 2025-07-29 19:00:45 +08:00
CJKmkp b3cb0bf93f improve:IACore 2025-07-29 19:00:32 +08:00
CJKmkp 07328eea2d Revert "delete:IACore释放"
This reverts commit bfb6346812.
2025-07-29 18:37:00 +08:00
CJKmkp 39d54cc493 更新版本号 2025-07-29 18:06:59 +08:00
CJKmkp d31f40408b fix:图片墨迹保存问题 2025-07-29 17:59:41 +08:00
CJKmkp 7f88d9ae27 fix:图片墨迹保存问题 2025-07-29 17:44:15 +08:00
CJKmkp 1c1dd81474 fix:图片墨迹保存问题 2025-07-29 17:38:58 +08:00
CJKmkp 53a498c581 fix:IACore 2025-07-29 16:28:22 +08:00
CJKmkp bfb6346812 delete:IACore释放 2025-07-29 16:08:24 +08:00
CJKmkp bd2fa1e427 improve:PPT模块 2025-07-29 09:43:18 +08:00
CJKmkp 6c4bfeff29 improve:PPT模块 2025-07-29 09:35:47 +08:00
CJKmkp 299a77eea8 improve:PPT模块 2025-07-29 09:19:27 +08:00
CJKmkp 351a00fb1e 更新版本号 2025-07-29 09:08:39 +08:00
CJKmkp 2140e1ebe1 improve:墨迹平滑 2025-07-29 09:02:03 +08:00
CJKmkp 497a820ba2 improve:PPT模块 2025-07-29 08:44:17 +08:00
CJKmkp 7182f3554a Revert "fix:issue #110"
This reverts commit f8e4732dcd.
2025-07-29 02:33:19 +08:00
CJKmkp 506ba52502 improve:直线拉直 2025-07-29 01:40:35 +08:00
CJKmkp 90c1630af4 improve:PPT模块 2025-07-29 01:34:51 +08:00
CJKmkp 5934abd448 fix:进退白板墨迹消失 2025-07-29 01:31:21 +08:00
CJKmkp 86f432ef01 improve:PPT模块 2025-07-29 01:24:42 +08:00
CJKmkp 4913019c5c 优化PPT模块 2025-07-29 01:15:32 +08:00
CJKmkp a6316797e6 更新软件信息 2025-07-29 00:01:47 +08:00
CJKmkp 00d7549bde 更新互斥锁 2025-07-28 23:57:50 +08:00
CJKmkp 8fc33f5649 更新软件名称 2025-07-28 23:51:14 +08:00
CJKmkp 729b544675 improve:PPT模块 2025-07-28 22:36:02 +08:00
CJKmkp 32e8324275 更新日志 2025-07-28 19:12:12 +08:00
CJKmkp 842f6dd726 更新版本号 2025-07-28 19:10:51 +08:00
CJKmkp 59f7d11df3 improve:单文件 2025-07-28 19:08:06 +08:00
CJKmkp dcd2f52c59 improve:插入图片 2025-07-28 19:02:45 +08:00
CJKmkp b45413c232 fix:墨迹纠正失效 2025-07-28 18:29:22 +08:00
CJKmkp b4481ff680 fix:issue #111 2025-07-28 18:23:07 +08:00
CJKmkp d7d7a3919f improve:日志输出 2025-07-28 18:11:20 +08:00
CJKmkp f8e4732dcd fix:issue #110 2025-07-28 17:44:15 +08:00
CJKmkp 1b92ed66b7 更新README 2025-07-28 16:19:19 +08:00
CJKmkp 9ba74b9504 更新版本号 2025-07-28 16:12:40 +08:00
CJKmkp 8cd49f12d1 更新README 2025-07-28 16:10:40 +08:00
CJKmkp c48ca9ee89 fix:issue #93 2025-07-28 16:04:36 +08:00
CJKmkp 43bcf71bf5 fix:issue #93 2025-07-28 15:47:18 +08:00
CJKmkp ee48813df1 fix:issue #93 2025-07-28 15:18:33 +08:00
CJKmkp f4a67e2822 fix:issue #93 2025-07-28 14:45:37 +08:00
CJKmkp f03733da04 优化代码 2025-07-28 14:40:44 +08:00
CJKmkp f38313ff2c 更新版本号 2025-07-28 11:37:58 +08:00
CJKmkp b5d9e21f37 improve:用户体验分级 2025-07-28 11:35:47 +08:00
CJKmkp 5d42a8957e fix:issue #93 2025-07-28 11:15:35 +08:00
CJK_mkp b276c60909 Merge pull request #108 from InkCanvasForClass/all-contributors/add-PrefacedCorg
docs: add PrefacedCorg as a contributor for code
2025-07-28 02:05:44 +08:00
allcontributors[bot] d03564bce9 docs: update .all-contributorsrc 2025-07-27 18:05:04 +00:00
allcontributors[bot] 41409c39d5 docs: update README.md 2025-07-27 18:05:03 +00:00
CJK_mkp aa9c5107d0 Merge pull request #107 from PrefacedCorg/beta
fix:issue #93
2025-07-28 02:02:57 +08:00
PrefacedCorg 7a141822e7 fix:issue #93 2025-07-28 01:49:54 +08:00
CJKmkp a4fd301d5a fix:issue #93 2025-07-28 00:48:50 +08:00
CJKmkp b2ef8b96ef fix:issue #93 2025-07-27 22:52:04 +08:00
CJKmkp baa9e1003e fix:issue #93 2025-07-27 22:00:37 +08:00
CJKmkp 36b97b2adc 更新版本号 2025-07-27 16:15:36 +08:00
CJKmkp f13bffa834 add:优化至单文件版本 2025-07-27 16:05:38 +08:00
CJKmkp 4394566ed3 fix:issue #105 2025-07-27 00:13:41 +08:00
2,2,3-三甲基戊烷 de95c24f66 fix: Fix the problems of the bandage of STCN 2025-07-26 19:42:27 +08:00
CJKmkp 6b20d3e268 Merge branch 'beta' of https://github.com/InkCanvasForClass/community into beta 2025-07-26 19:37:12 +08:00
CJKmkp ce037a437a 更新版本号 2025-07-26 19:36:39 +08:00
2,2,3-三甲基戊烷 1349dab6d4 fix: Update README.md 2025-07-26 19:35:16 +08:00
CJKmkp d3d31925ee Merge branch 'beta' of https://github.com/InkCanvasForClass/community into beta 2025-07-26 19:34:22 +08:00
CJKmkp d9fa77c86b 更新版本号 2025-07-26 19:34:06 +08:00
CJKmkp dad01235b0 fix:侧边栏中的退出放映按钮退出不完全的问题 2025-07-26 19:30:56 +08:00
2,2,3-三甲基戊烷 52d9c26076 Merge pull request #103 from InkCanvasForClass/all-contributors/add-awesome-iwb
docs: add awesome-iwb as a contributor for doc
2025-07-26 19:26:01 +08:00
allcontributors[bot] 1a0236237d docs: update .all-contributorsrc 2025-07-26 11:25:43 +00:00
allcontributors[bot] 58bb7a5ebc docs: update README.md 2025-07-26 11:25:42 +00:00
CJK_mkp efbab58bca Merge pull request #102 from InkCanvasForClass/all-contributors/add-Alan-CRL
docs: add Alan-CRL as a contributor for financial
2025-07-26 19:20:37 +08:00
2,2,3-三甲基戊烷 eedbc7a863 Merge branch 'beta' into all-contributors/add-Alan-CRL 2025-07-26 19:20:26 +08:00
allcontributors[bot] 626cda63ff docs: update .all-contributorsrc 2025-07-26 11:17:27 +00:00
allcontributors[bot] 7b7a9d93aa docs: update README.md 2025-07-26 11:17:26 +00:00
2,2,3-三甲基戊烷 f5c68dac61 Merge pull request #101 from InkCanvasForClass/all-contributors/add-MKStoler1024
docs: add MKStoler1024 as a contributor for doc, code, and design
2025-07-26 19:16:22 +08:00
allcontributors[bot] 2b6b106771 docs: update .all-contributorsrc 2025-07-26 11:15:47 +00:00
allcontributors[bot] 047586883e docs: update README.md 2025-07-26 11:15:46 +00:00
2,2,3-三甲基戊烷 0c1a25dd6b feat: Merge pull request #100 from InkCanvasForClass/all-contributors/add-Alan-CRL
docs: add Alan-CRL as a contributor for code, infra, and doc
2025-07-26 19:11:45 +08:00
allcontributors[bot] 7840a9a713 docs: update .all-contributorsrc 2025-07-26 11:11:01 +00:00
allcontributors[bot] 28f96ffcd3 docs: update README.md 2025-07-26 11:11:00 +00:00
CJKmkp 04b2663183 improve:墨迹平滑 2025-07-26 19:03:07 +08:00
2,2,3-三甲基戊烷 1a11027871 feat: Merge pull request #99 from InkCanvasForClass/all-contributors/add-2-2-3-trimethylpentane
docs: add 2-2-3-trimethylpentane as a contributor for blog, doc, and design
2025-07-26 19:00:48 +08:00
allcontributors[bot] 854a00803e docs: update .all-contributorsrc 2025-07-26 11:00:10 +00:00
allcontributors[bot] 11ae5f157f docs: update README.md 2025-07-26 11:00:09 +00:00
CJKmkp ecfe05139e improve:插件功能 2025-07-26 18:37:08 +08:00
CJKmkp 4a392e03a7 更新版本号 2025-07-26 16:24:30 +08:00
CJKmkp a66037f886 improve:用户体验分级 2025-07-26 16:22:55 +08:00
CJKmkp 58c399dcbe improve:用户体验分级 2025-07-26 16:08:22 +08:00
CJKmkp f33e617f44 improve:用户体验分级 2025-07-26 15:57:28 +08:00
CJKmkp 3e976c1026 improve:用户体验分级 2025-07-26 15:01:00 +08:00
CJKmkp c15c75075c improve:用户体验分级 2025-07-26 15:00:31 +08:00
CJKmkp bf8d988c75 improve:用户体验分级 2025-07-26 14:58:10 +08:00
CJKmkp 6fb7af3d46 add:用户体验分级 2025-07-26 14:29:24 +08:00
CJKmkp 1c2860c180 更新版本号 2025-07-26 12:41:44 +08:00
CJKmkp fc41f10c37 improve:自动更新 2025-07-26 12:37:39 +08:00
CJKmkp dedf366866 improve:自动更新 2025-07-26 12:33:08 +08:00
CJKmkp edb10096d6 improve:自动更新 2025-07-26 12:20:23 +08:00
CJKmkp ba42a1e6c9 improve:自动更新 2025-07-26 12:02:58 +08:00
CJKmkp a0058c104d 更新日志 2025-07-25 18:36:23 +08:00
CJKmkp 7f1f322d04 improve:白板时间显示 2025-07-25 18:32:03 +08:00
CJKmkp 57ac8d8771 更新版本号 2025-07-25 18:28:38 +08:00
CJKmkp bcd0509eff improve:窗口无焦点 2025-07-25 18:21:16 +08:00
CJKmkp 624af87795 fix:侧边栏显示及浮动栏高度计算 2025-07-25 18:12:46 +08:00
CJKmkp 616df56657 improve:任务栏高度计算 2025-07-25 18:02:46 +08:00
CJKmkp 4efd6abb56 improve:任务栏高度计算 2025-07-25 17:57:04 +08:00
CJKmkp 8c657a4ccf improve:PPT模块 2025-07-25 17:50:07 +08:00
CJKmkp db582f6c88 更新版本号 2025-07-25 11:07:12 +08:00
CJKmkp a7b861f83c improve:PPT模块 2025-07-25 10:21:55 +08:00
CJKmkp 19b1c7ae8b improve:PPT模块 2025-07-25 09:58:53 +08:00
CJKmkp 192cec68c7 improve:自动更新 2025-07-24 23:18:44 +08:00
CJKmkp 4afa66f3f3 更新版本号 2025-07-24 22:18:31 +08:00
CJKmkp 7fde157184 improve:自动更新 2025-07-24 22:16:38 +08:00
CJKmkp a1935e8299 improve:直线拉直 2025-07-24 21:02:00 +08:00
CJKmkp 50e993fd89 improve:直线拉直 2025-07-24 20:59:21 +08:00
CJKmkp a25ec6b0af fix:白板使用擦除后出现的线条异常BUG 2025-07-24 02:02:34 +08:00
CJKmkp efeb99aaac fix:触摸时长方体绘制多余直线 2025-07-24 00:58:03 +08:00
CJKmkp f19118432d improve:自动保存 2025-07-24 00:20:00 +08:00
CJKmkp b69eac2886 improve:默认设置 2025-07-23 23:16:49 +08:00
CJKmkp 4efc4e7f34 improve:默认配置文件 2025-07-23 23:14:29 +08:00
CJKmkp 4755eb06e2 improve:手掌擦 2025-07-23 23:12:37 +08:00
CJKmkp e4dc1c0b4e improve:手掌擦 2025-07-23 23:10:10 +08:00
CJKmkp 89f54c2b4a 更新版本号 2025-07-23 23:06:39 +08:00
CJKmkp abf52f0d49 add:新版手掌擦 2025-07-23 23:05:28 +08:00
CJKmkp 044df3f09c delete:手掌擦 2025-07-23 22:57:16 +08:00
CJKmkp 271829f9c1 Revert "improve:手掌擦"
This reverts commit eb0cf27218.
2025-07-23 22:16:43 +08:00
CJKmkp 13625b37a8 improve:自动更新 2025-07-23 21:45:29 +08:00
CJKmkp 781191196f 更新版本号 2025-07-23 19:44:06 +08:00
CJKmkp eb0cf27218 improve:手掌擦 2025-07-23 19:42:41 +08:00
CJKmkp 1706341283 improve:自动更新 2025-07-23 19:29:44 +08:00
CJKmkp 71f46b3bff improve:自动更新 2025-07-22 22:39:02 +08:00
CJKmkp 4c39798682 improve:设置界面 2025-07-22 22:02:21 +08:00
CJKmkp b861aa385d improve:设置界面 2025-07-22 21:39:22 +08:00
CJKmkp 156e8a2686 improve:自动更新 2025-07-22 21:01:25 +08:00
CJKmkp f88acf1375 improve:设置页面 2025-07-22 19:06:35 +08:00
CJKmkp be770d4607 improve:自动更新 2025-07-22 18:45:43 +08:00
CJKmkp 7565f624c9 improve:自动更新 2025-07-22 18:36:37 +08:00
CJKmkp 65d56297fd improve:自动更新 2025-07-22 18:25:04 +08:00
CJKmkp 86caac4a1d improve:自动更新 2025-07-22 18:08:22 +08:00
CJKmkp d382ac4fa2 improve:自动更新 2025-07-22 18:02:29 +08:00
CJKmkp f9ceeaad44 improve:自动更新 2025-07-22 17:36:02 +08:00
CJKmkp 0691293973 improve:自动更新 2025-07-22 17:07:27 +08:00
CJKmkp 9491b48eb6 improve:窗口无焦点 2025-07-22 16:20:37 +08:00
CJKmkp 6c7f63270f improve:白板时间显示 2025-07-22 16:12:42 +08:00
CJKmkp a62f793288 improve:设置 2025-07-21 22:45:55 +08:00
CJKmkp 901b54b829 更新版本号 2025-07-21 21:39:08 +08:00
CJKmkp 0efa1127a3 fix:issue #94 2025-07-21 21:02:23 +08:00
CJKmkp 28fc53799a fix:issue #92 #94 2025-07-21 20:30:07 +08:00
CJKmkp bdc4af7cd4 improve:任务栏高度计算 2025-07-21 18:53:47 +08:00
CJKmkp c68996ff20 improve:手掌擦 2025-07-21 18:39:42 +08:00
CJKmkp f517a63cda improve:手掌擦 2025-07-21 18:37:25 +08:00
CJKmkp fefb9b490e 更新版本号 2025-07-21 18:13:27 +08:00
CJKmkp 383e1d5368 improve:鸿合屏幕书写查杀后自动进入批注 #38 2025-07-21 17:57:08 +08:00
CJKmkp 4e4ce36e76 add:鸿合屏幕书写查杀后自动进入批注 #38 2025-07-21 17:28:52 +08:00
CJKmkp 19983a113e add:进入PPT放映自动回到首页 #38 2025-07-21 17:19:27 +08:00
CJKmkp 8eaac465ff improve:退出PPT放映自动恢复收纳模式 #38 2025-07-21 17:08:17 +08:00
CJKmkp 17b2d744ba add:退出PPT放映自动恢复收纳模式 #38 2025-07-21 16:53:11 +08:00
CJKmkp 166e0d400a add:侧边栏退出放映按钮 #38 2025-07-21 16:43:29 +08:00
CJKmkp 5cf409ce0b improve:PPT模块 2025-07-21 16:15:42 +08:00
CJKmkp e37e847a8b 删除无用using 2025-07-21 16:00:31 +08:00
CJKmkp 32c77d3743 improve:插入图片 2025-07-21 15:20:05 +08:00
CJKmkp 45e368d9e7 fix:issue #91 2025-07-21 14:35:30 +08:00
CJKmkp 97496302fb improve:插入照片 2025-07-21 14:19:55 +08:00
CJKmkp 675959e615 improve:插入图片 2025-07-21 12:44:05 +08:00
CJKmkp f641b282b6 improve:插入图片 2025-07-21 12:15:56 +08:00
CJKmkp e92a05683c add:插入图片 2025-07-21 11:37:20 +08:00
CJKmkp 93bef2e144 fix:白板页面预览无法使用触摸 2025-07-21 10:14:21 +08:00
CJKmkp 44e331ae96 fix:issue #91 2025-07-21 09:56:51 +08:00
CJKmkp f295c85668 fix:issue #90 2025-07-21 09:54:58 +08:00
CJKmkp 6f843bface improve:PPT模块 2025-07-21 08:43:16 +08:00
CJKmkp 2dea6076f0 improve:PPT模块 2025-07-21 08:37:37 +08:00
CJKmkp 78c6c7b571 improve:手掌擦 2025-07-20 22:54:49 +08:00
CJKmkp a50bec9326 improve:插件图标 2025-07-20 22:40:55 +08:00
CJKmkp 7d193d7de6 fix:错误的侧边栏按钮 2025-07-20 21:49:47 +08:00
CJKmkp 5bbb3e6a6c fix:错误的侧边栏按钮 2025-07-20 21:43:03 +08:00
CJKmkp 15198c32ea improve:PPT模块 2025-07-20 21:14:59 +08:00
CJKmkp 476503338f improve:窗口无焦点 2025-07-20 21:03:42 +08:00
CJKmkp ba6303dca0 improve:窗口无焦点 2025-07-20 21:01:15 +08:00
CJKmkp 23432465ac improve:PPT模块 2025-07-20 19:52:59 +08:00
CJKmkp 1f0b5cebeb improve:PPT模块 2025-07-20 19:40:10 +08:00
CJKmkp 1f83c84a7e improve:PPT模块 2025-07-20 19:36:58 +08:00
CJKmkp e209af9c57 improve:PPT模块 2025-07-20 19:31:01 +08:00
CJKmkp a714d312a8 improve:PPT日志输出 2025-07-20 19:23:43 +08:00
CJKmkp 4a776c1fe8 improve:墨迹平滑方案 2025-07-20 19:17:32 +08:00
CJKmkp da86f07cbe fix:PPT墨迹对应问题 2025-07-20 18:27:08 +08:00
CJKmkp 48e0ca887d improve:PPT联动模块 2025-07-20 17:20:33 +08:00
CJKmkp 0f3b6c4cec improve:墨迹平滑方案 2025-07-20 16:48:16 +08:00
CJKmkp 9ce9631135 更新版本号 2025-07-20 16:16:17 +08:00
CJKmkp c73a5c3a7e fix:翻页控件崩溃 2025-07-20 16:14:26 +08:00
CJKmkp 62d35127b1 improve:墨迹平滑方案 2025-07-20 15:57:51 +08:00
CJKmkp 09f17caabe fix:白板颜色无法保存的问题 2025-07-20 15:42:11 +08:00
CJKmkp c5355d7497 improve:墨迹平滑方案 2025-07-20 15:27:02 +08:00
CJKmkp d5142ad82c improve:墨迹平滑方案 2025-07-20 15:21:59 +08:00
CJKmkp 428b278c78 更新版本号 2025-07-20 15:02:03 +08:00
CJKmkp 33c1e04934 improve:issue #5 2025-07-20 15:00:11 +08:00
CJKmkp 6c075d80ba improve:issue #5 2025-07-20 12:36:21 +08:00
CJKmkp 38713108e0 improve:issue #5 2025-07-20 12:19:32 +08:00
CJKmkp 6b75fea813 improve:issue #5 2025-07-20 12:01:30 +08:00
CJKmkp de6fc84fec Revert "improve:联动模块"
This reverts commit ecd276a3a0.
2025-07-20 09:09:39 +08:00
CJKmkp ecd276a3a0 improve:联动模块 2025-07-20 00:37:13 +08:00
CJKmkp 86fbd0cebc 撤回模块改进 2025-07-20 00:25:33 +08:00
CJKmkp 6a97919f7a Revert "improve:联动模块"
This reverts commit f2e7e17bd1.
2025-07-20 00:21:16 +08:00
CJKmkp f2e7e17bd1 improve:联动模块 2025-07-20 00:16:23 +08:00
CJKmkp eedd6cee1d improve:联动模块 2025-07-20 00:13:21 +08:00
CJKmkp 25e11fa9de improve:联动模块 2025-07-20 00:09:48 +08:00
CJKmkp 4742600b86 improve:联动模块 2025-07-19 23:42:43 +08:00
CJKmkp b3e4850413 improve:插件图标 2025-07-19 22:01:02 +08:00
CJKmkp fd8d13447c 更新版本号 2025-07-19 17:31:08 +08:00
CJKmkp 758a3d3f99 improve:issue #79 2025-07-19 17:27:27 +08:00
CJKmkp fd8b4d94d6 improve:issue #79 2025-07-19 17:21:59 +08:00
CJKmkp fa7dae8177 fix:win7无法自动更新 2025-07-19 16:51:03 +08:00
CJKmkp 21638218c6 improve:启动台插件 2025-07-19 16:37:44 +08:00
CJKmkp a29a414e8a improve:issue #79 2025-07-19 16:21:03 +08:00
CJKmkp 251c7f399e improve:自动更新 2025-07-19 16:03:45 +08:00
CJKmkp 1da55f2011 improve:自动更新 2025-07-19 15:36:05 +08:00
CJKmkp 856125edc2 更新版本号 2025-07-19 14:35:33 +08:00
CJKmkp 32ef30ebd8 improve:橡皮图标 2025-07-19 14:34:06 +08:00
CJKmkp 8972e42fee Revert "improve:橡皮光标"
This reverts commit 91f206aad0.
2025-07-19 14:10:29 +08:00
CJKmkp 91f206aad0 improve:橡皮光标 2025-07-19 14:04:35 +08:00
CJKmkp 5626babcdf improve:橡皮光标 2025-07-19 13:36:42 +08:00
CJKmkp 98175152db improve:光标显示 2025-07-19 13:35:28 +08:00
CJKmkp 817ade3e34 improve:光标显示 2025-07-19 10:56:30 +08:00
CJKmkp ab5493f8c4 improve:光标显示 2025-07-19 10:18:16 +08:00
CJKmkp 796bd99377 improve:插件功能 2025-07-18 21:51:32 +08:00
CJKmkp a0dc60a403 improve:联动模块 2025-07-18 21:29:55 +08:00
CJKmkp a92e58abf1 improve:白板画布 2025-07-18 19:20:06 +08:00
CJKmkp e8f0793feb 更新版本号 2025-07-18 18:52:01 +08:00
CJKmkp 2d7eff8205 fix:触摸问题 2025-07-18 17:59:17 +08:00
CJKmkp 6412892985 fix:触摸问题 2025-07-18 17:02:17 +08:00
CJKmkp 69ae0ffc71 fix:触摸问题 2025-07-18 17:01:18 +08:00
CJKmkp 854be23cfb fix:触摸问题 2025-07-18 16:28:50 +08:00
CJKmkp 02e143217e fix:触摸问题 2025-07-18 16:21:39 +08:00
CJKmkp 4feec82b03 fix:触摸问题 2025-07-18 16:12:04 +08:00
CJKmkp 938ca648f1 撤销操作 2025-07-18 11:53:55 +08:00
CJKmkp ee018ea287 撤销 Commit ab88c34 2025-07-18 11:50:44 +08:00
CJKmkp 8ab60ad000 撤销 Commit ab88c34 2025-07-18 11:49:00 +08:00
CJKmkp 17eaf34500 撤销 Commit b46cbcc 2025-07-18 11:47:41 +08:00
CJKmkp 2485958f6e 撤销Commit 3645906 2025-07-18 11:38:32 +08:00
CJKmkp 7ac3a22fa6 improve:插件功能 2025-07-17 22:30:12 +08:00
CJKmkp 285f211f50 add:备份功能 2025-07-16 15:28:36 +08:00
CJKmkp 1e96477127 更新版本号 2025-07-16 14:04:40 +08:00
CJKmkp 87ffa48265 improve:插件功能 2025-07-16 14:02:54 +08:00
CJKmkp 8b64df435c improve:插件功能 2025-07-16 13:50:32 +08:00
CJKmkp dcf88ee510 improve:插件功能 2025-07-16 13:39:24 +08:00
CJKmkp b21a15376d add:插件功能 2025-07-16 13:35:17 +08:00
CJKmkp 3e87ed4f9b add:墨迹全屏保存 #79 2025-07-16 09:49:41 +08:00
CJKmkp a6cd9c955b 更新版本号 2025-07-16 09:17:46 +08:00
CJKmkp 86b52b76ed add:自定义白板背景色 #39 2025-07-16 09:16:36 +08:00
CJKmkp 853f380e5d improve:手掌擦机制 2025-07-16 08:03:08 +08:00
CJKmkp 027686a3b5 更新版本号 2025-07-15 21:43:44 +08:00
CJKmkp 79b87e59be improve:设置侧边栏 2025-07-15 21:10:49 +08:00
CJKmkp 3a37e55162 add:退出收纳模式自动进入批注选项 2025-07-15 21:00:00 +08:00
CJKmkp 1ff40c0016 add:自定义点名背景 2025-07-15 20:50:12 +08:00
CJKmkp 4f7c1021c8 improve:自定义图标保存了位置 2025-07-15 20:33:47 +08:00
CJKmkp e687c78ba8 add:自定义浮动栏图标 2025-07-15 20:30:10 +08:00
CJKmkp 2c2f46a0d8 improve:端点吸附 2025-07-15 18:30:25 +08:00
CJKmkp 29fa565258 fix:issue #75 2025-07-15 18:09:38 +08:00
CJKmkp 51f3d410c9 fix:issue #47 2025-07-15 17:55:22 +08:00
CJKmkp a0d159da9d improve:进程检测 2025-07-15 16:06:29 +08:00
CJKmkp 9edb58ee27 improve:自动更新 2025-07-15 14:36:54 +08:00
CJK_mkp ef8a894489 Merge pull request #84 from InkCanvasForClass/all-contributors/add-CreeperAWA
All contributors/add creeper awa
2025-07-15 14:09:46 +08:00
allcontributors[bot] 992f388a56 docs: update .all-contributorsrc 2025-07-14 08:23:15 +00:00
allcontributors[bot] a54e7206a0 docs: update README.md 2025-07-14 08:23:14 +00:00
Hydrogen c4e74b21fc Merge pull request #82 from InkCanvasForClass/all-contributors/add-Hydro11451
docs: add Hydro11451 as a contributor for code
2025-07-14 16:22:51 +08:00
allcontributors[bot] 7b9e07bdda docs: update .all-contributorsrc 2025-07-14 08:22:19 +00:00
allcontributors[bot] 19f5204253 docs: update README.md 2025-07-14 08:22:18 +00:00
Hydrogen c4ad5c5f81 Merge pull request #81 from InkCanvasForClass/all-contributors/add-CJKmkp
docs: add CJKmkp as a contributor for code
2025-07-14 16:21:27 +08:00
allcontributors[bot] e888118a20 docs: update .all-contributorsrc 2025-07-14 08:21:08 +00:00
allcontributors[bot] 7afce136f6 docs: update README.md 2025-07-14 08:21:07 +00:00
Hydrogen 71c4dadeee Delete myself from All Contributors
我已经退出ICC-CE管理组。——Hydrogen
2025-07-14 16:19:40 +08:00
Hydrogen a6d44685b3 Update README.md 2025-07-14 08:42:19 +08:00
CJK_mkp a8ce61dad9 Update Settings.cs 2025-07-12 17:33:13 +08:00
CJK_mkp 0f47d1473d Update Settings.cs 2025-07-12 17:32:05 +08:00
CJK_mkp 2134ee516a Update Settings.cs 2025-07-12 15:59:09 +08:00
CJK_mkp 6c60306bee Update MW_Settings.cs 2025-07-12 12:16:41 +08:00
CJK_mkp 816748833c Update MainWindow.xaml 2025-07-12 12:14:43 +08:00
CJK_mkp cac0fca3bb Update MW_Settings.cs 2025-07-12 10:49:24 +08:00
CJK_mkp 5ed28b121e Update MW_PPT.cs 2025-07-12 09:09:20 +08:00
CJK_mkp c4180eba6f Update MW_Save&OpenStrokes.cs 2025-07-12 09:01:49 +08:00
CJK_mkp 0065a1f81f Update MW_Screenshot.cs 2025-07-12 09:00:51 +08:00
CJK_mkp ed7ffbcb13 Merge pull request #77 from 2-2-3-trimethylpentane/beta
fix: correct the URL in the poster
2025-07-10 21:03:56 +08:00
2,2,3-三甲基戊烷 6a8d9db407 Rename ICC-CE宣传图.png to icc ce.png 2025-07-10 11:41:46 +08:00
2,2,3-三甲基戊烷 81140837f1 fix: Delete Images/icc ce.png 2025-07-10 11:41:20 +08:00
2,2,3-三甲基戊烷 70232645a8 fix: correct the URL in the picture 2025-07-10 11:38:51 +08:00
CJK_mkp 4d3b3ef3df Update MW_TouchEvents.cs 2025-07-06 22:07:05 +08:00
CJK_mkp d203314424 Update MW_FloatingBarIcons.cs 2025-07-06 21:09:01 +08:00
CJK_mkp a8c5ccda17 更新版本号 2025-07-06 16:23:33 +08:00
CJK_mkp 86b996637c fix:崩溃后重启选项无法修改,部分触摸问题 improve::自动更新 2025-07-06 15:39:37 +08:00
DotteringDoge471 1480d4a14e Update README.md 2025-07-05 23:13:16 +08:00
Hydrogen b8013afd64 Merge pull request #73 from InkCanvasForClass/all-contributors/add-CJKmkp
docs: add CJKmkp as a contributor for doc
2025-07-05 22:25:04 +08:00
allcontributors[bot] 812bc83939 docs: update .all-contributorsrc 2025-07-05 14:24:19 +00:00
allcontributors[bot] d6829744bb docs: update README.md 2025-07-05 14:24:18 +00:00
CJK_mkp a7a03544b6 Merge pull request #72 from InkCanvasForClass/main
合并分支
2025-07-03 22:12:55 +08:00
DotteringDoge471 ffa8729d10 Merge pull request #71 from CreeperAWA/issue_template 2025-07-03 04:24:02 +08:00
CreeperAWA ce291d3a77 improve:删除旧的 Bug 报告和功能请求模板,添加新的 .yml 格式模板以方便用户填写 2025-06-30 19:02:32 +08:00
CJK_mkp 297dbad60c Merge pull request #67 from InkCanvasForClass/beta
ICC CE Beta 1.7.0.3 更新合并
2025-06-29 16:42:40 +08:00
CJK_mkp 54982218f5 更新版本号 2025-06-29 16:25:32 +08:00
CJK_mkp c14f4df494 Merge branch 'beta' of https://github.com/InkCanvasForClass/community into beta 2025-06-29 16:00:42 +08:00
CJK_mkp f53f23aa4b improve:更新日志格式 2025-06-29 16:00:37 +08:00
CJK_mkp 10c59fb4b4 Update UpdateLog.md 2025-06-29 15:59:31 +08:00
CJK_mkp a5cffc5ea4 Rename UpdateLog.txt to UpdateLog.md 2025-06-29 15:58:21 +08:00
CJK_mkp 200c299ce7 fix:数位笔相关问题 2025-06-29 15:45:18 +08:00
CJK_mkp 8547276549 fix:手掌擦面积问题 2025-06-29 15:35:28 +08:00
CJK_mkp b09afcf725 fix:修复板擦面积问题 2025-06-29 15:29:25 +08:00
CJK_mkp a2860be7a3 fix:issue #40 2025-06-29 15:15:51 +08:00
CJK_mkp de9d026e3a Merge branch 'beta' of https://github.com/InkCanvasForClass/community into beta 2025-06-29 15:07:17 +08:00
CJK_mkp 27a1baae7b fix:修复了自动收纳的相关问题 2025-06-29 15:07:13 +08:00
Hydrogen f2584309d1 Merge pull request #66 from InkCanvasForClass/beta
Beta
2025-06-29 15:04:10 +08:00
Hydrogen 831fd09615 Update gesture-enabled icon
Replaces the existing gesture-enabled.png icon with a new version in the Resources/new-icons directory.
2025-06-29 15:01:42 +08:00
Hydrogen e0e22a09c0 Update gesture icon image
Replaces the existing gesture.png icon in Resources/new-icons with a new version.
2025-06-29 14:52:19 +08:00
CJK_mkp 60c6e0632d add:高精度直线拉直 2025-06-29 14:15:20 +08:00
CJK_mkp 6da13c4fc0 add:直接调Ci点名 2025-06-29 13:01:33 +08:00
CJK_mkp ec330aea69 improve:改进日志功能 2025-06-29 12:40:15 +08:00
CJK_mkp 318682b63a fix:版本修复按钮 2025-06-29 12:20:45 +08:00
CJK_mkp dd53d7ff0a Merge pull request #62 from InkCanvasForClass/beta
Update UpdateLog.txt
2025-06-29 12:09:00 +08:00
CJK_mkp b03207d287 Update UpdateLog.txt 2025-06-29 12:06:46 +08:00
537 changed files with 35841 additions and 16355 deletions
-31
View File
@@ -1,31 +0,0 @@
{
"projectName": "community",
"projectOwner": "InkCanvasForClass",
"files": [
"README.md"
],
"commitType": "docs",
"commitConvention": "angular",
"contributorsPerLine": 7,
"contributors": [
{
"login": "CJKmkp",
"name": "CJK_mkp",
"avatar_url": "https://avatars.githubusercontent.com/u/113243675?v=4",
"profile": "https://github.com/CJKmkp",
"contributions": [
"maintenance"
]
},
{
"login": "Hydro11451",
"name": "Hydrogen",
"avatar_url": "https://avatars.githubusercontent.com/u/214308559?v=4",
"profile": "https://github.com/Hydro11451",
"contributions": [
"maintenance",
"doc"
]
}
]
}
-1
View File
@@ -6,7 +6,6 @@ labels: bug
assignees: ''
---
## Version(or version link)
## Description
-35
View File
@@ -1,35 +0,0 @@
name: .NET Build
on:
push:
branches: [ main,beta ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4.2.2
- name: Setup MSbuild
uses: microsoft/setup-msbuild@v2
- name: Setup NuGet
uses: NuGet/setup-nuget@v2.0.1
- name: Restore NuGet Packages
run: nuget restore "Ink Canvas.sln"
- name: Build the Solution
run: |
msbuild -t:restore /p:GitFlow="Github Action"
msbuild /p:platform="Any CPU" /p:configuration="Release" /p:GitFlow="Github Action" "Ink Canvas/InkCanvasForClass.csproj"
- name: Upload to artifact
uses: actions/upload-artifact@v4.5.0
with:
name: InkCanvasForClass
path: "Ink Canvas/bin/Any CPU/Release/net472/"
+16 -3
View File
@@ -1,3 +1,16 @@
obj/
bin/
.vs
InkCanvasForClass/obj
InkCanvasForClass/bin
InkCanvasForClassX/obj
InkCanvasForClassX/bin
InkCanvasForClass.IACoreHelper/obj
InkCanvasForClass.IACoreHelper/bin
InkCanvasForClass.PowerPoint.InteropHelper/obj
InkCanvasForClass.PowerPoint.InteropHelper/bin
InkCanvasForClass.PowerPoint.VstoPlugin/obj
InkCanvasForClass.PowerPoint.VstoPlugin/bin
InkCanvasForClass.IccInkCanvas/obj
InkCanvasForClass.IccInkCanvas/bin
InkCanvasForClass.IccInkCanvas.Demo/obj
InkCanvasForClass.IccInkCanvas.Demo/bin
.vs
.idea
+4 -4
View File
@@ -1,12 +1,12 @@
# Default ignored files
# 默认忽略的文件
/shelf/
/workspace.xml
# Rider ignored files
# Rider 忽略的文件
/contentModel.xml
/projectSettingsUpdater.xml
/modules.xml
/contentModel.xml
/.idea.Ink Canvas.iml
# Editor-based HTTP Client requests
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
+1 -3
View File
@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders>
<Path>../../ICC CE main</Path>
</attachedFolders>
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,398 +0,0 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|c:\\users\\dubi906w\\source\\repos\\icc-ce\\ink canvas\\mainwindow_cs\\mw_floatingbaricons.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|solutionrelative:ink canvas\\mainwindow_cs\\mw_floatingbaricons.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\README.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:README.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\privacy.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:privacy.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Manual.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Manual.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\LICENSE||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:LICENSE||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas.sln.DotSettings.user||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Ink Canvas.sln.DotSettings.user||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
},
{
"AbsoluteMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|c:\\users\\dubi906w\\source\\repos\\icc-ce\\ink canvas\\mainwindow_cs\\mw_ppt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|solutionrelative:ink canvas\\mainwindow_cs\\mw_ppt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|c:\\users\\dubi906w\\source\\repos\\icc-ce\\ink canvas\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}",
"RelativeMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|solutionrelative:ink canvas\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 210,
"SelectedChildIndex": 48,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{e506b91c-c606-466a-90a9-123d1d1e12b3}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{387cb18d-6153-4156-9257-9ac3f9207bbe}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{e8b06f52-6d01-11d2-aa7d-00c04f990343}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{46c87f81-5a06-43a8-9e25-85d33bac49f8}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{269a02dc-6af8-11d3-bdc4-00c04f688e50}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{99b8fa2f-ab90-4f57-9c32-949f146f1914}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{c79b74ff-f1d7-4c94-aefa-4d22bfe1b1f9}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}"
},
{
"$type": "Bookmark",
"Name": "ST:2:0:{34c7837f-3b3a-449c-bdf0-bdad86cbaf4a}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{37aba9be-445a-11d3-9949-00c04f68fd0a}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{dcc4ea97-1c0c-482b-b205-e541c0df9728}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{75188d03-9892-4ae2-abf1-207126247ce5}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:129:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{eefa5220-e298-11d0-8f78-00a0c9110057}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{4a9b7e51-aa16-11d0-a8c5-00a0c921a4d2}"
},
{
"$type": "Bookmark",
"Name": "ST:132:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:133:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:3:0:{34c7837f-3b3a-449c-bdf0-bdad86cbaf4a}"
},
{
"$type": "Bookmark",
"Name": "ST:153:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:154:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:152:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:151:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:150:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:148:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:149:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:136:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:144:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:147:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:145:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:146:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:143:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:142:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:141:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:140:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:139:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:138:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:137:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:135:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:134:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:129:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}"
},
{
"$type": "Bookmark",
"Name": "ST:130:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:129:0:{75188d03-9892-4ae2-abf1-207126247ce5}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{b1e99781-ab81-11d0-b683-00aa00a3ee26}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "MW_FloatingBarIcons.cs",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"RelativeDocumentMoniker": "Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"RelativeToolTip": "Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"ViewState": "AgIAAOgCAAAAAAAAAAAuwEoGAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-31T10:49:24.719Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "README.md",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\README.md",
"RelativeDocumentMoniker": "README.md",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\README.md",
"RelativeToolTip": "README.md",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
"WhenOpened": "2025-05-31T10:48:22.883Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "MainWindow.xaml",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow.xaml",
"RelativeDocumentMoniker": "Ink Canvas\\MainWindow.xaml",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow.xaml",
"RelativeToolTip": "Ink Canvas\\MainWindow.xaml",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|",
"WhenOpened": "2025-05-24T13:22:56.715Z"
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "Microsoft.Common.CurrentVersion.targets",
"DocumentMoniker": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"RelativeDocumentMoniker": "..\\..\\..\\..\\..\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"ToolTip": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"RelativeToolTip": "..\\..\\..\\..\\..\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"ViewState": "AgIAAGsJAAAAAAAAAAAQwIEJAAAEAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003801|",
"WhenOpened": "2025-05-24T13:06:01.053Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "MW_PPT.cs",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"RelativeDocumentMoniker": "Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"RelativeToolTip": "Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"ViewState": "AgIAAFgAAAAAAAAAAAAUwHQAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-24T13:04:47.205Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "README.md",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"RelativeDocumentMoniker": "..\\..\\..\\..\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"RelativeToolTip": "..\\..\\..\\..\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
"WhenOpened": "2025-05-24T13:04:01.407Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "privacy.txt",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\privacy.txt",
"RelativeDocumentMoniker": "privacy.txt",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\privacy.txt",
"RelativeToolTip": "privacy.txt",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
"WhenOpened": "2025-05-24T13:04:01.337Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "Manual.md",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Manual.md",
"RelativeDocumentMoniker": "Manual.md",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Manual.md",
"RelativeToolTip": "Manual.md",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
"WhenOpened": "2025-05-24T13:04:00.986Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "LICENSE",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\LICENSE",
"RelativeDocumentMoniker": "LICENSE",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\LICENSE",
"RelativeToolTip": "LICENSE",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
"WhenOpened": "2025-05-24T13:04:00.902Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Ink Canvas.sln.DotSettings.user",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas.sln.DotSettings.user",
"RelativeDocumentMoniker": "Ink Canvas.sln.DotSettings.user",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas.sln.DotSettings.user",
"RelativeToolTip": "Ink Canvas.sln.DotSettings.user",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003464|",
"WhenOpened": "2025-05-24T13:04:00.792Z"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{d84ee353-0bef-5a41-a649-8f89aca5d84d}"
}
]
},
{
"DockedWidth": 204,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:1:0:{3ae79031-e1bc-11d0-8f78-00a0c9110057}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{590a070c-4fcd-52d9-87da-dfaa11710261}"
}
]
},
{
"DockedWidth": 190,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{f4fc5ff1-28ef-4b04-ad02-6b298310ccc7}"
}
]
}
]
}
]
}
-398
View File
@@ -1,398 +0,0 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|c:\\users\\dubi906w\\source\\repos\\icc-ce\\ink canvas\\mainwindow_cs\\mw_floatingbaricons.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|solutionrelative:ink canvas\\mainwindow_cs\\mw_floatingbaricons.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\README.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:README.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\privacy.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:privacy.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Manual.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Manual.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\LICENSE||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:LICENSE||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas.sln.DotSettings.user||{FA3CD31E-987B-443A-9B81-186104E8DAC1}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Ink Canvas.sln.DotSettings.user||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
},
{
"AbsoluteMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|c:\\users\\dubi906w\\source\\repos\\icc-ce\\ink canvas\\mainwindow_cs\\mw_ppt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|solutionrelative:ink canvas\\mainwindow_cs\\mw_ppt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|c:\\users\\dubi906w\\source\\repos\\icc-ce\\ink canvas\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}",
"RelativeMoniker": "D:0:0:{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}|Ink Canvas\\InkCanvasForClass.csproj|solutionrelative:ink canvas\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 210,
"SelectedChildIndex": 48,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{e506b91c-c606-466a-90a9-123d1d1e12b3}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{387cb18d-6153-4156-9257-9ac3f9207bbe}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{e8b06f52-6d01-11d2-aa7d-00c04f990343}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{46c87f81-5a06-43a8-9e25-85d33bac49f8}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{269a02dc-6af8-11d3-bdc4-00c04f688e50}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{99b8fa2f-ab90-4f57-9c32-949f146f1914}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{c79b74ff-f1d7-4c94-aefa-4d22bfe1b1f9}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}"
},
{
"$type": "Bookmark",
"Name": "ST:2:0:{34c7837f-3b3a-449c-bdf0-bdad86cbaf4a}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{37aba9be-445a-11d3-9949-00c04f68fd0a}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{dcc4ea97-1c0c-482b-b205-e541c0df9728}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{75188d03-9892-4ae2-abf1-207126247ce5}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:129:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{eefa5220-e298-11d0-8f78-00a0c9110057}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{4a9b7e51-aa16-11d0-a8c5-00a0c921a4d2}"
},
{
"$type": "Bookmark",
"Name": "ST:132:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:133:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:3:0:{34c7837f-3b3a-449c-bdf0-bdad86cbaf4a}"
},
{
"$type": "Bookmark",
"Name": "ST:153:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:154:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:152:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:151:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:150:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:148:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:149:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:136:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:144:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:147:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:145:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:146:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:143:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:142:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:141:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:140:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:139:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:138:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:137:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:135:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:134:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
},
{
"$type": "Bookmark",
"Name": "ST:129:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}"
},
{
"$type": "Bookmark",
"Name": "ST:130:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:129:0:{75188d03-9892-4ae2-abf1-207126247ce5}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{b1e99781-ab81-11d0-b683-00aa00a3ee26}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "MW_FloatingBarIcons.cs",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"RelativeDocumentMoniker": "Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"RelativeToolTip": "Ink Canvas\\MainWindow_cs\\MW_FloatingBarIcons.cs",
"ViewState": "AgIAAOgCAAAAAAAAAAAuwEoGAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-31T10:49:24.719Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "README.md",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\README.md",
"RelativeDocumentMoniker": "README.md",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\README.md",
"RelativeToolTip": "README.md",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
"WhenOpened": "2025-05-31T10:48:22.883Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "MainWindow.xaml",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow.xaml",
"RelativeDocumentMoniker": "Ink Canvas\\MainWindow.xaml",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow.xaml",
"RelativeToolTip": "Ink Canvas\\MainWindow.xaml",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|",
"WhenOpened": "2025-05-24T13:22:56.715Z"
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "Microsoft.Common.CurrentVersion.targets",
"DocumentMoniker": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"RelativeDocumentMoniker": "..\\..\\..\\..\\..\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"ToolTip": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"RelativeToolTip": "..\\..\\..\\..\\..\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\Microsoft.Common.CurrentVersion.targets",
"ViewState": "AgIAAGsJAAAAAAAAAAAQwIEJAAAEAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003801|",
"WhenOpened": "2025-05-24T13:06:01.053Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "MW_PPT.cs",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"RelativeDocumentMoniker": "Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"RelativeToolTip": "Ink Canvas\\MainWindow_cs\\MW_PPT.cs",
"ViewState": "AgIAAFgAAAAAAAAAAAAUwHQAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-24T13:04:47.205Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "README.md",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"RelativeDocumentMoniker": "..\\..\\..\\..\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"RelativeToolTip": "..\\..\\..\\..\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\README.md",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
"WhenOpened": "2025-05-24T13:04:01.407Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "privacy.txt",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\privacy.txt",
"RelativeDocumentMoniker": "privacy.txt",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\privacy.txt",
"RelativeToolTip": "privacy.txt",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
"WhenOpened": "2025-05-24T13:04:01.337Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "Manual.md",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Manual.md",
"RelativeDocumentMoniker": "Manual.md",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Manual.md",
"RelativeToolTip": "Manual.md",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
"WhenOpened": "2025-05-24T13:04:00.986Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "LICENSE",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\LICENSE",
"RelativeDocumentMoniker": "LICENSE",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\LICENSE",
"RelativeToolTip": "LICENSE",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
"WhenOpened": "2025-05-24T13:04:00.902Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Ink Canvas.sln.DotSettings.user",
"DocumentMoniker": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas.sln.DotSettings.user",
"RelativeDocumentMoniker": "Ink Canvas.sln.DotSettings.user",
"ToolTip": "C:\\Users\\dubi906w\\source\\repos\\icc-ce\\Ink Canvas.sln.DotSettings.user",
"RelativeToolTip": "Ink Canvas.sln.DotSettings.user",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003464|",
"WhenOpened": "2025-05-24T13:04:00.792Z"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{d84ee353-0bef-5a41-a649-8f89aca5d84d}"
}
]
},
{
"DockedWidth": 204,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:1:0:{3ae79031-e1bc-11d0-8f78-00a0c9110057}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{590a070c-4fcd-52d9-87da-dfaa11710261}"
}
]
},
{
"DockedWidth": 190,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{f4fc5ff1-28ef-4b04-ad02-6b298310ccc7}"
}
]
}
]
}
]
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
-7
View File
@@ -1,7 +0,0 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\Ink Canvas.sln",
"PreviewInSolutionExplorer": false
}
Binary file not shown.
@@ -1,290 +0,0 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\System.ValueTuple.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Settings.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\OSVersionExt.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Office.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.Wpf.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Newtonsoft.Json.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.Plugins.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\InkCanvasForClass.exe.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IAWinFX.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IALoader.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IACore.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"Children": [
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "System.ValueTuple.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\System.ValueTuple.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\System.ValueTuple.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\System.ValueTuple.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\System.ValueTuple.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:48.138Z"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "Settings.json",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Settings.json",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Settings.json",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Settings.json",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Settings.json",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
"WhenOpened": "2025-05-24T13:02:44.878Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "OSVersionExt.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\OSVersionExt.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\OSVersionExt.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\OSVersionExt.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\OSVersionExt.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.837Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "Office.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Office.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Office.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Office.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Office.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.774Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "NHotkey.Wpf.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.Wpf.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\NHotkey.Wpf.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.Wpf.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\NHotkey.Wpf.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.718Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "NHotkey.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\NHotkey.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\NHotkey.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.662Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "Newtonsoft.Json.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Newtonsoft.Json.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Newtonsoft.Json.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Newtonsoft.Json.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Newtonsoft.Json.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.589Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "Microsoft.Office.Interop.PowerPoint.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.932Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "MdXaml.Plugins.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.Plugins.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\MdXaml.Plugins.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.Plugins.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\MdXaml.Plugins.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.838Z"
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "MdXaml.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\MdXaml.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\MdXaml.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.776Z"
},
{
"$type": "Document",
"DocumentIndex": 10,
"Title": "iNKORE.UI.WPF.Modern.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.573Z"
},
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "iNKORE.UI.WPF.Modern.Controls.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.432Z"
},
{
"$type": "Document",
"DocumentIndex": 12,
"Title": "iNKORE.UI.WPF.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:42.807Z"
},
{
"$type": "Document",
"DocumentIndex": 13,
"Title": "InkCanvasForClass.exe.config",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000601|",
"WhenOpened": "2025-05-24T13:02:27.288Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 14,
"Title": "ICSharpCode.AvalonEdit.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.847Z"
},
{
"$type": "Document",
"DocumentIndex": 15,
"Title": "IAWinFX.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IAWinFX.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\IAWinFX.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IAWinFX.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\IAWinFX.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.816Z"
},
{
"$type": "Document",
"DocumentIndex": 16,
"Title": "IALoader.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IALoader.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\IALoader.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IALoader.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\IALoader.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.784Z"
},
{
"$type": "Document",
"DocumentIndex": 17,
"Title": "IACore.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IACore.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\IACore.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IACore.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\IACore.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.753Z"
},
{
"$type": "Document",
"DocumentIndex": 18,
"Title": "Hardcodet.NotifyIcon.Wpf.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.113Z"
}
]
}
]
}
]
}
-338
View File
@@ -1,338 +0,0 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\icc.png||{177559E0-D141-11D0-92DF-00A0C9138C45}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:icc.png||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\AutomaticUpdateVersionControl.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:AutomaticUpdateVersionControl.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\.gitignore||{3B902123-F8A7-4915-9F01-361F908088D0}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:.gitignore||{3B902123-F8A7-4915-9F01-361F908088D0}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\System.ValueTuple.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Settings.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\OSVersionExt.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Office.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.Wpf.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Newtonsoft.Json.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.Plugins.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\InkCanvasForClass.exe.config||{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IAWinFX.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IALoader.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IACore.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll||{177559E0-D141-11D0-92DF-00A0C9138C45}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"Children": [
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "icc.png - PNG [256x256, 32 \u4F4D, PNG]",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\icc.png",
"RelativeDocumentMoniker": "icc.png",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\icc.png - PNG [256x256, 32 \u4F4D, PNG]",
"RelativeToolTip": "icc.png - PNG [256x256, 32 \u4F4D, PNG]",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001533|",
"WhenOpened": "2025-05-24T13:03:45.63Z",
"EditorCaption": " - PNG [256x256, 32 \u4F4D, PNG]"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "AutomaticUpdateVersionControl.txt",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\AutomaticUpdateVersionControl.txt",
"RelativeDocumentMoniker": "AutomaticUpdateVersionControl.txt",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\AutomaticUpdateVersionControl.txt",
"RelativeToolTip": "AutomaticUpdateVersionControl.txt",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
"WhenOpened": "2025-05-24T13:03:45.517Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": ".gitignore",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\.gitignore",
"RelativeDocumentMoniker": ".gitignore",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.2\\.gitignore",
"RelativeToolTip": ".gitignore",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
"WhenOpened": "2025-05-24T13:03:43.13Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "System.ValueTuple.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\System.ValueTuple.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\System.ValueTuple.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\System.ValueTuple.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\System.ValueTuple.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:48.138Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "Settings.json",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Settings.json",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Settings.json",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Settings.json",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Settings.json",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
"WhenOpened": "2025-05-24T13:02:44.878Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "OSVersionExt.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\OSVersionExt.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\OSVersionExt.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\OSVersionExt.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\OSVersionExt.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.837Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "Office.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Office.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Office.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Office.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Office.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.774Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "NHotkey.Wpf.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.Wpf.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\NHotkey.Wpf.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.Wpf.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\NHotkey.Wpf.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.718Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "NHotkey.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\NHotkey.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\NHotkey.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\NHotkey.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.662Z"
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "Newtonsoft.Json.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Newtonsoft.Json.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Newtonsoft.Json.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Newtonsoft.Json.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Newtonsoft.Json.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:44.589Z"
},
{
"$type": "Document",
"DocumentIndex": 10,
"Title": "Microsoft.Office.Interop.PowerPoint.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Microsoft.Office.Interop.PowerPoint.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.932Z"
},
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "MdXaml.Plugins.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.Plugins.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\MdXaml.Plugins.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.Plugins.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\MdXaml.Plugins.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.838Z"
},
{
"$type": "Document",
"DocumentIndex": 12,
"Title": "MdXaml.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\MdXaml.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\MdXaml.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\MdXaml.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.776Z"
},
{
"$type": "Document",
"DocumentIndex": 13,
"Title": "iNKORE.UI.WPF.Modern.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.573Z"
},
{
"$type": "Document",
"DocumentIndex": 14,
"Title": "iNKORE.UI.WPF.Modern.Controls.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.Modern.Controls.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:43.432Z"
},
{
"$type": "Document",
"DocumentIndex": 15,
"Title": "iNKORE.UI.WPF.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\iNKORE.UI.WPF.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:42.807Z"
},
{
"$type": "Document",
"DocumentIndex": 16,
"Title": "InkCanvasForClass.exe.config",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\InkCanvasForClass.exe.config",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000601|",
"WhenOpened": "2025-05-24T13:02:27.288Z"
},
{
"$type": "Document",
"DocumentIndex": 17,
"Title": "ICSharpCode.AvalonEdit.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\ICSharpCode.AvalonEdit.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.847Z"
},
{
"$type": "Document",
"DocumentIndex": 18,
"Title": "IAWinFX.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IAWinFX.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\IAWinFX.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IAWinFX.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\IAWinFX.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.816Z"
},
{
"$type": "Document",
"DocumentIndex": 19,
"Title": "IALoader.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IALoader.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\IALoader.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IALoader.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\IALoader.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.784Z"
},
{
"$type": "Document",
"DocumentIndex": 20,
"Title": "IACore.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IACore.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\IACore.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\IACore.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\IACore.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.753Z"
},
{
"$type": "Document",
"DocumentIndex": 21,
"Title": "Hardcodet.NotifyIcon.Wpf.dll",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"RelativeDocumentMoniker": "..\\..\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"RelativeToolTip": "..\\..\\InkCanvasForClass\\Hardcodet.NotifyIcon.Wpf.dll",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001697|",
"WhenOpened": "2025-05-24T13:02:22.113Z"
}
]
}
]
}
]
}
Binary file not shown.
Binary file not shown.
@@ -1,67 +0,0 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\icc.png||{177559E0-D141-11D0-92DF-00A0C9138C45}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:icc.png||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\AutomaticUpdateVersionControl.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:AutomaticUpdateVersionControl.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\.gitignore||{3B902123-F8A7-4915-9F01-361F908088D0}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:.gitignore||{3B902123-F8A7-4915-9F01-361F908088D0}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"Children": [
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "icc.png",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\icc.png",
"RelativeDocumentMoniker": "icc.png",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\icc.png",
"RelativeToolTip": "icc.png",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001533|",
"WhenOpened": "2025-05-24T13:12:49.619Z"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "AutomaticUpdateVersionControl.txt",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\AutomaticUpdateVersionControl.txt",
"RelativeDocumentMoniker": "AutomaticUpdateVersionControl.txt",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\AutomaticUpdateVersionControl.txt",
"RelativeToolTip": "AutomaticUpdateVersionControl.txt",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
"WhenOpened": "2025-05-24T13:12:49.575Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": ".gitignore",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\.gitignore",
"RelativeDocumentMoniker": ".gitignore",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\.gitignore",
"RelativeToolTip": ".gitignore",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
"WhenOpened": "2025-05-24T13:12:49.025Z"
}
]
}
]
}
]
}
-72
View File
@@ -1,72 +0,0 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\icc.png||{177559E0-D141-11D0-92DF-00A0C9138C45}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:icc.png||{177559E0-D141-11D0-92DF-00A0C9138C45}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\AutomaticUpdateVersionControl.txt||{8B382828-6202-11D1-8870-0000F87579D2}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:AutomaticUpdateVersionControl.txt||{8B382828-6202-11D1-8870-0000F87579D2}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\.gitignore||{3B902123-F8A7-4915-9F01-361F908088D0}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:.gitignore||{3B902123-F8A7-4915-9F01-361F908088D0}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "icc.png - PNG [1328x1328, 32 \u4F4D, PNG]",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\icc.png",
"RelativeDocumentMoniker": "icc.png",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\icc.png - PNG [1328x1328, 32 \u4F4D, PNG]",
"RelativeToolTip": "icc.png - PNG [1328x1328, 32 \u4F4D, PNG]",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001533|",
"WhenOpened": "2025-05-24T13:12:49.619Z",
"EditorCaption": " - PNG [1328x1328, 32 \u4F4D, PNG]"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "AutomaticUpdateVersionControl.txt",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\AutomaticUpdateVersionControl.txt",
"RelativeDocumentMoniker": "AutomaticUpdateVersionControl.txt",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\AutomaticUpdateVersionControl.txt",
"RelativeToolTip": "AutomaticUpdateVersionControl.txt",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|",
"WhenOpened": "2025-05-24T13:12:49.575Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": ".gitignore",
"DocumentMoniker": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\.gitignore",
"RelativeDocumentMoniker": ".gitignore",
"ToolTip": "C:\\Users\\Administrator\\Desktop\\ICC CE\\icc-0610.2.3\\.gitignore",
"RelativeToolTip": ".gitignore",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
"WhenOpened": "2025-05-24T13:12:49.025Z"
}
]
}
]
}
]
}
Binary file not shown.
BIN
View File
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
1.7.0.0
+36
View File
@@ -0,0 +1,36 @@
rev-1.0.0.0:
1. 重写大部分代码中...
5.0.5.0:
1. 支持自动收纳希沃轻白板5C,希沃白板3,鸿合轻量白板。
2. 支持自动查杀鸿合屏幕书写。
3. 带来FitToCurve,给平滑墨迹加上了开关。
4. 修复了FitToCurve导致的部分形状绘制出错的问题也保留了其他墨迹的FitToCurve。
5. 白板,浮动工具栏,子面板,设置UI几乎全部优化。
6. 添加修改橡皮大小,橡皮形状的菜单。
7. PPT现在会自动提示是否关闭自动播放和排练计时。
8. 条件性的墨迹识别,可以关闭部分不需要的形状识别。可以修改是否为墨迹识别的三角形或矩形应用模拟压感值。
9. 带来了荧光笔功能并为荧光笔适配了形状识别。
10. 允许清空墨迹时可删除历史记录。
11. 带来了Quick Panel。
12. 浮动工具栏缩放调节,取消收纳按钮图标修改。
13. 修复了多指书写StylusDown事件可能触发在工具栏而不是inkCanvas上导致的Bug。
14. 修复了鼠标和触摸屏(无RealTimeStylus和非多指书写模式)的绘制时Pointer捕获Bug。
15. Merge了Ink Canvas的新撤回行为
16. 修复了白板模式下直接新增页面导致的TimeMachine不记录历史记录的Bug
17. 添加了一个简陋的白板页面列表。
18. 优化了墨迹重播,支持暂停,重新开始和倍速,拥有更人性化的UI。
19. 优化自动收纳行为和FoldFloatingBar函数的相关Bug修复。
20. 添加了EdgeGestureUtil实验性选项。
21. 添加了ForceFullScreen实验性选项
22. 添加了FullScreenHelper实验性选项。
23. 添加了ResolutionChangeDetection和DPIChangeDetection实验性选项。
24. 修复了同时打开ICC和ICA的冲突。
25. 修复浮动工具栏手势按钮开启多指书写时InkCanvas的InkCanvasEditingMode被修改为None的Bug。
26. 修复Merge ICA仓库代码后导致浮动工具栏批注按钮UI MouseLeave反馈的问题。
27. 为大部分UI的按钮添加了lastBorderMouseDown的检测代码和MouseDown的视觉反馈。
28. 支持自动收纳安道系列,艺云系列和 MAXHUB 白板书写。
4.5.8.0:
1. 将ICA的代码换了个名字变成了InkCanvasForClass,万物起源。
2. 优化了ICA的部分UI界面设计。
-128
View File
@@ -1,128 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
QQ:2564608840.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 568 KiB

+228 -21
View File
@@ -3,7 +3,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33530.505
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InkCanvasForClass", "Ink Canvas\InkCanvasForClass.csproj", "{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InkCanvasForClassX", "InkCanvasForClassX\InkCanvasForClassX.csproj", "{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InkCanvasForClass", "InkCanvasForClass\InkCanvasForClass.csproj", "{2474F5B0-6FA7-4D70-8A00-167BBB03264D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InkCanvasForClass.IACoreHelper", "InkCanvasForClass.IACoreHelper\InkCanvasForClass.IACoreHelper.csproj", "{693973B6-69C1-4A37-B329-F366A07BF60A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InkCanvasForClass.PowerPoint.InteropHelper", "InkCanvasForClass.PowerPoint.InteropHelper\InkCanvasForClass.PowerPoint.InteropHelper.csproj", "{2D8A9217-465A-4F57-BD58-CE02450390C4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InkCanvasForClass.PowerPoint.VstoPlugin", "InkCanvasForClass.PowerPoint.VstoPlugin\InkCanvasForClass.PowerPoint.VstoPlugin.csproj", "{8C593467-E54D-4FA7-881C-78F3CC48A867}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InkCanvasForClass.IccInkCanvas", "InkCanvasForClass.IccInkCanvas\InkCanvasForClass.IccInkCanvas.csproj", "{43929D8F-5630-4786-B75D-E203EA3E992F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InkCanvasForClass.IccInkCanvas.Demo", "InkCanvasForClass.IccInkCanvas.Demo\InkCanvasForClass.IccInkCanvas.Demo.csproj", "{94E97F70-CACD-453B-8114-08DFFDDA5A46}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -17,28 +29,223 @@ Global
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
x86 Debug|Any CPU = x86 Debug|Any CPU
x86 Debug|ARM = x86 Debug|ARM
x86 Debug|ARM64 = x86 Debug|ARM64
x86 Debug|x64 = x86 Debug|x64
x86 Debug|x86 = x86 Debug|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|ARM.Build.0 = Debug|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|ARM64.ActiveCfg = Debug|ARM64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|ARM64.Build.0 = Debug|ARM64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|x64.ActiveCfg = Debug|x64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|x64.Build.0 = Debug|x64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|x86.ActiveCfg = Debug|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Debug|x86.Build.0 = Debug|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|Any CPU.Build.0 = Release|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|ARM.ActiveCfg = Release|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|ARM.Build.0 = Release|Any CPU
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|ARM64.ActiveCfg = Release|ARM64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|ARM64.Build.0 = Release|ARM64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|x64.ActiveCfg = Release|x64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|x64.Build.0 = Release|x64
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|x86.ActiveCfg = Release|x86
{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|x86.Build.0 = Release|x86
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|ARM.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|ARM.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|ARM64.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|x64.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|x64.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|x86.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Debug|x86.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|Any CPU.Build.0 = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|ARM.ActiveCfg = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|ARM.Build.0 = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|ARM64.ActiveCfg = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|ARM64.Build.0 = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|x64.ActiveCfg = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|x64.Build.0 = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|x86.ActiveCfg = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.Release|x86.Build.0 = Release|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|Any CPU.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|ARM.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|ARM.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|ARM64.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|ARM64.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|x64.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|x64.Build.0 = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|x86.ActiveCfg = Debug|Any CPU
{98DF6AA1-DD4D-4C70-A0A2-4B2974D97D51}.x86 Debug|x86.Build.0 = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|ARM.Build.0 = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|ARM64.Build.0 = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|x64.ActiveCfg = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|x64.Build.0 = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|x86.ActiveCfg = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Debug|x86.Build.0 = Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|Any CPU.Build.0 = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|ARM.ActiveCfg = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|ARM.Build.0 = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|ARM64.ActiveCfg = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|ARM64.Build.0 = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|x64.ActiveCfg = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|x64.Build.0 = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|x86.ActiveCfg = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.Release|x86.Build.0 = Release|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|Any CPU.ActiveCfg = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|Any CPU.Build.0 = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|ARM.ActiveCfg = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|ARM.Build.0 = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|ARM64.ActiveCfg = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|ARM64.Build.0 = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|x64.ActiveCfg = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|x64.Build.0 = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|x86.ActiveCfg = x86 Debug|Any CPU
{2474F5B0-6FA7-4D70-8A00-167BBB03264D}.x86 Debug|x86.Build.0 = x86 Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|ARM.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|ARM64.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|x64.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|x64.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|x86.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Debug|x86.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|Any CPU.Build.0 = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|ARM.ActiveCfg = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|ARM.Build.0 = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|ARM64.ActiveCfg = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|ARM64.Build.0 = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|x64.ActiveCfg = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|x64.Build.0 = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|x86.ActiveCfg = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.Release|x86.Build.0 = Release|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|Any CPU.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|Any CPU.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|ARM.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|ARM.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|ARM64.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|ARM64.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|x64.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|x64.Build.0 = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|x86.ActiveCfg = Debug|Any CPU
{693973B6-69C1-4A37-B329-F366A07BF60A}.x86 Debug|x86.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|ARM.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|ARM64.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|x64.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|x64.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|x86.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Debug|x86.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|Any CPU.Build.0 = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|ARM.ActiveCfg = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|ARM.Build.0 = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|ARM64.ActiveCfg = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|ARM64.Build.0 = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|x64.ActiveCfg = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|x64.Build.0 = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|x86.ActiveCfg = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.Release|x86.Build.0 = Release|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|Any CPU.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|ARM.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|ARM.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|ARM64.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|ARM64.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|x64.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|x64.Build.0 = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|x86.ActiveCfg = Debug|Any CPU
{2D8A9217-465A-4F57-BD58-CE02450390C4}.x86 Debug|x86.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|ARM.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|ARM64.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|x64.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|x64.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|x86.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Debug|x86.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|Any CPU.Build.0 = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|ARM.ActiveCfg = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|ARM.Build.0 = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|ARM64.ActiveCfg = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|ARM64.Build.0 = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|x64.ActiveCfg = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|x64.Build.0 = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|x86.ActiveCfg = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.Release|x86.Build.0 = Release|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|Any CPU.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|ARM.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|ARM.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|ARM64.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|ARM64.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|x64.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|x64.Build.0 = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|x86.ActiveCfg = Debug|Any CPU
{8C593467-E54D-4FA7-881C-78F3CC48A867}.x86 Debug|x86.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|ARM.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|ARM64.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|x64.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|x64.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|x86.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Debug|x86.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|Any CPU.Build.0 = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|ARM.ActiveCfg = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|ARM.Build.0 = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|ARM64.ActiveCfg = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|ARM64.Build.0 = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|x64.ActiveCfg = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|x64.Build.0 = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|x86.ActiveCfg = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.Release|x86.Build.0 = Release|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|Any CPU.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|ARM.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|ARM.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|ARM64.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|ARM64.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|x64.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|x64.Build.0 = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|x86.ActiveCfg = Debug|Any CPU
{43929D8F-5630-4786-B75D-E203EA3E992F}.x86 Debug|x86.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|ARM.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|ARM.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|ARM64.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|x64.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|x64.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|x86.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Debug|x86.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|Any CPU.Build.0 = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|ARM.ActiveCfg = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|ARM.Build.0 = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|ARM64.ActiveCfg = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|ARM64.Build.0 = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|x64.ActiveCfg = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|x64.Build.0 = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|x86.ActiveCfg = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.Release|x86.Build.0 = Release|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|Any CPU.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|ARM.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|ARM.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|ARM64.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|ARM64.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|x64.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|x64.Build.0 = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|x86.ActiveCfg = Debug|Any CPU
{94E97F70-CACD-453B-8114-08DFFDDA5A46}.x86 Debug|x86.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+4 -1
View File
@@ -1,2 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">WARNING</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">WARNING</s:String>
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;&#xD;
&lt;Assembly Path="D:\vs\ica\InkCanvasForClass\IAWinFX.dll" /&gt;&#xD;
&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>
-803
View File
@@ -1,803 +0,0 @@
using Hardcodet.Wpf.TaskbarNotification;
using Ink_Canvas.Helpers;
using iNKORE.UI.WPF.Modern.Controls;
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Win32;
using System.Security; // 添加SecurityException所需命名空间
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Threading;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using MessageBox = System.Windows.MessageBox;
using Window = System.Windows.Window;
using System.Collections.Generic;
namespace Ink_Canvas
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
System.Threading.Mutex mutex;
public static string[] StartArgs = null;
public static string RootPath = Environment.GetEnvironmentVariable("APPDATA") + "\\Ink Canvas\\";
// 新增:保存看门狗进程对象
private static Process watchdogProcess = null;
// 新增:标记是否为软件内主动退出
public static bool IsAppExitByUser = false;
// 新增:退出信号文件路径
private static string watchdogExitSignalFile = Path.Combine(Path.GetTempPath(), "icc_watchdog_exit_" + System.Diagnostics.Process.GetCurrentProcess().Id + ".flag");
public App()
{
this.Startup += new StartupEventHandler(App_Startup);
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
StartHeartbeatMonitor();
StartWatchdogIfNeeded();
this.Exit += App_Exit; // 注册退出事件
}
// 增加字段保存崩溃后操作设置
public static CrashActionType CrashAction = CrashActionType.SilentRestart;
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
Ink_Canvas.MainWindow.ShowNewMessage("抱歉,出现未预期的异常,可能导致 InkCanvasForClass 运行不稳定。\n建议保存墨迹后重启应用。", true);
LogHelper.NewLog(e.Exception.ToString());
e.Handled = true;
// 修改:仅当非用户主动退出时才触发自动重启
if (CrashAction == CrashActionType.SilentRestart && !IsAppExitByUser)
{
StartupCount.Increment();
if (StartupCount.GetCount() >= 5)
{
MessageBox.Show("检测到程序已连续重启5次,已停止自动重启。请联系开发者或检查系统环境。", "重启次数过多", MessageBoxButton.OK, MessageBoxImage.Error);
StartupCount.Reset();
Environment.Exit(1);
}
try
{
string exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
System.Diagnostics.Process.Start(exePath);
}
catch { }
Environment.Exit(1);
}
// CrashActionType.NoAction 时不做处理
}
private TaskbarIcon _taskbar;
void App_Startup(object sender, StartupEventArgs e)
{
RunWatchdogIfNeeded();
/*if (!StoreHelper.IsStoreApp) */RootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
LogHelper.NewLog(string.Format("Ink Canvas Starting (Version: {0})", Assembly.GetExecutingAssembly().GetName().Version.ToString()));
bool ret;
mutex = new System.Threading.Mutex(true, "InkCanvasForClass", out ret);
if (!ret && !e.Args.Contains("-m")) //-m multiple
{
LogHelper.NewLog("Detected existing instance");
MessageBox.Show("已有一个程序实例正在运行");
LogHelper.NewLog("Ink Canvas automatically closed");
Environment.Exit(0);
}
_taskbar = (TaskbarIcon)FindResource("TaskbarTrayIcon");
StartArgs = e.Args;
// 新增:Office注册表检测
try
{
LogHelper.WriteLogToFile("开始Office注册表检测");
// 检查Office安装
if (!IsOfficeInstalled())
{
LogHelper.WriteLogToFile("未检测到Office安装", LogHelper.LogType.Warning);
return;
}
// 尝试获取所有可能的Office版本路径
var officeVersions = GetOfficeVersions();
if (officeVersions.Count == 0)
{
LogHelper.WriteLogToFile("未找到任何Office版本", LogHelper.LogType.Warning);
return;
}
foreach (var version in officeVersions)
{
string regPath = $"Software\\Microsoft\\Office\\{version}\\Common\\Security";
LogHelper.WriteLogToFile($"正在处理Office版本 {version}, 注册表路径: {regPath}");
try
{
using (Microsoft.Win32.RegistryKey baseKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath))
{
if (baseKey == null)
{
LogHelper.WriteLogToFile($"注册表路径不存在: {regPath}", LogHelper.LogType.Warning);
// 尝试创建路径
try
{
using (Microsoft.Win32.RegistryKey createKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regPath, true))
{
if (createKey != null)
{
createKey.SetValue("DisableProtectedView", 1, Microsoft.Win32.RegistryValueKind.DWord);
LogHelper.WriteLogToFile($"创建并设置注册表路径: {regPath}", LogHelper.LogType.Info);
}
}
}
catch (Exception createEx)
{
LogHelper.WriteLogToFile($"创建注册表路径失败: {createEx.Message}", LogHelper.LogType.Error);
}
continue;
}
// 备份路径更改为软件根目录下的saves/RegistryBackups文件夹
string backupPath = Path.Combine(RootPath, "saves", "RegistryBackups");
LogHelper.WriteLogToFile($"备份路径: {backupPath}");
if (!Directory.Exists(backupPath))
{
Directory.CreateDirectory(backupPath);
LogHelper.WriteLogToFile($"创建备份目录: {backupPath}");
}
string backupFile = Path.Combine(backupPath, $"SecurityBackup_{version}_{DateTime.Now:yyyyMMddHHmmss}.reg");
LogHelper.WriteLogToFile($"创建备份文件: {backupFile}");
// 使用UTF8编码写入注册表文件
using (StreamWriter sw = new StreamWriter(backupFile, false, System.Text.Encoding.UTF8))
{
sw.WriteLine("Windows Registry Editor Version 5.00\n");
sw.WriteLine();
sw.WriteLine($"[{Microsoft.Win32.Registry.CurrentUser.Name}\\{regPath}]");
foreach (string valueName in baseKey.GetValueNames())
{
object value = baseKey.GetValue(valueName);
sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}");
LogHelper.WriteLogToFile($"备份注册表值: {valueName} = {value}");
}
}
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regPath, true))
{
// 仅在值不存在或不等于1时更新
object currentValue = key.GetValue("DisableProtectedView");
if (currentValue == null || (int)currentValue != 1)
{
key.SetValue("DisableProtectedView", 1, Microsoft.Win32.RegistryValueKind.DWord);
LogHelper.WriteLogToFile($"Office {version} 注册表值已设置: DisableProtectedView = 1");
}
else
{
LogHelper.WriteLogToFile($"Office {version} 注册表值已存在且无需更改: DisableProtectedView = 1");
}
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理Office版本 {version} 时出错: {ex.Message}", LogHelper.LogType.Error);
continue;
}
}
// 处理Office 365的特殊路径
TryModifyOffice365Registry();
}
catch (SecurityException secEx)
{
LogHelper.WriteLogToFile($"安全异常: {secEx.Message}", LogHelper.LogType.Error);
ShowPermissionError();
}
catch (UnauthorizedAccessException authEx)
{
LogHelper.WriteLogToFile($"访问被拒绝: {authEx.Message}", LogHelper.LogType.Error);
ShowPermissionError();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"未知错误: {ex.GetType().FullName} - {ex.Message}", LogHelper.LogType.Error);
LogHelper.WriteLogToFile(ex.StackTrace, LogHelper.LogType.Info);
}
}
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
try
{
if (System.Windows.Forms.SystemInformation.MouseWheelScrollLines == -1)
e.Handled = false;
else
try
{
ScrollViewerEx SenderScrollViewer = (ScrollViewerEx)sender;
SenderScrollViewer.ScrollToVerticalOffset(SenderScrollViewer.VerticalOffset - e.Delta * 10 * System.Windows.Forms.SystemInformation.MouseWheelScrollLines / (double)120);
e.Handled = true;
}
catch { }
}
catch { }
}
// 新增:用于设置崩溃后操作类型
public enum CrashActionType
{
SilentRestart,
NoAction
}
// 心跳相关
private static Timer heartbeatTimer;
private static DateTime lastHeartbeat = DateTime.Now;
private static Timer watchdogTimer;
private void StartHeartbeatMonitor()
{
// 主线程定时更新心跳
heartbeatTimer = new Timer(_ => lastHeartbeat = DateTime.Now, null, 0, 1000);
// 辅助线程检测心跳超时
watchdogTimer = new Timer(_ =>
{
if ((DateTime.Now - lastHeartbeat).TotalSeconds > 10)
{
LogHelper.NewLog("检测到主线程无响应,自动重启。");
if (CrashAction == CrashActionType.SilentRestart)
{
StartupCount.Increment();
if (StartupCount.GetCount() >= 5)
{
MessageBox.Show("检测到程序已连续重启5次,已停止自动重启。请联系开发者或检查系统环境。", "重启次数过多", MessageBoxButton.OK, MessageBoxImage.Error);
StartupCount.Reset();
Environment.Exit(1);
}
try
{
string exePath = Process.GetCurrentProcess().MainModule.FileName;
Process.Start(exePath);
}
catch { }
Environment.Exit(1);
}
}
}, null, 0, 3000);
}
// 看门狗进程
private void StartWatchdogIfNeeded()
{
// 避免递归启动
if (Environment.GetCommandLineArgs().Contains("--watchdog")) return;
// 启动看门狗进程
string exePath = Process.GetCurrentProcess().MainModule.FileName;
var psi = new ProcessStartInfo
{
FileName = exePath,
Arguments = "--watchdog " + Process.GetCurrentProcess().Id + " \"" + watchdogExitSignalFile + "\"",
CreateNoWindow = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
watchdogProcess = Process.Start(psi);
}
// 看门狗主逻辑(在 Main 函数或 App_Startup 入口前加判断)
public static void RunWatchdogIfNeeded()
{
var args = Environment.GetCommandLineArgs();
if (args.Length >= 4 && args[1] == "--watchdog")
{
int pid = int.Parse(args[2]);
string exitSignalFile = args[3];
try
{
var proc = Process.GetProcessById(pid);
while (!proc.HasExited)
{
// 检查退出信号文件
if (File.Exists(exitSignalFile))
{
try { File.Delete(exitSignalFile); } catch { }
Environment.Exit(0);
}
Thread.Sleep(2000);
}
// 主进程异常退出,自动重启
StartupCount.Increment();
if (StartupCount.GetCount() >= 5)
{
MessageBox.Show("检测到程序已连续重启5次,已停止自动重启。请联系开发者或检查系统环境。", "重启次数过多", MessageBoxButton.OK, MessageBoxImage.Error);
StartupCount.Reset();
Environment.Exit(1);
}
string exePath = Process.GetCurrentProcess().MainModule.FileName;
Process.Start(exePath);
}
catch { }
Environment.Exit(0);
}
}
private void App_Exit(object sender, ExitEventArgs e)
{
// 仅在软件内主动退出时关闭看门狗,并写入退出信号
try
{
if (IsAppExitByUser)
{
// 写入退出信号文件,通知看门狗正常退出
StartupCount.Reset();
File.WriteAllText(watchdogExitSignalFile, "exit");
if (watchdogProcess != null && !watchdogProcess.HasExited)
{
watchdogProcess.Kill();
}
}
}
catch { }
}
/// <summary>
/// 检查Office是否安装
/// </summary>
private bool IsOfficeInstalled()
{
try
{
// 检查多个可能的注册表路径
// 1. 检查传统的Office版本
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office"))
{
if (key != null && key.GetSubKeyNames().Any(name => name.Contains(".0")))
{
LogHelper.WriteLogToFile("检测到传统Office安装", LogHelper.LogType.Info);
return true;
}
}
// 2. 检查64位注册表中的Office
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Microsoft\\Office"))
{
if (key != null && key.GetSubKeyNames().Any(name => name.Contains(".0")))
{
LogHelper.WriteLogToFile("检测到64位注册表中的Office安装", LogHelper.LogType.Info);
return true;
}
}
// 3. 检查Office 365/Click-to-Run安装
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun"))
{
if (key != null)
{
LogHelper.WriteLogToFile("检测到Office 365 Click-to-Run", LogHelper.LogType.Info);
return true;
}
}
// 4. 检查Office 365部署配置
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\15.0\\ClickToRun"))
{
if (key != null)
{
LogHelper.WriteLogToFile("检测到Office 365 (15.0)", LogHelper.LogType.Info);
return true;
}
}
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\16.0\\ClickToRun"))
{
if (key != null)
{
LogHelper.WriteLogToFile("检测到Office 365 (16.0)", LogHelper.LogType.Info);
return true;
}
}
// 5. 检查Office 365零售订阅信息
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun\\Configuration"))
{
if (key != null)
{
LogHelper.WriteLogToFile("检测到Office 365配置", LogHelper.LogType.Info);
return true;
}
}
LogHelper.WriteLogToFile("未检测到任何Office安装", LogHelper.LogType.Warning);
return false;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"检查Office安装时出错: {ex.Message}", LogHelper.LogType.Error);
return false;
}
}
/// <summary>
/// 显示权限不足的错误提示
/// </summary>
private void ShowPermissionError()
{
const string message = "需要管理员权限才能完成此操作\n请以管理员身份重新启动应用程序";
LogHelper.WriteLogToFile(message, LogHelper.LogType.Error);
System.Windows.MessageBox.Show(message, "权限错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
/// <summary>
/// 获取所有已安装的Office版本
/// </summary>
private List<string> GetOfficeVersions()
{
var versions = new List<string>();
try
{
// 检查HKLM
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office"))
{
if (key != null)
{
foreach (var subKeyName in key.GetSubKeyNames())
{
if (subKeyName.Contains(".0"))
{
versions.Add(subKeyName);
LogHelper.WriteLogToFile($"在HKLM中找到Office版本: {subKeyName}");
}
}
}
}
// 检查HKCU
using (var key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Office"))
{
if (key != null)
{
foreach (var subKeyName in key.GetSubKeyNames())
{
if (subKeyName.Contains(".0") && !versions.Contains(subKeyName))
{
versions.Add(subKeyName);
LogHelper.WriteLogToFile($"在HKCU中找到Office版本: {subKeyName}");
}
}
}
}
// 检查64位注册表
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Microsoft\\Office"))
{
if (key != null)
{
foreach (var subKeyName in key.GetSubKeyNames())
{
if (subKeyName.Contains(".0") && !versions.Contains(subKeyName))
{
versions.Add(subKeyName);
LogHelper.WriteLogToFile($"在64位注册表中找到Office版本: {subKeyName}");
}
}
}
}
// 检查Office 365的特殊路径
CheckOffice365Versions(versions);
// 如果没有找到任何版本,添加默认的Office 365版本号
if (versions.Count == 0 && IsOffice365Installed())
{
versions.Add("16.0");
LogHelper.WriteLogToFile("未找到具体版本,添加默认Office 365版本: 16.0");
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"获取Office版本时出错: {ex.Message}", LogHelper.LogType.Error);
}
// 按版本号排序
versions.Sort((a, b) =>
{
try
{
double va = double.Parse(a.Replace(".0", ""));
double vb = double.Parse(b.Replace(".0", ""));
return vb.CompareTo(va); // 降序排列,最新版本在前
}
catch
{
return 0;
}
});
return versions;
}
/// <summary>
/// 检测Office 365是否已安装
/// </summary>
private bool IsOffice365Installed()
{
try
{
// 检查多个Office 365特定路径
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun"))
{
if (key != null)
return true;
}
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\15.0\\ClickToRun"))
{
if (key != null)
return true;
}
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\16.0\\ClickToRun"))
{
if (key != null)
return true;
}
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun\\Configuration"))
{
if (key != null)
return true;
}
return false;
}
catch
{
return false;
}
}
/// <summary>
/// 检查Office 365特有的版本信息
/// </summary>
private void CheckOffice365Versions(List<string> versions)
{
try
{
// 检查Click-to-Run版本路径
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun\\Configuration"))
{
if (key != null)
{
var platformVersion = key.GetValue("Platform") as string;
var clickToRunVersion = key.GetValue("VersionToReport") as string;
if (!string.IsNullOrEmpty(platformVersion))
{
var majorVersion = platformVersion.Split('.').FirstOrDefault();
if (!string.IsNullOrEmpty(majorVersion) && !versions.Contains($"{majorVersion}.0"))
{
versions.Add($"{majorVersion}.0");
LogHelper.WriteLogToFile($"在Office 365配置中找到平台版本: {majorVersion}.0");
}
}
if (!string.IsNullOrEmpty(clickToRunVersion))
{
var majorVersion = clickToRunVersion.Split('.').FirstOrDefault();
if (!string.IsNullOrEmpty(majorVersion) && !versions.Contains($"{majorVersion}.0"))
{
versions.Add($"{majorVersion}.0");
LogHelper.WriteLogToFile($"在Office 365配置中找到报告版本: {majorVersion}.0");
}
}
}
}
// 检查安装路径来确认版本
var possibleVersions = new[] { "15.0", "16.0" }; // Office 2013 (15.0) 和 Office 2016/2019/365 (16.0)
foreach (var version in possibleVersions)
{
using (var key = Registry.LocalMachine.OpenSubKey($"Software\\Microsoft\\Office\\{version}\\Common\\InstallRoot"))
{
if (key != null && key.GetValue("Path") != null && !versions.Contains(version))
{
versions.Add(version);
LogHelper.WriteLogToFile($"在InstallRoot中找到Office版本: {version}");
}
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"检查Office 365版本时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 尝试修改Office 365的特殊注册表路径
/// </summary>
private void TryModifyOffice365Registry()
{
try
{
// 准备备份目录
string backupPath = Path.Combine(RootPath, "saves", "RegistryBackups");
if (!Directory.Exists(backupPath))
{
Directory.CreateDirectory(backupPath);
LogHelper.WriteLogToFile($"创建Office 365备份目录: {backupPath}");
}
// 检查Office 365 Outlook和PowerPoint的特定路径
string[] apps = { "outlook", "powerpoint" };
foreach (var app in apps)
{
// 检查用户级别的注册表
string regPath = $"Software\\Microsoft\\Office\\16.0\\{app}\\Security";
LogHelper.WriteLogToFile($"检查Office 365特定应用注册表: {regPath}");
try
{
// 先检查是否存在该路径
using (var baseKey = Registry.CurrentUser.OpenSubKey(regPath))
{
// 如果路径存在,先备份
if (baseKey != null)
{
string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_{app}_{DateTime.Now:yyyyMMddHHmmss}.reg");
LogHelper.WriteLogToFile($"创建Office 365 {app}备份文件: {backupFile}");
// 使用UTF8编码写入注册表文件
using (StreamWriter sw = new StreamWriter(backupFile, false, System.Text.Encoding.UTF8))
{
sw.WriteLine("Windows Registry Editor Version 5.00\n");
sw.WriteLine();
sw.WriteLine($"[{Microsoft.Win32.Registry.CurrentUser.Name}\\{regPath}]");
foreach (string valueName in baseKey.GetValueNames())
{
object value = baseKey.GetValue(valueName);
sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}");
LogHelper.WriteLogToFile($"备份Office 365 {app}注册表值: {valueName} = {value}");
}
}
}
}
// 修改或创建注册表项
using (var key = Registry.CurrentUser.CreateSubKey(regPath, true))
{
if (key != null)
{
object currentValue = key.GetValue("DisableProtectedView");
if (currentValue == null || (int)currentValue != 1)
{
key.SetValue("DisableProtectedView", 1, RegistryValueKind.DWord);
LogHelper.WriteLogToFile($"Office 365 {app} 注册表值已设置: DisableProtectedView = 1");
}
else
{
LogHelper.WriteLogToFile($"Office 365 {app} 注册表值已存在且无需更改");
}
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"修改 {app} 注册表时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
// 尝试通过Office信任中心路径修改
string trustCenterPath = "Software\\Microsoft\\Office\\16.0\\Common\\Security\\FileValidation";
LogHelper.WriteLogToFile($"检查信任中心路径: {trustCenterPath}");
try
{
// 先检查是否存在该路径
using (var baseKey = Registry.CurrentUser.OpenSubKey(trustCenterPath))
{
// 如果路径存在,先备份
if (baseKey != null)
{
string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_TrustCenter_{DateTime.Now:yyyyMMddHHmmss}.reg");
LogHelper.WriteLogToFile($"创建信任中心备份文件: {backupFile}");
// 使用UTF8编码写入注册表文件
using (StreamWriter sw = new StreamWriter(backupFile, false, System.Text.Encoding.UTF8))
{
sw.WriteLine("Windows Registry Editor Version 5.00\n");
sw.WriteLine();
sw.WriteLine($"[{Microsoft.Win32.Registry.CurrentUser.Name}\\{trustCenterPath}]");
foreach (string valueName in baseKey.GetValueNames())
{
object value = baseKey.GetValue(valueName);
sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}");
LogHelper.WriteLogToFile($"备份信任中心注册表值: {valueName} = {value}");
}
}
}
}
using (var key = Registry.CurrentUser.CreateSubKey(trustCenterPath, true))
{
if (key != null)
{
key.SetValue("DisableEditFromPV", 1, RegistryValueKind.DWord);
LogHelper.WriteLogToFile("已禁用受保护视图中的编辑");
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"修改信任中心路径时出错: {ex.Message}", LogHelper.LogType.Error);
}
// 尝试修改EnableEditWhileViewingPolicy
string policyPath = "Software\\Policies\\Microsoft\\Office\\16.0\\Common\\Security";
try
{
// 先检查是否存在该路径
using (var baseKey = Registry.CurrentUser.OpenSubKey(policyPath))
{
// 如果路径存在,先备份
if (baseKey != null)
{
string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_Policy_{DateTime.Now:yyyyMMddHHmmss}.reg");
LogHelper.WriteLogToFile($"创建策略备份文件: {backupFile}");
// 使用UTF8编码写入注册表文件
using (StreamWriter sw = new StreamWriter(backupFile, false, System.Text.Encoding.UTF8))
{
sw.WriteLine("Windows Registry Editor Version 5.00\n");
sw.WriteLine();
sw.WriteLine($"[{Microsoft.Win32.Registry.CurrentUser.Name}\\{policyPath}]");
foreach (string valueName in baseKey.GetValueNames())
{
object value = baseKey.GetValue(valueName);
sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}");
LogHelper.WriteLogToFile($"备份策略注册表值: {valueName} = {value}");
}
}
}
}
using (var key = Registry.CurrentUser.CreateSubKey(policyPath, true))
{
if (key != null)
{
key.SetValue("EnableEditWhileViewingPolicy", 1, RegistryValueKind.DWord);
LogHelper.WriteLogToFile("已启用查看时编辑策略");
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"修改策略路径时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"修改Office 365注册表时发生未知错误: {ex.Message}", LogHelper.LogType.Error);
}
}
}
}
-985
View File
@@ -1,985 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Reflection;
using System.Windows;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Controls;
using System.IO.Compression;
using System.Text;
namespace Ink_Canvas.Helpers
{
internal class AutoUpdateHelper
{
// 定义超时时间为10秒
private static readonly TimeSpan RequestTimeout = TimeSpan.FromSeconds(10);
public static async Task<string> CheckForUpdates(string proxy = null, UpdateChannel channel = UpdateChannel.Release)
{
try
{
string localVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
LogHelper.WriteLogToFile($"AutoUpdate | Local version: {localVersion}");
string remoteAddress = proxy;
// 根据通道选择URL
string primaryUrl, fallbackUrl;
if (channel == UpdateChannel.Release)
{
// Release通道版本信息地址
primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/AutomaticUpdateVersionControl.txt";
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
}
else
{
// Beta通道版本信息地址
primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
}
LogHelper.WriteLogToFile($"AutoUpdate | Checking for updates on {channel} channel");
// 先尝试主地址
remoteAddress += primaryUrl;
string remoteVersion = await GetRemoteVersion(remoteAddress);
// 如果主地址失败,尝试备用地址
if (remoteVersion == null)
{
LogHelper.WriteLogToFile($"AutoUpdate | Primary URL failed, trying fallback URL");
remoteVersion = await GetRemoteVersion(proxy + fallbackUrl);
}
if (remoteVersion != null)
{
LogHelper.WriteLogToFile($"AutoUpdate | Remote version: {remoteVersion}");
Version local = new Version(localVersion);
Version remote = new Version(remoteVersion);
if (remote > local)
{
LogHelper.WriteLogToFile($"AutoUpdate | New version available: {remoteVersion}");
return remoteVersion;
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | Current version is up to date");
return null;
}
}
else
{
LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve remote version from both URLs.", LogHelper.LogType.Error);
return null;
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error in CheckForUpdates: {ex.Message}", LogHelper.LogType.Error);
return null;
}
}
public static async Task<string> GetRemoteVersion(string fileUrl)
{
using (HttpClient client = new HttpClient())
{
try
{
// 设置超时时间为10秒
client.Timeout = RequestTimeout;
LogHelper.WriteLogToFile($"AutoUpdate | Sending HTTP request to: {fileUrl}");
// 使用带超时的Task.WhenAny来确保请求不会无限期等待
var downloadTask = client.GetAsync(fileUrl);
var timeoutTask = Task.Delay(RequestTimeout);
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
if (completedTask == timeoutTask)
{
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out after {RequestTimeout.TotalSeconds} seconds", LogHelper.LogType.Error);
return null;
}
// 请求完成,检查结果
HttpResponseMessage response = await downloadTask;
LogHelper.WriteLogToFile($"AutoUpdate | HTTP response status: {response.StatusCode}");
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
// Trim any whitespace, newlines, etc.
content = content.Trim();
// If the content contains HTML (likely the GitHub view page instead of raw content),
// try to extract the version number
if (content.Contains("<html") || content.Contains("<!DOCTYPE"))
{
LogHelper.WriteLogToFile($"AutoUpdate | Received HTML content instead of raw version number - trying to extract version");
// Try to extract version from GitHub page - look for text content in the file
int startPos = content.IndexOf("<table");
if (startPos > 0)
{
int endPos = content.IndexOf("</table>", startPos);
if (endPos > startPos)
{
string tableContent = content.Substring(startPos, endPos - startPos);
// Look for the version number pattern (like 1.2.3 or 1.2.3.4)
var match = System.Text.RegularExpressions.Regex.Match(tableContent, @"(\d+\.\d+\.\d+(\.\d+)?)");
if (match.Success)
{
content = match.Groups[1].Value;
LogHelper.WriteLogToFile($"AutoUpdate | Extracted version from HTML: {content}");
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | Could not extract version from HTML content");
return null;
}
}
}
}
LogHelper.WriteLogToFile($"AutoUpdate | Response content: {content}");
return content;
}
catch (HttpRequestException ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | HTTP request error: {ex.Message}", LogHelper.LogType.Error);
}
catch (TaskCanceledException ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out: {ex.Message}", LogHelper.LogType.Error);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error: {ex.Message}", LogHelper.LogType.Error);
}
return null;
}
}
private static string updatesFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoUpdate");
private static string statusFilePath = null;
public static async Task<bool> DownloadSetupFileAndSaveStatus(string version, string proxy = "", UpdateChannel channel = UpdateChannel.Release)
{
try
{
statusFilePath = Path.Combine(updatesFolderPath, $"DownloadV{version}Status.txt");
if (File.Exists(statusFilePath) && File.ReadAllText(statusFilePath).Trim().ToLower() == "true")
{
LogHelper.WriteLogToFile("AutoUpdate | Setup file already downloaded.");
return true;
}
// Ensure update directory exists
if (!Directory.Exists(updatesFolderPath))
{
Directory.CreateDirectory(updatesFolderPath);
LogHelper.WriteLogToFile($"AutoUpdate | Created updates directory: {updatesFolderPath}");
}
// 根据通道选择下载地址
string primaryUrl, fallbackUrl;
if (channel == UpdateChannel.Release)
{
// Release通道下载地址
primaryUrl = $"{proxy}https://github.com/InkCanvasForClass/community/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
fallbackUrl = $"{proxy}https://bgithub.xyz/InkCanvasForClass/community/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
}
else
{
// Beta通道下载地址
primaryUrl = $"{proxy}https://github.com/InkCanvasForClass/community-beta/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
fallbackUrl = $"{proxy}https://bgithub.xyz/InkCanvasForClass/community-beta/releases/download/{version}/InkCanvasForClass.CE.{version}.zip";
}
LogHelper.WriteLogToFile($"AutoUpdate | Primary download URL: {primaryUrl}");
SaveDownloadStatus(false);
string zipFilePath = Path.Combine(updatesFolderPath, $"InkCanvasForClass.CE.{version}.zip");
LogHelper.WriteLogToFile($"AutoUpdate | Target file path: {zipFilePath}");
// 先尝试主地址下载
bool downloadSuccess = await DownloadFile(primaryUrl, zipFilePath);
// 如果主地址下载失败,尝试备用地址
if (!downloadSuccess)
{
LogHelper.WriteLogToFile($"AutoUpdate | Primary download failed, trying fallback URL: {fallbackUrl}");
downloadSuccess = await DownloadFile(fallbackUrl, zipFilePath);
}
if (downloadSuccess)
{
SaveDownloadStatus(true);
LogHelper.WriteLogToFile("AutoUpdate | Setup file successfully downloaded.");
return true;
}
else
{
LogHelper.WriteLogToFile("AutoUpdate | Failed to download the update file from both URLs.", LogHelper.LogType.Error);
return false;
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error downloading update: {ex.Message}", LogHelper.LogType.Error);
if (ex.InnerException != null)
{
LogHelper.WriteLogToFile($"AutoUpdate | Inner exception: {ex.InnerException.Message}", LogHelper.LogType.Error);
}
SaveDownloadStatus(false);
return false;
}
}
private static async Task<bool> DownloadFile(string fileUrl, string destinationPath)
{
using (HttpClient client = new HttpClient())
{
try
{
// Configure client
client.Timeout = TimeSpan.FromMinutes(5); // 下载文件需要更长的超时时间
client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater");
LogHelper.WriteLogToFile($"AutoUpdate | Downloading from: {fileUrl}");
// 创建临时文件路径
string tempFilePath = destinationPath + ".tmp";
// 确保目标目录存在
string directory = Path.GetDirectoryName(destinationPath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// 使用带超时的Task.WhenAny来确保请求不会无限期等待
var downloadTask = client.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead);
var initialTimeoutTask = Task.Delay(RequestTimeout); // 使用全局定义的10秒超时
var completedTask = await Task.WhenAny(downloadTask, initialTimeoutTask);
if (completedTask == initialTimeoutTask)
{
LogHelper.WriteLogToFile($"AutoUpdate | Initial connection timed out after 30 seconds", LogHelper.LogType.Error);
return false;
}
// 请求完成,检查结果
HttpResponseMessage response = await downloadTask;
LogHelper.WriteLogToFile($"AutoUpdate | HTTP response status: {response.StatusCode}");
response.EnsureSuccessStatusCode();
// 获取文件总大小
long? totalBytes = response.Content.Headers.ContentLength;
LogHelper.WriteLogToFile($"AutoUpdate | File size: {(totalBytes.HasValue ? (totalBytes.Value / 1024.0 / 1024.0).ToString("F2") + " MB" : "Unknown")}");
// 创建临时文件流
using (var fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
// 获取下载流
using (var downloadStream = await response.Content.ReadAsStreamAsync())
{
byte[] buffer = new byte[8192]; // 8KB buffer
long totalBytesRead = 0;
int bytesRead;
DateTime lastProgressUpdate = DateTime.Now;
// 设置下载超时 - 如果60秒内没有数据传输,则认为下载超时
var downloadTimeoutTask = Task.Delay(TimeSpan.FromSeconds(60));
var readTask = Task.Run(async () => {
while ((bytesRead = await downloadStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
// 每5秒更新一次进度
if ((DateTime.Now - lastProgressUpdate).TotalSeconds >= 5)
{
if (totalBytes.HasValue)
{
double percentage = (double)totalBytesRead / totalBytes.Value * 100;
LogHelper.WriteLogToFile($"AutoUpdate | Download progress: {percentage:F1}% ({(totalBytesRead / 1024.0 / 1024.0):F2} MB / {(totalBytes.Value / 1024.0 / 1024.0):F2} MB)");
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | Downloaded: {(totalBytesRead / 1024.0 / 1024.0):F2} MB");
}
lastProgressUpdate = DateTime.Now;
// 重置下载超时
downloadTimeoutTask = Task.Delay(TimeSpan.FromSeconds(60));
}
}
return true;
});
// 等待下载完成或超时
if (await Task.WhenAny(readTask, downloadTimeoutTask) == downloadTimeoutTask)
{
LogHelper.WriteLogToFile($"AutoUpdate | Download timed out after 60 seconds of inactivity", LogHelper.LogType.Error);
return false;
}
// 确保下载任务完成
bool downloadCompleted = await readTask;
if (downloadCompleted)
{
LogHelper.WriteLogToFile($"AutoUpdate | Download completed: {(totalBytesRead / 1024.0 / 1024.0):F2} MB");
}
}
}
// 如果临时文件存在,则将其移动到目标位置
if (File.Exists(tempFilePath))
{
// 如果目标文件已存在,先删除
if (File.Exists(destinationPath))
{
File.Delete(destinationPath);
}
File.Move(tempFilePath, destinationPath);
LogHelper.WriteLogToFile($"AutoUpdate | File saved to: {destinationPath}");
return true;
}
return false;
}
catch (HttpRequestException ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | HTTP request error: {ex.Message}", LogHelper.LogType.Error);
}
catch (TaskCanceledException ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Download timed out: {ex.Message}", LogHelper.LogType.Error);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error downloading file: {ex.Message}", LogHelper.LogType.Error);
if (ex.InnerException != null)
{
LogHelper.WriteLogToFile($"AutoUpdate | Inner exception: {ex.InnerException.Message}", LogHelper.LogType.Error);
}
}
// 清理临时文件
try
{
string tempFilePath = destinationPath + ".tmp";
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
}
}
catch { }
return false;
}
}
private static void SaveDownloadStatus(bool isSuccess)
{
try
{
if (statusFilePath == null) return;
string directory = Path.GetDirectoryName(statusFilePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
File.WriteAllText(statusFilePath, isSuccess.ToString());
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error saving download status: {ex.Message}", LogHelper.LogType.Error);
}
}
public static void InstallNewVersionApp(string version, bool isInSilence)
{
try
{
string zipFilePath = Path.Combine(updatesFolderPath, $"InkCanvasForClass.CE.{version}.zip");
LogHelper.WriteLogToFile($"AutoUpdate | Checking for ZIP file: {zipFilePath}");
if (!File.Exists(zipFilePath))
{
LogHelper.WriteLogToFile($"AutoUpdate | ZIP file not found: {zipFilePath}", LogHelper.LogType.Error);
return;
}
// Verify ZIP file size and validity
FileInfo fileInfo = new FileInfo(zipFilePath);
if (fileInfo.Length == 0)
{
LogHelper.WriteLogToFile($"AutoUpdate | ZIP file is empty, cannot continue", LogHelper.LogType.Error);
return;
}
LogHelper.WriteLogToFile($"AutoUpdate | ZIP file size: {fileInfo.Length} bytes");
// 获取当前应用程序路径和进程ID
string currentAppDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
int currentProcessId = Process.GetCurrentProcess().Id;
string appPath = Assembly.GetExecutingAssembly().Location;
LogHelper.WriteLogToFile($"AutoUpdate | Current application directory: {currentAppDir}");
LogHelper.WriteLogToFile($"AutoUpdate | Current process ID: {currentProcessId}");
LogHelper.WriteLogToFile($"AutoUpdate | Silent update mode: {isInSilence}");
// 创建批处理文件来执行更新操作
string batchFilePath = Path.Combine(Path.GetTempPath(), "UpdateICC_" + Guid.NewGuid().ToString().Substring(0, 8) + ".bat");
LogHelper.WriteLogToFile($"AutoUpdate | Creating update batch file: {batchFilePath}");
// 构建批处理文件内容
StringBuilder batchContent = new StringBuilder();
batchContent.AppendLine("@echo off");
// 使窗口隐藏(使用VBS脚本运行隐藏窗口)
batchContent.AppendLine("echo Set objShell = CreateObject(\"WScript.Shell\") > \"%temp%\\hideme.vbs\"");
batchContent.AppendLine("echo objShell.Run \"cmd /c \"\"\" ^& WScript.Arguments(0) ^& \"\"\"\", 0, True >> \"%temp%\\hideme.vbs\"");
batchContent.AppendLine($"echo Wscript.Sleep 100 >> \"%temp%\\hideme.vbs\"");
// 创建真正的更新批处理文件
string updateBatPath = Path.Combine(Path.GetTempPath(), "ICCUpdate_" + Guid.NewGuid().ToString().Substring(0, 8) + ".bat");
batchContent.AppendLine($"echo @echo off > \"{updateBatPath}\"");
// 写入等待进程退出的代码到更新批处理文件
batchContent.AppendLine($"echo set PROC_ID={currentProcessId} >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo :CHECK_PROCESS >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo tasklist /fi \"PID eq %PROC_ID%\" ^| find \"%PROC_ID%\" ^> nul >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo if %%ERRORLEVEL%% == 0 ( >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo timeout /t 1 /nobreak ^> nul >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo goto CHECK_PROCESS >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo ) >> \"{updateBatPath}\"");
// 应用程序已关闭,开始更新操作
batchContent.AppendLine($"echo echo Application closed, starting update process... >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo timeout /t 2 /nobreak ^> nul >> \"{updateBatPath}\"");
// 创建临时解压目录
string extractPath = Path.Combine(updatesFolderPath, $"Extract_{version}");
batchContent.AppendLine($"echo echo Extracting update files... >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo if exist \"{extractPath}\" rd /s /q \"{extractPath}\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo mkdir \"{extractPath}\" >> \"{updateBatPath}\"");
// PowerShell解压ZIP文件(因为批处理不直接支持ZIP解压)
batchContent.AppendLine($"echo powershell -command \"Expand-Archive -Path '{zipFilePath.Replace("'", "''")}' -DestinationPath '{extractPath.Replace("'", "''")}' -Force\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo if %%ERRORLEVEL%% neq 0 ( >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo goto ERROR_EXIT >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo ) >> \"{updateBatPath}\"");
// 复制文件到应用程序目录
batchContent.AppendLine($"echo echo Copying updated files to application directory... >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo xcopy /s /y /e \"{extractPath}\\*\" \"{currentAppDir}\\\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo if %%ERRORLEVEL%% neq 0 ( >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo goto ERROR_EXIT >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo ) >> \"{updateBatPath}\"");
// 清理临时文件
batchContent.AppendLine($"echo echo Cleaning up temporary files... >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo if exist \"{extractPath}\" rd /s /q \"{extractPath}\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo if exist \"{zipFilePath}\" del /f /q \"{zipFilePath}\" >> \"{updateBatPath}\"");
// 启动更新后的应用程序
batchContent.AppendLine($"echo echo Update completed successfully! >> \"{updateBatPath}\"");
// 根据是否为静默更新模式决定是否自动启动应用程序
if (isInSilence)
{
// 静默更新模式下,自动启动应用程序
batchContent.AppendLine($"echo echo 自动启动应用程序... >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo start \"\" \"{appPath}\" >> \"{updateBatPath}\"");
}
else
{
// 非静默模式下,检查应用程序是否已经在运行
batchContent.AppendLine($"echo :: 检查应用程序是否已经在运行 >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo tasklist /FI \"IMAGENAME eq Ink Canvas.exe\" | find /i \"Ink Canvas.exe\" > nul >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo if %%ERRORLEVEL%% neq 0 ( >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo echo 启动应用程序... >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo start \"\" \"{appPath}\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo ) else ( >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo echo 应用程序已经在运行,不再重复启动 >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo ) >> \"{updateBatPath}\"");
}
batchContent.AppendLine($"echo exit /b 0 >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo goto EXIT >> \"{updateBatPath}\"");
// 错误退出处理
if (isInSilence)
{
// 静默模式下,不显示错误提示
batchContent.AppendLine($"echo :ERROR_EXIT >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo echo Update failed! >> \"%temp%\\icc_update_error.log\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo exit /b 1 >> \"{updateBatPath}\"");
}
else
{
// 非静默模式下,显示错误提示
batchContent.AppendLine($"echo :ERROR_EXIT >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo start \"\" cmd /c \"echo Update failed! ^& pause\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo exit /b 1 >> \"{updateBatPath}\"");
}
// 删除批处理文件自身
batchContent.AppendLine($"echo :EXIT >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo del \"{updateBatPath}\" >> \"{updateBatPath}\"");
batchContent.AppendLine($"echo exit >> \"{updateBatPath}\"");
// 使用VBS脚本执行更新批处理文件(隐藏窗口)
batchContent.AppendLine($"wscript \"%temp%\\hideme.vbs\" \"{updateBatPath}\"");
batchContent.AppendLine("del \"%temp%\\hideme.vbs\"");
batchContent.AppendLine("exit");
// 写入批处理文件
File.WriteAllText(batchFilePath, batchContent.ToString());
LogHelper.WriteLogToFile($"AutoUpdate | Created update batch file");
// 启动批处理文件(隐藏窗口)
Process.Start(new ProcessStartInfo
{
FileName = batchFilePath,
CreateNoWindow = true,
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden
});
LogHelper.WriteLogToFile($"AutoUpdate | Started update batch process with hidden window");
// 应用程序将由用户手动关闭或由MainWindow中的代码关闭
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error preparing update installation: {ex.Message}", LogHelper.LogType.Error);
if (ex.InnerException != null)
{
LogHelper.WriteLogToFile($"AutoUpdate | Inner exception: {ex.InnerException.Message}", LogHelper.LogType.Error);
}
}
}
private static bool CopyDirectory(string sourceDir, string destinationDir)
{
bool allCopiesSuccessful = true;
try
{
// 创建目标目录(如果不存在)
Directory.CreateDirectory(destinationDir);
LogHelper.WriteLogToFile($"AutoUpdate | Created/verified destination directory: {destinationDir}");
// 复制所有文件
foreach (string filePath in Directory.GetFiles(sourceDir))
{
string fileName = Path.GetFileName(filePath);
string destPath = Path.Combine(destinationDir, fileName);
try
{
LogHelper.WriteLogToFile($"AutoUpdate | Copying file: {fileName}");
// 如果目标文件存在,先删除
if (File.Exists(destPath))
{
File.Delete(destPath);
}
File.Copy(filePath, destPath);
}
catch (Exception ex)
{
allCopiesSuccessful = false;
LogHelper.WriteLogToFile($"AutoUpdate | Error copying file {fileName}: {ex.Message}", LogHelper.LogType.Error);
}
}
// 递归复制所有子目录
foreach (string subDirPath in Directory.GetDirectories(sourceDir))
{
string subDirName = Path.GetFileName(subDirPath);
string destSubDir = Path.Combine(destinationDir, subDirName);
bool subDirCopyResult = CopyDirectory(subDirPath, destSubDir);
if (!subDirCopyResult)
{
allCopiesSuccessful = false;
}
}
return allCopiesSuccessful;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error copying directory {sourceDir}: {ex.Message}", LogHelper.LogType.Error);
return false;
}
}
private static void RestartApplication()
{
try
{
string appPath = Assembly.GetExecutingAssembly().Location;
LogHelper.WriteLogToFile($"AutoUpdate | Restarting application: {appPath}");
// Create a batch file to wait briefly and then start the application
// This allows the current process to fully exit before starting the new instance
string batchFilePath = Path.Combine(Path.GetTempPath(), "RestartICC_" + Guid.NewGuid().ToString().Substring(0, 8) + ".bat");
string batchContent =
"@echo off\r\n" +
"timeout /t 2 /nobreak >nul\r\n" +
":: 检查应用程序是否已经在运行\r\n" +
"tasklist /FI \"IMAGENAME eq Ink Canvas.exe\" | find /i \"Ink Canvas.exe\" > nul\r\n" +
"if %ERRORLEVEL% neq 0 (\r\n" +
" echo 启动应用程序...\r\n" +
$" start \"\" \"{appPath}\"\r\n" +
") else (\r\n" +
" echo 应用程序已经在运行,不再重复启动\r\n" +
")\r\n" +
"timeout /t 1 /nobreak >nul\r\n" +
"del \"%~f0\"\r\n" +
"exit\r\n"; // 确保批处理进程结束
File.WriteAllText(batchFilePath, batchContent);
// Start the batch file
Process.Start(new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c start \"\" \"{batchFilePath}\"",
CreateNoWindow = true,
UseShellExecute = false
});
LogHelper.WriteLogToFile($"AutoUpdate | Created restart script at {batchFilePath}");
// Shutdown the application
LogHelper.WriteLogToFile($"AutoUpdate | Shutting down application for restart");
Application.Current.Dispatcher.Invoke(() =>
{
Application.Current.Shutdown();
});
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error restarting application: {ex.Message}", LogHelper.LogType.Error);
// Fallback direct restart approach
try
{
string appPath = Assembly.GetExecutingAssembly().Location;
LogHelper.WriteLogToFile($"AutoUpdate | Attempting direct restart: {appPath}");
// 检查是否已有实例运行
Process[] processes = Process.GetProcessesByName("Ink Canvas");
if (processes.Length <= 1) // 只有当前进程
{
Process.Start(appPath);
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | Application already running, not starting a new instance");
}
Application.Current.Dispatcher.Invoke(() =>
{
Application.Current.Shutdown();
});
}
catch (Exception fallbackEx)
{
LogHelper.WriteLogToFile($"AutoUpdate | Fallback restart also failed: {fallbackEx.Message}", LogHelper.LogType.Error);
}
}
}
private static void ExecuteCommandLine(string command)
{
try
{
ProcessStartInfo processStartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c {command} & exit", // 添加exit确保cmd进程退出
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (Process process = new Process { StartInfo = processStartInfo })
{
process.Start();
// 设置一个超时时间
bool exited = process.WaitForExit(500); // 等待500毫秒
if (!exited)
{
// 不等待进程完成,让它在后台运行
LogHelper.WriteLogToFile($"AutoUpdate | Command is running in background");
}
Application.Current.Shutdown();
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error executing command: {ex.Message}", LogHelper.LogType.Error);
}
}
public static void DeleteUpdatesFolder()
{
try
{
if (Directory.Exists(updatesFolderPath))
{
// Try to delete all files first in case of locking issues
foreach (string file in Directory.GetFiles(updatesFolderPath, "*", SearchOption.AllDirectories))
{
try
{
File.Delete(file);
LogHelper.WriteLogToFile($"AutoUpdate | Deleted file: {file}");
}
catch (Exception fileEx)
{
LogHelper.WriteLogToFile($"AutoUpdate | Could not delete file {file}: {fileEx.Message}", LogHelper.LogType.Warning);
}
}
// Then try to delete subdirectories
foreach (string dir in Directory.GetDirectories(updatesFolderPath))
{
try
{
Directory.Delete(dir, true);
LogHelper.WriteLogToFile($"AutoUpdate | Deleted directory: {dir}");
}
catch (Exception dirEx)
{
LogHelper.WriteLogToFile($"AutoUpdate | Could not delete directory {dir}: {dirEx.Message}", LogHelper.LogType.Warning);
}
}
// Finally try to delete the main directory
try
{
Directory.Delete(updatesFolderPath, true);
LogHelper.WriteLogToFile($"AutoUpdate | Deleted updates folder: {updatesFolderPath}");
}
catch (Exception mainDirEx)
{
LogHelper.WriteLogToFile($"AutoUpdate | Could not completely delete updates folder: {mainDirEx.Message}", LogHelper.LogType.Warning);
}
}
else
{
LogHelper.WriteLogToFile($"AutoUpdate | Updates folder does not exist: {updatesFolderPath}");
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error deleting updates folder: {ex.Message}", LogHelper.LogType.Error);
}
}
// 新增:版本修复方法,强制下载并安装指定通道的最新版本
public static async Task<bool> FixVersion(UpdateChannel channel = UpdateChannel.Release)
{
try
{
LogHelper.WriteLogToFile($"AutoUpdate | Starting version fix for {channel} channel");
// 获取当前通道的最新版本
string latestVersion = await CheckForUpdates(null, channel);
if (string.IsNullOrEmpty(latestVersion))
{
LogHelper.WriteLogToFile("AutoUpdate | No newer version found for fixing", LogHelper.LogType.Warning);
return false;
}
// 下载最新版本
bool downloadResult = await DownloadSetupFileAndSaveStatus(latestVersion, "", channel);
if (!downloadResult)
{
LogHelper.WriteLogToFile("AutoUpdate | Failed to download update for fixing", LogHelper.LogType.Error);
return false;
}
// 执行安装,非静默模式
InstallNewVersionApp(latestVersion, false);
// 设置为用户主动退出,避免被看门狗判定为崩溃
App.IsAppExitByUser = true;
// 关闭应用程序
Application.Current.Dispatcher.Invoke(() => {
Application.Current.Shutdown();
});
return true;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error in FixVersion: {ex.Message}", LogHelper.LogType.Error);
return false;
}
}
// 获取更新日志
public static async Task<string> GetUpdateLog(UpdateChannel channel = UpdateChannel.Release)
{
try
{
string primaryUrl, fallbackUrl;
if (channel == UpdateChannel.Release)
{
// Release通道更新日志地址
primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/UpdateLog.txt";
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/UpdateLog.txt";
}
else
{
// Beta通道更新日志地址
primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.txt";
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/UpdateLog.txt";
}
LogHelper.WriteLogToFile($"AutoUpdate | Getting update log from {channel} channel");
// 先尝试主地址
string updateLog = await GetRemoteContent(primaryUrl);
// 如果主地址失败,尝试备用地址
if (string.IsNullOrEmpty(updateLog))
{
LogHelper.WriteLogToFile($"AutoUpdate | Primary URL failed for update log, trying fallback URL");
updateLog = await GetRemoteContent(fallbackUrl);
}
if (!string.IsNullOrEmpty(updateLog))
{
LogHelper.WriteLogToFile($"AutoUpdate | Successfully retrieved update log");
return updateLog;
}
else
{
LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve update log from both URLs.", LogHelper.LogType.Error);
return $"# 无法获取更新日志\n\n无法从服务器获取更新日志信息,请检查网络连接后重试。";
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error in GetUpdateLog: {ex.Message}", LogHelper.LogType.Error);
return $"# 获取更新日志时发生错误\n\n错误信息: {ex.Message}";
}
}
// 获取远程内容的通用方法
private static async Task<string> GetRemoteContent(string fileUrl)
{
using (HttpClient client = new HttpClient())
{
try
{
// 设置超时时间为10秒
client.Timeout = RequestTimeout;
LogHelper.WriteLogToFile($"AutoUpdate | Sending HTTP request to: {fileUrl}");
// 使用带超时的Task.WhenAny来确保请求不会无限期等待
var downloadTask = client.GetAsync(fileUrl);
var timeoutTask = Task.Delay(RequestTimeout);
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
if (completedTask == timeoutTask)
{
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out after {RequestTimeout.TotalSeconds} seconds", LogHelper.LogType.Error);
return null;
}
// 请求完成,检查结果
HttpResponseMessage response = await downloadTask;
LogHelper.WriteLogToFile($"AutoUpdate | HTTP response status: {response.StatusCode}");
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (HttpRequestException ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | HTTP request error: {ex.Message}", LogHelper.LogType.Error);
}
catch (TaskCanceledException ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Request timed out: {ex.Message}", LogHelper.LogType.Error);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error: {ex.Message}", LogHelper.LogType.Error);
}
return null;
}
}
}
internal class AutoUpdateWithSilenceTimeComboBox
{
public static ObservableCollection<string> Hours { get; set; } = new ObservableCollection<string>();
public static ObservableCollection<string> Minutes { get; set; } = new ObservableCollection<string>();
public static void InitializeAutoUpdateWithSilenceTimeComboBoxOptions(ComboBox startTimeComboBox, ComboBox endTimeComboBox)
{
for (int hour = 0; hour <= 23; ++hour)
{
Hours.Add(hour.ToString("00"));
}
for (int minute = 0; minute <= 59; minute += 20)
{
Minutes.Add(minute.ToString("00"));
}
startTimeComboBox.ItemsSource = Hours.SelectMany(h => Minutes.Select(m => $"{h}:{m}"));
endTimeComboBox.ItemsSource = Hours.SelectMany(h => Minutes.Select(m => $"{h}:{m}"));
}
public static bool CheckIsInSilencePeriod(string startTime, string endTime)
{
if (startTime == endTime) return true;
DateTime currentTime = DateTime.Now;
DateTime StartTime = DateTime.ParseExact(startTime, "HH:mm", null);
DateTime EndTime = DateTime.ParseExact(endTime, "HH:mm", null);
if (StartTime <= EndTime)
{ // 单日时间段
return currentTime >= StartTime && currentTime <= EndTime;
}
else
{ // 跨越两天的时间段
return currentTime >= StartTime || currentTime <= EndTime;
}
}
}
}
-209
View File
@@ -1,209 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Forms;
namespace Ink_Canvas.Helpers
{
/// <summary>
/// 防止窗口进入全屏状态的辅助类
/// </summary>
public static partial class AvoidFullScreenHelper
{
private static readonly DependencyProperty IsAvoidFullScreenEnabledProperty =
DependencyProperty.RegisterAttached(
"IsAvoidFullScreenEnabled",
typeof(bool),
typeof(AvoidFullScreenHelper));
private static bool _isBoardMode = false;
public static void SetBoardMode(bool isBoardMode)
{
_isBoardMode = isBoardMode;
}
public static void StartAvoidFullScreen(Window window)
{
if (window == null)
throw new ArgumentNullException(nameof(window));
if (!(bool)window.GetValue(IsAvoidFullScreenEnabledProperty))
{
var hwndSource = PresentationSource.FromVisual(window) as HwndSource;
if (hwndSource != null)
{
hwndSource.AddHook(KeepInWorkingAreaHook);
window.SetValue(IsAvoidFullScreenEnabledProperty, true);
}
}
}
public static void StopAvoidFullScreen(Window window)
{
if (window == null)
throw new ArgumentNullException(nameof(window));
if ((bool)window.GetValue(IsAvoidFullScreenEnabledProperty))
{
var hwndSource = PresentationSource.FromVisual(window) as HwndSource;
if (hwndSource != null)
{
hwndSource.RemoveHook(KeepInWorkingAreaHook);
window.ClearValue(IsAvoidFullScreenEnabledProperty);
}
}
}
public static bool GetIsAvoidFullScreenEnabled(DependencyObject obj) => (bool)obj.GetValue(IsAvoidFullScreenEnabledProperty);
public static void SetIsAvoidFullScreenEnabled(DependencyObject obj, bool value) => obj.SetValue(IsAvoidFullScreenEnabledProperty, value);
private static IntPtr KeepInWorkingAreaHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// 只拦截主画布窗口的全屏(最大化)操作
var window = HwndSource.FromHwnd(hwnd)?.RootVisual as Window;
if (window == null) return IntPtr.Zero;
// 这里假设主画布窗口类名为MainWindow(如有不同请调整)
if (window.GetType().Name != "MainWindow") return IntPtr.Zero;
if (_isBoardMode)
{
// 画板模式下允许全屏/最大化,不拦截
return IntPtr.Zero;
}
const int WM_WINDOWPOSCHANGING = 0x0046;
const int WM_SYSCOMMAND = 0x0112;
const int SC_MAXIMIZE = 0xF030;
if (msg == WM_SYSCOMMAND && wParam.ToInt32() == SC_MAXIMIZE)
{
// 拦截最大化命令,强制还原窗口并调整到工作区
window.WindowState = WindowState.Normal;
var workingArea = GetWorkingArea(new Rect(window.Left, window.Top, window.Width, window.Height));
window.Left = workingArea.Left;
window.Top = workingArea.Top;
window.Width = workingArea.Width;
window.Height = workingArea.Height;
handled = true;
return IntPtr.Zero;
}
if (msg != WM_WINDOWPOSCHANGING)
return IntPtr.Zero;
try
{
var pos = (WindowPosition)Marshal.PtrToStructure(lParam, typeof(WindowPosition));
if ((pos.Flags & (WindowPositionFlags.SWP_NOMOVE | WindowPositionFlags.SWP_NOSIZE)) != 0)
return IntPtr.Zero;
// 只处理主画布窗口
// 计算目标矩形
var targetRect = new Rect(
(pos.Flags & WindowPositionFlags.SWP_NOMOVE) == 0 ? pos.X : window.Left,
(pos.Flags & WindowPositionFlags.SWP_NOMOVE) == 0 ? pos.Y : window.Top,
(pos.Flags & WindowPositionFlags.SWP_NOSIZE) == 0 ? pos.Width : window.Width,
(pos.Flags & WindowPositionFlags.SWP_NOSIZE) == 0 ? pos.Height : window.Height);
var workingArea = GetWorkingArea(targetRect);
var adjustedRect = AdjustRectToWorkingArea(targetRect, workingArea);
pos.X = (int)adjustedRect.Left;
pos.Y = (int)adjustedRect.Top;
pos.Width = (int)adjustedRect.Width;
pos.Height = (int)adjustedRect.Height;
pos.Flags &= ~(WindowPositionFlags.SWP_NOSIZE | WindowPositionFlags.SWP_NOMOVE | WindowPositionFlags.SWP_NOREDRAW);
pos.Flags |= WindowPositionFlags.SWP_NOCOPYBITS;
Marshal.StructureToPtr(pos, lParam, false);
}
catch (Exception ex)
{
Console.WriteLine($"窗口位置调整失败: {ex.Message}");
}
return IntPtr.Zero;
}
private static Rect GetWorkingArea(Rect windowRect)
{
// 获取所有显示器
var screens = System.Windows.Forms.Screen.AllScreens;
// 确定窗口主要位于哪个显示器上
System.Windows.Forms.Screen targetScreen = null;
double maxIntersection = 0;
foreach (var screen in screens)
{
var screenRect = new Rect(
screen.WorkingArea.X,
screen.WorkingArea.Y,
screen.WorkingArea.Width,
screen.WorkingArea.Height);
var intersection = Rect.Intersect(windowRect, screenRect);
if (intersection.Width * intersection.Height > maxIntersection)
{
maxIntersection = intersection.Width * intersection.Height;
targetScreen = screen;
}
}
// 如果没找到,使用主显示器
if (targetScreen == null)
targetScreen = System.Windows.Forms.Screen.PrimaryScreen;
return new Rect(
targetScreen.WorkingArea.X,
targetScreen.WorkingArea.Y,
targetScreen.WorkingArea.Width,
targetScreen.WorkingArea.Height);
}
private static Rect AdjustRectToWorkingArea(Rect windowRect, Rect workingArea)
{
// 调整尺寸以适应工作区域
if (windowRect.Width > workingArea.Width)
windowRect.Width = workingArea.Width;
if (windowRect.Height > workingArea.Height)
windowRect.Height = workingArea.Height;
// 调整位置以确保窗口完全在工作区域内
if (windowRect.Left < workingArea.Left)
windowRect.X = workingArea.Left;
else if (windowRect.Right > workingArea.Right)
windowRect.X = workingArea.Right - windowRect.Width;
if (windowRect.Top < workingArea.Top)
windowRect.Y = workingArea.Top;
else if (windowRect.Bottom > workingArea.Bottom)
windowRect.Y = workingArea.Bottom - windowRect.Height;
return windowRect;
}
}
// 使用WPF原生类型替代Win32结构
[StructLayout(LayoutKind.Sequential)]
internal struct WindowPosition
{
public IntPtr Hwnd;
public IntPtr HwndInsertAfter;
public int X;
public int Y;
public int Width;
public int Height;
public WindowPositionFlags Flags;
}
[Flags]
internal enum WindowPositionFlags : uint
{
SWP_NOSIZE = 0x0001,
SWP_NOMOVE = 0x0002,
SWP_NOZORDER = 0x0004,
SWP_NOREDRAW = 0x0008,
SWP_NOACTIVATE = 0x0010,
SWP_FRAMECHANGED = 0x0020,
SWP_SHOWWINDOW = 0x0040,
SWP_HIDEWINDOW = 0x0080,
SWP_NOCOPYBITS = 0x0100,
SWP_NOOWNERZORDER = 0x0200,
SWP_NOSENDCHANGING = 0x0400,
}
}
-201
View File
@@ -1,201 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace Ink_Canvas.Helpers
{
internal class ForegroundWindowInfo
{
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("shell32.dll")]
private static extern IntPtr SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);
[DllImport("user32.dll")]
private static extern int SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);
[DllImport("user32.dll")]
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
[DllImport("user32.dll")]
private static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
private const uint ABM_GETTASKBARPOS = 0x00000005;
private const uint ABM_GETSTATE = 0x00000004;
private const int SPI_GETWORKAREA = 0x0030;
private const uint MONITOR_DEFAULTTOPRIMARY = 1;
private const int ABS_AUTOHIDE = 0x0000001;
[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFO
{
public int cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
[StructLayout(LayoutKind.Sequential)]
private struct APPBARDATA
{
public int cbSize;
public IntPtr hWnd;
public uint uCallbackMessage;
public uint uEdge;
public RECT rc;
public IntPtr lParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left;
public int Top;
public int Right;
public int Bottom;
public int Width => Right - Left;
public int Height => Bottom - Top;
}
/// <summary>
/// 获取Windows任务栏的高度(仅计算任务栏,不包括其他应用的停靠栏)
/// </summary>
/// <param name="screen">当前屏幕</param>
/// <param name="dpiScaleY">DPI缩放Y值</param>
/// <returns>任务栏高度</returns>
public static double GetTaskbarHeight(System.Windows.Forms.Screen screen, double dpiScaleY)
{
try
{
// 创建APPBARDATA结构
var abd = new APPBARDATA();
abd.cbSize = Marshal.SizeOf(abd);
// 获取任务栏状态
IntPtr state = SHAppBarMessage(ABM_GETSTATE, ref abd);
bool isAutoHide = (state.ToInt32() & ABS_AUTOHIDE) == ABS_AUTOHIDE;
// 如果任务栏是自动隐藏的,返回0
if (isAutoHide)
{
LogHelper.WriteLogToFile("任务栏处于自动隐藏状态", LogHelper.LogType.Info);
return 0;
}
// 获取任务栏信息
IntPtr result = SHAppBarMessage(ABM_GETTASKBARPOS, ref abd);
if (result != IntPtr.Zero)
{
// 获取当前屏幕的工作区
RECT workArea = new RECT();
SystemParametersInfo(SPI_GETWORKAREA, 0, Marshal.AllocHGlobal(Marshal.SizeOf(workArea)), 0);
// 根据任务栏位置计算高度
int taskbarHeight = 0;
// 任务栏的uEdge: 0=左, 1=上, 2=右, 3=下
switch (abd.uEdge)
{
case 1: // 上
taskbarHeight = abd.rc.Height;
break;
case 3: // 下
taskbarHeight = abd.rc.Height;
break;
case 0: // 左
case 2: // 右
// 水平任务栏不影响高度
taskbarHeight = 0;
break;
}
// 考虑DPI缩放
return taskbarHeight / dpiScaleY;
}
}
catch (Exception ex)
{
Debug.WriteLine($"获取任务栏高度出错: {ex.Message}");
LogHelper.WriteLogToFile($"获取任务栏高度出错: {ex.Message}", LogHelper.LogType.Error);
}
// 如果获取失败,回退到通用方法
return (screen.Bounds.Height - screen.WorkingArea.Height) / dpiScaleY;
}
public static string WindowTitle() {
IntPtr foregroundWindowHandle = GetForegroundWindow();
const int nChars = 256;
StringBuilder windowTitle = new StringBuilder(nChars);
GetWindowText(foregroundWindowHandle, windowTitle, nChars);
return windowTitle.ToString();
}
public static string WindowClassName() {
IntPtr foregroundWindowHandle = GetForegroundWindow();
const int nChars = 256;
StringBuilder className = new StringBuilder(nChars);
GetClassName(foregroundWindowHandle, className, nChars);
return className.ToString();
}
public static RECT WindowRect() {
IntPtr foregroundWindowHandle = GetForegroundWindow();
RECT windowRect;
GetWindowRect(foregroundWindowHandle, out windowRect);
return windowRect;
}
public static string ProcessName() {
IntPtr foregroundWindowHandle = GetForegroundWindow();
uint processId;
GetWindowThreadProcessId(foregroundWindowHandle, out processId);
try {
Process process = Process.GetProcessById((int)processId);
return process.ProcessName;
} catch (ArgumentException) {
// Process with the given ID not found
return "Unknown";
}
}
public static string ProcessPath()
{
IntPtr foregroundWindowHandle = GetForegroundWindow();
uint processId;
GetWindowThreadProcessId(foregroundWindowHandle, out processId);
try
{
Process process = Process.GetProcessById((int)processId);
return process.MainModule.FileName;
}
catch {
// Process with the given ID not found
return "Unknown";
}
}
}
}
-74
View File
@@ -1,74 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace Ink_Canvas.Helpers
{
class LogHelper
{
public static string LogFile = "Log.txt";
public static void NewLog(string str)
{
WriteLogToFile(str, LogType.Info);
}
public static void NewLog(Exception ex)
{
if (ex == null) return;
var stackTrace = ex.StackTrace ?? "<no stack trace>";
var msg = $"[Exception] Type: {ex.GetType().FullName}\nMessage: {ex.Message}\nStackTrace: {stackTrace}";
if (ex.InnerException != null)
{
msg += $"\nInnerException: {ex.InnerException.GetType().FullName} - {ex.InnerException.Message}\n{ex.InnerException.StackTrace}";
}
WriteLogToFile(msg, LogType.Error);
}
public static void WriteLogToFile(string str, LogType logType = LogType.Info)
{
string strLogType = logType.ToString();
try
{
var file = App.RootPath + LogFile;
if (!Directory.Exists(App.RootPath))
{
Directory.CreateDirectory(App.RootPath);
}
var threadId = Thread.CurrentThread.ManagedThreadId;
var callingMethod = new StackTrace(2, true).GetFrame(0);
string callerInfo = "<unknown>";
if (callingMethod != null)
{
var method = callingMethod.GetMethod();
if (method != null)
{
var className = method.DeclaringType != null ? method.DeclaringType.FullName : "<no class>";
callerInfo = $"{className}.{method.Name}";
}
}
string logLine = string.Format("{0} [T{1}] [{2}] [{3}] {4}", DateTime.Now.ToString("O"), threadId, strLogType, callerInfo, str);
using (StreamWriter sw = new StreamWriter(file, true))
{
sw.WriteLine(logLine);
}
}
catch { }
}
internal static void WriteLogToFile(string v, object warning)
{
WriteLogToFile($"[Warning] {v}", LogType.Warning);
}
public enum LogType
{
Info,
Trace,
Error,
Event,
Warning
}
}
}
-52
View File
@@ -1,52 +0,0 @@
using System;
using System.IO;
namespace Ink_Canvas.Helpers
{
public static class StartupCount
{
private static readonly string CountFilePath = Path.Combine(App.RootPath, "startup-count");
private static readonly object fileLock = new object();
public static int GetCount()
{
try
{
if (File.Exists(CountFilePath))
{
var text = File.ReadAllText(CountFilePath).Trim();
if (int.TryParse(text, out int count))
return count;
}
}
catch { }
return 0;
}
public static void Increment()
{
lock (fileLock)
{
int count = GetCount() + 1;
try
{
File.WriteAllText(CountFilePath, count.ToString());
}
catch { }
}
}
public static void Reset()
{
lock (fileLock)
{
try
{
if (File.Exists(CountFilePath))
File.Delete(CountFilePath);
}
catch { }
}
}
}
}
-561
View File
@@ -1,561 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<RuntimeIdentifiers>win;win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<OutputType>WinExe</OutputType>
<RootNamespace>Ink_Canvas</RootNamespace>
<AssemblyName>InkCanvasForClass</AssemblyName>
<TargetFramework>net472</TargetFramework>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>2</ApplicationRevision>
<ApplicationVersion>2.0.2.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>false</BootstrapperEnabled>
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
<UseWPF>true</UseWPF>
<Configurations>Debug;Release;x86 Debug</Configurations>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>embedded</DebugType>
<OutputPath>bin\$(Configuration)\</OutputPath>
<Prefer32Bit>True</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='x86 Debug|AnyCPU'">
<DebugType>embedded</DebugType>
<OutputPath>bin\$(Configuration)\</OutputPath>
<Prefer32Bit>True</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>embedded</DebugType>
<OutputPath>bin\$(Configuration)\</OutputPath>
<Prefer32Bit>True</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\icc.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>full</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='x86 Debug|x86'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>full</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>pdbonly</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Title>InkCanvasForClass</Title>
<Version>5.0.4</Version>
<Authors>Dubi906w</Authors>
<Product>InkCanvasForClass</Product>
<Copyright>© Copyright HARKOTEK Studio 2024-now</Copyright>
<PackageProjectUrl>https://icc.bliemhax.com</PackageProjectUrl>
<FileVersion>bundled</FileVersion>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>full</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='x86 Debug|ARM64'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>full</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>pdbonly</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>full</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='x86 Debug|x64'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>full</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<DebugType>pdbonly</DebugType>
<LangVersion>7.3</LangVersion>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="IACore">
<HintPath>.\IACore.dll</HintPath>
</Reference>
<Reference Include="IALoader">
<HintPath>.\IALoader.dll</HintPath>
</Reference>
<Reference Include="IAWinFX">
<HintPath>.\IAWinFX.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="netstandard" />
<Reference Include="System.Windows.Forms" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml" />
<Reference Include="UIAutomationClient" />
<Reference Include="UIAutomationTypes" />
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup>
<None Include="app.manifest" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.9.27" />
<PackageReference Include="MdXaml" Version="1.27.0" />
<PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1018" />
<PackageReference Include="MicrosoftOfficeCore" Version="15.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NHotkey.Wpf" Version="3.0.0" />
<PackageReference Include="OSVersionExt" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="stdole">
<Guid>{00020430-0000-0000-C000-000000000046}</Guid>
<VersionMajor>2</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="VBIDE">
<Guid>{0002E157-0000-0000-C000-000000000046}</Guid>
<VersionMajor>5</VersionMajor>
<VersionMinor>3</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<None Include="Resources\TimerDownNotice.wav" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Cursors\Cursor.cur" />
<Resource Include="Resources\Cursors\Pen.cur" />
<Resource Include="Resources\DeveloperAvatars\aaaaaaccd.jpg" />
<Resource Include="Resources\DeveloperAvatars\Alan-CRL.png" />
<Resource Include="Resources\DeveloperAvatars\NetheriteBowl.png" />
<Resource Include="Resources\DeveloperAvatars\NotYoojun.png" />
<Resource Include="Resources\DeveloperAvatars\RaspberryKan.jpg" />
<Resource Include="Resources\DeveloperAvatars\wwei.png" />
<Resource Include="Resources\DeveloperAvatars\yuwenhui2020.png" />
<Resource Include="Resources\icc.ico" />
<Resource Include="Resources\Icons-png\AdmoxBooth.png" />
<Resource Include="Resources\Icons-png\AdmoxWhiteboard.png" />
<Resource Include="Resources\Icons-png\check-box-background.png" />
<Resource Include="Resources\Icons-png\Donview.png" />
<Resource Include="Resources\Icons-png\EasiNote3.png" />
<Resource Include="Resources\Icons-png\eraser-line.png" />
<Resource Include="Resources\Icons-png\eraser-outline.png" />
<Resource Include="Resources\Icons-png\HiteLightBoard.png" />
<Resource Include="Resources\Icons-png\ica.png" />
<Resource Include="Resources\Icons-png\icc-transparent-dark-small.png" />
<Resource Include="Resources\Icons-png\icc-transparent-dark.png" />
<Resource Include="Resources\Icons-png\icc-transparent.png" />
<Resource Include="Resources\Icons-png\icc.png" />
<Resource Include="Resources\Icons-png\InkCanvas.png" />
<Resource Include="Resources\Icons-png\kuanciya.png" />
<Resource Include="Resources\Icons-png\kuandogeyuanliangwo.png" />
<Resource Include="Resources\Icons-png\kuandoujiyanhuaji.png" />
<Resource Include="Resources\Icons-png\kuanneikuhuaji.png" />
<Resource Include="Resources\Icons-png\kuanshounvhuaji.png" />
<Resource Include="Resources\Icons-png\MaxHubWhiteboard.png" />
<Resource Include="Resources\Icons-png\playCircle.png" />
<Resource Include="Resources\Icons-png\redo.png" />
<Resource Include="Resources\Icons-png\Seewo2Annotation.png" />
<Resource Include="Resources\Icons-png\setting.png" />
<Resource Include="Resources\Icons-png\tiebahuaji.png" />
<Resource Include="Resources\Icons-png\transparent-grid.png" />
<Resource Include="Resources\Icons-png\undo.png" />
<Resource Include="Resources\Icons-png\minimize.png" />
<Resource Include="Resources\Icons-png\penUpright.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\twoFingelMove-Blue.png" />
<Resource Include="Resources\Icons-png\twoFingelMove.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\close-circle.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\DeveloperAvatars\ChangSakura.png" />
<Resource Include="Resources\DeveloperAvatars\clover-yan.png" />
<Resource Include="Resources\DeveloperAvatars\CN-Ironegg.jpg" />
<Resource Include="Resources\DeveloperAvatars\jiajiaxd.jpg" />
<Resource Include="Resources\DeveloperAvatars\kengwang.png" />
<Resource Include="Resources\DeveloperAvatars\STBBRD.png" />
<Resource Include="Resources\DeveloperAvatars\WXRIW.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\down.png" />
<Resource Include="Resources\Icons-png\up.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\EasiCamera.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\Desmos.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_cursor_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_lasso_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_settings_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_whiteboard_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_dark_theme_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_dual_screen_span_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_timer_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_delete_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_cursorWITHdelete_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_arrow_circle_left_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_arrow_circle_right_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_weather_moon_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_weather_sunny_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_signature_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_save_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_camera_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_copy_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_copy_add_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_add_circle_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_flip_horizontal_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_flip_vertical_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_edit_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_folder_open_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_people_money_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_person_money_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_arrow_rotate_clockwise_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_scale_fit_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_scales_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_arrow_clockwise_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_calendar_sync_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_dismiss_circle_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_drag_24_regular.png" />
<Resource Include="Resources\Icons-Fluent\ic_fluent_shapes_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_power_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_clock_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_book_question_mark_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_keyboard_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_control_button_24_regular.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_people_24_regular.png" />
<Resource Include="Resources\Icons-png\VComYouJiao.png" />
<Resource Include="Resources\Icons-png\WenXiang.png" />
<Resource Include="Resources\Icons-png\YiYunVisualPresenter.png" />
<Resource Include="Resources\Icons-png\YiYunWhiteboard.png" />
<Resource Include="Resources\new-icons\chevron-left.png" />
<Resource Include="Resources\new-icons\end-slides-show.png">
<CopyToOutputDirectory></CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\new-icons\eye.png" />
<Resource Include="Resources\new-icons\hand-move.png" />
<Resource Include="Resources\new-icons\highlighter-white.png" />
<Resource Include="Resources\new-icons\multi-touch.png" />
<Resource Include="Resources\new-icons\osu-lazer-triangles.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\pen-lined.png" />
<Resource Include="Resources\new-icons\pen-solid.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\cursor-lined.png" />
<Resource Include="Resources\new-icons\cursor-solid.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\eraser-lined.png" />
<Resource Include="Resources\new-icons\eraser-solid.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\circle-eraser-lined.png" />
<Resource Include="Resources\new-icons\circle-eraser-solid.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\lasso-select-lined.png" />
<Resource Include="Resources\new-icons\lasso-select-solid.png" />
<Resource Include="Resources\new-icons\pen-white.png" />
<Resource Include="Resources\new-icons\rotate.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\trash.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\shapes.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\eye-off.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\grid.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\blackboard.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\cursor-clear.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\DeveloperAvatars\dubi906w.jpg" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\gesture.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\gesture-enabled.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\close-white.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\checked-white.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\checked-black.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\pressdown-background.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\arrow.png" />
<Resource Include="Resources\Icons-png\geo-icons\dashed-line.png" />
<Resource Include="Resources\Icons-png\geo-icons\dotted-line.png" />
<Resource Include="Resources\Icons-png\geo-icons\line.png" />
<Resource Include="Resources\Icons-png\geo-icons\paralle-lines.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\centered-square.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\centered-circle.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\centered-circle-dashed.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\centered-oval.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\square.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\cylinder.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\cone.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\geo-icons\cube.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\EasiNote.png" />
<Resource Include="Resources\Icons-png\EasiNote3C.png" />
<Resource Include="Resources\Icons-png\EasiNote5C.png" />
<Resource Include="Resources\Icons-png\SeewoPinco.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\HiteBoard.png" />
<Resource Include="Resources\Icons-png\HiteCamera.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\Whiteboard.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\Powerpoint.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\PPTTools.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\WPS.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\hatsune-miku1.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-Fluent\party.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\redo.png" />
<Resource Include="Resources\new-icons\undo.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\new-icons\unfold-chevron.png" />
<Resource Include="Resources\new-icons\zoom.png" />
</ItemGroup>
<ItemGroup>
<Compile Remove="AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="MainWindow.xaml~RF6c3144.TMP" />
<None Remove="Resources\Cursors\Cursor.cur" />
<None Remove="Resources\Cursors\Pen.cur" />
<None Remove="Resources\DeveloperAvatars\aaaaaaccd.jpg" />
<None Remove="Resources\DeveloperAvatars\Alan-CRL.png" />
<None Remove="Resources\DeveloperAvatars\NetheriteBowl.png" />
<None Remove="Resources\DeveloperAvatars\NotYoojun.png" />
<None Remove="Resources\DeveloperAvatars\RaspberryKan.jpg" />
<None Remove="Resources\DeveloperAvatars\wwei.png" />
<None Remove="Resources\DeveloperAvatars\yuwenhui2020.png" />
<None Remove="Resources\icc.ico" />
<None Remove="Resources\Icons-png\AdmoxBooth.png" />
<None Remove="Resources\Icons-png\AdmoxWhiteboard.png" />
<None Remove="Resources\Icons-png\Donview.png" />
<None Remove="Resources\Icons-png\EasiNote3.png" />
<None Remove="Resources\Icons-png\HiteAnnotation.png" />
<None Remove="Resources\Icons-png\HiteLightBoard.png" />
<None Remove="Resources\Icons-png\ica.png" />
<None Remove="Resources\Icons-png\icc-transparent-dark-small.png" />
<None Remove="Resources\Icons-png\icc-transparent-dark.png" />
<None Remove="Resources\Icons-png\icc-transparent.png" />
<None Remove="Resources\Icons-png\icc.png" />
<None Remove="Resources\Icons-png\idt.png" />
<None Remove="Resources\Icons-png\InkCanvas.png" />
<None Remove="Resources\Icons-png\kuanciya.png" />
<None Remove="Resources\Icons-png\kuandogeyuanliangwo.png" />
<None Remove="Resources\Icons-png\kuandoujiyanhuaji.png" />
<None Remove="Resources\Icons-png\kuanneikuhuaji.png" />
<None Remove="Resources\Icons-png\kuanshounvhuaji.png" />
<None Remove="Resources\Icons-png\MaxHubWhiteboard.png" />
<None Remove="Resources\Icons-png\Seewo2Annotation.png" />
<None Remove="Resources\Icons-png\tiebahuaji.png" />
<None Remove="Resources\Icons-png\transparent-grid.png" />
<None Remove="Resources\Icons-png\VComYouJiao.png" />
<None Remove="Resources\Icons-png\WenXiang.png" />
<None Remove="Resources\Icons-png\YiYunVisualPresenter.png" />
<None Remove="Resources\Icons-png\YiYunWhiteboard.png" />
<None Remove="Resources\new-icons\chevron-left.png" />
<None Remove="Resources\new-icons\end-slides-show.png" />
<None Remove="Resources\new-icons\eye.png" />
<None Remove="Resources\new-icons\hand-move.png" />
<None Remove="Resources\new-icons\highlighter-white.png" />
<None Remove="Resources\new-icons\multi-touch.png" />
<None Remove="Resources\new-icons\osu-lazer-triangles.png" />
<None Remove="Resources\new-icons\pen-white.png" />
<None Remove="Resources\new-icons\rotate.png" />
<None Remove="Resources\new-icons\unfold-chevron.png" />
<None Remove="Resources\new-icons\zoom.png" />
<None Remove="Resources\PresentationExample\bottombar-dark.png" />
<None Remove="Resources\PresentationExample\bottombar-white.png" />
<None Remove="Resources\PresentationExample\page.jpg" />
<None Remove="Resources\PresentationExample\sidebar-dark.png" />
<None Remove="Resources\PresentationExample\sidebar-white.png" />
<None Remove="Resources\PresentationExample\toolbar.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\idt.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons-png\HiteAnnotation.png" />
<Resource Include="Resources\PresentationExample\bottombar-dark.png" />
<Resource Include="Resources\PresentationExample\bottombar-white.png" />
<Resource Include="Resources\PresentationExample\page.jpg" />
<Resource Include="Resources\PresentationExample\sidebar-dark.png" />
<Resource Include="Resources\PresentationExample\sidebar-white.png" />
<Resource Include="Resources\PresentationExample\toolbar.png" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_LastSelectedProfileId>D:\vs\ica\Ink Canvas\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
</PropertyGroup>
</Project>
-812
View File
@@ -1,812 +0,0 @@
using Ink_Canvas.Helpers;
using iNKORE.UI.WPF.Modern;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Media;
using System.Diagnostics;
using File = System.IO.File;
using MessageBox = System.Windows.MessageBox;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows.Controls.Primitives;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32;
using System.Windows.Input;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media.Animation;
using System.Reflection;
namespace Ink_Canvas {
public partial class MainWindow : Window {
#region Window Initialization
public MainWindow() {
/*
处于画板模式内:Topmost == false / currentMode != 0
处于 PPT 放映内:BtnPPTSlideShowEnd.Visibility
*/
InitializeComponent();
BlackboardLeftSide.Visibility = Visibility.Collapsed;
BlackboardCenterSide.Visibility = Visibility.Collapsed;
BlackboardRightSide.Visibility = Visibility.Collapsed;
BorderTools.Visibility = Visibility.Collapsed;
BorderSettings.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
BorderSettings.Margin = new Thickness(0, 0, 0, 0);
TwoFingerGestureBorder.Visibility = Visibility.Collapsed;
BoardTwoFingerGestureBorder.Visibility = Visibility.Collapsed;
BorderDrawShape.Visibility = Visibility.Collapsed;
BoardBorderDrawShape.Visibility = Visibility.Collapsed;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
//if (!App.StartArgs.Contains("-o"))
ViewBoxStackPanelMain.Visibility = Visibility.Collapsed;
ViewBoxStackPanelShapes.Visibility = Visibility.Collapsed;
var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
ViewboxFloatingBar.Margin = new Thickness(
(workingArea.Width - 284) / 2,
workingArea.Bottom - 60 - workingArea.Top,
-2000, -200);
ViewboxFloatingBarMarginAnimation(100, true);
try {
if (File.Exists("debug.ini")) Label.Visibility = Visibility.Visible;
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
try {
if (File.Exists("Log.txt")) {
var fileInfo = new FileInfo("Log.txt");
var fileSizeInKB = fileInfo.Length / 1024;
if (fileSizeInKB > 512)
try {
File.Delete("Log.txt");
LogHelper.WriteLogToFile(
"The Log.txt file has been successfully deleted. Original file size: " + fileSizeInKB +
" KB", LogHelper.LogType.Info);
}
catch (Exception ex) {
LogHelper.WriteLogToFile(
ex + " | Can not delete the Log.txt file. File size: " + fileSizeInKB + " KB",
LogHelper.LogType.Error);
}
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
InitTimers();
timeMachine.OnRedoStateChanged += TimeMachine_OnRedoStateChanged;
timeMachine.OnUndoStateChanged += TimeMachine_OnUndoStateChanged;
inkCanvas.Strokes.StrokesChanged += StrokesOnStrokesChanged;
Microsoft.Win32.SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged;
try {
if (File.Exists("SpecialVersion.ini")) SpecialVersionResetToSuggestion_Click();
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
CheckColorTheme(true);
CheckPenTypeUIState();
// 注册输入事件
inkCanvas.PreviewMouseDown += inkCanvas_PreviewMouseDown;
inkCanvas.StylusDown += inkCanvas_StylusDown;
inkCanvas.TouchDown += inkCanvas_TouchDown;
inkCanvas.TouchUp += inkCanvas_TouchUp;
}
#endregion
#region Ink Canvas Functions
private System.Windows.Media.Color Ink_DefaultColor = Colors.Red;
private DrawingAttributes drawingAttributes;
private void loadPenCanvas() {
try {
//drawingAttributes = new DrawingAttributes();
drawingAttributes = inkCanvas.DefaultDrawingAttributes;
drawingAttributes.Color = Ink_DefaultColor;
drawingAttributes.Height = 2.5;
drawingAttributes.Width = 2.5;
drawingAttributes.IsHighlighter = false;
drawingAttributes.FitToCurve = Settings.Canvas.FitToCurve;
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
inkCanvas.Gesture += InkCanvas_Gesture;
}
catch { }
}
//ApplicationGesture lastApplicationGesture = ApplicationGesture.AllGestures;
private DateTime lastGestureTime = DateTime.Now;
private void InkCanvas_Gesture(object sender, InkCanvasGestureEventArgs e) {
var gestures = e.GetGestureRecognitionResults();
try {
foreach (var gest in gestures)
//Trace.WriteLine(string.Format("Gesture: {0}, Confidence: {1}", gest.ApplicationGesture, gest.RecognitionConfidence));
if (StackPanelPPTControls.Visibility == Visibility.Visible) {
if (gest.ApplicationGesture == ApplicationGesture.Left)
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
if (gest.ApplicationGesture == ApplicationGesture.Right)
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
}
}
catch { }
}
private void inkCanvas_EditingModeChanged(object sender, RoutedEventArgs e) {
var inkCanvas1 = sender as InkCanvas;
if (inkCanvas1 == null) return;
// 使用辅助方法设置光标
SetCursorBasedOnEditingMode(inkCanvas1);
if (inkCanvas1.EditingMode == InkCanvasEditingMode.Ink) forcePointEraser = !forcePointEraser;
}
#endregion Ink Canvas
#region Definations and Loading
public static Settings Settings = new Settings();
public static string settingsFileName = "Settings.json";
private bool isLoaded = false;
private void Window_Loaded(object sender, RoutedEventArgs e) {
loadPenCanvas();
//加载设置
LoadSettings(true);
// HasNewUpdateWindow hasNewUpdateWindow = new HasNewUpdateWindow();
if (Environment.Is64BitProcess) GroupBoxInkRecognition.Visibility = Visibility.Collapsed;
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
SystemEvents_UserPreferenceChanged(null, null);
//TextBlockVersion.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
LogHelper.WriteLogToFile("Ink Canvas Loaded", LogHelper.LogType.Event);
isLoaded = true;
BlackBoardLeftSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection;
BlackBoardRightSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection;
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush =
new SolidColorBrush(System.Windows.Media.Color.FromArgb(127, 24, 24, 27));
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
BtnRightWhiteBoardSwitchPreviousGeometry.Brush =
new SolidColorBrush(System.Windows.Media.Color.FromArgb(127, 24, 24, 27));
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
BtnWhiteBoardSwitchPrevious.IsEnabled = CurrentWhiteboardIndex != 1;
BorderInkReplayToolBox.Visibility = Visibility.Collapsed;
// 提前加载IA库,优化第一笔等待时间
if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) {
var strokeEmpty = new StrokeCollection();
InkRecognizeHelper.RecognizeShape(strokeEmpty);
}
SystemEvents.DisplaySettingsChanged += SystemEventsOnDisplaySettingsChanged;
// 自动收纳到侧边栏
if (Settings.Startup.IsFoldAtStartup)
{
FoldFloatingBar_MouseUp(null, null);
}
// 恢复崩溃后操作设置
if (App.CrashAction == App.CrashActionType.SilentRestart)
RadioCrashSilentRestart.IsChecked = true;
else
RadioCrashNoAction.IsChecked = true;
}
private void SystemEventsOnDisplaySettingsChanged(object sender, EventArgs e) {
if (!Settings.Advanced.IsEnableResolutionChangeDetection) return;
ShowNotification($"检测到显示器信息变化,变为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}");
new Thread(() => {
var isFloatingBarOutsideScreen = false;
var isInPPTPresentationMode = false;
Dispatcher.Invoke(() => {
isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar);
isInPPTPresentationMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible;
});
if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000, null, () => {
if (!isFloatingBarFolded)
{
if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60);
else ViewboxFloatingBarMarginAnimation(100, true);
}
});
}).Start();
}
public DelayAction dpiChangedDelayAction = new DelayAction();
private void MainWindow_OnDpiChanged(object sender, DpiChangedEventArgs e)
{
if (e.OldDpi.DpiScaleX != e.NewDpi.DpiScaleX && e.OldDpi.DpiScaleY != e.NewDpi.DpiScaleY && Settings.Advanced.IsEnableDPIChangeDetection)
{
ShowNotification($"系统DPI发生变化,从 {e.OldDpi.DpiScaleX}x{e.OldDpi.DpiScaleY} 变化为 {e.NewDpi.DpiScaleX}x{e.NewDpi.DpiScaleY}");
new Thread(() => {
var isFloatingBarOutsideScreen = false;
var isInPPTPresentationMode = false;
Dispatcher.Invoke(() => {
isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar);
isInPPTPresentationMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible;
});
if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000,null, () => {
if (!isFloatingBarFolded)
{
if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60);
else ViewboxFloatingBarMarginAnimation(100, true);
}
});
}).Start();
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
LogHelper.WriteLogToFile("Ink Canvas closing", LogHelper.LogType.Event);
if (!CloseIsFromButton && Settings.Advanced.IsSecondConfirmWhenShutdownApp) {
e.Cancel = true;
if (MessageBox.Show("是否继续关闭 InkCanvasForClass,这将丢失当前未保存的墨迹。", "InkCanvasForClass",
MessageBoxButton.OKCancel, MessageBoxImage.Warning) == MessageBoxResult.OK)
if (MessageBox.Show("真的狠心关闭 InkCanvasForClass吗?", "InkCanvasForClass", MessageBoxButton.OKCancel,
MessageBoxImage.Error) == MessageBoxResult.OK)
if (MessageBox.Show("是否取消关闭 InkCanvasForClass", "InkCanvasForClass", MessageBoxButton.OKCancel,
MessageBoxImage.Error) != MessageBoxResult.OK)
e.Cancel = false;
}
if (e.Cancel) LogHelper.WriteLogToFile("Ink Canvas closing cancelled", LogHelper.LogType.Event);
}
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) {
if (Settings.Advanced.IsEnableForceFullScreen) {
if (isLoaded) ShowNotification(
$"检测到窗口大小变化,已自动恢复到全屏:{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}(缩放比例为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight}");
WindowState = WindowState.Maximized;
MoveWindow(new WindowInteropHelper(this).Handle, 0, 0,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, true);
}
}
private void Window_Closed(object sender, EventArgs e) {
SystemEvents.DisplaySettingsChanged -= SystemEventsOnDisplaySettingsChanged;
LogHelper.WriteLogToFile("Ink Canvas closed", LogHelper.LogType.Event);
// 检查是否有待安装的更新
CheckPendingUpdates();
}
private void CheckPendingUpdates()
{
try
{
// 如果有可用的更新版本且启用了自动更新
if (AvailableLatestVersion != null && Settings.Startup.IsAutoUpdate)
{
// 检查更新文件是否已下载
string updatesFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoUpdate");
string statusFilePath = Path.Combine(updatesFolderPath, $"DownloadV{AvailableLatestVersion}Status.txt");
if (File.Exists(statusFilePath) && File.ReadAllText(statusFilePath).Trim().ToLower() == "true")
{
LogHelper.WriteLogToFile($"AutoUpdate | Installing pending update v{AvailableLatestVersion} on application close");
// 设置为用户主动退出,避免被看门狗判定为崩溃
App.IsAppExitByUser = true;
// 创建批处理脚本并启动,软件关闭后会执行更新操作
AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, true);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error checking pending updates: {ex.Message}", LogHelper.LogType.Error);
}
}
private async void AutoUpdate() {
// 使用当前选择的更新通道检查更新
AvailableLatestVersion = await AutoUpdateHelper.CheckForUpdates(null, Settings.Startup.UpdateChannel);
// 声明下载状态变量,用于整个方法
bool isDownloadSuccessful = false;
if (AvailableLatestVersion != null) {
// 检测到新版本
LogHelper.WriteLogToFile($"AutoUpdate | New version available: {AvailableLatestVersion}");
// 检查是否是用户选择跳过的版本
if (!string.IsNullOrEmpty(Settings.Startup.SkippedVersion) &&
Settings.Startup.SkippedVersion == AvailableLatestVersion) {
LogHelper.WriteLogToFile($"AutoUpdate | Version {AvailableLatestVersion} was marked to be skipped by the user");
return; // 跳过此版本,不执行更新操作
}
// 如果检测到的版本与跳过的版本不同,则清除跳过版本记录
// 这确保用户只能跳过当前最新版本,而不是永久跳过所有更新
if (!string.IsNullOrEmpty(Settings.Startup.SkippedVersion) &&
Settings.Startup.SkippedVersion != AvailableLatestVersion) {
LogHelper.WriteLogToFile($"AutoUpdate | Detected new version {AvailableLatestVersion} different from skipped version {Settings.Startup.SkippedVersion}, clearing skip record");
Settings.Startup.SkippedVersion = "";
SaveSettingsToFile();
}
// 获取当前版本
string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
// 如果启用了静默更新,则自动下载更新而不显示提示
if (Settings.Startup.IsAutoUpdateWithSilence) {
LogHelper.WriteLogToFile("AutoUpdate | Silent update enabled, downloading update automatically without notification");
// 静默下载更新,传递当前选择的更新通道
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFileAndSaveStatus(AvailableLatestVersion, "", Settings.Startup.UpdateChannel);
if (isDownloadSuccessful) {
LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will install when conditions are met");
// 启动检查定时器,定期检查是否可以安装
timerCheckAutoUpdateWithSilence.Start();
} else {
LogHelper.WriteLogToFile("AutoUpdate | Silent update download failed", LogHelper.LogType.Error);
}
return;
}
// 如果没有启用静默更新,则显示常规更新窗口
string releaseDate = DateTime.Now.ToString("yyyy年MM月dd日");
// 从服务器获取更新日志
string releaseNotes = await AutoUpdateHelper.GetUpdateLog(Settings.Startup.UpdateChannel);
// 如果获取失败,使用默认文本
if (string.IsNullOrEmpty(releaseNotes))
{
releaseNotes = $@"# InkCanvasForClass v{AvailableLatestVersion}更新
无法获取更新日志,但新版本已准备就绪。";
}
// 创建并显示更新窗口
HasNewUpdateWindow updateWindow = new HasNewUpdateWindow(currentVersion, AvailableLatestVersion, releaseDate, releaseNotes);
bool? dialogResult = updateWindow.ShowDialog();
// 如果窗口被关闭但没有点击按钮,则不执行任何操作
if (dialogResult != true) {
LogHelper.WriteLogToFile("AutoUpdate | Update dialog closed without selection");
return;
}
// 不再从更新窗口获取自动更新设置
// 根据用户选择处理更新
switch (updateWindow.Result) {
case HasNewUpdateWindow.UpdateResult.UpdateNow:
// 立即更新:显示下载进度,下载完成后立即安装
LogHelper.WriteLogToFile("AutoUpdate | User chose to update now");
// 显示下载进度提示
MessageBox.Show("开始下载更新,请稍候...", "正在更新", MessageBoxButton.OK, MessageBoxImage.Information);
// 下载更新文件,传递当前选择的更新通道
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFileAndSaveStatus(AvailableLatestVersion, "", Settings.Startup.UpdateChannel);
if (isDownloadSuccessful) {
// 下载成功,提示用户准备安装
MessageBoxResult result = MessageBox.Show("更新已下载完成,点击确定后将关闭软件并安装新版本!", "安装更新", MessageBoxButton.OKCancel, MessageBoxImage.Information);
// 只有当用户点击确定按钮后才关闭软件
if (result == MessageBoxResult.OK) {
// 设置为用户主动退出,避免被看门狗判定为崩溃
App.IsAppExitByUser = true;
// 准备批处理脚本
AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, false);
// 关闭软件,让安装程序接管
Application.Current.Shutdown();
} else {
LogHelper.WriteLogToFile("AutoUpdate | User cancelled update installation");
}
} else {
// 下载失败
MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
}
break;
case HasNewUpdateWindow.UpdateResult.UpdateLater:
// 稍后更新:静默下载,在软件关闭时自动安装
LogHelper.WriteLogToFile("AutoUpdate | User chose to update later");
// 不管设置如何,都进行下载
isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFileAndSaveStatus(AvailableLatestVersion, "", Settings.Startup.UpdateChannel);
if (isDownloadSuccessful) {
LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will install when application closes");
// 设置标志,在应用程序关闭时安装
Settings.Startup.IsAutoUpdate = true;
Settings.Startup.IsAutoUpdateWithSilence = true;
// 启动检查定时器
timerCheckAutoUpdateWithSilence.Start();
// 通知用户
MessageBox.Show("更新已下载完成,将在软件关闭时自动安装。", "更新已准备就绪", MessageBoxButton.OK, MessageBoxImage.Information);
} else {
LogHelper.WriteLogToFile("AutoUpdate | Update download failed", LogHelper.LogType.Error);
MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error);
}
break;
case HasNewUpdateWindow.UpdateResult.SkipVersion:
// 跳过该版本:记录到设置中
LogHelper.WriteLogToFile($"AutoUpdate | User chose to skip version {AvailableLatestVersion}");
// 记录要跳过的版本号
Settings.Startup.SkippedVersion = AvailableLatestVersion;
// 保存设置到文件
SaveSettingsToFile();
// 通知用户
MessageBox.Show($"已设置跳过版本 {AvailableLatestVersion},在下次发布新版本之前不会再提示更新。",
"已跳过此版本",
MessageBoxButton.OK,
MessageBoxImage.Information);
break;
}
} else {
AutoUpdateHelper.DeleteUpdatesFolder();
}
}
// 新增:崩溃后操作设置按钮事件
private void RadioCrashAction_Checked(object sender, RoutedEventArgs e)
{
if (RadioCrashSilentRestart != null && RadioCrashSilentRestart.IsChecked == true)
{
App.CrashAction = App.CrashActionType.SilentRestart;
}
else if (RadioCrashNoAction != null && RadioCrashNoAction.IsChecked == true)
{
App.CrashAction = App.CrashActionType.NoAction;
}
SaveSettingsToFile();
}
// 添加一个辅助方法,根据当前编辑模式设置光标
private void SetCursorBasedOnEditingMode(InkCanvas canvas)
{
if (Settings.Canvas.IsShowCursor) {
canvas.UseCustomCursor = true;
canvas.ForceCursor = true;
// 根据编辑模式设置不同的光标
if (canvas.EditingMode == InkCanvasEditingMode.EraseByPoint) {
canvas.Cursor = Cursors.Cross;
} else if (canvas.EditingMode == InkCanvasEditingMode.Ink) {
var sri = Application.GetResourceStream(new Uri("Resources/Cursors/Pen.cur", UriKind.Relative));
if (sri != null)
canvas.Cursor = new Cursor(sri.Stream);
} else if (canvas.EditingMode == InkCanvasEditingMode.Select) {
canvas.Cursor = Cursors.Cross;
}
// 确保光标可见,无论是鼠标、触控还是手写笔
System.Windows.Forms.Cursor.Show();
// 强制应用光标设置
canvas.ForceCursor = true;
// 确保手写笔模式下也能显示光标
if (Tablet.TabletDevices.Count > 0) {
foreach (TabletDevice device in Tablet.TabletDevices) {
if (device.Type == TabletDeviceType.Stylus) {
// 手写笔设备存在,强制显示光标
System.Windows.Forms.Cursor.Show();
break;
}
}
}
} else {
canvas.UseCustomCursor = false;
canvas.ForceCursor = false;
System.Windows.Forms.Cursor.Show();
}
}
// 鼠标输入
private void inkCanvas_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// 使用辅助方法设置光标
SetCursorBasedOnEditingMode(inkCanvas);
}
// 手写笔输入
private void inkCanvas_StylusDown(object sender, StylusDownEventArgs e)
{
// 使用辅助方法设置光标
SetCursorBasedOnEditingMode(inkCanvas);
}
// 触摸输入,不隐藏光标
private void inkCanvas_TouchDown(object sender, TouchEventArgs e)
{
// 使用辅助方法设置光标
SetCursorBasedOnEditingMode(inkCanvas);
}
// 触摸结束,恢复光标
private void inkCanvas_TouchUp(object sender, TouchEventArgs e)
{
// 使用辅助方法设置光标
SetCursorBasedOnEditingMode(inkCanvas);
// 确保光标可见
if (Settings.Canvas.IsShowCursor) {
inkCanvas.ForceCursor = true;
inkCanvas.UseCustomCursor = true;
System.Windows.Forms.Cursor.Show();
}
}
#endregion Definations and Loading
#region Navigation Sidebar Methods
// 侧边栏导航按钮事件处理
private void NavStartup_Click(object sender, RoutedEventArgs e)
{
// 切换到启动设置页面
ShowSettingsSection("startup");
}
private void NavCanvas_Click(object sender, RoutedEventArgs e)
{
// 切换到画布设置页面
ShowSettingsSection("canvas");
}
private void NavGesture_Click(object sender, RoutedEventArgs e)
{
// 切换到手势设置页面
ShowSettingsSection("gesture");
}
private void NavInkRecognition_Click(object sender, RoutedEventArgs e)
{
// 切换到墨迹识别设置页面
ShowSettingsSection("inkrecognition");
}
private void NavCrashAction_Click(object sender, RoutedEventArgs e)
{
// 切换到崩溃处理设置页面
ShowSettingsSection("crashaction");
}
private void NavPPT_Click(object sender, RoutedEventArgs e)
{
// 切换到PPT设置页面
ShowSettingsSection("ppt");
}
private void NavAdvanced_Click(object sender, RoutedEventArgs e)
{
// 切换到高级设置页面
ShowSettingsSection("advanced");
}
private void NavAutomation_Click(object sender, RoutedEventArgs e)
{
// 切换到自动化设置页面
ShowSettingsSection("automation");
}
private void NavRandomWindow_Click(object sender, RoutedEventArgs e)
{
// 切换到随机窗口设置页面
ShowSettingsSection("randomwindow");
}
private void NavAbout_Click(object sender, RoutedEventArgs e)
{
// 切换到关于页面
ShowSettingsSection("about");
}
// 新增:个性化设置
private void NavTheme_Click(object sender, RoutedEventArgs e)
{
// 切换到个性化设置页面
ShowSettingsSection("theme");
}
// 新增:快捷键设置
private void NavShortcuts_Click(object sender, RoutedEventArgs e)
{
// 切换到快捷键设置页面
ShowSettingsSection("shortcuts");
// 如果设置部分尚未快捷键
MessageBox.Show("设置功能正在开发中", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}
private void BtnCloseSettings_Click(object sender, RoutedEventArgs e)
{
// 关闭设置面板
BorderSettings.Visibility = Visibility.Collapsed;
// 设置蒙版为不可点击,并清除背景
BorderSettingsMask.IsHitTestVisible = false;
BorderSettingsMask.Background = null; // 确保清除蒙层背景
}
// 新增:折叠侧边栏
private void CollapseNavSidebar_Click(object sender, RoutedEventArgs e)
{
// 折叠/展开侧边栏
var columnDefinitions = ((Grid)BorderSettings.Child).ColumnDefinitions;
if (columnDefinitions[0].Width.Value == 50)
{
// 折叠侧边栏
columnDefinitions[0].Width = new GridLength(0);
}
else
{
// 展开侧边栏
columnDefinitions[0].Width = new GridLength(50);
}
}
// 新增:显示侧边栏
private void ShowNavSidebar_Click(object sender, RoutedEventArgs e)
{
// 确保侧边栏展开
var columnDefinitions = ((Grid)BorderSettings.Child).ColumnDefinitions;
columnDefinitions[0].Width = new GridLength(50);
}
// 辅助方法:显示指定的设置部分
private void ShowSettingsSection(string sectionTag)
{
// 显示设置面板
BorderSettings.Visibility = Visibility.Visible;
// 设置蒙版为可点击,并添加半透明背景
BorderSettingsMask.IsHitTestVisible = true;
BorderSettingsMask.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(1, 0, 0, 0));
// 获取SettingsPanelScrollViewer中的所有GroupBox
var stackPanel = SettingsPanelScrollViewer.Content as StackPanel;
if (stackPanel == null) return;
// 首先隐藏所有GroupBox
foreach (var child in stackPanel.Children)
{
if (child is GroupBox groupBox)
{
groupBox.Visibility = Visibility.Collapsed;
}
}
// 根据传入的sectionTag显示相应的设置部分
switch (sectionTag.ToLower())
{
case "startup":
// 显示启动设置
ShowGroupBoxByHeader(stackPanel, "启动");
break;
case "canvas":
// 显示画板和墨迹设置
ShowGroupBoxByHeader(stackPanel, "画板和墨迹");
break;
case "gesture":
// 显示手势设置
ShowGroupBoxByHeader(stackPanel, "手势");
break;
case "inkrecognition":
// 显示墨迹纠正设置
ShowGroupBoxByHeader(stackPanel, "墨迹纠正");
if (GroupBoxInkRecognition != null)
GroupBoxInkRecognition.Visibility = Visibility.Visible;
break;
case "crashaction":
// 显示崩溃后操作设置
ShowGroupBoxByHeader(stackPanel, "崩溃后操作");
break;
case "ppt":
// 显示PPT联动设置
ShowGroupBoxByHeader(stackPanel, "PPT联动");
break;
case "advanced":
// 显示高级设置
// 这里可能需要根据实际情况调整
break;
case "automation":
// 显示自动化设置
// 这里可能需要根据实际情况调整
break;
case "randomwindow":
// 显示随机窗口设置
if (GroupBoxRandWindow != null)
GroupBoxRandWindow.Visibility = Visibility.Visible;
break;
case "theme":
// 显示主题设置
if (GroupBoxAppearanceNewUI != null)
GroupBoxAppearanceNewUI.Visibility = Visibility.Visible;
break;
case "shortcuts":
// 显示快捷键设置
// 快捷键设置部分可能尚未实现
break;
case "about":
// 显示关于页面
ShowGroupBoxByHeader(stackPanel, "关于");
break;
default:
// 默认显示第一个GroupBox
if (stackPanel.Children.Count > 0 && stackPanel.Children[0] is GroupBox firstGroupBox)
{
firstGroupBox.Visibility = Visibility.Visible;
}
break;
}
// 滚动到顶部
SettingsPanelScrollViewer.ScrollToTop();
}
// 根据Header文本查找并显示GroupBox
private void ShowGroupBoxByHeader(StackPanel parent, string headerText)
{
foreach (var child in parent.Children)
{
if (child is GroupBox groupBox)
{
// 查找GroupBox的Header
if (groupBox.Header is TextBlock headerTextBlock &&
headerTextBlock.Text != null &&
headerTextBlock.Text.Contains(headerText))
{
groupBox.Visibility = Visibility.Visible;
return;
}
}
}
}
#endregion Navigation Sidebar Methods
}
}
-6
View File
@@ -1,6 +0,0 @@
namespace Ink_Canvas
{
internal class ConfigHelper
{
}
}
@@ -1,204 +0,0 @@
using Ink_Canvas.Helpers;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
using System.Windows.Controls;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private StrokeCollection[] strokeCollections = new StrokeCollection[101];
private bool[] whiteboadLastModeIsRedo = new bool[101];
private StrokeCollection lastTouchDownStrokeCollection = new StrokeCollection();
private int CurrentWhiteboardIndex = 1;
private int WhiteboardTotalCount = 1;
private TimeMachineHistory[][] TimeMachineHistories = new TimeMachineHistory[101][]; //最多99页,0用来存储非白板时的墨迹以便还原
private void SaveStrokes(bool isBackupMain = false) {
if (isBackupMain) {
var timeMachineHistory = timeMachine.ExportTimeMachineHistory();
TimeMachineHistories[0] = timeMachineHistory;
timeMachine.ClearStrokeHistory();
} else {
var timeMachineHistory = timeMachine.ExportTimeMachineHistory();
TimeMachineHistories[CurrentWhiteboardIndex] = timeMachineHistory;
timeMachine.ClearStrokeHistory();
}
}
private void ClearStrokes(bool isErasedByCode) {
_currentCommitType = CommitReason.ClearingCanvas;
if (isErasedByCode) _currentCommitType = CommitReason.CodeInput;
inkCanvas.Strokes.Clear();
_currentCommitType = CommitReason.UserInput;
}
private void RestoreStrokes(bool isBackupMain = false) {
try {
if (TimeMachineHistories[CurrentWhiteboardIndex] == null) return; //防止白板打开后不居中
if (isBackupMain) {
timeMachine.ImportTimeMachineHistory(TimeMachineHistories[0]);
foreach (var item in TimeMachineHistories[0]) ApplyHistoryToCanvas(item);
} else {
timeMachine.ImportTimeMachineHistory(TimeMachineHistories[CurrentWhiteboardIndex]);
foreach (var item in TimeMachineHistories[CurrentWhiteboardIndex]) ApplyHistoryToCanvas(item);
}
}
catch {
// ignored
}
}
private async void BtnWhiteBoardPageIndex_Click(object sender, EventArgs e) {
if (sender == BtnLeftPageListWB) {
if (BoardBorderLeftPageListView.Visibility == Visibility.Visible) {
AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView);
} else {
AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView);
RefreshBlackBoardSidePageListView();
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderLeftPageListView);
await Task.Delay(1);
ScrollViewToVerticalTop(
(ListViewItem)BlackBoardLeftSidePageListView.ItemContainerGenerator.ContainerFromIndex(
CurrentWhiteboardIndex - 1), BlackBoardLeftSidePageListScrollViewer);
}
} else if (sender == BtnRightPageListWB)
{
if (BoardBorderRightPageListView.Visibility == Visibility.Visible) {
AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView);
} else {
AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView);
RefreshBlackBoardSidePageListView();
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderRightPageListView);
await Task.Delay(1);
ScrollViewToVerticalTop(
(ListViewItem)BlackBoardRightSidePageListView.ItemContainerGenerator.ContainerFromIndex(
CurrentWhiteboardIndex - 1), BlackBoardRightSidePageListScrollViewer);
}
}
}
private void BtnWhiteBoardSwitchPrevious_Click(object sender, EventArgs e) {
if (CurrentWhiteboardIndex <= 1) return;
SaveStrokes();
ClearStrokes(true);
CurrentWhiteboardIndex--;
RestoreStrokes();
UpdateIndexInfoDisplay();
}
private void BtnWhiteBoardSwitchNext_Click(object sender, EventArgs e) {
Trace.WriteLine("113223234");
if (Settings.Automation.IsAutoSaveStrokesAtClear &&
inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true);
if (CurrentWhiteboardIndex >= WhiteboardTotalCount) {
// 在最后一页时,点击“新页面”按钮直接新增一页
BtnWhiteBoardAdd_Click(sender, e);
return;
}
SaveStrokes();
ClearStrokes(true);
CurrentWhiteboardIndex++;
RestoreStrokes();
UpdateIndexInfoDisplay();
}
private void BtnWhiteBoardAdd_Click(object sender, EventArgs e) {
if (WhiteboardTotalCount >= 99) return;
if (Settings.Automation.IsAutoSaveStrokesAtClear &&
inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true);
SaveStrokes();
ClearStrokes(true);
WhiteboardTotalCount++;
CurrentWhiteboardIndex++;
if (CurrentWhiteboardIndex != WhiteboardTotalCount)
for (var i = WhiteboardTotalCount; i > CurrentWhiteboardIndex; i--)
TimeMachineHistories[i] = TimeMachineHistories[i - 1];
UpdateIndexInfoDisplay();
if (WhiteboardTotalCount >= 99) BtnWhiteBoardAdd.IsEnabled = false;
if (BlackBoardLeftSidePageListView.Visibility == Visibility.Visible) {
RefreshBlackBoardSidePageListView();
}
}
private void BtnWhiteBoardDelete_Click(object sender, RoutedEventArgs e) {
ClearStrokes(true);
if (CurrentWhiteboardIndex != WhiteboardTotalCount)
for (var i = CurrentWhiteboardIndex; i <= WhiteboardTotalCount; i++)
TimeMachineHistories[i] = TimeMachineHistories[i + 1];
else
CurrentWhiteboardIndex--;
WhiteboardTotalCount--;
RestoreStrokes();
UpdateIndexInfoDisplay();
if (WhiteboardTotalCount < 99) BtnWhiteBoardAdd.IsEnabled = true;
}
private void UpdateIndexInfoDisplay() {
TextBlockWhiteBoardIndexInfo.Text =
$"{CurrentWhiteboardIndex}/{WhiteboardTotalCount}";
bool isLastPage = CurrentWhiteboardIndex == WhiteboardTotalCount;
bool isMaxPage = WhiteboardTotalCount >= 99;
// 设置按钮文本
BtnLeftWhiteBoardSwitchNextLabel.Text = isLastPage ? "新页面" : "下一页";
BtnRightWhiteBoardSwitchNextLabel.Text = isLastPage ? "新页面" : "下一页";
// 始终允许点击“下一页/新页面”按钮(除非已达最大页数)
BtnWhiteBoardSwitchNext.IsEnabled = !isMaxPage;
// 保持按钮常亮(高亮)
BtnLeftWhiteBoardSwitchNextGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnLeftWhiteBoardSwitchNextLabel.Opacity = 1;
BtnRightWhiteBoardSwitchNextGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnRightWhiteBoardSwitchNextLabel.Opacity = 1;
BtnWhiteBoardSwitchPrevious.IsEnabled = true;
if (CurrentWhiteboardIndex == 1) {
BtnWhiteBoardSwitchPrevious.IsEnabled = false;
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27));
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27));
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
} else {
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 1;
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 1;
}
BtnWhiteBoardDelete.IsEnabled = WhiteboardTotalCount != 1;
}
}
}
-94
View File
@@ -1,94 +0,0 @@
using Ink_Canvas.Helpers;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private void BoardChangeBackgroundColorBtn_MouseUp(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Canvas.UsingWhiteboard = !Settings.Canvas.UsingWhiteboard;
SaveSettingsToFile();
if (Settings.Canvas.UsingWhiteboard) {
if (inkColor == 5) lastBoardInkColor = 0;
ICCWaterMarkDark.Visibility = Visibility.Visible;
ICCWaterMarkWhite.Visibility = Visibility.Collapsed;
}
else {
if (inkColor == 0) lastBoardInkColor = 5;
ICCWaterMarkWhite.Visibility = Visibility.Visible;
ICCWaterMarkDark.Visibility = Visibility.Collapsed;
}
CheckColorTheme(true);
}
private void BoardEraserIcon_Click(object sender, RoutedEventArgs e) {
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint ||
inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke) {
if (BoardEraserSizePanel.Visibility == Visibility.Collapsed) {
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardEraserSizePanel);
} else {
AnimationsHelper.HideWithSlideAndFade(BoardEraserSizePanel);
}
} else {
forceEraser = true;
forcePointEraser = true;
// 使用统一的方法应用橡皮擦形状,确保一致性
ApplyCurrentEraserShape();
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
drawingShapeMode = 0;
inkCanvas_EditingModeChanged(inkCanvas, null);
CancelSingleFingerDragMode();
HideSubPanels("eraser");
}
}
private void BoardEraserIconByStrokes_Click(object sender, RoutedEventArgs e) {
//if (BoardEraserByStrokes.Background.ToString() == "#FF679CF4") {
// AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardDeleteIcon);
//}
//else {
forceEraser = true;
forcePointEraser = false;
inkCanvas.EraserShape = new EllipseStylusShape(5, 5);
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
drawingShapeMode = 0;
inkCanvas_EditingModeChanged(inkCanvas, null);
CancelSingleFingerDragMode();
HideSubPanels("eraserByStrokes");
//}
}
private void BoardSymbolIconDelete_MouseUp(object sender, RoutedEventArgs e) {
PenIcon_Click(null, null);
SymbolIconDelete_MouseUp(null, null);
}
private void BoardSymbolIconDeleteInkAndHistories_MouseUp(object sender, RoutedEventArgs e)
{
PenIcon_Click(null, null);
SymbolIconDelete_MouseUp(null, null);
if (Settings.Canvas.ClearCanvasAndClearTimeMachine == false) timeMachine.ClearStrokeHistory();
}
private void BoardLaunchEasiCamera_MouseUp(object sender, MouseButtonEventArgs e) {
ImageBlackboard_MouseUp(null, null);
SoftwareLauncher.LaunchEasiCamera("希沃视频展台");
}
private void BoardLaunchDesmos_MouseUp(object sender, MouseButtonEventArgs e) {
HideSubPanelsImmediately();
ImageBlackboard_MouseUp(null, null);
Process.Start("https://www.desmos.com/calculator?lang=zh-CN");
}
}
}
-45
View File
@@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ink_Canvas {
public static class XamlGraphicsIconGeometries {
public static string LinedCursorIcon =
"F1 M24,24z M0,0z M5.72106,15.9716L3.71327,3.00395C3.6389,2.6693 3.65747,2.41831 3.76902,2.25099 3.88057,2.08366 4.0479,2 4.271,2 4.4941,2 4.71711,2.07437 4.94021,2.2231 6.72502,3.39438 9.28149,5.10481 12.6094,7.3544 15.677,9.45526 18.1125,11.1285 19.9159,12.3742 20.1204,12.5229 20.2505,12.6995 20.3062,12.904 20.362,13.1085 20.3249,13.2944 20.1947,13.4618 20.0832,13.6105 19.8973,13.6849 19.637,13.6849L13.3902,13.6849 17.6291,19.7365C17.722,19.8666 17.75,20.0153 17.7128,20.1827 17.6942,20.3314 17.6198,20.4522 17.4897,20.5452L15.5654,21.8838C15.4353,21.9768 15.2865,22.0139 15.1192,21.9953 14.9704,21.9582 14.8496,21.8745 14.7566,21.7444L10.2389,15.2745 7.58956,19.9038C7.45942,20.1269 7.30144,20.2756 7.11552,20.35 6.92961,20.4058 6.75292,20.3872 6.5856,20.2942 6.43686,20.2013 6.34392,20.0339 6.30673,19.7922L6.00007,17.8959C5.88852,17.0779,5.79543,16.4364,5.72106,15.9716z";
public static string LinedPenIcon =
"F1 M24,24z M0,0z M16.996,2.34419L21.6823,7.00397C21.8941,7.23343 22,7.49819 22,7.79825 22,8.09831 21.8941,8.35425 21.6823,8.56606L10.8271,19.4212 4.57877,13.1994 15.4339,2.34419C15.6457,2.11473 15.9017,2 16.2018,2 16.5195,2 16.7842,2.11473 16.996,2.34419z M9.63571,20.5862L9.50333,20.6391 2.6725,21.9894C2.47834,22.0247 2.31066,21.9718 2.16946,21.8306 2.02825,21.707 1.97529,21.5481 2.01059,21.354L3.38736,14.5232C3.38736,14.4879,3.40502,14.4349,3.44032,14.3643L9.63571,20.5862z";
public static string SolidPenIcon =
"F1 M24,24z M0,0z M16.996,2.34419L21.6823,7.00397C21.8941,7.23343 22,7.49819 22,7.79825 22,8.09831 21.8941,8.35425 21.6823,8.56606L10.8271,19.4212 4.57877,13.1994 15.4339,2.34419C15.6457,2.11473 15.9017,2 16.2018,2 16.5195,2 16.7842,2.11473 16.996,2.34419z M9.63571,20.5862L9.50333,20.6391 2.6725,21.9894C2.47834,22.0247 2.31066,21.9718 2.16946,21.8306 2.02825,21.707 1.97529,21.5481 2.01059,21.354L3.38736,14.5232C3.38736,14.4879,3.40502,14.4349,3.44032,14.3643L9.63571,20.5862z";
public static string LinedEraserStrokeIcon =
"F1 M24,24z M0,0z M19.0625,7.99501C19.2863,7.99501 19.4861,8.06695 19.662,8.21083 19.8538,8.35471 19.9897,8.53856 20.0696,8.76237 20.4054,9.94539 20.7011,11.2563 20.9569,12.6951 21.1967,14.0859 21.3646,15.4368 21.4605,16.7477L21.4845,17.2993C21.5005,17.5551 21.5084,17.9068 21.5084,18.3544 21.5084,19.2017 21.2926,19.8412 20.861,20.2728 20.4453,20.7044 19.7099,21.0482 18.6548,21.3039 18.3191,21.3679 17.7836,20.4327 17.0482,18.4983 16.5845,20.8643 16.1129,22.0313 15.6333,21.9994 13.9227,21.9674 12.468,21.8954 11.269,21.7835L10.8134,21.7356C9.83817,21.6077 8.86297,21.4398 7.88778,21.232 7.1524,21.0721 6.32109,20.8563 5.39386,20.5845 4.61051,20.3447 3.97904,20.089 3.49944,19.8172 3.01984,19.5454 2.70809,19.2337 2.56421,18.882 2.40434,18.4823 2.50827,18.0746 2.87596,17.659L3.09176,17.3952 3.18769,17.2273 3.23565,17.1074 3.37954,16.8197 3.47544,16.5559 3.6433,15.9324 3.73923,15.6207 3.85912,15.1411 4.17088,13.5824 4.57853,11.1844 4.98621,9.05013C5.03417,8.79435 5.16203,8.55455 5.36986,8.33073 5.59367,8.10692 5.8255,7.99501 6.0653,7.99501L19.0625,7.99501z M14.4823,2C14.7861,2 15.0418,2.08793 15.2496,2.26378 15.4575,2.43963 15.5614,2.64746 15.5614,2.88726L15.5614,4.99751 19.0625,4.99751C19.3343,4.99751 19.5661,5.10142 19.7579,5.30925 19.9498,5.50109 20.0457,5.73289 20.0457,6.00467 20.0457,6.27644 19.9498,6.51624 19.7579,6.72407 19.5661,6.91591 19.3343,7.01183 19.0625,7.01183L6.0653,7.01183C5.79352,7.01183 5.55372,6.91591 5.34589,6.72407 5.15405,6.51624 5.05814,6.27644 5.05814,6.00467 5.05814,5.73289 5.15405,5.50109 5.34589,5.30925 5.55372,5.10142 5.79352,4.99751 6.0653,4.99751L9.56638,4.99751 9.56638,2.88726C9.56638,2.66345 9.65432,2.47161 9.83017,2.31174 10.022,2.15187 10.2538,2.05595 10.5256,2.02398L10.6455,2 14.4823,2z";
public static string SolidEraserStrokeIcon =
"F1 M24,24z M0,0z M19.0625,7.99501C19.2863,7.99501 19.4861,8.06695 19.662,8.21083 19.8538,8.35471 19.9897,8.53856 20.0696,8.76237 20.4054,9.94539 20.7011,11.2563 20.9569,12.6951 21.1967,14.0859 21.3646,15.4368 21.4605,16.7477L21.4845,17.2993C21.5005,17.5551 21.5084,17.9068 21.5084,18.3544 21.5084,19.2017 21.2926,19.8412 20.861,20.2728 20.4453,20.7044 19.7099,21.0482 18.6548,21.3039 18.3191,21.3679 17.7836,20.4327 17.0482,18.4983 16.5845,20.8643 16.1129,22.0313 15.6333,21.9994 13.9227,21.9674 12.468,21.8954 11.269,21.7835L10.8134,21.7356C9.83817,21.6077 8.86297,21.4398 7.88778,21.232 7.1524,21.0721 6.32109,20.8563 5.39386,20.5845 4.61051,20.3447 3.97904,20.089 3.49944,19.8172 3.01984,19.5454 2.70809,19.2337 2.56421,18.882 2.40434,18.4823 2.50827,18.0746 2.87596,17.659L3.09176,17.3952 3.18769,17.2273 3.23565,17.1074 3.37954,16.8197 3.47544,16.5559 3.6433,15.9324 3.73923,15.6207 3.85912,15.1411 4.17088,13.5824 4.57853,11.1844 4.98621,9.05013C5.03417,8.79435 5.16203,8.55455 5.36986,8.33073 5.59367,8.10692 5.8255,7.99501 6.0653,7.99501L19.0625,7.99501z M14.4823,2C14.7861,2 15.0418,2.08793 15.2496,2.26378 15.4575,2.43963 15.5614,2.64746 15.5614,2.88726L15.5614,4.99751 19.0625,4.99751C19.3343,4.99751 19.5661,5.10142 19.7579,5.30925 19.9498,5.50109 20.0457,5.73289 20.0457,6.00467 20.0457,6.27644 19.9498,6.51624 19.7579,6.72407 19.5661,6.91591 19.3343,7.01183 19.0625,7.01183L6.0653,7.01183C5.79352,7.01183 5.55372,6.91591 5.34589,6.72407 5.15405,6.51624 5.05814,6.27644 5.05814,6.00467 5.05814,5.73289 5.15405,5.50109 5.34589,5.30925 5.55372,5.10142 5.79352,4.99751 6.0653,4.99751L9.56638,4.99751 9.56638,2.88726C9.56638,2.66345 9.65432,2.47161 9.83017,2.31174 10.022,2.15187 10.2538,2.05595 10.5256,2.02398L10.6455,2 14.4823,2z";
public static string LinedEraserCircleIcon =
"F1 M24,24z M0,0z M15.0665,2.29557L21.6921,8.92118C21.8892,9.11823 21.9877,9.36453 21.9877,9.6601 21.9877,9.93924 21.8892,10.1773 21.6921,10.3744L10.3621,21.6798C10.165,21.8933 9.92694,22 9.6478,22 9.36865,22 9.12235,21.8933 8.90888,21.6798L2.30789,15.0788C2.11085,14.8654 2.01233,14.619 2.01233,14.3399 2.01233,14.0608 2.11085,13.8227 2.30789,13.6256L13.6133,2.29557C13.8103,2.09852 14.0485,2 14.3276,2 14.6232,2 14.8695,2.09852 15.0665,2.29557z M8.19458,11.5813C8.09606,11.4828 7.97292,11.4335 7.82514,11.4335 7.69377,11.4335 7.57883,11.4828 7.48031,11.5813L5.28818,13.7734C5.18965,13.8719 5.14041,13.9951 5.14041,14.1429 5.14041,14.2906 5.18965,14.4138 5.28818,14.5123L9.47539,18.6995C9.59033,18.8144 9.71347,18.8719 9.84483,18.8719 9.99261,18.8719 10.1158,18.8144 10.2143,18.6995L12.4064,16.5074C12.5049,16.4089 12.5542,16.2939 12.5542,16.1626 12.5542,16.0148 12.5049,15.8916 12.4064,15.7931L8.19458,11.5813z";
public static string SolidEraserCircleIcon =
"F1 M24,24z M0,0z M15.0665,2.29557L21.6921,8.92118C21.8892,9.11823 21.9877,9.36453 21.9877,9.6601 21.9877,9.93924 21.8892,10.1773 21.6921,10.3744L10.3621,21.6798C10.165,21.8933 9.92694,22 9.6478,22 9.36865,22 9.12235,21.8933 8.90888,21.6798L2.30789,15.0788C2.11085,14.8654 2.01233,14.619 2.01233,14.3399 2.01233,14.0608 2.11085,13.8227 2.30789,13.6256L13.6133,2.29557C13.8103,2.09852 14.0485,2 14.3276,2 14.6232,2 14.8695,2.09852 15.0665,2.29557z M8.19458,11.5813C8.09606,11.4828 7.97292,11.4335 7.82514,11.4335 7.69377,11.4335 7.57883,11.4828 7.48031,11.5813L5.28818,13.7734C5.18965,13.8719 5.14041,13.9951 5.14041,14.1429 5.14041,14.2906 5.18965,14.4138 5.28818,14.5123L9.47539,18.6995C9.59033,18.8144 9.71347,18.8719 9.84483,18.8719 9.99261,18.8719 10.1158,18.8144 10.2143,18.6995L12.4064,16.5074C12.5049,16.4089 12.5542,16.2939 12.5542,16.1626 12.5542,16.0148 12.5049,15.8916 12.4064,15.7931L8.19458,11.5813z";
public static string LinedLassoSelectIcon =
"F0 M24,24z M0,0z M21.1749,3.19033C21.2959,3.31432,21.3512,3.45083,21.3512,3.62667L21.3512,15.7344 18.9141,14.0608 18.9141,5.43716 5.30084,5.43716 5.30084,19.0505 14.7641,19.0505 15.0947,21.4876 3.49029,21.4876C3.31451,21.4876 3.178,21.4323 3.05397,21.3113 2.92046,21.1636 2.86368,21.0107 2.86368,20.8334L2.86368,3.62667C2.86368,3.44751 2.92108,3.30918 3.04695,3.18331 3.17285,3.0574 3.31118,3 3.49029,3L20.697,3C20.8743,3,21.0272,3.0568,21.1749,3.19033z M15.042,13.7475L16.02,20.0637C16.0562,20.2901,16.1015,20.6026,16.1559,21.001L16.3052,21.9247C16.3234,22.0424 16.3686,22.1239 16.4411,22.1692 16.5226,22.2144 16.6086,22.2235 16.6992,22.1963 16.7897,22.1601 16.8667,22.0877 16.9301,21.979L18.2205,19.7242 20.421,22.8755C20.4663,22.9389 20.5251,22.9796 20.5976,22.9978 20.6791,23.0068 20.7515,22.9887 20.8149,22.9434L21.7522,22.2914C21.8156,22.2461 21.8518,22.1873 21.8609,22.1148 21.879,22.0333 21.8654,21.9609 21.8201,21.8975L19.7555,18.9499 22.7981,18.9499C22.9249,18.9499 23.0154,18.9137 23.0698,18.8412 23.1332,18.7597 23.1512,18.6692 23.1241,18.5696 23.0969,18.47 23.0336,18.3839 22.934,18.3115 22.0556,17.7048 20.8693,16.8898 19.3751,15.8665 17.7542,14.7708 16.509,13.9377 15.6396,13.3672 15.531,13.2947 15.4224,13.2585 15.3137,13.2585 15.205,13.2585 15.1235,13.2992 15.0692,13.3807 15.0149,13.4622 15.0058,13.5845 15.042,13.7475z";
public static string SolidLassoSelectIcon =
"F0 M24,24z M0,0z M21.1749,3.19033C21.2959,3.31432,21.3512,3.45083,21.3512,3.62667L21.3512,15.7344 18.9141,14.0608 18.9141,5.43716 5.30084,5.43716 5.30084,19.0505 14.7641,19.0505 15.0947,21.4876 3.49029,21.4876C3.31451,21.4876 3.178,21.4323 3.05397,21.3113 2.92046,21.1636 2.86368,21.0107 2.86368,20.8334L2.86368,3.62667C2.86368,3.44751 2.92108,3.30918 3.04695,3.18331 3.17285,3.0574 3.31118,3 3.49029,3L20.697,3C20.8743,3,21.0272,3.0568,21.1749,3.19033z M15.042,13.7475L16.02,20.0637C16.0562,20.2901,16.1015,20.6026,16.1559,21.001L16.3052,21.9247C16.3234,22.0424 16.3686,22.1239 16.4411,22.1692 16.5226,22.2144 16.6086,22.2235 16.6992,22.1963 16.7897,22.1601 16.8667,22.0877 16.9301,21.979L18.2205,19.7242 20.421,22.8755C20.4663,22.9389 20.5251,22.9796 20.5976,22.9978 20.6791,23.0068 20.7515,22.9887 20.8149,22.9434L21.7522,22.2914C21.8156,22.2461 21.8518,22.1873 21.8609,22.1148 21.879,22.0333 21.8654,21.9609 21.8201,21.8975L19.7555,18.9499 22.7981,18.9499C22.9249,18.9499 23.0154,18.9137 23.0698,18.8412 23.1332,18.7597 23.1512,18.6692 23.1241,18.5696 23.0969,18.47 23.0336,18.3839 22.934,18.3115 22.0556,17.7048 20.8693,16.8898 19.3751,15.8665 17.7542,14.7708 16.509,13.9377 15.6396,13.3672 15.531,13.2947 15.4224,13.2585 15.3137,13.2585 15.205,13.2585 15.1235,13.2992 15.0692,13.3807 15.0149,13.4622 15.0058,13.5845 15.042,13.7475z";
public static string DisabledGestureIcon =
"F0 M24,24z M0,0z M7.82154,10.0753L7.82154,3.74613C7.82154,3.06603 8.08946,2.40655 8.57377,1.92224 9.05808,1.43793 9.70726,1.17001 10.3977,1.17001 11.0881,1.17001 11.7372,1.43793 12.2216,1.92224 12.7059,2.40655 12.9738,3.05573 12.9738,3.74613L12.9738,6.37308C13.1415,6.33947 13.3139,6.32225 13.489,6.32225 14.1794,6.32225 14.8286,6.59016 15.3129,7.07447 15.4484,7.21001 15.567,7.35845 15.6675,7.5171 15.9551,7.40916 16.2634,7.35269 16.5803,7.35269 17.2707,7.35269 17.9199,7.62061 18.4042,8.10492 18.5461,8.24683 18.6695,8.4029 18.7729,8.57001 19.6856,8.26338 20.7674,8.45871 21.4647,9.15599 21.949,9.6403 22.2169,10.2998 22.2169,10.9799L22.2169,15.6169C22.2169,17.5438 21.4647,19.3574 20.1045,20.7176 18.7443,22.0778 16.9307,22.83 15.0038,22.83L13.149,22.83 13.1799,22.8094 12.8398,22.8094C11.7682,22.7579 10.7068,22.4694 9.75878,21.9541 8.70773,21.3874 7.81124,20.563 7.15175,19.5738L6.94566,19.2647C6.60562,18.7494 5.49273,16.8019 3.52458,13.3087 3.19484,12.7213 3.1021,12.0412 3.27727,11.3818 3.45245,10.7326 3.86463,10.1761 4.44168,9.83608 5.00842,9.49604 5.66791,9.35177 6.31709,9.43421 6.86548,9.50385 7.39181,9.7279 7.82154,10.0753z M10.037,3.38547C10.1297,3.28243 10.2637,3.23091 10.3977,3.23091 10.5316,3.23091 10.6656,3.29273 10.7583,3.38547 10.8614,3.47821 10.9129,3.61217 10.9129,3.74613L10.9129,11.4745C10.9129,12.0412 11.3766,12.5049 11.9433,12.5049 12.5101,12.5049 12.9738,12.0412 12.9738,11.4745L12.9738,8.89836C12.9738,8.7644 13.0356,8.63045 13.1283,8.53771 13.2211,8.43466 13.355,8.38314 13.489,8.38314 13.623,8.38314 13.7569,8.44497 13.8497,8.53771 13.9527,8.63045 14.0042,8.7644 14.0042,8.89836L14.0042,11.4745C14.0042,12.0412 14.4679,12.5049 15.0347,12.5049 15.6014,12.5049 16.0651,12.0412 16.0651,11.4745L16.0651,9.92881C16.0651,9.79485 16.1269,9.66089 16.2197,9.56815 16.3124,9.46511 16.4464,9.41359 16.5803,9.41359 16.7143,9.41359 16.8483,9.47541 16.941,9.56815 17.044,9.66089 17.0956,9.79485 17.0956,9.92881L17.0956,10.5869C17.0752,10.7163 17.0646,10.8477 17.0646,10.9799 17.0646,11.0661 17.0754,11.1499 17.0956,11.2301L17.0956,11.4745C17.0956,12.0412 17.5593,12.5049 18.126,12.5049 18.6928,12.5049 19.1565,12.0412 19.1565,11.4745L19.1565,10.8128C19.1834,10.7399 19.2266,10.6727 19.2801,10.6192 19.4759,10.4234 19.8159,10.4234 20.0117,10.6192 20.1148,10.712 20.1663,10.8459 20.1663,10.9799L20.1663,15.6169C20.1663,16.9977 19.6408,18.296 18.6618,19.2647 17.6829,20.2333 16.3949,20.7691 15.0141,20.7691L13.1593,20.7691C12.3143,20.7691 11.4796,20.5527 10.7274,20.1509 9.98548,19.749 9.3363,19.1616 8.8726,18.4506L8.66651,18.1415C8.35737,17.6675 7.23419,15.7096 5.31756,12.2988 5.24543,12.1752 5.23512,12.0412 5.26604,11.9073 5.30725,11.7733 5.38969,11.6703 5.50304,11.5981 5.66791,11.4951 5.874,11.4539 6.06978,11.4745 6.26557,11.5054 6.45105,11.5878 6.59531,11.7321L8.11007,13.2469C8.49419,13.631 9.10425,13.648 9.50833,13.2978 9.73651,13.1084 9.88244,12.8229 9.88244,12.5049L9.88244,3.74613C9.88244,3.61217,9.94426,3.47821,10.037,3.38547z M2.99905,6.31195L1.78313,4.65293 2.61779,4.04497C3.46275,3.4267,4.37985,2.89087,5.33817,2.46838L6.27587,2.0459 7.12084,3.93162 6.18313,4.3541C5.35878,4.72506,4.56533,5.17846,3.83372,5.71429L2.99905,6.32225 2.99905,6.31195z M18.2806,5.20935L19.1565,5.75549 20.259,4.01404 19.3831,3.4679C18.1157,2.67446,16.7452,2.0768,15.3026,1.68523L14.303,1.41731 13.7672,3.40607 14.7667,3.67399C16.0033,4.00373,17.1883,4.51895,18.2806,5.20935z";
public static string EnabledGestureIcon =
"F1 M24,24z M0,0z M7.29844,9.85586L7.29844,3.52668C7.29844,2.84658 7.56636,2.1871 8.05067,1.70279 8.53498,1.21848 9.18416,0.950562 9.87456,0.950562 10.565,0.950562 11.2141,1.21848 11.6984,1.70279 12.1828,2.1871 12.4507,2.83628 12.4507,3.52668L12.4507,6.15363C12.6184,6.12002 12.7908,6.10279 12.9659,6.10279 13.6563,6.10279 14.3055,6.37071 14.7898,6.85502 14.9253,6.99055 15.0439,7.139 15.1444,7.29765 15.432,7.18971 15.7403,7.13324 16.0572,7.13324 16.7476,7.13324 17.3968,7.40116 17.8811,7.88547 18.023,8.02738 18.1464,8.18344 18.2498,8.35055 19.1625,8.04393 20.2443,8.23925 20.9416,8.93654 21.4259,9.42085 21.6938,10.0803 21.6938,10.7604L21.6938,14.2958C21.1174,13.741,20.4192,13.3118,19.6432,13.0524L19.6432,10.7604C19.6432,10.6265 19.5917,10.4925 19.4886,10.3998 19.2928,10.204 18.9528,10.204 18.757,10.3998 18.7035,10.4532 18.6603,10.5204 18.6334,10.5934L18.6334,11.255C18.6334,11.8218 18.1697,12.2855 17.6029,12.2855 17.0362,12.2855 16.5725,11.8218 16.5725,11.255L16.5725,11.0106C16.5523,10.9304 16.5415,10.8466 16.5415,10.7604 16.5415,10.6283 16.5521,10.4969 16.5725,10.3674L16.5725,9.70936C16.5725,9.5754 16.5209,9.44144 16.4179,9.3487 16.3252,9.25596 16.1912,9.19413 16.0572,9.19413 15.9233,9.19413 15.7893,9.24566 15.6966,9.3487 15.6038,9.44144 15.542,9.5754 15.542,9.70936L15.542,11.255C15.542,11.8218 15.0783,12.2855 14.5116,12.2855 13.9448,12.2855 13.4811,11.8218 13.4811,11.255L13.4811,8.67891C13.4811,8.54495 13.4296,8.41099 13.3266,8.31825 13.2338,8.22551 13.0999,8.16369 12.9659,8.16369 12.8319,8.16369 12.698,8.21521 12.6052,8.31825 12.5125,8.41099 12.4507,8.54495 12.4507,8.67891L12.4507,11.255C12.4507,11.8218 11.987,12.2855 11.4202,12.2855 10.8535,12.2855 10.3898,11.8218 10.3898,11.255L10.3898,3.52668C10.3898,3.39272 10.3383,3.25876 10.2352,3.16602 10.1425,3.07328 10.0085,3.01145 9.87456,3.01145 9.7406,3.01145 9.60664,3.06298 9.5139,3.16602 9.42116,3.25876 9.35933,3.39272 9.35933,3.52668L9.35933,12.2855C9.35933,12.6034 9.21341,12.8889 8.98523,13.0783 8.58114,13.4285 7.97109,13.4115 7.58697,13.0274L6.07221,11.5127C5.92795,11.3684 5.74247,11.286 5.54668,11.255 5.3509,11.2344 5.14481,11.2756 4.97994,11.3787 4.86659,11.4508 4.78415,11.5539 4.74293,11.6878 4.71202,11.8218 4.72232,11.9557 4.79446,12.0794 6.71109,15.4902 7.83427,17.448 8.14341,17.922L8.3495,18.2312C8.8132,18.9422 9.46238,19.5295 10.2043,19.9314 10.9565,20.3333 11.7912,20.5497 12.6362,20.5497L12.9829,20.5497C13.3696,21.3681 13.9542,22.0748 14.6748,22.608 14.6102,22.6097 14.5455,22.6106 14.4807,22.6106L12.6258,22.6106 12.6568,22.59 12.3167,22.59C11.2451,22.5384 10.1837,22.2499 9.23568,21.7347 8.18463,21.1679 7.28814,20.3436 6.62865,19.3544L6.42256,19.0452C6.08251,18.53 4.96963,16.5824 3.00148,13.0892 2.67174,12.5019 2.579,11.8218 2.75417,11.1623 2.92935,10.5131 3.34153,9.95668 3.91858,9.61663 4.48532,9.27658 5.14481,9.13232 5.79399,9.21476 6.34238,9.28439 6.86871,9.50845 7.29844,9.85586z M2.47595,6.0925L1.26003,4.43348 2.09469,3.82551C2.93965,3.20725,3.85675,2.67141,4.81507,2.24893L5.75277,1.82645 6.59774,3.71216 5.66003,4.13465C4.83567,4.50561,4.04223,4.959,3.31061,5.49484L2.47595,6.1028 2.47595,6.0925z M17.7575,4.9899L18.6334,5.53604 19.7359,3.79458 18.86,3.24845C17.5926,2.455,16.2221,1.85734,14.7795,1.46577L13.7799,1.19786 13.2441,3.18662 14.2436,3.45454C15.4802,3.78428,16.6652,4.2995,17.7575,4.9899z";
public static string EnabledGestureIconBadgeCheck =
"M22.74,18.2234C22.74,20.8888 20.5793,23.0494 17.914,23.0494 15.2487,23.0494 13.088,20.8888 13.088,18.2234 13.088,15.5581 15.2487,13.3975 17.914,13.3975 20.5793,13.3975 22.74,15.5581 22.74,18.2234z M21.1673,15.8009C21.4651,16.0889,21.473,16.5637,21.1851,16.8614L17.5425,20.6282C17.4012,20.7743 17.2066,20.8568 17.0034,20.8568 16.8001,20.8568 16.6055,20.7743 16.4642,20.6282L14.6429,18.7448C14.355,18.447 14.3629,17.9722 14.6607,17.6843 14.9585,17.3963 15.4333,17.4043 15.7212,17.7021L17.0034,19.0279 20.1068,15.8187C20.3947,15.5209,20.8695,15.513,21.1673,15.8009z";
}
}
@@ -1,35 +0,0 @@
using Ink_Canvas.Helpers;
using System;
using System.Linq;
using System.Threading;
using System.Windows;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private int lastNotificationShowTime = 0;
private int notificationShowTime = 2500;
public static void ShowNewMessage(string notice, bool isShowImmediately = true) {
(Application.Current?.Windows.Cast<Window>().FirstOrDefault(window => window is MainWindow) as MainWindow)
?.ShowNotification(notice, isShowImmediately);
}
public void ShowNotification(string notice, bool isShowImmediately = true) {
try {
lastNotificationShowTime = Environment.TickCount;
TextBlockNotice.Text = notice;
AnimationsHelper.ShowWithSlideFromBottomAndFade(GridNotifications);
new Thread(new ThreadStart(() => {
Thread.Sleep(notificationShowTime + 300);
if (Environment.TickCount - lastNotificationShowTime >= notificationShowTime)
Application.Current.Dispatcher.Invoke(() => {
AnimationsHelper.HideWithSlideAndFade(GridNotifications);
});
})).Start();
}
catch { }
}
}
}
File diff suppressed because it is too large Load Diff
-131
View File
@@ -1,131 +0,0 @@
using System;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private void SaveScreenShot(bool isHideNotification, string fileName = null) {
var savePath = Settings.Automation.IsSaveScreenshotsInDateFolders
? GetDateFolderPath(fileName)
: GetDefaultFolderPath();
CaptureAndSaveScreenshot(savePath, isHideNotification);
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot)
SaveInkCanvasStrokes(false, false);
}
private void SaveScreenShotToDesktop() {
var desktopPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
$"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png");
CaptureAndSaveScreenshot(desktopPath, false);
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot)
SaveInkCanvasStrokes(false, false);
}
// 提取公共的截图和保存逻辑
private void CaptureAndSaveScreenshot(string savePath, bool isHideNotification) {
var rc = System.Windows.Forms.SystemInformation.VirtualScreen;
using (var bitmap = new System.Drawing.Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb))
using (var memoryGraphics = System.Drawing.Graphics.FromImage(bitmap)) {
memoryGraphics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy);
var directory = Path.GetDirectoryName(savePath);
if (!Directory.Exists(directory)) {
Directory.CreateDirectory(directory);
}
try {
// 新增双重目录检查
Directory.CreateDirectory(directory); // 防止多线程场景下的竞争条件
bitmap.Save(savePath, ImageFormat.Png);
}
catch (Exception ex) when (ex is IOException ||
ex is UnauthorizedAccessException ||
ex is ExternalException) { // 新增GDI+异常捕获
// 改进备用路径处理
var docPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Auto Saved - Screenshots",
DateTime.Now.ToString("yyyyMMdd"),
Path.GetFileNameWithoutExtension(savePath) + "_retry.png"); // 添加重试后缀
try {
var docDir = Path.GetDirectoryName(docPath);
Directory.CreateDirectory(docDir);
bitmap.Save(docPath, ImageFormat.Png);
savePath = docPath;
}
catch (Exception fallbackEx) {
// 最终错误处理
if (!isHideNotification) {
ShowNotification($"截图保存失败: {fallbackEx.Message}");
}
return;
}
}
}
if (!isHideNotification) {
try {
ShowNotification($"截图成功保存至 {savePath}");
}
catch {
// 防止通知系统自身异常导致崩溃
}
}
}
// 获取日期文件夹路径
private string GetDateFolderPath(string fileName) {
var basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Saves");
var dateFolder = DateTime.Now.ToString("yyyyMMdd");
var fullPath = Path.Combine(basePath, "Auto Saved - Screenshots", dateFolder);
try {
if (!Directory.Exists(fullPath)) {
Directory.CreateDirectory(fullPath);
}
}
catch (Exception ex) when
(ex is IOException ||
ex is UnauthorizedAccessException)
{
// 如果创建失败则使用软件根目录作为最终备选
basePath = AppDomain.CurrentDomain.BaseDirectory;
fullPath = Path.Combine(basePath, "Auto Saved - Screenshots", dateFolder);
Directory.CreateDirectory(fullPath);
}
return Path.Combine(fullPath, $"{fileName}.png");
}
private string GetDefaultFolderPath() {
var basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Saves");
var screenshotsFolder = Path.Combine(basePath, "Auto Saved - Screenshots");
try {
if (!Directory.Exists(screenshotsFolder)) {
Directory.CreateDirectory(screenshotsFolder);
}
}
catch (Exception) {
// 如果创建失败则使用文档目录
basePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
screenshotsFolder = Path.Combine(basePath, "Auto Saved - Screenshots");
Directory.CreateDirectory(screenshotsFolder);
}
return Path.Combine(
screenshotsFolder,
$"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png");
}
}
}
@@ -1,426 +0,0 @@
using iNKORE.UI.WPF.Modern.Controls;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Point = System.Windows.Point;
namespace Ink_Canvas {
public partial class MainWindow : Window {
#region Floating Control
private object lastBorderMouseDownObject;
private void Border_MouseDown(object sender, MouseButtonEventArgs e) {
// 如果发送者是 RandomDrawPanel 或 SingleDrawPanel,且它们被隐藏,则不处理事件
if (sender is SimpleStackPanel panel) {
if ((panel == RandomDrawPanel || panel == SingleDrawPanel) &&
panel.Visibility != Visibility.Visible) {
return;
}
}
lastBorderMouseDownObject = sender;
}
private bool isStrokeSelectionCloneOn = false;
private void BorderStrokeSelectionClone_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
if (isStrokeSelectionCloneOn) {
BorderStrokeSelectionClone.Background = Brushes.Transparent;
isStrokeSelectionCloneOn = false;
}
else {
BorderStrokeSelectionClone.Background = new SolidColorBrush(StringToColor("#FF1ED760"));
isStrokeSelectionCloneOn = true;
}
}
private void BorderStrokeSelectionCloneToNewBoard_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
var strokes = inkCanvas.GetSelectedStrokes();
inkCanvas.Select(new StrokeCollection());
strokes = strokes.Clone();
BtnWhiteBoardAdd_Click(null, null);
inkCanvas.Strokes.Add(strokes);
}
private void BorderStrokeSelectionDelete_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
SymbolIconDelete_MouseUp(sender, e);
}
private void GridPenWidthDecrease_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
ChangeStrokeThickness(0.8);
}
private void GridPenWidthIncrease_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
ChangeStrokeThickness(1.25);
}
private void ChangeStrokeThickness(double multipler) {
foreach (var stroke in inkCanvas.GetSelectedStrokes()) {
var newWidth = stroke.DrawingAttributes.Width * multipler;
var newHeight = stroke.DrawingAttributes.Height * multipler;
if (!(newWidth >= DrawingAttributes.MinWidth) || !(newWidth <= DrawingAttributes.MaxWidth)
|| !(newHeight >= DrawingAttributes.MinHeight) ||
!(newHeight <= DrawingAttributes.MaxHeight)) continue;
stroke.DrawingAttributes.Width = newWidth;
stroke.DrawingAttributes.Height = newHeight;
}
if (DrawingAttributesHistory.Count > 0)
{
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
foreach (var item in DrawingAttributesHistoryFlag)
{
item.Value.Clear();
}
}
}
private void GridPenWidthRestore_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
foreach (var stroke in inkCanvas.GetSelectedStrokes()) {
stroke.DrawingAttributes.Width = inkCanvas.DefaultDrawingAttributes.Width;
stroke.DrawingAttributes.Height = inkCanvas.DefaultDrawingAttributes.Height;
}
}
private void ImageFlipHorizontal_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
var m = new Matrix();
// Find center of element and then transform to get current location of center
var fe = e.Source as FrameworkElement;
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.ScaleAt(-1, 1, center.X, center.Y); // 缩放
var targetStrokes = inkCanvas.GetSelectedStrokes();
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
if (DrawingAttributesHistory.Count > 0)
{
//var collecion = new StrokeCollection();
//foreach (var item in DrawingAttributesHistory)
//{
// collecion.Add(item.Key);
//}
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
foreach (var item in DrawingAttributesHistoryFlag)
{
item.Value.Clear();
}
}
//updateBorderStrokeSelectionControlLocation();
}
private void ImageFlipVertical_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
var m = new Matrix();
// Find center of element and then transform to get current location of center
var fe = e.Source as FrameworkElement;
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.ScaleAt(1, -1, center.X, center.Y); // 缩放
var targetStrokes = inkCanvas.GetSelectedStrokes();
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
if (DrawingAttributesHistory.Count > 0)
{
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
foreach (var item in DrawingAttributesHistoryFlag)
{
item.Value.Clear();
}
}
}
private void ImageRotate45_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
var m = new Matrix();
// Find center of element and then transform to get current location of center
var fe = e.Source as FrameworkElement;
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.RotateAt(45, center.X, center.Y); // 旋转
var targetStrokes = inkCanvas.GetSelectedStrokes();
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
if (DrawingAttributesHistory.Count > 0)
{
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
foreach (var item in DrawingAttributesHistoryFlag)
{
item.Value.Clear();
}
}
}
private void ImageRotate90_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
var m = new Matrix();
// Find center of element and then transform to get current location of center
var fe = e.Source as FrameworkElement;
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.RotateAt(90, center.X, center.Y); // 旋转
var targetStrokes = inkCanvas.GetSelectedStrokes();
foreach (var stroke in targetStrokes) stroke.Transform(m, false);
if (DrawingAttributesHistory.Count > 0)
{
var collecion = new StrokeCollection();
foreach (var item in DrawingAttributesHistory)
{
collecion.Add(item.Key);
}
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
foreach (var item in DrawingAttributesHistoryFlag)
{
item.Value.Clear();
}
}
}
#endregion
private bool isGridInkCanvasSelectionCoverMouseDown = false;
private StrokeCollection StrokesSelectionClone = new StrokeCollection();
private void GridInkCanvasSelectionCover_MouseDown(object sender, MouseButtonEventArgs e) {
isGridInkCanvasSelectionCoverMouseDown = true;
}
private void GridInkCanvasSelectionCover_MouseUp(object sender, MouseButtonEventArgs e) {
if (!isGridInkCanvasSelectionCoverMouseDown) return;
isGridInkCanvasSelectionCoverMouseDown = false;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
}
private void BtnSelect_Click(object sender, RoutedEventArgs e) {
forceEraser = true;
drawingShapeMode = 0;
inkCanvas.IsManipulationEnabled = false;
if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) {
if (inkCanvas.GetSelectedStrokes().Count == inkCanvas.Strokes.Count) {
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
}
else {
var selectedStrokes = new StrokeCollection();
foreach (var stroke in inkCanvas.Strokes)
if (stroke.GetBounds().Width > 0 && stroke.GetBounds().Height > 0)
selectedStrokes.Add(stroke);
inkCanvas.Select(selectedStrokes);
}
}
else {
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
}
}
private double BorderStrokeSelectionControlWidth = 490.0;
private double BorderStrokeSelectionControlHeight = 80.0;
private bool isProgramChangeStrokeSelection = false;
private void inkCanvas_SelectionChanged(object sender, EventArgs e) {
if (isProgramChangeStrokeSelection) return;
if (inkCanvas.GetSelectedStrokes().Count == 0) {
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
}
else {
GridInkCanvasSelectionCover.Visibility = Visibility.Visible;
BorderStrokeSelectionClone.Background = Brushes.Transparent;
isStrokeSelectionCloneOn = false;
updateBorderStrokeSelectionControlLocation();
}
}
private void updateBorderStrokeSelectionControlLocation() {
var borderLeft = (inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Right -
BorderStrokeSelectionControlWidth) / 2;
var borderTop = inkCanvas.GetSelectionBounds().Bottom + 1;
if (borderLeft < 0) borderLeft = 0;
if (borderTop < 0) borderTop = 0;
if (Width - borderLeft < BorderStrokeSelectionControlWidth || double.IsNaN(borderLeft))
borderLeft = Width - BorderStrokeSelectionControlWidth;
if (Height - borderTop < BorderStrokeSelectionControlHeight || double.IsNaN(borderTop))
borderTop = Height - BorderStrokeSelectionControlHeight;
if (borderTop > 60) borderTop -= 60;
BorderStrokeSelectionControl.Margin = new Thickness(borderLeft, borderTop, 0, 0);
}
private void GridInkCanvasSelectionCover_ManipulationStarting(object sender, ManipulationStartingEventArgs e) {
e.Mode = ManipulationModes.All;
}
private void GridInkCanvasSelectionCover_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
if (StrokeManipulationHistory?.Count > 0)
{
timeMachine.CommitStrokeManipulationHistory(StrokeManipulationHistory);
foreach (var item in StrokeManipulationHistory)
{
StrokeInitialHistory[item.Key] = item.Value.Item2;
}
StrokeManipulationHistory = null;
}
if (DrawingAttributesHistory.Count > 0)
{
timeMachine.CommitStrokeDrawingAttributesHistory(DrawingAttributesHistory);
DrawingAttributesHistory = new Dictionary<Stroke, Tuple<DrawingAttributes, DrawingAttributes>>();
foreach (var item in DrawingAttributesHistoryFlag)
{
item.Value.Clear();
}
}
}
private void GridInkCanvasSelectionCover_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) {
// 手掌擦时禁止移动/缩放
if (isLastTouchEraser || inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
return;
// 三指及以上禁止缩放
bool disableScale = dec.Count >= 3;
try {
if (dec.Count >= 1) {
var md = e.DeltaManipulation;
var trans = md.Translation; // 获得位移矢量
var rotate = md.Rotation; // 获得旋转角度
var scale = md.Scale; // 获得缩放倍数
var m = new Matrix();
// Find center of element and then transform to get current location of center
var fe = e.Source as FrameworkElement;
var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.Translate(trans.X, trans.Y); // 移动
if (!disableScale)
m.ScaleAt(scale.X, scale.Y, center.X, center.Y); // 缩放
var strokes = inkCanvas.GetSelectedStrokes();
if (StrokesSelectionClone.Count != 0)
strokes = StrokesSelectionClone;
else if (Settings.Gesture.IsEnableTwoFingerRotationOnSelection)
m.RotateAt(rotate, center.X, center.Y); // 旋转
foreach (var stroke in strokes) {
stroke.Transform(m, false);
try {
stroke.DrawingAttributes.Width *= md.Scale.X;
stroke.DrawingAttributes.Height *= md.Scale.Y;
}
catch { }
}
updateBorderStrokeSelectionControlLocation();
}
}
catch { }
}
private void GridInkCanvasSelectionCover_TouchDown(object sender, TouchEventArgs e) { }
private void GridInkCanvasSelectionCover_TouchUp(object sender, TouchEventArgs e) { }
private Point lastTouchPointOnGridInkCanvasCover = new Point(0, 0);
private void GridInkCanvasSelectionCover_PreviewTouchDown(object sender, TouchEventArgs e) {
dec.Add(e.TouchDevice.Id);
//设备1个的时候,记录中心点
if (dec.Count == 1) {
var touchPoint = e.GetTouchPoint(null);
centerPoint = touchPoint.Position;
lastTouchPointOnGridInkCanvasCover = touchPoint.Position;
if (isStrokeSelectionCloneOn) {
var strokes = inkCanvas.GetSelectedStrokes();
isProgramChangeStrokeSelection = true;
inkCanvas.Select(new StrokeCollection());
StrokesSelectionClone = strokes.Clone();
inkCanvas.Select(strokes);
isProgramChangeStrokeSelection = false;
inkCanvas.Strokes.Add(StrokesSelectionClone);
}
else {
// 新增:启动套索选择模式
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
inkCanvas.Select(new StrokeCollection());
}
}
}
private void GridInkCanvasSelectionCover_PreviewTouchUp(object sender, TouchEventArgs e) {
dec.Remove(e.TouchDevice.Id);
if (dec.Count >= 1) return;
isProgramChangeStrokeSelection = false;
if (lastTouchPointOnGridInkCanvasCover == e.GetTouchPoint(null).Position) {
if (!(lastTouchPointOnGridInkCanvasCover.X < inkCanvas.GetSelectionBounds().Left) &&
!(lastTouchPointOnGridInkCanvasCover.Y < inkCanvas.GetSelectionBounds().Top) &&
!(lastTouchPointOnGridInkCanvasCover.X > inkCanvas.GetSelectionBounds().Right) &&
!(lastTouchPointOnGridInkCanvasCover.Y > inkCanvas.GetSelectionBounds().Bottom)) return;
inkCanvas.Select(new StrokeCollection());
StrokesSelectionClone = new StrokeCollection();
}
else if (inkCanvas.GetSelectedStrokes().Count == 0) {
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
StrokesSelectionClone = new StrokeCollection();
}
else {
GridInkCanvasSelectionCover.Visibility = Visibility.Visible;
StrokesSelectionClone = new StrokeCollection();
}
}
}
}
@@ -1,999 +0,0 @@
using Ink_Canvas.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using Point = System.Windows.Point;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private StrokeCollection newStrokes = new StrokeCollection();
private List<Circle> circles = new List<Circle>();
private const double LINE_STRAIGHTEN_THRESHOLD = 0.20; // 默认灵敏度阈值,与UI默认值对应
private void inkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e) {
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = false;
try {
inkCanvas.Opacity = 1;
// 应用屏蔽压感功能 - 如果启用,所有笔画都使用统一粗细
if (Settings.Canvas.DisablePressure) {
var uniformPoints = new StylusPointCollection();
foreach (StylusPoint point in e.Stroke.StylusPoints) {
StylusPoint newPoint = new StylusPoint(point.X, point.Y, 0.5f); // 统一压感值为0.5
uniformPoints.Add(newPoint);
}
e.Stroke.StylusPoints = uniformPoints;
}
// 应用压感触屏模式 - 如果启用并且检测到触屏输入
else if (Settings.Canvas.EnablePressureTouchMode) {
bool isTouchInput = true;
foreach (StylusPoint point in e.Stroke.StylusPoints) {
// 检测是否为压感笔输入(压感笔的PressureFactor不等于0.5或0
if ((point.PressureFactor > 0.501 || point.PressureFactor < 0.5) && point.PressureFactor != 0) {
isTouchInput = false;
break;
}
}
// 如果是触屏输入,则应用模拟压感
if (isTouchInput) {
switch (Settings.Canvas.InkStyle) {
case 1:
if (penType == 0)
try {
var stylusPoints = new StylusPointCollection();
var n = e.Stroke.StylusPoints.Count - 1;
for (var i = 0; i <= n; i++) {
var speed = GetPointSpeed(e.Stroke.StylusPoints[Math.Max(i - 1, 0)].ToPoint(),
e.Stroke.StylusPoints[i].ToPoint(),
e.Stroke.StylusPoints[Math.Min(i + 1, n)].ToPoint());
var point = new StylusPoint();
if (speed >= 0.25)
point.PressureFactor = (float)(0.5 - 0.3 * (Math.Min(speed, 1.5) - 0.3) / 1.2);
else if (speed >= 0.05)
point.PressureFactor = (float)0.5;
else
point.PressureFactor = (float)(0.5 + 0.4 * (0.05 - speed) / 0.05);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
e.Stroke.StylusPoints = stylusPoints;
}
catch { }
break;
case 0:
if (penType == 0)
try {
var stylusPoints = new StylusPointCollection();
var n = e.Stroke.StylusPoints.Count - 1;
var pressure = 0.1;
var x = 10;
if (n == 1) return;
if (n >= x) {
for (var i = 0; i < n - x; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
for (var i = n - x; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
else {
for (var i = 0; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)(0.4 * (n - i) / n + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
e.Stroke.StylusPoints = stylusPoints;
}
catch { }
break;
}
}
}
// Apply line straightening and endpoint snapping if ink-to-shape is enabled
if (Settings.InkToShape.IsInkToShapeEnabled) {
// 检查是否启用了直线自动拉直功能
if (Settings.Canvas.AutoStraightenLine && IsPotentialStraightLine(e.Stroke)) {
// Get start and end points of the stroke
Point startPoint = e.Stroke.StylusPoints[0].ToPoint();
Point endPoint = e.Stroke.StylusPoints[e.Stroke.StylusPoints.Count - 1].ToPoint();
// 记录是否需要拉直线条,默认不拉直
bool shouldStraighten = false;
bool snapped = false;
// 首先检查是否应该拉直线条(使用灵敏度设置),这是主要判断条件
// 读取实际的灵敏度设置值
double sensitivity = Settings.InkToShape.LineStraightenSensitivity;
System.Diagnostics.Debug.WriteLine($"当前灵敏度值: {sensitivity}");
// 将灵敏度值传递给判断函数
shouldStraighten = ShouldStraightenLine(e.Stroke);
// 输出一些调试信息,帮助理解灵敏度设置的效果
System.Diagnostics.Debug.WriteLine($"LineStraightenSensitivity: {Settings.InkToShape.LineStraightenSensitivity}, ShouldStraighten: {shouldStraighten}");
// 再检查端点吸附功能,这是独立的可选功能
if (Settings.Canvas.LineEndpointSnapping) {
// 只有在启用了形状识别(矩形或三角形)时才执行端点吸附
if (Settings.InkToShape.IsInkToShapeRectangle || Settings.InkToShape.IsInkToShapeTriangle) {
Point[] snappedPoints = GetSnappedEndpoints(startPoint, endPoint);
if (snappedPoints != null) {
startPoint = snappedPoints[0];
endPoint = snappedPoints[1];
snapped = true;
}
}
}
// 如果满足任一条件(需要拉直或成功吸附),则创建直线
// 这确保灵敏度设置独立于端点吸附功能发挥作用
if (shouldStraighten || snapped) {
StylusPointCollection straightLinePoints = CreateStraightLine(startPoint, endPoint);
Stroke straightStroke = new Stroke(straightLinePoints) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
// Replace the original stroke with the straightened one
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(e.Stroke);
inkCanvas.Strokes.Add(straightStroke);
_currentCommitType = CommitReason.UserInput;
// We can't modify e.Stroke directly, but we need to update newStrokes
// to ensure proper shape recognition for the straightened line
if (newStrokes.Contains(e.Stroke)) {
newStrokes.Remove(e.Stroke);
newStrokes.Add(straightStroke);
}
}
}
}
if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) {
void InkToShapeProcess() {
try {
newStrokes.Add(e.Stroke);
if (newStrokes.Count > 4) newStrokes.RemoveAt(0);
for (var i = 0; i < newStrokes.Count; i++)
if (!inkCanvas.Strokes.Contains(newStrokes[i]))
newStrokes.RemoveAt(i--);
for (var i = 0; i < circles.Count; i++)
if (!inkCanvas.Strokes.Contains(circles[i].Stroke))
circles.RemoveAt(i);
var strokeReco = new StrokeCollection();
var result = InkRecognizeHelper.RecognizeShape(newStrokes);
for (var i = newStrokes.Count - 1; i >= 0; i--) {
strokeReco.Add(newStrokes[i]);
var newResult = InkRecognizeHelper.RecognizeShape(strokeReco);
if (newResult.InkDrawingNode.GetShapeName() == "Circle" ||
newResult.InkDrawingNode.GetShapeName() == "Ellipse") {
result = newResult;
break;
}
//Label.Visibility = Visibility.Visible;
//Label.Content = circles.Count.ToString() + "\n" + newResult.InkDrawingNode.GetShapeName();
}
if (result.InkDrawingNode.GetShapeName() == "Circle" &&
Settings.InkToShape.IsInkToShapeRounded == true) {
var shape = result.InkDrawingNode.GetShape();
if (shape.Width > 75) {
foreach (var circle in circles)
//判断是否画同心圆
if (Math.Abs(result.Centroid.X - circle.Centroid.X) / shape.Width < 0.12 &&
Math.Abs(result.Centroid.Y - circle.Centroid.Y) / shape.Width < 0.12) {
result.Centroid = circle.Centroid;
break;
}
else {
var d = (result.Centroid.X - circle.Centroid.X) *
(result.Centroid.X - circle.Centroid.X) +
(result.Centroid.Y - circle.Centroid.Y) *
(result.Centroid.Y - circle.Centroid.Y);
d = Math.Sqrt(d);
//判断是否画外切圆
var x = shape.Width / 2.0 + circle.R - d;
if (Math.Abs(x) / shape.Width < 0.1) {
var sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d;
var cosTheta = (result.Centroid.X - circle.Centroid.X) / d;
var newX = result.Centroid.X + x * cosTheta;
var newY = result.Centroid.Y + x * sinTheta;
result.Centroid = new Point(newX, newY);
}
//判断是否画外切圆
x = Math.Abs(circle.R - shape.Width / 2.0) - d;
if (Math.Abs(x) / shape.Width < 0.1) {
var sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d;
var cosTheta = (result.Centroid.X - circle.Centroid.X) / d;
var newX = result.Centroid.X + x * cosTheta;
var newY = result.Centroid.Y + x * sinTheta;
result.Centroid = new Point(newX, newY);
}
}
var iniP = new Point(result.Centroid.X - shape.Width / 2,
result.Centroid.Y - shape.Height / 2);
var endP = new Point(result.Centroid.X + shape.Width / 2,
result.Centroid.Y + shape.Height / 2);
var pointList = GenerateEllipseGeometry(iniP, endP);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(point) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
circles.Add(new Circle(result.Centroid, shape.Width / 2.0, stroke));
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
newStrokes = new StrokeCollection();
}
}
else if (result.InkDrawingNode.GetShapeName().Contains("Ellipse") &&
Settings.InkToShape.IsInkToShapeRounded == true) {
var shape = result.InkDrawingNode.GetShape();
//var shape1 = result.InkDrawingNode.GetShape();
//shape1.Fill = Brushes.Gray;
//Canvas.Children.Add(shape1);
var p = result.InkDrawingNode.HotPoints;
var a = GetDistance(p[0], p[2]) / 2; //长半轴
var b = GetDistance(p[1], p[3]) / 2; //短半轴
if (a < b) {
var t = a;
a = b;
b = t;
}
result.Centroid = new Point((p[0].X + p[2].X) / 2, (p[0].Y + p[2].Y) / 2);
var needRotation = true;
if (shape.Width > 75 || (shape.Height > 75 && p.Count == 4)) {
var iniP = new Point(result.Centroid.X - shape.Width / 2,
result.Centroid.Y - shape.Height / 2);
var endP = new Point(result.Centroid.X + shape.Width / 2,
result.Centroid.Y + shape.Height / 2);
foreach (var circle in circles)
//判断是否画同心椭圆
if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2 &&
Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) {
result.Centroid = circle.Centroid;
iniP = new Point(result.Centroid.X - shape.Width / 2,
result.Centroid.Y - shape.Height / 2);
endP = new Point(result.Centroid.X + shape.Width / 2,
result.Centroid.Y + shape.Height / 2);
//再判断是否与圆相切
if (Math.Abs(a - circle.R) / a < 0.2) {
if (shape.Width >= shape.Height) {
iniP.X = result.Centroid.X - circle.R;
endP.X = result.Centroid.X + circle.R;
iniP.Y = result.Centroid.Y - b;
endP.Y = result.Centroid.Y + b;
}
else {
iniP.Y = result.Centroid.Y - circle.R;
endP.Y = result.Centroid.Y + circle.R;
iniP.X = result.Centroid.X - a;
endP.X = result.Centroid.X + a;
}
}
break;
}
else if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2) {
var sinTheta = Math.Abs(circle.Centroid.Y - result.Centroid.Y) /
circle.R;
var cosTheta = Math.Sqrt(1 - sinTheta * sinTheta);
var newA = circle.R * cosTheta;
if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 &&
Math.Abs(newA - a) / newA < 0.3) {
iniP.X = circle.Centroid.X - newA;
endP.X = circle.Centroid.X + newA;
iniP.Y = result.Centroid.Y - newA / 5;
endP.Y = result.Centroid.Y + newA / 5;
var topB = endP.Y - iniP.Y;
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
newStrokes = new StrokeCollection();
var _pointList = GenerateEllipseGeometry(iniP, endP, false, true);
var _point = new StylusPointCollection(_pointList);
var _stroke = new Stroke(_point) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
var _dashedLineStroke =
GenerateDashedLineEllipseStrokeCollection(iniP, endP, true, false);
var strokes = new StrokeCollection() {
_stroke,
_dashedLineStroke
};
inkCanvas.Strokes.Add(strokes);
_currentCommitType = CommitReason.UserInput;
return;
}
}
else if (Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) {
var cosTheta = Math.Abs(circle.Centroid.X - result.Centroid.X) /
circle.R;
var sinTheta = Math.Sqrt(1 - cosTheta * cosTheta);
var newA = circle.R * sinTheta;
if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 &&
Math.Abs(newA - a) / newA < 0.3) {
iniP.X = result.Centroid.X - newA / 5;
endP.X = result.Centroid.X + newA / 5;
iniP.Y = circle.Centroid.Y - newA;
endP.Y = circle.Centroid.Y + newA;
needRotation = false;
}
}
//纠正垂直与水平关系
var newPoints = FixPointsDirection(p[0], p[2]);
p[0] = newPoints[0];
p[2] = newPoints[1];
newPoints = FixPointsDirection(p[1], p[3]);
p[1] = newPoints[0];
p[3] = newPoints[1];
var pointList = GenerateEllipseGeometry(iniP, endP);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(point) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
if (needRotation) {
var m = new Matrix();
var fe = e.Source as FrameworkElement;
var tanTheta = (p[2].Y - p[0].Y) / (p[2].X - p[0].X);
var theta = Math.Atan(tanTheta);
m.RotateAt(theta * 180.0 / Math.PI, result.Centroid.X, result.Centroid.Y);
stroke.Transform(m, false);
}
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
newStrokes = new StrokeCollection();
}
}
else if (result.InkDrawingNode.GetShapeName().Contains("Triangle") &&
Settings.InkToShape.IsInkToShapeTriangle == true) {
var shape = result.InkDrawingNode.GetShape();
var p = result.InkDrawingNode.HotPoints;
if ((Math.Max(Math.Max(p[0].X, p[1].X), p[2].X) -
Math.Min(Math.Min(p[0].X, p[1].X), p[2].X) >= 100 ||
Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y) -
Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y) >= 100) &&
result.InkDrawingNode.HotPoints.Count == 3) {
//纠正垂直与水平关系
var newPoints = FixPointsDirection(p[0], p[1]);
p[0] = newPoints[0];
p[1] = newPoints[1];
newPoints = FixPointsDirection(p[0], p[2]);
p[0] = newPoints[0];
p[2] = newPoints[1];
newPoints = FixPointsDirection(p[1], p[2]);
p[1] = newPoints[0];
p[2] = newPoints[1];
var pointList = p.ToList();
//pointList.Add(p[0]);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(GenerateFakePressureTriangle(point)) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
newStrokes = new StrokeCollection();
}
}
else if ((result.InkDrawingNode.GetShapeName().Contains("Rectangle") ||
result.InkDrawingNode.GetShapeName().Contains("Diamond") ||
result.InkDrawingNode.GetShapeName().Contains("Parallelogram") ||
result.InkDrawingNode.GetShapeName().Contains("Square") ||
result.InkDrawingNode.GetShapeName().Contains("Trapezoid")) &&
Settings.InkToShape.IsInkToShapeRectangle == true) {
var shape = result.InkDrawingNode.GetShape();
var p = result.InkDrawingNode.HotPoints;
if ((Math.Max(Math.Max(Math.Max(p[0].X, p[1].X), p[2].X), p[3].X) -
Math.Min(Math.Min(Math.Min(p[0].X, p[1].X), p[2].X), p[3].X) >= 100 ||
Math.Max(Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y), p[3].Y) -
Math.Min(Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y), p[3].Y) >= 100) &&
result.InkDrawingNode.HotPoints.Count == 4) {
//纠正垂直与水平关系
var newPoints = FixPointsDirection(p[0], p[1]);
p[0] = newPoints[0];
p[1] = newPoints[1];
newPoints = FixPointsDirection(p[1], p[2]);
p[1] = newPoints[0];
p[2] = newPoints[1];
newPoints = FixPointsDirection(p[2], p[3]);
p[2] = newPoints[0];
p[3] = newPoints[1];
newPoints = FixPointsDirection(p[3], p[0]);
p[3] = newPoints[0];
p[0] = newPoints[1];
var pointList = p.ToList();
pointList.Add(p[0]);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(GenerateFakePressureRectangle(point)) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
newStrokes = new StrokeCollection();
}
}
}
catch { }
}
InkToShapeProcess();
}
foreach (var stylusPoint in e.Stroke.StylusPoints)
//LogHelper.WriteLogToFile(stylusPoint.PressureFactor.ToString(), LogHelper.LogType.Info);
// 检查是否是压感笔书写
//if (stylusPoint.PressureFactor != 0.5 && stylusPoint.PressureFactor != 0)
if ((stylusPoint.PressureFactor > 0.501 || stylusPoint.PressureFactor < 0.5) &&
stylusPoint.PressureFactor != 0)
return;
try {
if (e.Stroke.StylusPoints.Count > 3) {
var random = new Random();
var _speed = GetPointSpeed(
e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint(),
e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint(),
e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint());
RandWindow.randSeed = (int)(_speed * 100000 * 1000);
}
}
catch { }
switch (Settings.Canvas.InkStyle) {
case 1:
if (penType == 0)
try {
var stylusPoints = new StylusPointCollection();
var n = e.Stroke.StylusPoints.Count - 1;
var s = "";
for (var i = 0; i <= n; i++) {
var speed = GetPointSpeed(e.Stroke.StylusPoints[Math.Max(i - 1, 0)].ToPoint(),
e.Stroke.StylusPoints[i].ToPoint(),
e.Stroke.StylusPoints[Math.Min(i + 1, n)].ToPoint());
s += speed.ToString() + "\t";
var point = new StylusPoint();
if (speed >= 0.25)
point.PressureFactor = (float)(0.5 - 0.3 * (Math.Min(speed, 1.5) - 0.3) / 1.2);
else if (speed >= 0.05)
point.PressureFactor = (float)0.5;
else
point.PressureFactor = (float)(0.5 + 0.4 * (0.05 - speed) / 0.05);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
e.Stroke.StylusPoints = stylusPoints;
}
catch { }
break;
case 0:
if (penType == 0)
try {
var stylusPoints = new StylusPointCollection();
var n = e.Stroke.StylusPoints.Count - 1;
var pressure = 0.1;
var x = 10;
if (n == 1) return;
if (n >= x) {
for (var i = 0; i < n - x; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
for (var i = n - x; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
else {
for (var i = 0; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)(0.4 * (n - i) / n + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
e.Stroke.StylusPoints = stylusPoints;
}
catch { }
break;
}
}
catch { }
if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = true;
}
// New method: Checks if a stroke is potentially a straight line
private bool IsPotentialStraightLine(Stroke stroke) {
// 确保有足够的点来进行线条分析
if (stroke.StylusPoints.Count < 5)
return false;
Point start = stroke.StylusPoints.First().ToPoint();
Point end = stroke.StylusPoints.Last().ToPoint();
double lineLength = GetDistance(start, end);
// 线条必须足够长才考虑拉直,使用设置中的阈值
if (lineLength < Settings.Canvas.AutoStraightenLineThreshold)
return false;
// 获取用户设置的灵敏度值,确保使用正确的设置
double sensitivity = Settings.InkToShape.LineStraightenSensitivity;
// 输出当前灵敏度值(调试用)
System.Diagnostics.Debug.WriteLine($"IsPotentialStraightLine - sensitivity: {sensitivity}, length: {lineLength}");
// 根据灵敏度调整快速检查阈值
double quickThreshold;
// 如果灵敏度超过1.0,使用更宽松的快速检查标准
if (sensitivity > 1.0) {
// 高灵敏度模式 - 使用更宽松的阈值
quickThreshold = Math.Min(0.2 + (sensitivity - 1.0) * 0.3, 0.5); // 映射到0.2-0.5范围
} else {
// 常规灵敏度模式
quickThreshold = Math.Min(sensitivity * 1.5, 0.20);
}
System.Diagnostics.Debug.WriteLine($"使用快速检查阈值: {quickThreshold}");
// 快速检查:计算几个关键点与直线的距离
if (stroke.StylusPoints.Count >= 10) {
// 取中点和1/4、3/4位置的点,快速检查偏差
int quarterIdx = stroke.StylusPoints.Count / 4;
int midIdx = stroke.StylusPoints.Count / 2;
int threeQuarterIdx = quarterIdx * 3;
Point quarterPoint = stroke.StylusPoints[quarterIdx].ToPoint();
Point midPoint = stroke.StylusPoints[midIdx].ToPoint();
Point threeQuarterPoint = stroke.StylusPoints[threeQuarterIdx].ToPoint();
double quarterDeviation = DistanceFromLineToPoint(start, end, quarterPoint);
double midDeviation = DistanceFromLineToPoint(start, end, midPoint);
double threeQuarterDeviation = DistanceFromLineToPoint(start, end, threeQuarterPoint);
// 使用相对偏差:偏差与线长的比例,并使用灵敏度进行调整
double quickRelativeThreshold = lineLength * quickThreshold;
// 记录检测到的偏差(调试用)
System.Diagnostics.Debug.WriteLine($"Deviations: q={quarterDeviation}, m={midDeviation}, tq={threeQuarterDeviation}, threshold={quickRelativeThreshold}");
// 如果灵敏度超过1.5,则即使有一个点满足条件也认为可能是直线
if (sensitivity > 1.5) {
// 超高灵敏度模式:只要有一个关键点偏差小,就认为可能是直线
if (quarterDeviation <= quickRelativeThreshold ||
midDeviation <= quickRelativeThreshold ||
threeQuarterDeviation <= quickRelativeThreshold) {
return true;
}
} else {
// 常规判断:如果任一点偏离太大,直接排除
if (quarterDeviation > quickRelativeThreshold ||
midDeviation > quickRelativeThreshold ||
threeQuarterDeviation > quickRelativeThreshold) {
return false;
}
}
}
return true;
}
// New method: Determines if a stroke should be straightened into a line
private bool ShouldStraightenLine(Stroke stroke) {
// Basic implementation: check if points roughly follow a straight line
Point start = stroke.StylusPoints.First().ToPoint();
Point end = stroke.StylusPoints.Last().ToPoint();
// Calculate max deviation from the straight line between start and end
double maxDeviation = 0;
double lineLength = GetDistance(start, end);
// 如果线条太短,不进行拉直处理,使用设置中的阈值
if (lineLength < Settings.Canvas.AutoStraightenLineThreshold) {
// 显示调试信息 - 线条长度不足
// MessageBox.Show($"线条太短: {lineLength} < {Settings.Canvas.AutoStraightenLineThreshold}", "调试信息");
return false;
}
// 获取用户设置的灵敏度值,确保使用正确的值进行后续判断
double sensitivity = Settings.InkToShape.LineStraightenSensitivity;
// 输出详细的调试信息
System.Diagnostics.Debug.WriteLine($"ShouldStraightenLine - sensitivity: {sensitivity}, length: {lineLength}");
// 临时:显示调试消息框
// MessageBox.Show($"灵敏度值: {sensitivity}", "调试信息");
// 计算点与直线的偏差
double totalDeviation = 0;
int pointCount = 0;
// Calculate deviation for each point
foreach (StylusPoint sp in stroke.StylusPoints) {
Point p = sp.ToPoint();
double deviation = DistanceFromLineToPoint(start, end, p);
maxDeviation = Math.Max(maxDeviation, deviation);
totalDeviation += deviation;
pointCount++;
}
// 计算平均偏差
double avgDeviation = totalDeviation / pointCount;
// 更详细的调试信息
System.Diagnostics.Debug.WriteLine($"Max deviation: {maxDeviation}, Avg: {avgDeviation}, Threshold: {sensitivity * lineLength}");
// 支持更广泛的灵敏度范围 (0.05-2.0)
// 如果灵敏度高于1.0,使用更宽松的判断标准
if (sensitivity > 1.0) {
// 高灵敏度模式 - 允许更大的偏差
double adjustedSensitivity = 0.5 + (sensitivity - 1.0) * 1.5; // 映射到0.5-2.0范围
// 只判断平均偏差和相对偏差
if (maxDeviation / lineLength < adjustedSensitivity && avgDeviation < lineLength * 0.1 * adjustedSensitivity) {
System.Diagnostics.Debug.WriteLine("接受拉直 (高灵敏度模式)");
return true;
}
System.Diagnostics.Debug.WriteLine("拒绝拉直 (高灵敏度模式)");
return false;
}
// 否则使用常规判断标准
else {
// 检查点分布的一致性 - 如果有些点偏离很大而其他点很接近直线,表明线条有明显弯曲
double deviationVariance = 0;
foreach (StylusPoint sp in stroke.StylusPoints) {
Point p = sp.ToPoint();
double deviation = DistanceFromLineToPoint(start, end, p);
deviationVariance += Math.Pow(deviation - avgDeviation, 2);
}
deviationVariance /= pointCount;
// 输出更多调试信息
System.Diagnostics.Debug.WriteLine($"Deviation variance: {deviationVariance}, Threshold: {sensitivity * lineLength * 0.05}");
// 如果最大偏差超过线长的阈值比例,或者偏差方差较大(表示不均匀弯曲),则不拉直
// 灵敏度越大,容许的偏差越大,更容易将线条识别为直线
if ((maxDeviation / lineLength) > sensitivity) {
System.Diagnostics.Debug.WriteLine("拒绝拉直:最大偏差过大");
return false;
}
// 如果偏差方差大,说明线条弯曲不均匀
// 灵敏度越大,容许的偏差方差越大
if (deviationVariance > (sensitivity * lineLength * 0.05)) {
System.Diagnostics.Debug.WriteLine("拒绝拉直:偏差方差过大");
return false;
}
// 检查中点偏离情况 - 针对弧形线条特别有效
if (stroke.StylusPoints.Count > 10) {
int midIndex = stroke.StylusPoints.Count / 2;
Point midPoint = stroke.StylusPoints[midIndex].ToPoint();
double midDeviation = DistanceFromLineToPoint(start, end, midPoint);
// 输出中点偏差信息
System.Diagnostics.Debug.WriteLine($"Mid deviation: {midDeviation}, Threshold: {lineLength * sensitivity * 0.8}");
// 如果中点偏离过大,不拉直
// 使用灵敏度作为判断基准,灵敏度越大,容许的中点偏离越大
if (midDeviation > (lineLength * sensitivity * 0.8)) {
System.Diagnostics.Debug.WriteLine("拒绝拉直:中点偏差过大");
return false;
}
}
System.Diagnostics.Debug.WriteLine("接受拉直");
return true;
}
}
// New method: Creates a straight line stroke between two points
private StylusPointCollection CreateStraightLine(Point start, Point end) {
StylusPointCollection points = new StylusPointCollection();
// 根据是否启用压感触屏模式决定如何设置压感
// 如果未启用压感触屏模式,则使用均匀粗细
if (!Settings.Canvas.EnablePressureTouchMode || Settings.Canvas.DisablePressure ||
Settings.InkToShape.IsInkToShapeNoFakePressureRectangle == true || penType == 1) {
// 使用均匀粗细(所有点压感值都是0.5f)
points.Add(new StylusPoint(start.X, start.Y, 0.5f));
// 可以添加一些额外的中间点使线条更平滑(均匀粗细)
double distance = GetDistance(start, end);
if (distance > 100) {
// 对于较长的线条,添加几个中间点
for (int i = 1; i < 3; i++) {
double ratio = i / 3.0;
Point midPoint = new Point(
start.X + (end.X - start.X) * ratio,
start.Y + (end.Y - start.Y) * ratio);
points.Add(new StylusPoint(midPoint.X, midPoint.Y, 0.5f));
}
}
points.Add(new StylusPoint(end.X, end.Y, 0.5f));
} else {
// 启用了压感触屏模式,使用变化的粗细(原有行为)
points.Add(new StylusPoint(start.X, start.Y, 0.4f));
// 添加中点,压感值较高,使线条中间较粗
Point midPoint = new Point((start.X + end.X) / 2, (start.Y + end.Y) / 2);
points.Add(new StylusPoint(midPoint.X, midPoint.Y, 0.8f));
points.Add(new StylusPoint(end.X, end.Y, 0.4f));
}
return points;
}
// New method: Gets distance from point to a line defined by two points
private double DistanceFromLineToPoint(Point lineStart, Point lineEnd, Point point) {
// Calculate distance from point to line defined by lineStart and lineEnd
double lineLength = GetDistance(lineStart, lineEnd);
if (lineLength == 0) return GetDistance(point, lineStart);
// Calculate the cross product to get the perpendicular distance
double distance = Math.Abs((lineEnd.Y - lineStart.Y) * point.X -
(lineEnd.X - lineStart.X) * point.Y +
lineEnd.X * lineStart.Y - lineEnd.Y * lineStart.X) / lineLength;
return distance;
}
// New method: Attempts to snap endpoints to existing stroke endpoints
private Point[] GetSnappedEndpoints(Point start, Point end) {
// 如果端点吸附功能关闭,直接返回null
// 这里不再返回原始点,因为调用此方法的地方会判断返回值是否为null
if (!Settings.Canvas.LineEndpointSnapping)
return null;
bool startSnapped = false;
bool endSnapped = false;
Point snappedStart = start;
Point snappedEnd = end;
// 使用设置中的吸附距离阈值
double snapThreshold = Settings.Canvas.LineEndpointSnappingThreshold;
// Check all strokes in canvas for potential snap points
foreach (Stroke stroke in inkCanvas.Strokes) {
if (stroke.StylusPoints.Count == 0) continue;
// Get stroke endpoints
Point strokeStart = stroke.StylusPoints.First().ToPoint();
Point strokeEnd = stroke.StylusPoints.Last().ToPoint();
// Check if start point should snap to an endpoint
if (!startSnapped) {
if (GetDistance(start, strokeStart) < snapThreshold) {
snappedStart = strokeStart;
startSnapped = true;
} else if (GetDistance(start, strokeEnd) < snapThreshold) {
snappedStart = strokeEnd;
startSnapped = true;
}
}
// Check if end point should snap to an endpoint
if (!endSnapped) {
if (GetDistance(end, strokeStart) < snapThreshold) {
snappedEnd = strokeStart;
endSnapped = true;
} else if (GetDistance(end, strokeEnd) < snapThreshold) {
snappedEnd = strokeEnd;
endSnapped = true;
}
}
// If both endpoints are snapped, we're done
if (startSnapped && endSnapped) break;
}
// Return snapped points if any snapping occurred
if (startSnapped || endSnapped) {
return new Point[] { snappedStart, snappedEnd };
}
return null;
}
private void SetNewBackupOfStroke() {
lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone();
var whiteboardIndex = CurrentWhiteboardIndex;
if (currentMode == 0) whiteboardIndex = 0;
strokeCollections[whiteboardIndex] = lastTouchDownStrokeCollection;
}
public double GetDistance(Point point1, Point point2) {
return Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) +
(point1.Y - point2.Y) * (point1.Y - point2.Y));
}
public double GetPointSpeed(Point point1, Point point2, Point point3) {
return (Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) +
(point1.Y - point2.Y) * (point1.Y - point2.Y))
+ Math.Sqrt((point3.X - point2.X) * (point3.X - point2.X) +
(point3.Y - point2.Y) * (point3.Y - point2.Y)))
/ 20;
}
public Point[] FixPointsDirection(Point p1, Point p2) {
if (Math.Abs(p1.X - p2.X) / Math.Abs(p1.Y - p2.Y) > 8) {
//水平
var x = Math.Abs(p1.Y - p2.Y) / 2;
if (p1.Y > p2.Y) {
p1.Y -= x;
p2.Y += x;
}
else {
p1.Y += x;
p2.Y -= x;
}
}
else if (Math.Abs(p1.Y - p2.Y) / Math.Abs(p1.X - p2.X) > 8) {
//垂直
var x = Math.Abs(p1.X - p2.X) / 2;
if (p1.X > p2.X) {
p1.X -= x;
p2.X += x;
}
else {
p1.X += x;
p2.X -= x;
}
}
return new Point[2] { p1, p2 };
}
public StylusPointCollection GenerateFakePressureTriangle(StylusPointCollection points) {
if (Settings.InkToShape.IsInkToShapeNoFakePressureTriangle == true || penType == 1) {
var newPoint = new StylusPointCollection();
newPoint.Add(new StylusPoint(points[0].X, points[0].Y));
var cPoint = GetCenterPoint(points[0], points[1]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y));
cPoint = GetCenterPoint(points[1], points[2]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y));
cPoint = GetCenterPoint(points[2], points[0]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y));
newPoint.Add(new StylusPoint(points[0].X, points[0].Y));
return newPoint;
}
else {
var newPoint = new StylusPointCollection();
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
var cPoint = GetCenterPoint(points[0], points[1]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
cPoint = GetCenterPoint(points[1], points[2]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
cPoint = GetCenterPoint(points[2], points[0]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
return newPoint;
}
}
public StylusPointCollection GenerateFakePressureRectangle(StylusPointCollection points) {
if (Settings.InkToShape.IsInkToShapeNoFakePressureRectangle == true || penType == 1) {
return points;
}
else {
var newPoint = new StylusPointCollection();
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
var cPoint = GetCenterPoint(points[0], points[1]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
cPoint = GetCenterPoint(points[1], points[2]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
cPoint = GetCenterPoint(points[2], points[3]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[3].X, points[3].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[3].X, points[3].Y, (float)0.4));
cPoint = GetCenterPoint(points[3], points[0]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
return newPoint;
}
}
public Point GetCenterPoint(Point point1, Point point2) {
return new Point((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
}
public StylusPoint GetCenterPoint(StylusPoint point1, StylusPoint point2) {
return new StylusPoint((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

@@ -1,84 +0,0 @@
<Window x:Class="Ink_Canvas.HasNewUpdateWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ink_Canvas"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:mdxam="clr-namespace:MdXaml;assembly=MdXaml"
mc:Ignorable="d"
ui:WindowHelper.UseModernWindowStyle = "True"
ui:WindowHelper.SystemBackdropType="Mica"
ui:TitleBar.Height="36"
Title="InkCanvasForClass CE有新版本可用" Height="600" Width="850" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<Grid Background="#fafafa" Margin="0,0,0,30">
<ui:SimpleStackPanel VerticalAlignment="Stretch" Spacing="0">
<!-- 标题栏 -->
<ui:SimpleStackPanel Orientation="Horizontal" Background="#2563eb" Margin="0,0,0,0">
<ui:SimpleStackPanel Orientation="Vertical" Width="735" Margin="24,18,0,12" Spacing="2">
<TextBlock Text="InkCanvasForClass CE新版本来了!" FontSize="24" FontWeight="Bold" Foreground="White" TextAlignment="Left"/>
<TextBlock Text="希望您能喜欢我们的新版本 :-)" FontSize="20" TextAlignment="Left" Foreground="White"/>
</ui:SimpleStackPanel>
<Image Source="/Resources/Icons-fluent/party.png" Width="72" Height="72"/>
</ui:SimpleStackPanel>
<!-- 更新内容 -->
<Border BorderBrush="#3f3f46" Background="White" BorderThickness="1" CornerRadius="4" Margin="24,16,24,0">
<ui:ScrollViewerEx Margin="0" VerticalScrollBarVisibility="Auto" Height="180" PanningMode="VerticalOnly">
<mdxam:MarkdownScrollViewer x:Name="markdownContent" xml:space="preserve" Foreground="Black" MarkdownStyleName="GithubLike">
# InkCanvasForClass v5.0.2更新
你好,旅行者们,本次InkCanvasForClass Community Edition更新带来了如下新功能供您探索:
1. 全新设计的UI界面,包括浮动工具栏和白板页面均经过重新设计,更加现代化的UI让您在使用的过程中更加舒适。
2. 带来了实时修改橡皮大小和橡皮形状的菜单。您可以选择使用圆形橡皮,方形橡皮,和类似希沃白板的真实黑板擦(矩形)橡皮。
3. 白板页面支持显示当前时间和日期
4. 自动收纳新增对希沃轻白板、智绘教、鸿合屏幕书写等软件的支持,自动查杀新增对鸿合屏幕书写、希沃轻白板等软件的支持。
5. 为设置界面重写了全新的UI。
6. 重写了随机抽选模块,现在支持更丰富的抽选机制和自定义选项。
7. 修复了部分小Bug,提升了整体的用户体验。
8. 带来了基于FitToCurve的笔迹平滑,基于贝塞尔曲线平滑,让墨迹线条更加优美好看。
</mdxam:MarkdownScrollViewer>
</ui:ScrollViewerEx>
</Border>
<!-- 版本信息 -->
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="16" Margin="0,16,0,0">
<TextBlock x:Name="updateVersionInfo" Text="本次更新: 4.9.1 -> 5.9.1" FontWeight="Bold" FontSize="15" TextAlignment="Center"/>
<TextBlock x:Name="updateDateInfo" Text="2024年8月4日发布更新" FontSize="15" TextAlignment="Center"/>
</ui:SimpleStackPanel>
<!-- 更新按钮组 -->
<Border Background="#f1f5f9" BorderBrush="#e2e8f0" BorderThickness="1" CornerRadius="4" Margin="24,16,24,20">
<ui:SimpleStackPanel Orientation="Vertical" HorizontalAlignment="Center" Spacing="14" Margin="0,16,0,16">
<TextBlock Text="请选择更新方式" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center" Margin="0,0,0,6"/>
<!-- 立即更新按钮 -->
<Button x:Name="UpdateNowButton" Content="立刻下载并安装" Foreground="White" FontSize="15" FontWeight="SemiBold"
Padding="20,10" Width="360" Height="48" HorizontalAlignment="Center"
Click="UpdateNowButton_Click" ToolTip="立即下载更新并在完成后安装" Visibility="Visible" IsEnabled="True">
<Button.Resources>
<SolidColorBrush x:Key="{x:Static ui:ThemeKeys.ButtonBackgroundKey}" Color="#15803d"/>
<SolidColorBrush x:Key="{x:Static ui:ThemeKeys.ButtonBackgroundPointerOverKey}" Color="#15803d"/>
<SolidColorBrush x:Key="{x:Static ui:ThemeKeys.ButtonBackgroundPressedKey}" Color="#166534"/>
</Button.Resources>
</Button>
<!-- 稍后更新按钮 -->
<Button x:Name="UpdateLaterButton" Content="下载并在软件关闭时安装" Foreground="Black" FontSize="15"
Padding="20,10" Width="360" Height="48" HorizontalAlignment="Center"
Click="UpdateLaterButton_Click" Background="#e2e8f0" BorderBrush="#cbd5e1"
ToolTip="后台下载更新,在软件关闭时自动安装" Visibility="Visible" IsEnabled="True"/>
<!-- 跳过版本按钮 -->
<Button x:Name="SkipVersionButton" Content="跳过该版本" HorizontalAlignment="Center" Foreground="#71717a"
FontSize="15" Padding="20,10" Width="360" Height="48" Click="SkipVersionButton_Click"
Background="#f8fafc" BorderBrush="#cbd5e1" ToolTip="跳过此版本更新" Visibility="Visible" IsEnabled="True"/>
</ui:SimpleStackPanel>
</Border>
</ui:SimpleStackPanel>
</Grid>
</ScrollViewer>
</Window>
@@ -1,292 +0,0 @@
using Ink_Canvas.Helpers;
using iNKORE.UI.WPF.Modern.Controls.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Ink_Canvas
{
/// <summary>
/// HasNewUpdateWindow.xaml 的交互逻辑
/// </summary>
///
public partial class HasNewUpdateWindow : Window
{
[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
private const int DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19;
private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
private static bool UseImmersiveDarkMode(IntPtr handle, bool enabled)
{
if (IsWindows10OrGreater(17763))
{
var attribute = DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
if (IsWindows10OrGreater(18985))
{
attribute = DWMWA_USE_IMMERSIVE_DARK_MODE;
}
int useImmersiveDarkMode = enabled ? 1 : 0;
return DwmSetWindowAttribute(handle, attribute, ref useImmersiveDarkMode, sizeof(int)) == 0;
}
return false;
}
private static bool IsWindows10OrGreater(int build = -1)
{
return Environment.OSVersion.Version.Major >= 10 && Environment.OSVersion.Version.Build >= build;
}
// 存储更新版本信息
public string CurrentVersion { get; set; }
public string NewVersion { get; set; }
public string ReleaseDate { get; set; }
public string ReleaseNotes { get; set; }
// 更新按钮结果
public enum UpdateResult
{
UpdateNow,
UpdateLater,
SkipVersion
}
public UpdateResult Result { get; private set; } = UpdateResult.UpdateLater;
public HasNewUpdateWindow(string currentVersion, string newVersion, string releaseDate, string releaseNotes = null)
{
InitializeComponent();
// 设置版本信息
CurrentVersion = currentVersion;
NewVersion = newVersion;
ReleaseDate = releaseDate;
ReleaseNotes = releaseNotes;
// 更新UI
updateVersionInfo.Text = $"本次更新: {CurrentVersion} -> {NewVersion}";
updateDateInfo.Text = $"{ReleaseDate}发布更新";
// 如果有发布说明,设置到Markdown内容中
if (!string.IsNullOrEmpty(ReleaseNotes))
{
markdownContent.Markdown = ReleaseNotes;
}
// 自动更新和静默更新设置已移至设置界面,此处不再需要
// 确保按钮可见且可用
EnsureButtonsVisibility();
// 显示窗口动画
AnimationsHelper.ShowWithFadeIn(this, 0.25);
// 设置深色模式
UseImmersiveDarkMode(new WindowInteropHelper(this).Handle, true);
// 窗口加载完成后再次确保按钮可见
this.Loaded += HasNewUpdateWindow_Loaded;
}
private void HasNewUpdateWindow_Loaded(object sender, RoutedEventArgs e)
{
// 窗口加载完成后再次确保按钮可见
EnsureButtonsVisibility();
// 调整窗口大小以适应屏幕分辨率
AdjustWindowSizeForScreenResolution();
}
// 确保按钮可见并启用
private void EnsureButtonsVisibility()
{
// 确保立即更新按钮可见
UpdateNowButton.Visibility = Visibility.Visible;
UpdateNowButton.IsEnabled = true;
// 确保稍后更新按钮可见
UpdateLaterButton.Visibility = Visibility.Visible;
UpdateLaterButton.IsEnabled = true;
// 确保跳过版本按钮可见
SkipVersionButton.Visibility = Visibility.Visible;
SkipVersionButton.IsEnabled = true;
// 强制刷新UI
UpdateLayout();
// 记录日志
LogHelper.WriteLogToFile("AutoUpdate | Update dialog buttons visibility ensured");
}
private void UpdateNowButton_Click(object sender, RoutedEventArgs e)
{
LogHelper.WriteLogToFile("AutoUpdate | Update Now button clicked");
// 设置结果为立即更新
Result = UpdateResult.UpdateNow;
// 关闭窗口,返回到MainWindow处理后续下载和安装流程
DialogResult = true;
Close();
}
private void UpdateLaterButton_Click(object sender, RoutedEventArgs e)
{
LogHelper.WriteLogToFile("AutoUpdate | Update Later button clicked");
// 设置结果为稍后更新
Result = UpdateResult.UpdateLater;
// 关闭窗口
DialogResult = true;
Close();
}
private void SkipVersionButton_Click(object sender, RoutedEventArgs e)
{
LogHelper.WriteLogToFile("AutoUpdate | Skip Version button clicked");
// 设置结果为跳过该版本
Result = UpdateResult.SkipVersion;
// 关闭窗口
DialogResult = true;
Close();
}
// 根据屏幕分辨率调整窗口大小
private void AdjustWindowSizeForScreenResolution()
{
try
{
// 获取主屏幕分辨率
double screenWidth = SystemParameters.PrimaryScreenWidth;
double screenHeight = SystemParameters.PrimaryScreenHeight;
LogHelper.WriteLogToFile($"AutoUpdate | Screen resolution: {screenWidth}x{screenHeight}");
// 始终确保窗口不超过屏幕大小的85%
double maxHeight = screenHeight * 0.85;
double maxWidth = screenWidth * 0.85;
bool needsAdjustment = false;
// 如果窗口高度超过最大允许高度,调整窗口高度
if (this.Height > maxHeight)
{
this.Height = maxHeight;
needsAdjustment = true;
LogHelper.WriteLogToFile($"AutoUpdate | Adjusted window height to: {this.Height}");
}
// 如果窗口宽度超过最大允许宽度,调整窗口宽度
if (this.Width > maxWidth)
{
this.Width = maxWidth;
needsAdjustment = true;
LogHelper.WriteLogToFile($"AutoUpdate | Adjusted window width to: {this.Width}");
}
// 如果屏幕分辨率较低,调整更多UI元素
if (screenHeight < 768 || screenWidth < 1024 || needsAdjustment)
{
// 查找相关控件并调整大小
var markdownViewer = this.FindName("markdownContent") as MdXaml.MarkdownScrollViewer;
var updateNowButton = this.FindName("UpdateNowButton") as Button;
var updateLaterButton = this.FindName("UpdateLaterButton") as Button;
var skipVersionButton = this.FindName("SkipVersionButton") as Button;
// 查找包含ScrollViewer的边框控件,减小其高度
var contentBorders = this.FindVisualChildren<Border>().ToList();
foreach (var border in contentBorders)
{
if (border.Child is ScrollViewer || border.Child is iNKORE.UI.WPF.Modern.Controls.ScrollViewerEx)
{
// 减小内容显示区域的高度
if (border.Height > 180)
{
border.Height = 160;
LogHelper.WriteLogToFile("AutoUpdate | Reduced content area height");
}
else if (border.Child is iNKORE.UI.WPF.Modern.Controls.ScrollViewerEx scrollViewer && scrollViewer.Height > 160)
{
scrollViewer.Height = 160;
LogHelper.WriteLogToFile("AutoUpdate | Reduced scroll viewer height");
}
}
}
// 调整按钮大小
if (updateNowButton != null && updateLaterButton != null && skipVersionButton != null)
{
updateNowButton.Height = 42;
updateLaterButton.Height = 42;
skipVersionButton.Height = 42;
updateNowButton.Padding = new Thickness(15, 8, 15, 8);
updateLaterButton.Padding = new Thickness(15, 8, 15, 8);
skipVersionButton.Padding = new Thickness(15, 8, 15, 8);
LogHelper.WriteLogToFile("AutoUpdate | Reduced button sizes for small screen");
}
}
// 确保窗口在屏幕范围内
if (this.Left < 0) this.Left = 0;
if (this.Top < 0) this.Top = 0;
if (this.Left + this.Width > screenWidth) this.Left = screenWidth - this.Width;
if (this.Top + this.Height > screenHeight) this.Top = screenHeight - this.Height;
LogHelper.WriteLogToFile($"AutoUpdate | Final window size: {this.Width}x{this.Height}");
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"AutoUpdate | Error adjusting window size: {ex.Message}", LogHelper.LogType.Error);
}
}
// 递归查找指定类型的所有子控件
private IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj = null) where T : DependencyObject
{
if (depObj == null)
depObj = this;
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
}
}
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{693973B6-69C1-4A37-B329-F366A07BF60A}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>InkCanvasForClass.IACoreHelper</RootNamespace>
<AssemblyName>InkCanvasForClass.IACoreHelper</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+12
View File
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace InkCanvasForClass.IACoreHelper {
internal class Program {
static void Main(string[] args) {
}
}
}
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("InkCanvasForClass.IACoreHelper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("InkCanvasForClass.IACoreHelper")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("693973b6-69c1-4a37-b329-f366a07bf60a")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+3
View File
@@ -0,0 +1,3 @@
# InkCanvasForClass.IACoreHelper
该项目实现了基于 .NET Framework 4.7.2 和 x86 运行环境的墨迹识别库 IACore 的封装
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
@@ -0,0 +1,9 @@
<Application x:Class="InkCanvasForClass.IccInkCanvas.Demo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:InkCanvasForClass.IccInkCanvas.Demo"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace InkCanvasForClass.IccInkCanvas.Demo {
/// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : Application {
}
}
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{94E97F70-CACD-453B-8114-08DFFDDA5A46}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>InkCanvasForClass.IccInkCanvas.Demo</RootNamespace>
<AssemblyName>InkCanvasForClass.IccInkCanvas.Demo</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\InkCanvasForClass.IccInkCanvas\InkCanvasForClass.IccInkCanvas.csproj">
<Project>{43929d8f-5630-4786-b75d-e203ea3e992f}</Project>
<Name>InkCanvasForClass.IccInkCanvas</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -0,0 +1,71 @@
<Window x:Class="InkCanvasForClass.IccInkCanvas.Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:InkCanvasForClass.IccInkCanvas.Demo"
xmlns:iccInkCanvas="clr-namespace:InkCanvasForClass.IccInkCanvas;assembly=InkCanvasForClass.IccInkCanvas"
mc:Ignorable="d"
Title="MainWindow" Height="950" Width="800">
<Grid>
<TabControl>
<TabItem Header="IccInkCanvasOld">
<StackPanel Orientation="Vertical" Margin="8">
<TextBlock FontSize="24">IccInkCanvasDemo</TextBlock>
<iccInkCanvas:IccBoard EditingMode="None" Name="IccBoard" Width="512" Height="512"/>
<WrapPanel Orientation="Horizontal">
<Button Content="EditingMode = None" Click="EditingModeChangeToNone_ButtonClick"/>
<Button Content="EditingMode = Writing" Click="EditingModeChangeToWriting_ButtonClick"/>
<Button Content="EditingMode = GeometryErasing" Click="EditingModeChangeToGeometryErasing_ButtonClick"/>
<Button Content="EditingMode = AreaErasing" Click="EditingModeChangeToAreaErasing_ButtonClick"/>
<Button Content="EditingMode = RoamingMode" Click="EditingModeChangeToRoamingMode_ButtonClick"/>
</WrapPanel>
<TextBlock Name="BoardSettingsTextBlock"/>
<WrapPanel Orientation="Horizontal">
<Button Content="BoardSettings.NibSize = 2" Click="BoardSettingsNibSizeChangeTo2_ButtonClick"/>
<Button Content="BoardSettings.NibSize = 4" Click="BoardSettingsNibSizeChangeTo4_ButtonClick"/>
<Button Content="BoardSettings.NibSize = 6" Click="BoardSettingsNibSizeChangeTo6_ButtonClick"/>
<Button Content="BoardSettings.NibColor = Red" Click="BoardSettingsNibColorChangeToRed_ButtonClick"/>
<Button Content="BoardSettings.NibColor = Blue" Click="BoardSettingsNibColorChangeToBlue_ButtonClick"/>
<Button Content="BoardSettings.NibColor = Green" Click="BoardSettingsNibColorChangeToGreen_ButtonClick"/>
<Button Content="BoardSettings.NibColor = Black" Click="BoardSettingsNibColorChangeToBlack_ButtonClick"/>
<Button Content="BoardSettings.StrokeNibStyle = Solid" Click="BoardSettingsStrokeNibStyleChangeToSolid_ButtonClick"/>
<Button Content="BoardSettings.StrokeNibStyle = Beautiful" Click="BoardSettingsStrokeNibStyleChangeToBeautiful_ButtonClick"/>
</WrapPanel>
<TextBlock Name="BoardPageTextBlock"/>
<WrapPanel Orientation="Horizontal">
<Button Content="AddPage" Click="AddPage_ButtonClick"/>
<Button Content="SwitchToPreviousPage" Click="SwitchToPreviousPage_ButtonClick"/>
<Button Content="SwitchToNextPage" Click="SwitchToNextPage_ButtonClick"/>
<Button Content="RemoveCurrentPage" Click="RemoveCurrentPage_ButtonClick"/>
</WrapPanel>
<WrapPanel Orientation="Horizontal">
<Button Content="BoardSettings.EraserSize = 16" Click="BoardSettingsEraserSizeChangeTo16_ButtonClick"/>
<Button Content="BoardSettings.EraserSize = 32" Click="BoardSettingsEraserSizeChangeTo32_ButtonClick"/>
<Button Content="BoardSettings.EraserSize = 48" Click="BoardSettingsEraserSizeChangeTo48_ButtonClick"/>
<Button Content="BoardSettings.EraserSize = 64" Click="BoardSettingsEraserSizeChangeTo64_ButtonClick"/>
<Button Content="BoardSettings.EraserType = Rectangle" Click="BoardSettingsEraserTypeChangeToRectangle_ButtonClick"/>
<Button Content="BoardSettings.EraserType = Ellipse" Click="BoardSettingsEraserTypeChangeToEllipse_ButtonClick"/>
</WrapPanel>
<TextBlock Name="TimeMachineTextBlock"/>
<WrapPanel Orientation="Horizontal">
<Button Content="Undo" Click="Undo_ButtonClick"/>
<Button Content="Undo 2" Click="Undo2_ButtonClick"/>
<Button Content="Redo" Click="Redo_ButtonClick"/>
<Button Content="Redo 2" Click="Redo2_ButtonClick"/>
</WrapPanel>
<TextBlock Text="TimeMachineV2 Test"/>
<TextBlock Name="TimeMachineV2Status"/>
<WrapPanel Orientation="Horizontal">
<Button Content="PushTestAction" Click="PushTestAction_TimeMachineV2_ButtonClick"/>
<Button Content="Undo" Click="Undo_TimeMachineV2_ButtonClick"/>
<Button Content="Redo" Click="Redo_TimeMachineV2_ButtonClick"/>
</WrapPanel>
</StackPanel>
</TabItem>
<TabItem Header="IccInkCanvasNew">
<iccInkCanvas:InkBoard Width="269" Height="269"/>
</TabItem>
</TabControl>
</Grid>
</Window>
@@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using InkCanvasForClass.IccInkCanvas.Settings;
namespace InkCanvasForClass.IccInkCanvas.Demo {
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window {
private TimeMachineV2 tm = new TimeMachineV2();
public MainWindow() {
InitializeComponent();
RegisterEventsForBoardSettings();
UpdateBoardSettingsTextBlock();
IccBoard.CurrentPageChanged += (sender, args) => {
Trace.WriteLine("Page Counter Updated");
BoardPageTextBlock.Text = $"{IccBoard.CurrentPage+1}/{IccBoard.PagesCount} IsLast:{IccBoard.IsCurrentLastPage} IsFirst:{IccBoard.IsCurrentFirstPage}";
};
IccBoard.UndoRedoStateChanged += (sender, args) => {
TimeMachineTextBlock.Text = $"CurrentPageHistoriesCount:{IccBoard.CurrentPageHistoriesCount} CanUndo:{IccBoard.CanUndo} CanRedo:{IccBoard.CanRedo}";
};
TimeMachineV2Status.Text = $"Current: {tm.CurrentIndex} Count: {tm.ActionsCount}";
tm.UndoRedoStateChanged += (_, __) => {
TimeMachineV2Status.Text = $"Current: {tm.CurrentIndex} Count: {tm.ActionsCount}";
};
}
private void UpdateBoardSettingsTextBlock() {
BoardSettingsTextBlock.Text =
$@"Width:{IccBoard.BoardSettings.NibWidth} Height:{IccBoard.BoardSettings.NibHeight} Color:{IccBoard.BoardSettings.NibColor.ToString()}";
}
private void RegisterEventsForBoardSettings() {
IccBoard.BoardSettings.NibWidthChanged += (s, e) => UpdateBoardSettingsTextBlock();
IccBoard.BoardSettings.NibHeightChanged += (s, e) => UpdateBoardSettingsTextBlock();
IccBoard.BoardSettings.NibColorChanged += (s, e) => UpdateBoardSettingsTextBlock();
}
private void EditingModeChangeToNone_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.EditingMode = EditingMode.NoneWithHitTest;
}
private void EditingModeChangeToWriting_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.EditingMode = EditingMode.Writing;
}
private void EditingModeChangeToGeometryErasing_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.EditingMode = EditingMode.GeometryErasing;
}
private void EditingModeChangeToAreaErasing_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.EditingMode = EditingMode.AreaErasing;
}
private void EditingModeChangeToRoamingMode_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.EditingMode = EditingMode.RoamingMode;
}
private void BoardSettingsNibSizeChangeTo2_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.NibWidth = 2;
IccBoard.BoardSettings.NibHeight = 2;
}
private void BoardSettingsNibSizeChangeTo4_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.NibWidth = 4;
IccBoard.BoardSettings.NibHeight = 4;
}
private void BoardSettingsNibSizeChangeTo6_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.NibWidth = 6;
IccBoard.BoardSettings.NibHeight = 6;
}
private void BoardSettingsNibColorChangeToRed_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.NibColor = Color.FromRgb(220, 38, 38);
}
private void BoardSettingsNibColorChangeToBlue_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.NibColor = Color.FromRgb(37, 99, 235);
}
private void BoardSettingsNibColorChangeToGreen_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.NibColor = Color.FromRgb(34, 197, 94);
}
private void BoardSettingsNibColorChangeToBlack_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.NibColor = Colors.Black;
}
private void BoardSettingsStrokeNibStyleChangeToSolid_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.StrokeNibStyle = StrokeNibStyle.Solid;
}
private void BoardSettingsStrokeNibStyleChangeToBeautiful_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.StrokeNibStyle = StrokeNibStyle.Beautiful;
}
private void AddPage_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.AddPage();
}
private void SwitchToPreviousPage_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.GoToPreviousPage();
}
private void SwitchToNextPage_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.GoToNextPage();
}
private async void RemoveCurrentPage_ButtonClick(object sender, RoutedEventArgs e) {
await IccBoard.RemovePage();
}
private void BoardSettingsEraserSizeChangeTo16_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.EraserSize = 16;
}
private void BoardSettingsEraserSizeChangeTo32_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.EraserSize = 32;
}
private void BoardSettingsEraserSizeChangeTo48_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.EraserSize = 48;
}
private void BoardSettingsEraserSizeChangeTo64_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.EraserSize = 64;
}
private void BoardSettingsEraserTypeChangeToRectangle_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.EraserType = EraserType.Rectangle;
}
private void BoardSettingsEraserTypeChangeToEllipse_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.BoardSettings.EraserType = EraserType.Ellipse;
}
private void Undo_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.Undo();
}
private void Redo_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.Redo();
}
private void Undo2_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.Undo(2);
}
private void Redo2_ButtonClick(object sender, RoutedEventArgs e) {
IccBoard.Redo(2);
}
private void PushTestAction_TimeMachineV2_ButtonClick(object sender, RoutedEventArgs e) {
tm.PushTestAction();
}
private void Undo_TimeMachineV2_ButtonClick(object sender, RoutedEventArgs e) {
tm.Undo(false);
}
private void Redo_TimeMachineV2_ButtonClick(object sender, RoutedEventArgs e) {
tm.Redo();
}
}
}
@@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("InkCanvasForClass.IccInkCanvas.Demo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("InkCanvasForClass.IccInkCanvas.Demo")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
//若要开始生成可本地化的应用程序,请设置
//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
//在 <PropertyGroup> 中。例如,如果你使用的是美国英语。
//使用的是美国英语,请将 <UICulture> 设置为 en-US。 然后取消
//对以下 NeutralResourceLanguage 特性的注释。 更新
//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //主题特定资源词典所处位置
//(未在页面中找到资源时使用,
//或应用程序资源字典中找到时使用)
ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
//(未在页面中找到资源时使用,
//、应用程序或任何主题专用资源字典中找到时使用)
)]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace InkCanvasForClass.IccInkCanvas.Demo.Properties {
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if ((resourceMan == null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("InkCanvasForClass.IccInkCanvas.Demo.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InkCanvasForClass.IccInkCanvas.Demo.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}
@@ -0,0 +1,113 @@
using InkCanvasForClass.IccInkCanvas.Utils.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
namespace InkCanvasForClass.IccInkCanvas {
/// <summary>
/// 基于 InkPresenter 优化和魔改的 InkBoard 控件
/// </summary>
public class InkBoard : FrameworkElement {
private readonly VisualCollection _children;
// Tuple 1为Dispatcher的Guid2为对应Dispatcher
private List<Tuple<Guid, Dispatcher>> _asyncDispatchers;
private const int HalfIntMax = 1073741823;
private const float HalfFloatMax = 1073741823f;
private const int QuarterSInt = 536756397;
private const float QuarterSFloat = 536756397f;
public InkBoard() {
VisualCacheMode = new BitmapCache(0);
ClipToBounds = true;
_children = new VisualCollection(this);
test();
}
#region Dispatchers
/// <summary>
/// 创建一个 Dispatcher
/// </summary>
/// <param name="customWorkerDispatcherName">如果可用,会使用这个名字创建Dispatcher(但是不会忽略GUID</param>
/// <returns>Tuple1为Guid2为Dispatcher</returns>
private async Task<Tuple<Guid, Dispatcher>> CreateDispathcer(string customWorkerDispatcherName = "IccInkCanvas") {
var guid = Guid.NewGuid();
var dispatcher = await UIDispatcher.RunNewAsync($"{customWorkerDispatcherName}_" + guid);
return new Tuple<Guid, Dispatcher>(guid, dispatcher);
}
/// <summary>
/// 注册一个新的 Dispatcher,这将会把 Dispatcher 给记录到 _asyncDispatchers 中
/// </summary>
/// <param name="customWorkerDispatcherName">如果可用,会使用这个名字创建Dispatcher(但是不会忽略GUID</param>
private async void RegisterNewDispatcher(string customWorkerDispatcherName = "IccInkCanvas") {
var dispatcher = await CreateDispathcer(customWorkerDispatcherName);
_asyncDispatchers.Add(dispatcher);
}
/// <summary>
/// 让一个 Dispatcher 停止工作并销毁
/// </summary>
/// <param name="dispatcher"></param>
private void DisposeDispatcher(Dispatcher dispatcher) {
dispatcher.BeginInvokeShutdown(DispatcherPriority.Send);
GC.Collect();
}
/// <summary>
/// 判断一个 Dispatcher 是否被挂起
/// </summary>
/// <param name="dispatcher"></param>
/// <returns></returns>
private static async Task<bool> CheckDispatcherHangAsync(Dispatcher dispatcher)
{
var taskCompletionSource = new TaskCompletionSource<bool>();
_ = dispatcher.InvokeAsync(() => taskCompletionSource.TrySetResult(true));
await Task.WhenAny(taskCompletionSource.Task, Task.Delay(TimeSpan.FromMilliseconds(1500)));
return taskCompletionSource.Task.IsCompleted is false;
}
#endregion
/// <summary>
/// 创建跨线程 InkPresenter,使用传入的 Dispatcher
/// </summary>
/// <returns></returns>
private async Task CreateInkPresenterWithDispatcher() {
await UIDispatcher.RunNewAsync("IccInkCanvas_" + Guid.NewGuid());
}
private async Task test() {
var di = new IccDispatcherInkCanvasInfo();
await di.InitDispatcher();
var control = await di.Dispatcher.InvokeAsync(() => new TextBlock() {
Text = "Helloworld!",
Foreground = new SolidColorBrush(Colors.Black),
FontSize = 24,
});
var dc = new DispatcherContainer();
await dc.SetChildAsync(control);
_children.Add(dc);
InvalidateVisual();
}
protected override int VisualChildrenCount {
get { return _children.Count; }
}
protected override Visual GetVisualChild(int index) {
if (index < 0 || index >= _children.Count) new ArgumentOutOfRangeException();
return _children[index];
}
}
}
@@ -0,0 +1,94 @@
<UserControl x:Class="InkCanvasForClass.IccInkCanvas.IccBoard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:InkCanvasForClass.IccInkCanvas"
mc:Ignorable="d" d:DesignHeight="512" d:DesignWidth="512">
<UserControl.Resources>
<DrawingImage x:Key="RectangleEraserImageSource">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V56 H38 V0 H0 Z">
<GeometryDrawing Brush="#FFF2EEEB" Geometry="F1 M38,56z M0,0z M0,4C0,1.79086,1.79086,0,4,0L34,0C36.2091,0,38,1.79086,38,4L38,52C38,54.2091,36.2091,56,34,56L4,56C1.79086,56,0,54.2091,0,52L0,4z" />
<GeometryDrawing Brush="#FFCDCDCD" Geometry="F0 M38,56z M0,0z M34,1L4,1C2.34315,1,1,2.34315,1,4L1,52C1,53.6569,2.34315,55,4,55L34,55C35.6569,55,37,53.6569,37,52L37,4C37,2.34315,35.6569,1,34,1z M4,0C1.79086,0,0,1.79086,0,4L0,52C0,54.2091,1.79086,56,4,56L34,56C36.2091,56,38,54.2091,38,52L38,4C38,1.79086,36.2091,0,34,0L4,0z" />
<GeometryDrawing Brush="#FFD1CFCD" Geometry="F1 M38,56z M0,0z M12,19.5C12,18.1193,13.1193,17,14.5,17L14.5,17C15.8807,17,17,18.1193,17,19.5L17,36.5C17,37.8807,15.8807,39,14.5,39L14.5,39C13.1193,39,12,37.8807,12,36.5L12,19.5z" />
<GeometryDrawing Geometry="F0 M38,56z M0,0z M11.5,19.5C11.5,17.8431 12.8431,16.5 14.5,16.5 16.1569,16.5 17.5,17.8431 17.5,19.5L17.5,36.5C17.5,38.1569 16.1569,39.5 14.5,39.5 12.8431,39.5 11.5,38.1569 11.5,36.5L11.5,19.5z M14.5,17.5C13.3954,17.5,12.5,18.3954,12.5,19.5L12.5,36.5C12.5,37.6046 13.3954,38.5 14.5,38.5 15.6046,38.5 16.5,37.6046 16.5,36.5L16.5,19.5C16.5,18.3954,15.6046,17.5,14.5,17.5z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF6F6F6F" Opacity="0.25" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD1CFCD" Geometry="F1 M38,56z M0,0z M21,19.5C21,18.1193,22.1193,17,23.5,17L23.5,17C24.8807,17,26,18.1193,26,19.5L26,36.5C26,37.8807,24.8807,39,23.5,39L23.5,39C22.1193,39,21,37.8807,21,36.5L21,19.5z" />
<GeometryDrawing Geometry="F0 M38,56z M0,0z M20.5,19.5C20.5,17.8431 21.8431,16.5 23.5,16.5 25.1569,16.5 26.5,17.8431 26.5,19.5L26.5,36.5C26.5,38.1569 25.1569,39.5 23.5,39.5 21.8431,39.5 20.5,38.1569 20.5,36.5L20.5,19.5z M23.5,17.5C22.3954,17.5,21.5,18.3954,21.5,19.5L21.5,36.5C21.5,37.6046 22.3954,38.5 23.5,38.5 24.6046,38.5 25.5,37.6046 25.5,36.5L25.5,19.5C25.5,18.3954,24.6046,17.5,23.5,17.5z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF6F6F6F" Opacity="0.25" />
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="EllipseEraserImageSource">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V56 H56 V0 H0 Z">
<GeometryDrawing Brush="#FFF2EEEB" Geometry="F1 M56,56z M0,0z M0,28C0,12.536,12.536,0,28,0L28,0C43.464,0,56,12.536,56,28L56,28C56,43.464,43.464,56,28,56L28,56C12.536,56,0,43.464,0,28L0,28z" />
<GeometryDrawing Brush="#FFCDCDCD" Geometry="F0 M56,56z M0,0z M1,28C1,42.9117 13.0883,55 28,55 42.9117,55 55,42.9117 55,28 55,13.0883 42.9117,1 28,1 13.0883,1 1,13.0883 1,28z M28,0C12.536,0 0,12.536 0,28 0,43.464 12.536,56 28,56 43.464,56 56,43.464 56,28 56,12.536 43.464,0 28,0z" />
<GeometryDrawing Brush="#FFD1CFCD" Geometry="F1 M56,56z M0,0z M21,19.5C21,18.1193,22.1193,17,23.5,17L23.5,17C24.8807,17,26,18.1193,26,19.5L26,36.5C26,37.8807,24.8807,39,23.5,39L23.5,39C22.1193,39,21,37.8807,21,36.5L21,19.5z" />
<GeometryDrawing Geometry="F0 M56,56z M0,0z M20.5,19.5C20.5,17.8431 21.8431,16.5 23.5,16.5 25.1569,16.5 26.5,17.8431 26.5,19.5L26.5,36.5C26.5,38.1569 25.1569,39.5 23.5,39.5 21.8431,39.5 20.5,38.1569 20.5,36.5L20.5,19.5z M23.5,17.5C22.3954,17.5,21.5,18.3954,21.5,19.5L21.5,36.5C21.5,37.6046 22.3954,38.5 23.5,38.5 24.6046,38.5 25.5,37.6046 25.5,36.5L25.5,19.5C25.5,18.3954,24.6046,17.5,23.5,17.5z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF6F6F6F" Opacity="0.25" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD1CFCD" Geometry="F1 M56,56z M0,0z M30,19.5C30,18.1193,31.1193,17,32.5,17L32.5,17C33.8807,17,35,18.1193,35,19.5L35,36.5C35,37.8807,33.8807,39,32.5,39L32.5,39C31.1193,39,30,37.8807,30,36.5L30,19.5z" />
<GeometryDrawing Geometry="F0 M56,56z M0,0z M29.5,19.5C29.5,17.8431 30.8431,16.5 32.5,16.5 34.1569,16.5 35.5,17.8431 35.5,19.5L35.5,36.5C35.5,38.1569 34.1569,39.5 32.5,39.5 30.8431,39.5 29.5,38.1569 29.5,36.5L29.5,19.5z M32.5,17.5C31.3954,17.5,30.5,18.3954,30.5,19.5L30.5,36.5C30.5,37.6046 31.3954,38.5 32.5,38.5 33.6046,38.5 34.5,37.6046 34.5,36.5L34.5,19.5C34.5,18.3954,33.6046,17.5,32.5,17.5z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF6F6F6F" Opacity="0.25" />
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</UserControl.Resources>
<Grid Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualHeight}">
<Canvas Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualHeight}"
ClipToBounds="True" x:Name="InkCanvasHostCanvas" x:FieldModifier="private" Loaded="HostCanvas_Loaded" SizeChanged="HostCanvas_SizeChanged">
<Canvas.Clip>
<CombinedGeometry GeometryCombineMode="Exclude" x:Name="HostCanvasClipGeometry" x:FieldModifier="private">
<CombinedGeometry.Geometry1>
<RectangleGeometry x:Name="HostCanvasClipGeometry1" x:FieldModifier="private"/>
</CombinedGeometry.Geometry1>
</CombinedGeometry>
</Canvas.Clip>
</Canvas>
<Canvas Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualHeight}"
ClipToBounds="True" x:Name="InkCanvasWrapperCanvas" x:FieldModifier="private" Visibility="Visible">
<local:IccInkCanvas x:Name="WrapperInkCanvas" Background="Transparent" x:FieldModifier="private" Loaded="WrapperInkCanvas_Loaded">
<local:IccInkCanvas.RenderTransform>
<MatrixTransform x:Name="WrapperInkCanvasMatrixTransform" x:FieldModifier="private"/>
</local:IccInkCanvas.RenderTransform>
</local:IccInkCanvas>
</Canvas>
<Canvas Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualHeight}"
ClipToBounds="True" Loaded="EraserOverlayCanvas_Loaded" x:Name="EraserCanvas" Background="Transparent" x:FieldModifier="private">
<Image Canvas.Left="0" Canvas.Top="0" RenderTransformOrigin="0,0" Width="0" x:Name="EraserFeedback" x:FieldModifier="private">
<Image.RenderTransform>
<TranslateTransform x:Name="EraserFeedbackTranslateTransform" x:FieldModifier="private"/>
</Image.RenderTransform>
</Image>
</Canvas>
<Canvas Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualHeight}"
ClipToBounds="True" Loaded="RectangleAreaEraserCanvas_Loaded" x:Name="RectangleAreaEraserCanvas" Background="Transparent" x:FieldModifier="private">
<Border Visibility="Collapsed" x:Name="AreaErasingFeedback" x:FieldModifier="private" Width="128" Height="128" BorderBrush="#9971717a" BorderThickness="1" Background="#3371717a">
<Border VerticalAlignment="Center" HorizontalAlignment="Center" Width="68" Height="22" CornerRadius="10" Background="#b91c1c">
<TextBlock Margin="8,2" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White">区域擦除</TextBlock>
</Border>
</Border>
</Canvas>
<Border Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl}}, Path=ActualHeight}"
x:Name="RoamingHitTestBorder" x:FieldModifier="private" Background="Transparent" Loaded="RoamingHitTestBorder_Loaded"/>
</Grid>
</UserControl>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
using InkCanvasForClass.IccInkCanvas.Utils.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
namespace InkCanvasForClass.IccInkCanvas {
public class IccBoardPage {
public Guid GUID { get; set; }
public Dispatcher Dispatcher { get; set; }
public DispatcherContainer Container { get; set; }
public InkCanvas InkCanvas { get; set; }
public TimeMachine TimeMachine { get; set; } = new TimeMachine();
public long LastStrokeID { get; set; } = 0;
public Matrix TransformMatrix { get; set; } = new Matrix();
}
}
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
using InkCanvasForClass.IccInkCanvas.Utils.Threading;
namespace InkCanvasForClass.IccInkCanvas {
public class IccDispatcherInkCanvasInfo {
public Dispatcher Dispatcher { get; private set; }
public Guid GUID { get; private set; } = Guid.NewGuid();
public async Task InitDispatcher() {
Dispatcher = await UIDispatcher.RunNewAsync("IccInkCanvas_" + GUID.ToString());
}
}
}
@@ -0,0 +1,311 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Media;
using InkCanvasForClass.IccInkCanvas.Settings;
namespace InkCanvasForClass.IccInkCanvas {
class CustomDynamicRenderer : DynamicRenderer {
private class StylusProcessedCallbackData {
public int StylusDeviceID;
public int TabletDeviceID;
}
private Point prevPoint;
private IccInkCanvas _inkCanvas;
private List<StylusPoint> pointsList = new List<StylusPoint>();
private StylusProcessedCallbackData _stylusProcessedCallbackData;
public InputtingDeviceType InputType = InputtingDeviceType.None;
private void ClearPointsList() {
pointsList.Clear();
}
private void PushPoint(StylusPoint point) {
pointsList.Add(point);
if (pointsList.Count > 15) {
pointsList.RemoveRange(0,pointsList.Count - 15);
}
}
public CustomDynamicRenderer(IccInkCanvas iccInkCanvas) {
_inkCanvas = iccInkCanvas;
}
protected override void OnStylusDown(RawStylusInput rawStylusInput) {
prevPoint = new Point(double.NegativeInfinity, double.NegativeInfinity);
ClearPointsList();
// 判断当前设备类型
var styDevice = rawStylusInput.StylusDeviceId;
var tabletDevice = rawStylusInput.TabletDeviceId;
var pts = rawStylusInput.GetStylusPoints();
if (pts.Count == 1) {
PushPoint(pts.Single());
} else if (pts.Count > 1) {
PushPoint(pts[pts.Count-1]);
}
base.OnStylusDown(rawStylusInput);
_stylusProcessedCallbackData = new StylusProcessedCallbackData() {
StylusDeviceID = styDevice,
TabletDeviceID = tabletDevice,
};
}
protected override void OnStylusDownProcessed(object callbackData, bool targetVerified) {
var data = _stylusProcessedCallbackData;
var tabletDevices = Tablet.TabletDevices;
if (data.StylusDeviceID == 0 && data.TabletDeviceID == 0) InputType = InputtingDeviceType.Mouse;
foreach (TabletDevice tabletDevice in tabletDevices) {
if (tabletDevice.Id == data.TabletDeviceID && tabletDevice.Type == TabletDeviceType.Stylus)
InputType = InputtingDeviceType.Stylus;
if (tabletDevice.Id == data.TabletDeviceID && tabletDevice.Type == TabletDeviceType.Touch)
InputType = InputtingDeviceType.Touch;
}
base.OnStylusDownProcessed(callbackData, targetVerified);
}
protected override void OnStylusMove(RawStylusInput rawStylusInput) {
base.OnStylusMove(rawStylusInput);
var pts = rawStylusInput.GetStylusPoints();
if (pts.Count == 1) {
PushPoint(pts.Single());
} else if (pts.Count > 1) {
if (InputType != InputtingDeviceType.Stylus) PushPoint(pts[pts.Count-1]);
}
}
protected override void OnStylusUpProcessed(object callbackData, bool targetVerified) {
//InputType = InputtingDeviceType.None;
// TODO: 触摸支持
base.OnStylusUpProcessed(callbackData, targetVerified);
}
private void DrawBeautifulNibStroke(DrawingContext drawingContext) {
try {
var sp = new StylusPointCollection();
var n = pointsList.Count - 1;
var pressure = 0.1;
var x = 10;
if (n == 1) return;
if (n >= x) {
for (var i = 0; i < n - x; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = pointsList[i].X;
point.Y = pointsList[i].Y;
sp.Add(point);
}
for (var i = n - x; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure);
point.X = pointsList[i].X;
point.Y = pointsList[i].Y;
sp.Add(point);
}
} else {
for (var i = 0; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)(0.4 * (n - i) / n + pressure);
point.X = pointsList[i].X;
point.Y = pointsList[i].Y;
sp.Add(point);
}
}
var da = DrawingAttributes.Clone();
da.Width -= 0.5;
da.Height -= 0.5;
var stk = new Stroke(sp, da);
stk.Draw(drawingContext);
} catch {}
}
private void DrawSolidNibStroke(DrawingContext drawingContext) {
try {
var sp = new StylusPointCollection();
foreach (var pt in pointsList) {
var point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = pt.X;
point.Y = pt.Y;
sp.Add(point);
}
var da = DrawingAttributes.Clone();
da.Width -= 0.5;
da.Height -= 0.5;
var stk = new Stroke(sp, da);
stk.Draw(drawingContext);
}
catch {}
}
private void DrawSolidNibStrokeForStylus(StylusPointCollection stylusPoints, DrawingContext drawingContext) {
try {
var sp = new StylusPointCollection();
foreach (var pt in stylusPoints) {
var point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = pt.X;
point.Y = pt.Y;
sp.Add(point);
}
var da = DrawingAttributes.Clone();
var stk = new Stroke(sp, da);
stk.Draw(drawingContext);
}
catch {}
}
protected override void OnDraw(DrawingContext drawingContext,
StylusPointCollection stylusPoints,
Geometry geometry, Brush fillBrush) {
if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Beautiful && InputType != InputtingDeviceType.Stylus) {
DrawBeautifulNibStroke(drawingContext);
} else if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Solid && InputType != InputtingDeviceType.Stylus) {
DrawSolidNibStroke(drawingContext);
} else if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Solid && InputType == InputtingDeviceType.Stylus) {
DrawSolidNibStrokeForStylus(stylusPoints, drawingContext);
} else if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Default) {
base.OnDraw(drawingContext, stylusPoints, geometry, fillBrush);
} else {
base.OnDraw(drawingContext, stylusPoints, geometry, fillBrush);
}
}
}
internal class IccInkCanvas : InkCanvas {
CustomDynamicRenderer customDynamicRenderer;
public BoardSettings BoardSettings { get; set; } = new BoardSettings();
public IccInkCanvas() {
customDynamicRenderer = new CustomDynamicRenderer(this);
DynamicRenderer = customDynamicRenderer;
// 通过反射移除InkCanvas自带的默认 Delete按键事件
var commandBindingsField =
typeof(CommandManager).GetField("_classCommandBindings", BindingFlags.NonPublic | BindingFlags.Static);
var bnds = commandBindingsField.GetValue(null) as HybridDictionary;
var inkCanvasBindings = bnds[typeof(InkCanvas)] as CommandBindingCollection;
var enumerator = inkCanvasBindings.GetEnumerator();
while (enumerator.MoveNext()) {
var item = (CommandBinding)enumerator.Current;
if (item.Command == ApplicationCommands.Delete) {
var executedField =
typeof(CommandBinding).GetField("Executed", BindingFlags.NonPublic | BindingFlags.Instance);
var canExecuteField =
typeof(CommandBinding).GetField("CanExecute", BindingFlags.NonPublic | BindingFlags.Instance);
executedField.SetValue(item, new ExecutedRoutedEventHandler((sender, args) => { }));
canExecuteField.SetValue(item, new CanExecuteRoutedEventHandler((sender, args) => { }));
}
}
// 为IccInkCanvas注册自定义的 Delete按键Command并Invoke OnDeleteCommandFired。
CommandManager.RegisterClassCommandBinding(typeof(IccInkCanvas), new CommandBinding(ApplicationCommands.Delete,
(sender, args) => {
DeleteKeyCommandFired?.Invoke(this, new RoutedEventArgs());
}, (sender, args) => {
args.CanExecute = GetSelectedStrokes().Count != 0;
}));
}
protected override void OnStrokeCollected(InkCanvasStrokeCollectedEventArgs e) {
IccStroke customStroke = new IccStroke(e.Stroke.StylusPoints, e.Stroke.DrawingAttributes);
if (e.Stroke is IccStroke) {
Strokes.Add(e.Stroke);
} else {
Strokes.Remove(e.Stroke);
Strokes.Add(customStroke);
}
if (BoardSettings.StrokeNibStyle == StrokeNibStyle.Beautiful && customDynamicRenderer.InputType != InputtingDeviceType.Stylus) {
try {
var stylusPoints = new StylusPointCollection();
var n = customStroke.StylusPoints.Count - 1;
var pressure = 0.1;
var x = 10;
if (n == 1) return;
if (n >= x) {
for (var i = 0; i < n - x; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = customStroke.StylusPoints[i].X;
point.Y = customStroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
for (var i = n - x; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure);
point.X = customStroke.StylusPoints[i].X;
point.Y = customStroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
else {
for (var i = 0; i <= n; i++) {
var point = new StylusPoint();
point.PressureFactor = (float)(0.4 * (n - i) / n + pressure);
point.X = customStroke.StylusPoints[i].X;
point.Y = customStroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
customStroke.StylusPoints = stylusPoints;
} catch { }
} else if (BoardSettings.StrokeNibStyle == StrokeNibStyle.Solid) {
try {
var sp = new StylusPointCollection();
foreach (var pt in customStroke.StylusPoints) {
var point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = pt.X;
point.Y = pt.Y;
sp.Add(point);
}
customStroke.StylusPoints = sp;
} catch { }
}
InkCanvasStrokeCollectedEventArgs args =
new InkCanvasStrokeCollectedEventArgs(customStroke);
base.OnStrokeCollected(args);
Trace.WriteLine("dfsffdsdfdfsfds");
}
public event EventHandler<RoutedEventArgs> DeleteKeyCommandFired;
public InputtingDeviceType InputtingDeviceType { get; private set; }
}
}

Some files were not shown because too many files have changed in this diff Show More