diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f905cbc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,64 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain +.vs \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff4070c --- /dev/null +++ b/.gitignore @@ -0,0 +1,263 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +.vs \ No newline at end of file diff --git a/Bin/Debug4KSO/config/EXCEL.xml b/Bin/Debug4KSO/config/EXCEL.xml new file mode 100644 index 0000000..0d41f95 --- /dev/null +++ b/Bin/Debug4KSO/config/EXCEL.xml @@ -0,0 +1,374 @@ + + + excel.application + 33 + 115 + 70 + Application.Left + Application.Width + Application.Top + Selection.Text + + + + 字体颜色[zitiyanse] : 自动[zidong] + Selection.Font.Color + 将所选字体的颜色设置为自动 + + -16777216 + 0 + + + + 字体颜色[zitiyanse] : 红色[hongse] + Selection.Font.Color + 将所选字体的颜色设置为红色 + + 255 + 0 + + + + 字体颜色[zitiyanse] : 蓝色[lanse] + Selection.Font.Color + 将所选字体的颜色设置为蓝色 + + 16711680 + 0 + + + + 字体颜色[zitiyanse] : 白色[baise] + Selection.Font.Color + 将所选字体的颜色设置为白色 + + 16777215 + 0 + + + + 字体颜色[zitiyanse] : 黄色[huangse] + Selection.Font.Color + 将所选字体的颜色设置为黄色 + + 65535 + 0 + + + + 字体颜色[zitiyanse] : 绿色[lvse] + Selection.Font.Color + 将所选字体的颜色设置为绿色 + + 32768 + 0 + + + + 字体颜色[zitiyanse] : 黑色[heise] + Selection.Font.Color + 将所选字体的颜色设置为黑色 + + 0 + 0 + + + + 字体颜色[zitiyanse] : 选择颜色[xuanzeyanse] + @Win32Color("Selection.Font.Color")!Selection.Font.Color + 从颜色对话框中选择字体颜色 + + -16777216 + 0 + + + + 字体[ziti] : 宋体[songti] + Selection.Font.Name + 将所选文字的字体设置为宋体 + + 宋体 + 0 + + + + 字体[ziti] : 仿宋[fangsong] + Selection.Font.Name + 将所选文字的字体设置为仿宋 + + 仿宋 + 0 + + + + 字体[ziti] : 隶书[lishu] + Selection.Font.Name + 将所选文字的字体设置为隶书 + + 隶书 + 0 + + + + 字体[ziti] : 微软雅黑[weiruanyahei] + Selection.Font.Name + 将所选文字的字体设置为微软雅黑 + + 微软雅黑 + 0 + + + + 字体[ziti] : 黑体[heiti] + Selection.Font.Name + 将所选文字的字体设置为黑体 + + 黑体 + 0 + + + + 字体[ziti] : Times New Roman + Selection.Font.Name + 将所选文字的字体设置为Times New Roman + + "Times New Roman" + 0 + + + + 字体[ziti] : Consolas + Selection.Font.Name + 将所选文字的字体设置为Consolas + + Consolas + 0 + + + + 字体[ziti] : Arial + Selection.Font.Name + 将所选文字的字体设置为Arial + + Arial + 0 + + + + 字体[ziti] : 字体名 + Selection.Font.Name + 将所选的文字设置为指定名称的字体 + . + + 0 + + + + 视图[shitu] : 分页预览[fenyeyulan] + ActiveWindow.View + 将视图设置为分页预览 + + 2 + 0 + + + + 视图[shitu] : 普通视图[putongshitu] + ActiveWindow.View + 将视图设置为普通视图 + + 1 + 0 + + + + 填充[tianchong] : 自动[zidong] + Selection.Interior.Color + 将所选单元格的填充颜色设置为自动 + + -16777216 + 0 + + + + 填充[tianchong] : 红色[hongse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为红色 + + 255 + 0 + + + + 填充[tianchong] : 蓝色[lanse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为蓝色 + + 16711680 + 0 + + + + 填充[tianchong] : 白色[baise] + Selection.Interior.Color + 将所选单元格的填充颜色设置为白色 + + 16777215 + 0 + + + + 填充[tianchong] : 黄色[huangse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为黄色 + + 65535 + 0 + + + + 填充[tianchong] : 绿色[lvse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为绿色 + + 32768 + 0 + + + + 填充[tianchong] : 黑色[heise] + Selection.Interior.Color + 将所选单元格的填充颜色设置为黑色 + + 0 + 0 + + + + 填充[tianchong] : 选择颜色[xuanzeyanse] + @Win32Color("Selection.Interior.Color")!Selection.Interior.Color + 从颜色对话框中选择字体颜色 + + -16777216 + 0 + + + + 批注[pizhu] : 插入[charupizhu] + @AuthorAndContent("Application.UserName", "{$1}")!ActiveCell.AddComment("{$1}") + 为单元格插入一个批注 + . + + 0 + + + + 纸张方向[zhizhangfangxiang] : 横向[hengxiang] + ActiveSheet.PageSetup.Orientation + 更改页面设置中的纸张方向为横向 + + 2 + 0 + + + + 纸张方向[zhizhangfangxiang] : 纵向[zongxiang] + ActiveSheet.PageSetup.Orientation + 更改页面设置中的纸张方向为纵向 + + 1 + 0 + + + + 纸张大小[zhizhangdaxiao] : A3 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为A3 + + 8 + 0 + + + + 纸张大小[zhizhangdaxiao] : A4 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为A4 + + 9 + 0 + + + + 纸张大小[zhizhangdaxiao] : B4 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为B4 + + 12 + 0 + + + + 纸张大小[zhizhangdaxiao] : B5 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为B5 + + 13 + 0 + + + + 纸张大小[zhizhangdaxiao] : 信纸[xinzhi] + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为Letter + + 1 + 0 + + + + 纸张大小[zhizhangdaxiao] : 法律专用纸[falvzhuanyongzhi] + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为Legal + + 5 + 0 + + + + 设置打印区域[shezhidayinquyu] + @GetObject("{$1}")!ActiveSheet.PageSetup.PrintArea + 将当前选择区域设置为打印区域 + + Selection.Address + 0 + + + + 取消打印区域[quxiaodayinquyu] + @EmptyString()!ActiveSheet.PageSetup.PrintArea + 清除之前设置的打印区域 + + + 0 + + + + 窗口最大化[chuangkouzuidahua maximum] + Application.WindowState + 使程序窗口最大化 + + -4137 + 0 + + + + 窗口还原[chuangkouhuanyuan normal] + Application.WindowState + 使程序窗口大小还原 + + -4143 + 0 + + + + \ No newline at end of file diff --git a/Bin/Debug4KSO/config/POWERPNT.xml b/Bin/Debug4KSO/config/POWERPNT.xml new file mode 100644 index 0000000..4427f41 --- /dev/null +++ b/Bin/Debug4KSO/config/POWERPNT.xml @@ -0,0 +1,185 @@ + + + powerpoint.application + 231 + 121 + 55 + Left + Width + Top + ActiveWindow.Selection.TextRange.Text + + + + 字体颜色[zitiyanse] : 自动[zidong] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为自动 + + -16777216 + 0 + + + + 字体颜色[zitiyanse] : 红色[hongse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为红色 + + 255 + 0 + + + + 字体颜色[zitiyanse] : 蓝色[lanse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为蓝色 + + 16711680 + 0 + + + + 字体颜色[zitiyanse] : 白色[baise] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为白色 + + 16777215 + 0 + + + + 字体颜色[zitiyanse] : 黄色[huangse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为黄色 + + 65535 + 0 + + + + 字体颜色[zitiyanse] : 绿色[lvse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为绿色 + + 32768 + 0 + + + + 字体颜色[zitiyanse] : 黑色[heise] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为黑色 + + 0 + 0 + + + + 字体颜色[zitiyanse] : 选择颜色[xuanzeyanse] + @Win32Color("ActiveWindow.Selection.TextRange.Font.Color.RGB")!ActiveWindow.Selection.TextRange.Font.Color + 从颜色对话框中选择字体颜色 + + + 0 + + + + 字体[ziti] : 宋体[songti] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为宋体 + + 宋体 + 0 + + + + 字体[ziti] : 仿宋[fangsong] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为仿宋 + + 仿宋 + 0 + + + + 字体[ziti] : 隶书[lishu] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为隶书 + + 隶书 + 0 + + + + 字体[ziti] : 微软雅黑[weiruanyahei] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为微软雅黑 + + 微软雅黑 + 0 + + + + 字体[ziti] : 黑体[heiti] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为黑体 + + 黑体 + 0 + + + + 字体[ziti] : Times New Roman + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为Times New Roman + + "Times New Roman" + 0 + + + + 字体[ziti] : Consolas + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为Consolas + + Consolas + 0 + + + + 字体[ziti] : Arial + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为Arial + + Arial + 0 + + + + 字体[ziti] : 字体名 + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为指定名称的字体 + . + + 0 + + + + 窗口最大化[chuangkouzuidahua maximum] + WindowState + 使程序窗口最大化 + + 3 + 0 + + + + 窗口还原[chuangkouhuanyuan normal] + WindowState + 使程序窗口大小还原 + + 1 + 0 + + + + \ No newline at end of file diff --git a/Bin/Debug4KSO/config/WINWORD.xml b/Bin/Debug4KSO/config/WINWORD.xml new file mode 100644 index 0000000..1b63920 --- /dev/null +++ b/Bin/Debug4KSO/config/WINWORD.xml @@ -0,0 +1,697 @@ + + + word.application + 77 + 130 + 228 + Application.Left + Application.Width + Application.Top + Selection.Text + + + + 标尺[biaochi] : 切换[qiehuan] + !ActiveWindow.DisplayRulers + 显示或隐藏标尺 + + True + 0 + + + + 表格[biaoge] : 插入[charubiaoge] {x,y} + Selection.Tables.Add(Selection.Range, {$1}, {$2}) + 在光标位置插入一个x行、y列的表格,默认为5行2列 + \d + 5,2 + 0 + + + + 表格[biaoge] : 删除[shanchubiaoge] + Selection.Tables[1].Delete() + 删除光标所在的表格 + + + 0 + + + + 表格[biaoge] : 拆分单元格[chaifendanyuange] {x,y} + Selection.Cells.Split({$1}, {$2}) + 拆分光标所在的表格为x行、y列 + \d + + 0 + + + + 表格[biaoge] : 合并单元格[hebingdanyuange] + Selection.Cells.Merge() + 合并所选单元格 + + + 0 + + + + 表格[biaoge] : 拆分表格[chaifenbiaoge] + Selection.SplitTable() + 拆分当前表格 + + + 0 + + + + 表格[biaoge] : 删除行[shanchuhang] + Selection.Rows.Delete() + 删除光标所选的表格行 + + + 0 + + + + 表格[biaoge] : 删除列[shanchulie] + Selection.Columns.Delete() + 删除光标所选的表格列 + + + 0 + + + + 表格[biaoge] : 插入行[charuhang] 上[shang] + Selection.Rows.Add(Selection.Rows[1]) + 在光标所在表格行的上方插入新的一表格行 + + + 0 + + + + 表格[biaoge] : 插入行[charuhang] 下[xia] + Selection.Rows.Add() + 在光标所在表格行的下方插入新的一表格行 + + + 0 + + + + 表格[biaoge] : 插入列[charulie] 左[zuo] + Selection.Columns.Add(Selection.Columns[1]) + 在光标所在表格列的左方插入新的一表格列 + + + 0 + + + + 表格[biaoge] : 插入列[charulie] 右[you] + Selection.Columns.Add() + 在光标所在表格列的右方插入新的一表格列 + + + 0 + + + + 画布[huabu] : 插入画布[charuhuabu] + ActiveDocument.Shapes.AddCanvas(90, 70, 420, 140) + 在默认位置插入一个画布 + + + 0 + + + + 上标[shangbiao] : 开[kai] + Selection.Font.Superscript + 为所选文字设置上标 + + 1 + 0 + + + + 上标[shangbiao] : 关[guan] + Selection.Font.Superscript + 为所选文字取消设置上标 + + 0 + 0 + + + + 下标[xiabiao] : 开[kai] + Selection.Font.Subscript + 为所选文字设置下标 + + 1 + 0 + + + + 下标[xiabiao] : 关[guan] + Selection.Font.Subscript + 为所选文字取消设置下标 + + 0 + 0 + + + + 阴影[yinying] : 开[kai] + Selection.Font.Shadow + 为所选文字设置阴影 + + 1 + 0 + + + + 阴影[yinying] : 关[guan] + Selection.Font.Shadow + 为所选文字取消设置阴影 + + 0 + 0 + + + + 清除字体格式[qingchuzitigeshi] + Selection.ClearFormatting() + 清除所选文字的格式 + + + 0 + + + + 字体颜色[zitiyanse] : 自动[zidong] + Selection.Font.Color + 将所选字体的颜色设置为自动 + + -16777216 + 0 + + + + 字体颜色[zitiyanse] : 红色[hongse] + Selection.Font.Color + 将所选字体的颜色设置为红色 + + 255 + 0 + + + + 字体颜色[zitiyanse] : 蓝色[lanse] + Selection.Font.Color + 将所选字体的颜色设置为蓝色 + + 16711680 + 0 + + + + 字体颜色[zitiyanse] : 白色[baise] + Selection.Font.Color + 将所选字体的颜色设置为白色 + + 16777215 + 0 + + + + 字体颜色[zitiyanse] : 黄色[huangse] + Selection.Font.Color + 将所选字体的颜色设置为黄色 + + 65535 + 0 + + + + 字体颜色[zitiyanse] : 绿色[lvse] + Selection.Font.Color + 将所选字体的颜色设置为绿色 + + 32768 + 0 + + + + 字体颜色[zitiyanse] : 黑色[heise] + Selection.Font.Color + 将所选字体的颜色设置为黑色 + + 0 + 0 + + + + 字体颜色[zitiyanse] : 选择颜色[xuanzeyanse] + @Win32Color("Selection.Font.Color")!Selection.Font.Color + 从颜色对话框中选择字体颜色 + + + 0 + + + + 字体[ziti] : 宋体[songti] + Selection.Font.Name + 将所选文字的字体设置为宋体 + + 宋体 + 0 + + + + 字体[ziti] : 仿宋[fangsong] + Selection.Font.Name + 将所选文字的字体设置为仿宋 + + 仿宋 + 0 + + + + 字体[ziti] : 隶书[lishu] + Selection.Font.Name + 将所选文字的字体设置为隶书 + + 隶书 + 0 + + + + 字体[ziti] : 微软雅黑[weiruanyahei] + Selection.Font.Name + 将所选文字的字体设置为微软雅黑 + + 微软雅黑 + 0 + + + + 字体[ziti] : 黑体[heiti] + Selection.Font.Name + 将所选文字的字体设置为黑体 + + 黑体 + 0 + + + + 字体[ziti] : Times New Roman + Selection.Font.Name + 将所选文字的字体设置为Times New Roman + + "Times New Roman" + 0 + + + + 字体[ziti] : Consolas + Selection.Font.Name + 将所选文字的字体设置为Consolas + + Consolas + 0 + + + + 字体[ziti] : Arial + Selection.Font.Name + 将所选文字的字体设置为Arial + + Arial + 0 + + + + 字体[ziti] : 字体名 + Selection.Font.Name + 将所选文字的字体设置为指定名称的字体 + . + + 0 + + + + 批注[pizhu] : 插入[charupizhu] 批注内容 + Selection.Comments.Add(Selection.Range, "{$1}") + 为所选内容插入一个批注 + . + 修改批注 + 0 + + + + 批注[pizhu] : 删除[shanchupizhu] + Selection.Comments[1].Delete() + 删除当前批注 + + + 0 + + + + 批注[pizhu] : 修改[xiugaipizhu] 批注内容 + Selection.Comments[1].Range.Text + 修改当前批注 + . + + 0 + + + + 书签[shuqian] : 插入[charushuqian] 书签名 + Selection.Bookmarks.Add("{$1}", Selection.Range) + 在当前位置插入一个书签 + . + + 0 + + + + 修订[xiuding] : 开[kai] + ActiveDocument.TrackRevisions + 打开修订模式 + + True + 0 + + + + 修订[xiuding] : 关[guan] + ActiveDocument.TrackRevisions + 关闭修订模式 + + False + 0 + + + + 修订[xiuding] : 接受此处[jieshoucichu] + Selection.Range.Revisions.AcceptAll() + 接受光标选择区域的所有修订 + + + 0 + + + + 修订[xiuding] : 拒绝此处[jujuecichu] + Selection.Range.Revisions.RejectAll() + 接受光标选择区域的所有修订 + + + 0 + + + + 修订[xiuding] : 接受全部[jieshouquanbu] + ActiveDocument.AcceptAllRevisions() + 接受文档中的全部修订 + + + 0 + + + + 修订[xiuding] : 拒绝全部[jujuequanbu] + ActiveDocument.RejectAllRevisions() + 拒绝文档中的全部修订 + + + 0 + + + + 书签[shuqian] : 删除[shanchushuqian] + Selection.Bookmarks[1].Delete() + 修改当前书签 + + + 0 + + + + 跳转[gotopage tiaozhuan] : 页码[yema] + Selection.GoTo(1, 1, {$1}, "") + 光标跳转到指定页码 + \d + + 0 + + + + 跳转[gotosection tiaozhuan] : 节[jie] + Selection.GoTo(0, 1, {$1}, "") + 光标跳转到指定节 + \d + + 0 + + + + 跳转[gotoline tiaozhuan] : 行[hang] + Selection.GoTo(3, 1, {$1}, "") + 光标跳转到指定行 + \d + + 0 + + + + 跳转[gotobookmark tiaozhuan] : 书签[shuqian] 书签名 + Selection.GoTo(-1, 1, 0, "{$1}") + 光标跳转到指定书签 + . + + 0 + + + + 样式[yangshi] : 正文[zhengwen] + Selection.Range.Style + 将所选内容的样式设置为正文 + + 正文 + 0 + + + + 样式[yangshi] : 标题 1[biaoti 1] + Selection.Range.Style + 将所选内容的样式设置为标题 1 + + "标题 1" + 0 + + + + 样式[yangshi] : 标题 2[biaoti 2] + Selection.Range.Style + 将所选内容的样式设置为标题 2 + + "标题 2" + 0 + + + + 样式[yangshi] : 标题 3[biaoti 3] + Selection.Range.Style + 将所选内容的样式设置为标题 3 + + "标题 3" + 0 + + + + 样式[yangshi] : 样式名 + Selection.Range.Style + 将所选内容的样式设置为输入的样式名 + . + + 0 + + + + 视图[shitu] : 页面视图[yemianshitu] + ActiveWindow.View.Type + 将页面视图切换为页面视图 + + 3 + 0 + + + + 视图[shitu] : 大纲视图[dagangshitu] + ActiveWindow.View.Type + 将页面视图切换为大纲视图 + + 2 + 0 + + + + 视图[shitu] : Web视图[shitu] + ActiveWindow.View.Type + 将页面视图切换为Web视图 + + 6 + 0 + + + + 拆分窗口[chaifenchuangkou] 切换[qiehuan] + !ActiveWindow.Split + 打开或取消拆分窗口 + + + 0 + + + + 打印[dayin] : 全部[quanbu] + ActiveDocument.PrintOut(false, true, 0) + 打印文档的全部内容 + + + 0 + + + + 打印[dayin] : 当前页[dangqianye] + ActiveDocument.PrintOut(false, true, 2) + 打印文档的当前页 + + + 0 + + + + 打印[dayin] : 页码范围[yemafanwei] {x,y} + ActiveDocument.PrintOut(false, true, 3, "", {$1}, {$2}) + 打印文档的第a页到第b页 + \d + + 0 + + + + 纸张方向[zhizhangfangxiang] : 横向[hengxiang] + ActiveDocument.PageSetup.Orientation + 更改页面设置中的纸张方向为横向 + + 1 + 0 + + + + 纸张方向[zhizhangfangxiang] : 纵向[zongxiang] + ActiveDocument.PageSetup.Orientation + 更改页面设置中的纸张方向为纵向 + + 0 + 0 + + + + 纸张大小[zhizhangdaxiao] : A3 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为A3 + + 6 + 0 + + + + 纸张大小[zhizhangdaxiao] : A4 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为A4 + + 7 + 0 + + + + 纸张大小[zhizhangdaxiao] : B4 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为B4 + + 10 + 0 + + + + 纸张大小[zhizhangdaxiao] : B5 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为B5 + + 11 + 0 + + + + 纸张大小[zhizhangdaxiao] : 信纸[xinzhi] + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为Letter + + 2 + 0 + + + + 纸张大小[zhizhangdaxiao] : 法律专用纸[falvzhuanyongzhi] + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为Legal + + 4 + 0 + + + + 兼容模式[jianrongmoshi] + ActiveDocument.SetCompatibilityMode(11) + 将文档模式改为wdWord2003 + + + 0 + + + + 非兼容模式[feijianrongmoshi] + ActiveDocument.SetCompatibilityMode(14) + 将文档模式改为wdWord2010 + + + 0 + + + + 窗口最大化[chuangkouzuidahua maximum] + Application.WindowState + 使程序窗口最大化 + + 1 + 0 + + + + 窗口还原[chuangkouhuanyuan normal] + Application.WindowState + 使程序窗口大小还原 + + 0 + 0 + + + \ No newline at end of file diff --git a/Bin/Debug4KSO/config/__global.xml b/Bin/Debug4KSO/config/__global.xml new file mode 100644 index 0000000..13db282 --- /dev/null +++ b/Bin/Debug4KSO/config/__global.xml @@ -0,0 +1,45 @@ + + + + 255 + 255 + 255 + Left + Width + Top + GetSelection + + + BM + Call("http://wpswebsvr.wps.kingsoft.net/ksbm/", "") + 打开Bug Manager + + + 0 + + + BM {ID} + Call("http://wpswebsvr.wps.kingsoft.net/ksbm/ViewIssue.aspx?IssueID={$1}", "") + 跳转到Bug Mananger中指定的Bug ID + . + + 0 + + + 代码审查[daimashencha] + Call("http://10.20.172.159/reviews/dashboard/", "") + 打开在线代码审查页面 + + + 0 + + + 代码审查[daimashencha] {ID} + Call("http://10.20.172.159/reviews/r/{$1}/", "") + 跳转到在线代码审查中指定的条目 + . + + 0 + + + \ No newline at end of file diff --git a/Bin/Debug4KSO/config/et.xml b/Bin/Debug4KSO/config/et.xml new file mode 100644 index 0000000..4e5421b --- /dev/null +++ b/Bin/Debug4KSO/config/et.xml @@ -0,0 +1,374 @@ + + + ket.application, et.application + 99 + 180 + 47 + Application.Left + Application.Width + Application.Top + Selection.Text + + + + 字体颜色[zitiyanse] : 自动[zidong] + Selection.Font.Color + 将所选字体的颜色设置为自动 + + -16777216 + 0 + + + + 字体颜色[zitiyanse] : 红色[hongse] + Selection.Font.Color + 将所选字体的颜色设置为红色 + + 255 + 0 + + + + 字体颜色[zitiyanse] : 蓝色[lanse] + Selection.Font.Color + 将所选字体的颜色设置为蓝色 + + 16711680 + 0 + + + + 字体颜色[zitiyanse] : 白色[baise] + Selection.Font.Color + 将所选字体的颜色设置为白色 + + 16777215 + 0 + + + + 字体颜色[zitiyanse] : 黄色[huangse] + Selection.Font.Color + 将所选字体的颜色设置为黄色 + + 65535 + 0 + + + + 字体颜色[zitiyanse] : 绿色[lvse] + Selection.Font.Color + 将所选字体的颜色设置为绿色 + + 32768 + 0 + + + + 字体颜色[zitiyanse] : 黑色[heise] + Selection.Font.Color + 将所选字体的颜色设置为黑色 + + 0 + 0 + + + + 字体颜色[zitiyanse] : 选择颜色[xuanzeyanse] + @Win32Color("Selection.Font.Color")!Selection.Font.Color + 从颜色对话框中选择字体颜色 + + -16777216 + 0 + + + + 字体[ziti] : 宋体[songti] + Selection.Font.Name + 将所选文字的字体设置为宋体 + + 宋体 + 0 + + + + 字体[ziti] : 仿宋[fangsong] + Selection.Font.Name + 将所选文字的字体设置为仿宋 + + 仿宋 + 0 + + + + 字体[ziti] : 隶书[lishu] + Selection.Font.Name + 将所选文字的字体设置为隶书 + + 隶书 + 0 + + + + 字体[ziti] : 微软雅黑[weiruanyahei] + Selection.Font.Name + 将所选文字的字体设置为微软雅黑 + + 微软雅黑 + 0 + + + + 字体[ziti] : 黑体[heiti] + Selection.Font.Name + 将所选文字的字体设置为黑体 + + 黑体 + 0 + + + + 字体[ziti] : Times New Roman + Selection.Font.Name + 将所选文字的字体设置为Times New Roman + + "Times New Roman" + 0 + + + + 字体[ziti] : Consolas + Selection.Font.Name + 将所选文字的字体设置为Consolas + + Consolas + 0 + + + + 字体[ziti] : Arial + Selection.Font.Name + 将所选文字的字体设置为Arial + + Arial + 0 + + + + 字体[ziti] : 字体名 + Selection.Font.Name + 将所选的文字设置为指定名称的字体 + . + + 0 + + + + 视图[shitu] : 分页预览[fenyeyulan] + ActiveWindow.View + 将视图设置为分页预览 + + 2 + 0 + + + + 视图[shitu] : 普通视图[putongshitu] + ActiveWindow.View + 将视图设置为普通视图 + + 1 + 0 + + + + 填充[tianchong] : 自动[zidong] + Selection.Interior.Color + 将所选单元格的填充颜色设置为自动 + + -16777216 + 0 + + + + 填充[tianchong] : 红色[hongse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为红色 + + 255 + 0 + + + + 填充[tianchong] : 蓝色[lanse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为蓝色 + + 16711680 + 0 + + + + 填充[tianchong] : 白色[baise] + Selection.Interior.Color + 将所选单元格的填充颜色设置为白色 + + 16777215 + 0 + + + + 填充[tianchong] : 黄色[huangse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为黄色 + + 65535 + 0 + + + + 填充[tianchong] : 绿色[lvse] + Selection.Interior.Color + 将所选单元格的填充颜色设置为绿色 + + 32768 + 0 + + + + 填充[tianchong] : 黑色[heise] + Selection.Interior.Color + 将所选单元格的填充颜色设置为黑色 + + 0 + 0 + + + + 填充[tianchong] : 选择颜色[xuanzeyanse] + @Win32Color("Selection.Interior.Color")!Selection.Interior.Color + 从颜色对话框中选择字体颜色 + + -16777216 + 0 + + + + 批注[pizhu] : 插入[charupizhu] + @AuthorAndContent("Application.UserName", "{$1}")!ActiveCell.AddComment("{$1}") + 为单元格插入一个批注 + . + + 0 + + + + 纸张方向[zhizhangfangxiang] : 横向[hengxiang] + ActiveSheet.PageSetup.Orientation + 更改页面设置中的纸张方向为横向 + + 2 + 0 + + + + 纸张方向[zhizhangfangxiang] : 纵向[zongxiang] + ActiveSheet.PageSetup.Orientation + 更改页面设置中的纸张方向为纵向 + + 1 + 0 + + + + 纸张大小[zhizhangdaxiao] : A3 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为A3 + + 8 + 0 + + + + 纸张大小[zhizhangdaxiao] : A4 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为A4 + + 9 + 0 + + + + 纸张大小[zhizhangdaxiao] : B4 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为B4 + + 12 + 0 + + + + 纸张大小[zhizhangdaxiao] : B5 + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为B5 + + 13 + 0 + + + + 纸张大小[zhizhangdaxiao] : 信纸[xinzhi] + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为Letter + + 1 + 0 + + + + 纸张大小[zhizhangdaxiao] : 法律专用纸[falvzhuanyongzhi] + ActiveWorkbook.ActiveSheet.PageSetup.PaperSize + 将纸张大小更改为Legal + + 5 + 0 + + + + 设置打印区域[shezhidayinquyu] + @GetObject("{$1}")!ActiveSheet.PageSetup.PrintArea + 将当前选择区域设置为打印区域 + + Selection.Address + 0 + + + + 取消打印区域[quxiaodayinquyu] + @EmptyString()!ActiveSheet.PageSetup.PrintArea + 清除之前设置的打印区域 + + + 0 + + + + 窗口最大化[chuangkouzuidahua maximum] + Application.WindowState + 使程序窗口最大化 + + -4137 + 0 + + + + 窗口还原[chuangkouhuanyuan normal] + Application.WindowState + 使程序窗口大小还原 + + -4143 + 0 + + + + \ No newline at end of file diff --git a/Bin/Debug4KSO/config/wpp.xml b/Bin/Debug4KSO/config/wpp.xml new file mode 100644 index 0000000..f2ee0e9 --- /dev/null +++ b/Bin/Debug4KSO/config/wpp.xml @@ -0,0 +1,185 @@ + + + kwpp.application, wpp.application + 231 + 121 + 55 + Left + Width + Top + ActiveWindow.Selection.TextRange.Text + + + + 字体颜色[zitiyanse] : 自动[zidong] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为自动 + + -16777216 + 0 + + + + 字体颜色[zitiyanse] : 红色[hongse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为红色 + + 255 + 0 + + + + 字体颜色[zitiyanse] : 蓝色[lanse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为蓝色 + + 16711680 + 0 + + + + 字体颜色[zitiyanse] : 白色[baise] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为白色 + + 16777215 + 0 + + + + 字体颜色[zitiyanse] : 黄色[huangse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为黄色 + + 65535 + 0 + + + + 字体颜色[zitiyanse] : 绿色[lvse] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为绿色 + + 32768 + 0 + + + + 字体颜色[zitiyanse] : 黑色[heise] + ActiveWindow.Selection.TextRange.Font.Color + 将所选字体的颜色设置为黑色 + + 0 + 0 + + + + 字体颜色[zitiyanse] : 选择颜色[xuanzeyanse] + @Win32Color("ActiveWindow.Selection.TextRange.Font.Color.RGB")!ActiveWindow.Selection.TextRange.Font.Color + 从颜色对话框中选择字体颜色 + + + 0 + + + + 字体[ziti] : 宋体[songti] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为宋体 + + 宋体 + 0 + + + + 字体[ziti] : 仿宋[fangsong] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为仿宋 + + 仿宋 + 0 + + + + 字体[ziti] : 隶书[lishu] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为隶书 + + 隶书 + 0 + + + + 字体[ziti] : 微软雅黑[weiruanyahei] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为微软雅黑 + + 微软雅黑 + 0 + + + + 字体[ziti] : 黑体[heiti] + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为黑体 + + 黑体 + 0 + + + + 字体[ziti] : Times New Roman + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为Times New Roman + + "Times New Roman" + 0 + + + + 字体[ziti] : Consolas + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为Consolas + + Consolas + 0 + + + + 字体[ziti] : Arial + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为Arial + + Arial + 0 + + + + 字体[ziti] : 字体名 + ActiveWindow.Selection.TextRange.Font.Name + 将所选文字的字体设置为指定名称的字体 + . + + 0 + + + + 窗口最大化[chuangkouzuidahua maximum] + WindowState + 使程序窗口最大化 + + 3 + 0 + + + + 窗口还原[chuangkouhuanyuan normal] + WindowState + 使程序窗口大小还原 + + 1 + 0 + + + + \ No newline at end of file diff --git a/Bin/Debug4KSO/config/wps.xml b/Bin/Debug4KSO/config/wps.xml new file mode 100644 index 0000000..4305414 --- /dev/null +++ b/Bin/Debug4KSO/config/wps.xml @@ -0,0 +1,629 @@ + + + kwps.application, wps.application + 77 + 130 + 228 + Application.Left + Application.Width + Application.Top + Selection.Text + + + 标尺[biaochi] : 切换[qiehuan] + !ActiveWindow.DisplayRulers + 显示或隐藏标尺 + + True + 0 + + + 表格[biaoge] : 插入[charubiaoge] {x,y} + Selection.Tables.Add(Selection.Range, {$1}, {$2}) + 在光标位置插入一个x行、y列的表格,默认为5行2列 + \d + 5,2 + 0 + + + 表格[biaoge] : 删除[shanchubiaoge] + Selection.Tables[1].Delete() + 删除光标所在的表格 + + + 0 + + + 表格[biaoge] : 拆分单元格[chaifendanyuange] {x,y} + Selection.Cells.Split({$1}, {$2}) + 拆分光标所在的表格为x行、y列 + \d + + 0 + + + 表格[biaoge] : 合并单元格[hebingdanyuange] + Selection.Cells.Merge() + 合并所选单元格 + + + 0 + + + 表格[biaoge] : 拆分表格[chaifenbiaoge] + Selection.SplitTable() + 拆分当前表格 + + + 0 + + + 表格[biaoge] : 删除行[shanchuhang] + Selection.Rows.Delete() + 删除光标所选的表格行 + + + 0 + + + 表格[biaoge] : 删除列[shanchulie] + Selection.Columns.Delete() + 删除光标所选的表格列 + + + 0 + + + 表格[biaoge] : 插入行[charuhang] 上[shang] + Selection.Rows.Add(Selection.Rows[1]) + 在光标所在表格行的上方插入新的一表格行 + + + 0 + + + 表格[biaoge] : 插入行[charuhang] 下[xia] + Selection.Rows.Add() + 在光标所在表格行的下方插入新的一表格行 + + + 0 + + + 表格[biaoge] : 插入列[charulie] 左[zuo] + Selection.Columns.Add(Selection.Columns[1]) + 在光标所在表格列的左方插入新的一表格列 + + + 0 + + + 表格[biaoge] : 插入列[charulie] 右[you] + Selection.Columns.Add() + 在光标所在表格列的右方插入新的一表格列 + + + 0 + + + 画布[huabu] : 插入画布[charuhuabu] + ActiveDocument.Shapes.AddCanvas(90, 70, 420, 140) + 在默认位置插入一个画布 + + + 0 + + + 上标[shangbiao] : 开[kai] + Selection.Font.Superscript + 为所选文字设置上标 + + 1 + 0 + + + 上标[shangbiao] : 关[guan] + Selection.Font.Superscript + 为所选文字取消设置上标 + + 0 + 0 + + + 下标[xiabiao] : 开[kai] + Selection.Font.Subscript + 为所选文字设置下标 + + 1 + 0 + + + 下标[xiabiao] : 关[guan] + Selection.Font.Subscript + 为所选文字取消设置下标 + + 0 + 0 + + + 阴影[yinying] : 开[kai] + Selection.Font.Shadow + 为所选文字设置阴影 + + 1 + 0 + + + 阴影[yinying] : 关[guan] + Selection.Font.Shadow + 为所选文字取消设置阴影 + + 0 + 0 + + + 清除字体格式[qingchuzitigeshi] + Selection.ClearFormatting() + 清除所选文字的格式 + + + 0 + + + 字体颜色[zitiyanse] : 自动[zidong] + Selection.Font.Color + 将所选字体的颜色设置为自动 + + -16777216 + 0 + + + 字体颜色[zitiyanse] : 红色[hongse] + Selection.Font.Color + 将所选字体的颜色设置为红色 + + 255 + 0 + + + 字体颜色[zitiyanse] : 蓝色[lanse] + Selection.Font.Color + 将所选字体的颜色设置为蓝色 + + 16711680 + 0 + + + 字体颜色[zitiyanse] : 白色[baise] + Selection.Font.Color + 将所选字体的颜色设置为白色 + + 16777215 + 0 + + + 字体颜色[zitiyanse] : 黄色[huangse] + Selection.Font.Color + 将所选字体的颜色设置为黄色 + + 65535 + 0 + + + 字体颜色[zitiyanse] : 绿色[lvse] + Selection.Font.Color + 将所选字体的颜色设置为绿色 + + 32768 + 0 + + + 字体颜色[zitiyanse] : 黑色[heise] + Selection.Font.Color + 将所选字体的颜色设置为黑色 + + 0 + 0 + + + 字体颜色[zitiyanse] : 选择颜色[xuanzeyanse] + @Win32Color("Selection.Font.Color")!Selection.Font.Color + 从颜色对话框中选择字体颜色 + + + 0 + + + 字体[ziti] : 宋体[songti] + Selection.Font.Name + 将所选文字的字体设置为宋体 + + 宋体 + 0 + + + 字体[ziti] : 仿宋[fangsong] + Selection.Font.Name + 将所选文字的字体设置为仿宋 + + 仿宋 + 0 + + + 字体[ziti] : 隶书[lishu] + Selection.Font.Name + 将所选文字的字体设置为隶书 + + 隶书 + 0 + + + 字体[ziti] : 微软雅黑[weiruanyahei] + Selection.Font.Name + 将所选文字的字体设置为微软雅黑 + + 微软雅黑 + 0 + + + 字体[ziti] : 黑体[heiti] + Selection.Font.Name + 将所选文字的字体设置为黑体 + + 黑体 + 0 + + + 字体[ziti] : Times New Roman + Selection.Font.Name + 将所选文字的字体设置为Times New Roman + + "Times New Roman" + 0 + + + 字体[ziti] : Consolas + Selection.Font.Name + 将所选文字的字体设置为Consolas + + Consolas + 0 + + + 字体[ziti] : Arial + Selection.Font.Name + 将所选文字的字体设置为Arial + + Arial + 0 + + + 字体[ziti] : 字体名 + Selection.Font.Name + 将所选文字的字体设置为指定名称的字体 + . + + 0 + + + 批注[pizhu] : 插入[charupizhu] 批注内容 + Selection.Comments.Add(Selection.Range, "{$1}") + 为所选内容插入一个批注 + . + 修改批注 + 0 + + + 批注[pizhu] : 删除[shanchupizhu] + Selection.Comments[1].Delete() + 删除当前批注 + + + 0 + + + 批注[pizhu] : 修改[xiugaipizhu] 批注内容 + Selection.Comments[1].Range.Text + 修改当前批注 + . + + 0 + + + 书签[shuqian] : 插入[charushuqian] 书签名 + Selection.Bookmarks.Add("{$1}", Selection.Range) + 在当前位置插入一个书签 + . + + 0 + + + 修订[xiuding] : 开[kai] + ActiveDocument.TrackRevisions + 打开修订模式 + + True + 0 + + + 修订[xiuding] : 关[guan] + ActiveDocument.TrackRevisions + 关闭修订模式 + + False + 0 + + + 修订[xiuding] : 接受此处[jieshoucichu] + Selection.Range.Revisions.AcceptAll() + 接受光标选择区域的所有修订 + + + 0 + + + 修订[xiuding] : 拒绝此处[jujuecichu] + Selection.Range.Revisions.RejectAll() + 接受光标选择区域的所有修订 + + + 0 + + + 修订[xiuding] : 接受全部[jieshouquanbu] + ActiveDocument.AcceptAllRevisions() + 接受文档中的全部修订 + + + 0 + + + 修订[xiuding] : 拒绝全部[jujuequanbu] + ActiveDocument.RejectAllRevisions() + 拒绝文档中的全部修订 + + + 0 + + + 书签[shuqian] : 删除[shanchushuqian] + Selection.Bookmarks[1].Delete() + 修改当前书签 + + + 0 + + + 跳转[gotopage tiaozhuan] : 页码[yema] + Selection.GoTo(1, 1, {$1}, "") + 光标跳转到指定页码 + \d + + 0 + + + 跳转[gotosection tiaozhuan] : 节[jie] + Selection.GoTo(0, 1, {$1}, "") + 光标跳转到指定节 + \d + + 0 + + + 跳转[gotoline tiaozhuan] : 行[hang] + Selection.GoTo(3, 1, {$1}, "") + 光标跳转到指定行 + \d + + 0 + + + 跳转[gotobookmark tiaozhuan] : 书签[shuqian] 书签名 + Selection.GoTo(-1, 1, 0, "{$1}") + 光标跳转到指定书签 + . + + 0 + + + 样式[yangshi] : 正文[zhengwen] + Selection.Range.Style + 将所选内容的样式设置为正文 + + 正文 + 0 + + + 样式[yangshi] : 标题 1[biaoti 1] + Selection.Range.Style + 将所选内容的样式设置为标题 1 + + "标题 1" + 0 + + + 样式[yangshi] : 标题 2[biaoti 2] + Selection.Range.Style + 将所选内容的样式设置为标题 2 + + "标题 2" + 0 + + + 样式[yangshi] : 标题 3[biaoti 3] + Selection.Range.Style + 将所选内容的样式设置为标题 3 + + "标题 3" + 0 + + + 样式[yangshi] : 样式名 + Selection.Range.Style + 将所选内容的样式设置为输入的样式名 + . + + 0 + + + 视图[shitu] : 页面视图[yemianshitu] + ActiveWindow.View.Type + 将页面视图切换为页面视图 + + 3 + 0 + + + 视图[shitu] : 大纲视图[dagangshitu] + ActiveWindow.View.Type + 将页面视图切换为大纲视图 + + 2 + 0 + + + 视图[shitu] : Web视图[shitu] + ActiveWindow.View.Type + 将页面视图切换为Web视图 + + 6 + 0 + + + 拆分窗口[chaifenchuangkou] 切换[qiehuan] + !ActiveWindow.Split + 打开或取消拆分窗口 + + + 0 + + + 打印[dayin] : 全部[quanbu] + ActiveDocument.PrintOut(false, true, 0) + 打印文档的全部内容 + + + 0 + + + 打印[dayin] : 当前页[dangqianye] + ActiveDocument.PrintOut(false, true, 2) + 打印文档的当前页 + + + 0 + + + 打印[dayin] : 页码范围[yemafanwei] {x,y} + ActiveDocument.PrintOut(false, true, 3, "", {$1}, {$2}) + 打印文档的第a页到第b页 + \d + + 0 + + + 纸张方向[zhizhangfangxiang] : 横向[hengxiang] + ActiveDocument.PageSetup.Orientation + 更改页面设置中的纸张方向为横向 + + 1 + 0 + + + 纸张方向[zhizhangfangxiang] : 纵向[zongxiang] + ActiveDocument.PageSetup.Orientation + 更改页面设置中的纸张方向为纵向 + + 0 + 0 + + + 纸张大小[zhizhangdaxiao] : A3 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为A3 + + 6 + 0 + + + 纸张大小[zhizhangdaxiao] : A4 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为A4 + + 7 + 0 + + + 纸张大小[zhizhangdaxiao] : B4 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为B4 + + 10 + 0 + + + 纸张大小[zhizhangdaxiao] : B5 + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为B5 + + 11 + 0 + + + 纸张大小[zhizhangdaxiao] : 信纸[xinzhi] + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为Letter + + 2 + 0 + + + 纸张大小[zhizhangdaxiao] : 法律专用纸[falvzhuanyongzhi] + ActiveDocument.PageSetup.PaperSize + 将纸张大小更改为Legal + + 4 + 0 + + + 兼容模式[jianrongmoshi] + ActiveDocument.SetCompatibilityMode(11) + 将文档模式改为wdWord2003 + + + 0 + + + 非兼容模式[feijianrongmoshi] + ActiveDocument.SetCompatibilityMode(14) + 将文档模式改为wdWord2010 + + + 0 + + + 窗口最大化[chuangkouzuidahua maximum] + Application.WindowState + 使程序窗口最大化 + + 1 + 0 + + + 窗口还原[chuangkouhuanyuan normal] + Application.WindowState + 使程序窗口大小还原 + + 0 + 0 + + + CP + @RunFile("Utilities/wpscp.vbs","{$1}") + CP + \d + + 0 + + + \ No newline at end of file diff --git a/Bin/Debug4KSO/plugins/3rdparty/everything/everything.exe b/Bin/Debug4KSO/plugins/3rdparty/everything/everything.exe new file mode 100644 index 0000000..db310db Binary files /dev/null and b/Bin/Debug4KSO/plugins/3rdparty/everything/everything.exe differ diff --git a/Bin/Debug4KSO/plugins/3rdparty/everything/everything32.dll b/Bin/Debug4KSO/plugins/3rdparty/everything/everything32.dll new file mode 100644 index 0000000..fab7296 Binary files /dev/null and b/Bin/Debug4KSO/plugins/3rdparty/everything/everything32.dll differ diff --git a/Bin/Debug4KSO/plugins/3rdparty/everything/everything64.dll b/Bin/Debug4KSO/plugins/3rdparty/everything/everything64.dll new file mode 100644 index 0000000..8f1b615 Binary files /dev/null and b/Bin/Debug4KSO/plugins/3rdparty/everything/everything64.dll differ diff --git a/Bin/Intro.pptx b/Bin/Intro.pptx new file mode 100644 index 0000000..ee8aef2 Binary files /dev/null and b/Bin/Intro.pptx differ diff --git a/Bin/Release/QuickDotfuscator.xml b/Bin/Release/QuickDotfuscator.xml new file mode 100644 index 0000000..9c83374 --- /dev/null +++ b/Bin/Release/QuickDotfuscator.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Bin/Release4KSO/QuickDotfuscator.xml b/Bin/Release4KSO/QuickDotfuscator.xml new file mode 100644 index 0000000..1f2f145 --- /dev/null +++ b/Bin/Release4KSO/QuickDotfuscator.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Bin/Scripts/r4kso.bat b/Bin/Scripts/r4kso.bat new file mode 100644 index 0000000..a459107 --- /dev/null +++ b/Bin/Scripts/r4kso.bat @@ -0,0 +1,21 @@ +@echo off +echo ʼĿ... +SET PATH=%PATH%;C:\Program Files\WinRAR +cd /d %~dp0 +rd /s /q Release4KSO +md Release4KSO +xcopy /i /y ..\Debug4KSO\config .\Release4KSO\config +copy /y ..\Release4KSO\Quick.exe .\Release4KSO\Quick.exe +copy /y ..\Release4KSO\QuickUpdate.exe .\Release4KSO\QuickUpdate.exe +copy /y ..\Release4KSO\QuickUI.dll .\Release4KSO\QuickUI.dll +md Release4KSO\plugins\3rdparty\everything +copy /y ..\Release4KSO\plugins\quickplugin.dll .\Release4KSO\plugins\quickplugin.dll +copy /y ..\Release4KSO\plugins\3rdparty\everything\everything.exe .\Release4KSO\plugins\3rdparty\everything\everything.exe +copy /y ..\Release4KSO\plugins\3rdparty\everything\everything32.dll .\Release4KSO\plugins\3rdparty\everything\everything32.dll +copy /y ..\Release4KSO\plugins\3rdparty\everything\everything64.dll .\Release4KSO\plugins\3rdparty\everything\everything64.dll + +cd Release4KSO +rar a -r Quick.rar + +echo +pause \ No newline at end of file diff --git a/Bin/Scripts/release.bat b/Bin/Scripts/release.bat new file mode 100644 index 0000000..2ed7224 --- /dev/null +++ b/Bin/Scripts/release.bat @@ -0,0 +1,21 @@ +@echo off +echo ʼĿ... +SET PATH=%PATH%;C:\Program Files\WinRAR +cd /d %~dp0 +rd /s /q Release +md Release +xcopy /i /y ..\Debug4KSO\config .\Release\config +copy /y ..\Release\Quick.exe .\Release\Quick.exe +copy /y ..\Release\QuickUpdate.exe .\Release\QuickUpdate.exe +copy /y ..\Release\QuickUI.dll .\Release\QuickUI.dll +md Release\plugins\3rdparty\everything +copy /y ..\Release\plugins\quickplugin.dll .\Release\plugins\quickplugin.dll +copy /y ..\Release\plugins\3rdparty\everything\everything.exe .\Release\plugins\3rdparty\everything\everything.exe +copy /y ..\Release\plugins\3rdparty\everything\everything32.dll .\Release\plugins\3rdparty\everything\everything32.dll +copy /y ..\Release\plugins\3rdparty\everything\everything64.dll .\Release\plugins\3rdparty\everything\everything64.dll + +cd Release +rar a -r Quick.rar + +echo +pause \ No newline at end of file diff --git a/Coding/Quick.sln b/Coding/Quick.sln new file mode 100644 index 0000000..25b23ca --- /dev/null +++ b/Coding/Quick.sln @@ -0,0 +1,133 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quick", "Quick\Quick.csproj", "{D26B7BEA-D131-4801-A19B-E0AFC6740322}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickUpdate", "QuickUpdate\QuickUpdate.csproj", "{E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickPlugin", "QuickPlugin\QuickPlugin.csproj", "{EA358646-8755-4A40-AABC-200C03CF86CC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickUI", "QuickUI\QuickUI.csproj", "{F36B622E-4F74-4D69-912C-FB9DE8915362}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + D4KSO|Any CPU = D4KSO|Any CPU + D4KSO|Mixed Platforms = D4KSO|Mixed Platforms + D4KSO|Win32 = D4KSO|Win32 + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + R4KSO|Any CPU = R4KSO|Any CPU + R4KSO|Mixed Platforms = R4KSO|Mixed Platforms + R4KSO|Win32 = R4KSO|Win32 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Template|Any CPU = Template|Any CPU + Template|Mixed Platforms = Template|Mixed Platforms + Template|Win32 = Template|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.D4KSO|Any CPU.ActiveCfg = D4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.D4KSO|Any CPU.Build.0 = D4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.D4KSO|Mixed Platforms.ActiveCfg = D4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.D4KSO|Mixed Platforms.Build.0 = D4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.D4KSO|Win32.ActiveCfg = D4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.R4KSO|Any CPU.ActiveCfg = R4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.R4KSO|Any CPU.Build.0 = R4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.R4KSO|Any CPU.Deploy.0 = R4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.R4KSO|Mixed Platforms.ActiveCfg = R4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.R4KSO|Mixed Platforms.Build.0 = R4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.R4KSO|Win32.ActiveCfg = R4KSO|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Release|Any CPU.Build.0 = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Release|Win32.ActiveCfg = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Template|Any CPU.ActiveCfg = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Template|Any CPU.Build.0 = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322}.Template|Win32.ActiveCfg = Release|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.D4KSO|Any CPU.ActiveCfg = D4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.D4KSO|Any CPU.Build.0 = D4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.D4KSO|Any CPU.Deploy.0 = D4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.D4KSO|Mixed Platforms.ActiveCfg = D4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.D4KSO|Win32.ActiveCfg = D4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.R4KSO|Any CPU.ActiveCfg = R4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.R4KSO|Any CPU.Build.0 = R4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.R4KSO|Mixed Platforms.ActiveCfg = R4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.R4KSO|Win32.ActiveCfg = R4KSO|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Release|Any CPU.Build.0 = Release|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Release|Win32.ActiveCfg = Release|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Template|Any CPU.ActiveCfg = Release|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28}.Template|Win32.ActiveCfg = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.D4KSO|Any CPU.ActiveCfg = D4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.D4KSO|Any CPU.Build.0 = D4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.D4KSO|Mixed Platforms.ActiveCfg = D4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.D4KSO|Mixed Platforms.Build.0 = D4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.D4KSO|Win32.ActiveCfg = D4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Debug|Win32.ActiveCfg = Debug|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.R4KSO|Any CPU.ActiveCfg = R4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.R4KSO|Any CPU.Build.0 = R4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.R4KSO|Mixed Platforms.ActiveCfg = R4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.R4KSO|Mixed Platforms.Build.0 = R4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.R4KSO|Win32.ActiveCfg = R4KSO|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Release|Any CPU.Build.0 = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Release|Win32.ActiveCfg = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Template|Any CPU.ActiveCfg = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Template|Any CPU.Build.0 = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {EA358646-8755-4A40-AABC-200C03CF86CC}.Template|Win32.ActiveCfg = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.D4KSO|Any CPU.ActiveCfg = D4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.D4KSO|Any CPU.Build.0 = D4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.D4KSO|Mixed Platforms.ActiveCfg = D4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.D4KSO|Mixed Platforms.Build.0 = D4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.D4KSO|Win32.ActiveCfg = D4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Debug|Win32.ActiveCfg = Debug|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.R4KSO|Any CPU.ActiveCfg = R4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.R4KSO|Any CPU.Build.0 = R4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.R4KSO|Mixed Platforms.ActiveCfg = R4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.R4KSO|Mixed Platforms.Build.0 = R4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.R4KSO|Win32.ActiveCfg = R4KSO|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Release|Any CPU.Build.0 = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Release|Win32.ActiveCfg = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Template|Any CPU.ActiveCfg = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Template|Any CPU.Build.0 = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Template|Mixed Platforms.ActiveCfg = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Template|Mixed Platforms.Build.0 = Release|Any CPU + {F36B622E-4F74-4D69-912C-FB9DE8915362}.Template|Win32.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Coding/Quick/Config.cs b/Coding/Quick/Config.cs new file mode 100644 index 0000000..2f63b74 --- /dev/null +++ b/Coding/Quick/Config.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; +using System.Windows.Forms; +using System.Xml.Serialization; + +namespace Froser.Quick +{ + public class QuickConfig + { + public Boolean FirstRun { get; set; } + public Keys HotKey { get; set; } + public Int32 HotKeyFlags { get; set; } + public Boolean SearchToogle { get; set; } + + private static String ConfigDir + { + get + { + String strConfigDirector = Application.StartupPath; + if (!Directory.Exists(strConfigDirector)) + { + Directory.CreateDirectory(strConfigDirector); + } + return strConfigDirector; + } + } + + private static String ConfigPath + { + get + { + return Path.Combine(ConfigDir, "quick.config"); + } + } + + private static QuickConfig _config; + public static QuickConfig ThisConfig + { + get + { + if (_config == null) + { + _config = Load(); + } + return _config; + } + } + + private QuickConfig() + { + FirstRun = true; + HotKey = Keys.Q; + HotKeyFlags = (int)Hotkey.KeyFlags.MOD_CONTROL; + SearchToogle = true; + } + + public bool TrySave() + { + return TrySave(this); + } + + /// + /// 读取一个配置文件,并返回一个PluginConfig对象。若XML配置文件不存在,则会用初始化本类的方式(使用默认初始化值)来创建一个配置文件。 + /// + private static QuickConfig Load() + { + QuickConfig instance; + if (!File.Exists(ConfigPath)) + { + //配置文件不存在,则创建一个新的实例 + instance = new QuickConfig(); + TrySave(instance); + } + else + { + //如果文件存在,则反序列化它 + XmlSerializer xmlsLoad = new XmlSerializer(typeof(QuickConfig)); + using (FileStream fs = new FileStream(ConfigPath, FileMode.Open, FileAccess.Read)) + { + instance = (QuickConfig)xmlsLoad.Deserialize(fs); + } + } + return instance; + } + + private static bool TrySave(QuickConfig instance) + { + try + { + //注意:以下操作线程不安全 + //将密码暂时加密 + XmlSerializer xmlsSave = new XmlSerializer(typeof(QuickConfig)); + using (FileStream fs = new FileStream(ConfigPath, FileMode.Create, FileAccess.Write)) + { + xmlsSave.Serialize(fs, instance); + } + return true; + } + catch + { + return false; + } + } + } +} diff --git a/Coding/Quick/Extension.cs b/Coding/Quick/Extension.cs new file mode 100644 index 0000000..3776f6f --- /dev/null +++ b/Coding/Quick/Extension.cs @@ -0,0 +1,128 @@ +using System.Windows.Forms; +using System; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Windows.Media.Imaging; +using System.Drawing; +using System.Windows.Interop; +using System.Windows; +using System.Windows.Input; + +namespace Froser.Quick +{ + public static class Extension + { + //判断某字符串是否按顺序含有子字符串,如abcd含有ac但是不含有ca + public static bool HasString(this String str, String substr) + { + //包含在{}中的字符表示,不作为查找依据。例如,{x, y}中,忽略x, y这几个字符,当然{}本身也不包含在内 + Regex brace = new Regex(@"\{(.*?)\}"); + //先统一大小写 + str = str.ToLower(); + substr = substr.ToLower(); + + bool result = false; + String rec_str = brace.Replace(str, ""); + for (int i = 0; i < substr.Length; i++) + { + int index = rec_str.IndexOf(substr[i]); + if (index < 0) + { + return false; + } + else + { + if (rec_str.Length == 1) return ( i == substr.Length - 1); + rec_str = rec_str.Substring(index + 1); + result = true; + } + } + + return result; + } + + public static int Plus(this object lhs, object addend) + { + if (lhs is int) + { + if (addend is int) + { + return (int)lhs + (int)addend; + } + else if (addend is float || addend is double) + { + return (int)((int)lhs + double.Parse(addend.ToString())); + } + else + { + throw new NotSupportedException(); + } + } + else if (lhs is float || lhs is double) + { + if (addend is int) + { + return (int)(double.Parse (lhs.ToString ()) + (int)addend); + } + else if (addend is float || addend is double) + { + return (int)(double.Parse(lhs.ToString()) + double.Parse(addend.ToString())); + } + else + { + throw new NotSupportedException(); + } + } + else + { + throw new NotSupportedException(); + } + } + + public static void ShowBalloonTip(this NotifyIcon notify, String text) + { + notify.ShowBalloonTip(500, System.Windows.Forms.Application.ProductName, text, ToolTipIcon.Info); + } + + public static void Swap(this IList list, object a, object b) + { + int indexOfB = list.IndexOf (b); + list.Insert(list.IndexOf (a), b); + list.Remove(a); + list.Remove(b); + list.Insert(indexOfB, a); + } + + public static string KeyToString(this Key key) + { + switch (key.ToString().ToLower()) + { + case "oem3": + return "`"; + default: + return key.ToString(); + } + } + + public static bool ContainsKey(this Dictionary dic, String key, bool ignoreCase, out string keyInModel) + { + keyInModel = ""; + foreach (var item in dic.Keys) + { + if (String.Compare(item, key, ignoreCase) == 0) { + keyInModel = item; + return true; + } + } + return false; + } + + public static BitmapSource ToBitmapSource(this Icon icon) + { + var bitmap = icon.ToBitmap(); + var hbitmap = bitmap.GetHbitmap(); + return Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); + } + } +} diff --git a/Coding/Quick/Global.Designer.cs b/Coding/Quick/Global.Designer.cs new file mode 100644 index 0000000..e86ec3d --- /dev/null +++ b/Coding/Quick/Global.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 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 Global { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Global() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Froser.Quick.Global", typeof(Global).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Coding/Quick/Global.resx b/Coding/Quick/Global.resx new file mode 100644 index 0000000..2f96abe --- /dev/null +++ b/Coding/Quick/Global.resx @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + \ No newline at end of file diff --git a/Coding/Quick/Hotkey.cs b/Coding/Quick/Hotkey.cs new file mode 100644 index 0000000..7a0f4d6 --- /dev/null +++ b/Coding/Quick/Hotkey.cs @@ -0,0 +1,87 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Input; + +namespace Froser.Quick +{ + internal delegate void HotkeyEventHandler(int HotKeyID); + + internal class Hotkey : global::System.Windows.Forms.IMessageFilter + { + global::System.Collections.Hashtable keyIDs = new global::System.Collections.Hashtable(); + IntPtr hWnd; + + + + public event HotkeyEventHandler OnHotkey; + + public enum KeyFlags + { + MOD_NONE = 0x0, + MOD_ALT = 0x1, + MOD_CONTROL = 0x2, + MOD_SHIFT = 0x4, + MOD_WIN = 0x8, + MOD_NOREPEAT = 0x4000 + } + [DllImport("user32.dll")] + private static extern UInt32 RegisterHotKey(IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk); + + [DllImport("user32.dll")] + private static extern UInt32 UnregisterHotKey(IntPtr hWnd, UInt32 id); + + [DllImport("kernel32.dll")] + private static extern UInt32 GlobalAddAtom(String lpString); + + [DllImport("kernel32.dll")] + private static extern UInt32 GlobalDeleteAtom(UInt32 nAtom); + + public Hotkey(IntPtr hWnd) + { + this.hWnd = hWnd; + global::System.Windows.Forms.Application.AddMessageFilter(this); + } + + public int RegisterHotkey(Key Key, KeyFlags keyflags) + { + try + { + UInt32 hotkeyid = GlobalAddAtom(global::System.Guid.NewGuid().ToString()); + int keycode = KeyInterop.VirtualKeyFromKey(Key); + RegisterHotKey((IntPtr)hWnd, hotkeyid, (UInt32)keyflags, (UInt32)keycode); + keyIDs.Add(hotkeyid, hotkeyid); + return (int)hotkeyid; + } + catch { return 0; }; + } + + public void UnregisterHotkeys() + { + global::System.Windows.Forms.Application.RemoveMessageFilter(this); + foreach (UInt32 key in keyIDs.Values) + { + UnregisterHotKey(hWnd, key); + GlobalDeleteAtom(key); + } + } + + public bool PreFilterMessage(ref global::System.Windows.Forms.Message m) + { + if (m.Msg == 0x312) + { + if (OnHotkey != null) + { + foreach (UInt32 key in keyIDs.Values) + { + if ((UInt32)m.WParam == key) + { + OnHotkey((int)m.WParam); + return true; + } + } + } + } + return false; + } + } +} \ No newline at end of file diff --git a/Coding/Quick/IQuickPlugin.cs b/Coding/Quick/IQuickPlugin.cs new file mode 100644 index 0000000..1e485ae --- /dev/null +++ b/Coding/Quick/IQuickPlugin.cs @@ -0,0 +1,31 @@ +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace Froser.Quick +{ + public interface IQuickPlugin + { + IQuickPluginMethod[] GetMethods(); + } + + public interface IQuickPluginMethod + { + string GetName(); + string GetDescription(IQuickWindow quickWindow); + string AvailableApplicationName(); + void Invoke(object sender, IQuickWindow quickWindow); + bool AcceptArgs(); + bool GetIcon(IQuickWindow quickWindow, out ImageSource icon); + + // 事件回调 + // 插件在激活状态下按下一个键时 + void KeyDown(IQuickWindow quickWindow, KeyEventArgs e); + // 插件在激活状态下搜索文本有变化时 + void TextChanged(IQuickWindow quickWindow, TextChangedEventArgs e); + // 主窗体关闭时 + void Closed(IQuickWindow quickWindow); + void PageDown(IQuickWindow quickWindow); + void PageUp(IQuickWindow quickWindow); + } +} diff --git a/Coding/Quick/IQuickWindow.cs b/Coding/Quick/IQuickWindow.cs new file mode 100644 index 0000000..cda3084 --- /dev/null +++ b/Coding/Quick/IQuickWindow.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls; + +namespace Froser.Quick +{ + public interface IQuickWindow + { + string GetPluginsPath(); + void SetQueryText(string text); + string GetQueryText(); + string GetArgument(); + RichTextBox GetQueryTextBox(); + void ReplaceMethods(IQuickPluginMethod[] methods); + void ResetMethods(); + void Refresh(int selectIndex); + int GetCurrentPage(); + void LockWindow(); + void UnlockWindow(); + void AsyncInvoke(Action action); + } +} diff --git a/Coding/Quick/Program.cs b/Coding/Quick/Program.cs new file mode 100644 index 0000000..a6cef1e --- /dev/null +++ b/Coding/Quick/Program.cs @@ -0,0 +1,82 @@ +using System; +using System.Threading; +using System.Drawing; +using System.Collections.Generic; +using System.IO; +using System.Xml.Linq; +using System.Security.Principal; +using System.Windows.Forms; + +namespace Froser.Quick +{ + static class Program + { + public static NotifyIcon notify = new NotifyIcon(); + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + if (QuickUpdate.LocalUpdate()) + { + Environment.Exit(0); + return; + } + + if (Init()) + { + Application.Run(); + } + } + + public static void Quit() + { + notify.Visible = false; + Application.ExitThread(); + } + + static bool Init() + { + const string adminComment = "Quick当前是以管理员身份运行。此时,您的宿主程序也必须是以管理员身份运行,这样Quick快捷菜单才能正常出现。"; + + var mutexStr = "__QUICK____QUICK____QUICK____QUICK____QUICK__"; + bool canCreateMutex; + Mutex programMutex = new Mutex(false, mutexStr, out canCreateMutex); + if (canCreateMutex) + { + notify = QuickNotify.GetNotify(); + notify.Visible = true; + + if (QuickConfig.ThisConfig.FirstRun) + { + QuickConfig.ThisConfig.FirstRun = false; + QuickConfig.ThisConfig.TrySave(); + + string additional = IsAdministrator() ? adminComment : string.Empty; + + notify.ShowBalloonTip("Quick已经运行,您可以点击右键查看其选项。" + " " + adminComment); + } + else if (IsAdministrator()) + notify.ShowBalloonTip(adminComment); + + Action silenceUpdate = () => + { + QuickUpdate.SilenceUpdate(); + }; + silenceUpdate.BeginInvoke(null, null); + + QuickListener.Listener.Run(); + return true; + } + return false; + } + + public static bool IsAdministrator() + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + } +} diff --git a/Coding/Quick/Properties/AssemblyInfo.cs b/Coding/Quick/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ebfdc9f --- /dev/null +++ b/Coding/Quick/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过以下 +// 特性集控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Quick")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Froser")] +[assembly: AssemblyProduct("Quick")] +[assembly: AssemblyCopyright("Froser")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("f3a5a152-cbb0-4ccf-9edc-3ad4ca42371c")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] diff --git a/Coding/Quick/Properties/Resources.Designer.cs b/Coding/Quick/Properties/Resources.Designer.cs new file mode 100644 index 0000000..a9bc656 --- /dev/null +++ b/Coding/Quick/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 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() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Froser.Quick.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap quick { + get { + object obj = ResourceManager.GetObject("quick", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Coding/Quick/Properties/Resources.resx b/Coding/Quick/Properties/Resources.resx new file mode 100644 index 0000000..199bb5a --- /dev/null +++ b/Coding/Quick/Properties/Resources.resx @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACIUlEQVRYR7XXP0gWcRzH8SeNtCBJMojA + ooQgBCcDt1qaitw0NzcxaAtBabIlQfAPuAgKDdLkotDmpBKiIrQ0JeigSUFB0KOo5ftzfC8e5Mvd/c7z + A6/t9/18fR7vvLOUlvJqW+wt/uV0hG5EXUGxoYuYhVeexRbuw1oDoiFcxwa88ixGUA1rDYiG0Ixv8MrT + /MBDWGNgNIguHMBbkEa/uiuwxoBoCBcwCa88zR88RdQVHBu8ikV4C9Ks4AasMTAaxD3oKvYWJNGt14N8 + n16x4efQV+ktSbKJJlhbYDRoJuAtSDOEKlhjYDSIOizDW5DkbLeeomE8wA68JUn+33qxoFQM9kIXk7ck + ySdMYRqvcA3WniE6jBrMwVsQ4hCvEfVmih2+g6/wSkONI/sFqYPIe/ud9gtPkO0biA9iFF5hiGO8wyXY + hpToIPR1fYBXGmIJt2DtGaLDZhB57oDYHh4j6guKDekl5AX6MWDe4DO8hZV05fch30uIFxXhMhbgLa30 + EfoANl1AVIab+AJvaWwbrYhmCosVtuA7vMWyDz2C9RJjkwVFhehE0qvZDPQAs6mCokIzBm+x6Fejh1d0 + ttBYqf6YzMNb/hsdKH65YsX1WMfp5X+h9/5a2ETBUTHuwns31KO3EXb6HKJy6Nb6icrlu3iE6My5xRY8 + g26zeHkZL5H/vS9rtADtiH8APSOGke8/ntBoCW5jDVr+Hg2wE3lTKp0AUQK3//kdzGoAAAAASUVORK5C + YII= + + + \ No newline at end of file diff --git a/Coding/Quick/Properties/Settings.Designer.cs b/Coding/Quick/Properties/Settings.Designer.cs new file mode 100644 index 0000000..d5f8b80 --- /dev/null +++ b/Coding/Quick/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.18444 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick.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; + } + } + } +} diff --git a/Coding/Quick/Properties/Settings.settings b/Coding/Quick/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Coding/Quick/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Coding/Quick/Properties/app.manifest b/Coding/Quick/Properties/app.manifest new file mode 100644 index 0000000..8a1f331 --- /dev/null +++ b/Coding/Quick/Properties/app.manifest @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Coding/Quick/Quick.csproj b/Coding/Quick/Quick.csproj new file mode 100644 index 0000000..7843ce0 --- /dev/null +++ b/Coding/Quick/Quick.csproj @@ -0,0 +1,251 @@ + + + + + Debug + AnyCPU + {D26B7BEA-D131-4801-A19B-E0AFC6740322} + WinExe + Properties + Froser.Quick + Quick + v4.0 + 512 + + + false + 发布\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 1 + 1.0.0.%2a + false + true + true + + + ..\..\obj\Debug\ + AnyCPU + true + full + false + ..\..\Bin\Debug\ + TRACE;DEBUG + prompt + 4 + + + ..\..\obj\Release\ + AnyCPU + pdbonly + true + ..\..\Bin\Release\ + TRACE + prompt + 4 + + + quick.ico + + + Always + + + ..\..\obj\Debug4KSO\ + ..\..\Bin\Debug4KSO\ + TRACE;DEBUG;KSO + full + true + true + + + ..\..\obj\Release4KSO\ + ..\..\Bin\Release4KSO\ + TRACE;KSO + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + false + + + EC45F88B427F93107FACAA7D83D542648AA13D1E + + + Quick_TemporaryKey.pfx + + + false + + + Custom + + + + false + + + Properties\app.manifest + + + Froser.Quick.Program + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Global.resx + + + + + + + + + + + + + + + + + ResXFileCodeGenerator + Global.Designer.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + False + Microsoft .NET Framework 4 %28x86 和 x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 4.5 + true + + + + + {f36b622e-4f74-4d69-912c-fb9de8915362} + QuickUI + + + + + + + + + set config=$(ConfigurationName) +IF /I %25config%25==Debug ( +xcopy /e /y /i $(OutDir)..\Debug4KSO\config $(OutDir)config +xcopy /e /y /i $(OutDir)..\Debug4KSO\intro $(OutDir)intro +md $(OutDir)plugins\3rdparty\everything +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything.exe $(OutDir)plugins\3rdparty\everything\everything.exe +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything32.dll $(OutDir)plugins\3rdparty\everything\everything32.dll +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything64.dll $(OutDir)plugins\3rdparty\everything\everything64.dll +) + +IF /I %25config%25==Release ( +xcopy /e /y /i $(OutDir)..\Debug4KSO\config $(OutDir)config +xcopy /e /y /i $(OutDir)..\Debug4KSO\intro $(OutDir)intro +md $(OutDir)plugins\3rdparty\everything +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything.exe $(OutDir)plugins\3rdparty\everything\everything.exe +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything32.dll $(OutDir)plugins\3rdparty\everything\everything32.dll +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything64.dll $(OutDir)plugins\3rdparty\everything\everything64.dll +) + +IF /I %25config%25==R4KSO ( +xcopy /e /y /i $(OutDir)..\Debug4KSO\config $(OutDir)config +xcopy /e /y /i $(OutDir)..\Debug4KSO\intro $(OutDir)intro +md $(OutDir)plugins\3rdparty\everything +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything.exe $(OutDir)plugins\3rdparty\everything\everything.exe +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything32.dll $(OutDir)plugins\3rdparty\everything\everything32.dll +copy /y $(OutDir)..\Debug4KSO\plugins\3rdparty\everything\everything64.dll $(OutDir)plugins\3rdparty\everything\everything64.dll +) + + + \ No newline at end of file diff --git a/Coding/Quick/Quick.v11.suo b/Coding/Quick/Quick.v11.suo new file mode 100644 index 0000000..ca2b65a Binary files /dev/null and b/Coding/Quick/Quick.v11.suo differ diff --git a/Coding/Quick/QuickCommonObject.cs b/Coding/Quick/QuickCommonObject.cs new file mode 100644 index 0000000..8ea2348 --- /dev/null +++ b/Coding/Quick/QuickCommonObject.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace Froser.Quick +{ + [Serializable] + internal class QuickCommonObject + { + [DllImport("user32.dll", EntryPoint = "keybd_event")] + public static extern void keybd_event( + byte bVk, //虚拟键值 + byte bScan,// 一般为0 + int dwFlags, //这里是整数类型 0 为按下,2为释放 + int dwExtraInfo //这里是整数类型 一般情况下设成为 0 + ); + + [DllImport("user32.dll")] + private static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect); + public struct Rect + { + public int Left; + public int Top; + public int Right; + public int Bottom; + } + private IntPtr currentWindowPtr; + private bool isGlobal; + + public QuickCommonObject(IntPtr windowPtr, bool isGlobal) + { + currentWindowPtr = windowPtr; + this.isGlobal = isGlobal; + } + + + public Rect GetWindowRect() + { + Rect lpRect; + if (isGlobal) + { + var rect = Screen.GetWorkingArea(new Point(0, 0)); + lpRect.Left = rect.Left; + lpRect.Right = rect.Right; + lpRect.Top = rect.Top; + lpRect.Bottom = rect.Bottom; + } + else + { + GetWindowRect(currentWindowPtr, out lpRect); + } + return lpRect; + } + + public String GetSelection + { + get + { + keybd_event((byte)Keys.LControlKey, 0, 0, 0); + keybd_event((byte)Keys.C, 0, 0, 0); + keybd_event((byte)Keys.LControlKey, 0, 2, 0); + keybd_event((byte)Keys.C, 0, 2, 0); + Thread.Sleep(10); + return Clipboard.GetText(); + } + } + + public void Call(String cmd, String arg) + { + Process.Start(cmd, arg); + } + } +} diff --git a/Coding/Quick/QuickConfig.cs b/Coding/Quick/QuickConfig.cs new file mode 100644 index 0000000..7656647 --- /dev/null +++ b/Coding/Quick/QuickConfig.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Windows.Forms; +using System.Windows.Input; +using System.Xml.Serialization; +namespace Froser.Quick +{ + public class QuickConfig + { + public class ContextMenuItem + { + public const string Replacement = "{$1}"; + public string Name { get; set; } + public string Exec { get; set; } + public string Argument { get; set; } + public ContextMenuItem() + { + Name = "上下文名称"; + Exec = "打开的地址"; + Argument = "运行参数"; + } + public ContextMenuItem(string name, string exec, string argument) + { + Name = name; + Exec = exec; + Argument = argument; + } + } + + private static String ConfigDir + { + get + { + String strConfigDirector = Application.StartupPath; + if (!Directory.Exists(strConfigDirector)) + { + Directory.CreateDirectory(strConfigDirector); + } + return strConfigDirector; + } + } + + private static String ConfigPath + { + get + { + return Path.Combine(ConfigDir, "quick.config"); + } + } + + private static QuickConfig _config; + public static QuickConfig ThisConfig + { + get + { + if (_config == null) + { + _config = Load(); + TrySave(_config); + } + return _config; + } + } + + private QuickConfig(bool isTemplate) + { + Init(); + if (isTemplate) + { + ModelName = new List(); + ModelName.Add("wps"); + ModelName.Add("et"); + ModelName.Add("wpp"); + ModelName.Add("winword"); + ModelName.Add("excel"); + ModelName.Add("powerpnt"); + + ContextMenuList = new List(); + ContextMenuList.Add(new ContextMenuItem("用BugManager搜索", "http://wpswebsvr.wps.kingsoft.net/ksbm/ViewIssue.aspx?IssueID={$1}", "")); + ContextMenuList.Add(new ContextMenuItem("用Google搜索", "https://www.google.com.hk/webhp?hl=zh-CN&sourceid=cnhp&gws_rd=ssl#newwindow=1&safe=strict&hl=zh-CN&q={$1}", "")); + ContextMenuList.Add(new ContextMenuItem("用Baidu搜索", "http://www.baidu.com/baidu?wd={$1}", "")); + } + } + + private QuickConfig() + { + Init(); + } + + private void Init() + { + FirstRun = true; + QuickHotKey = Key.Q; + QuickHotKeyFlags = (int)Hotkey.KeyFlags.MOD_CONTROL; + ContextMenuHotKey = Key.OemTilde; + ContextMenuHotKeyFlags = (int)Hotkey.KeyFlags.MOD_CONTROL; + ContextMenuToogle = true; + LockWindow = false; + } + + public void SetDefaultConfig() + { + QuickHotKey = Key.Q; + QuickHotKeyFlags = (int)Hotkey.KeyFlags.MOD_CONTROL; + ContextMenuHotKey = Key.OemTilde; + ContextMenuHotKeyFlags = (int)Hotkey.KeyFlags.MOD_CONTROL; + ContextMenuToogle = true; + + ContextMenuList = new List(); + ContextMenuList.Add(new ContextMenuItem("用BugManager搜索", "http://wpswebsvr.wps.kingsoft.net/ksbm/ViewIssue.aspx?IssueID={$1}", "")); + ContextMenuList.Add(new ContextMenuItem("用Google搜索", "https://www.google.com.hk/webhp?hl=zh-CN&sourceid=cnhp&gws_rd=ssl#newwindow=1&safe=strict&hl=zh-CN&q={$1}", "")); + ContextMenuList.Add(new ContextMenuItem("用Baidu搜索", "http://www.baidu.com/baidu?wd={$1}", "")); + } + + public bool TrySave() + { + return TrySave(this); + } + + public void Reload() + { + _config = Load(); + } + + /// + /// 读取一个配置文件,并返回一个PluginConfig对象。若XML配置文件不存在,则会用初始化本类的方式(使用默认初始化值)来创建一个配置文件。 + /// + private static QuickConfig Load() + { + QuickConfig instance; + if (!File.Exists(ConfigPath)) + { + //配置文件不存在,则创建一个新的实例 + instance = new QuickConfig(true); + TrySave(instance); + } + else + { + //如果文件存在,则反序列化它 + XmlSerializer xmlsLoad = new XmlSerializer(typeof(QuickConfig)); + using (FileStream fs = new FileStream(ConfigPath, FileMode.Open, FileAccess.Read)) + { + instance = (QuickConfig)xmlsLoad.Deserialize(fs); + } + } + return instance; + } + + private static bool TrySave(QuickConfig instance) + { + try + { + XmlSerializer xmlsSave = new XmlSerializer(typeof(QuickConfig)); + using (FileStream fs = new FileStream(ConfigPath, FileMode.Create, FileAccess.Write)) + { + xmlsSave.Serialize(fs, instance); + } + return true; + } + catch + { + return false; + } + } + + public Boolean FirstRun { get; set; } + public Key QuickHotKey { get; set; } + public Int32 QuickHotKeyFlags { get; set; } + public Key ContextMenuHotKey { get; set; } + public Int32 ContextMenuHotKeyFlags { get; set; } + public Boolean ContextMenuToogle { get; set; } + public List ModelName { get; set; } + public List ContextMenuList { get; set; } + public String CurrentVersion { get; set; } + public List Plugins { get; set; } + public Boolean LockWindow { get; set; } + } +} diff --git a/Coding/Quick/QuickContext.cs b/Coding/Quick/QuickContext.cs new file mode 100644 index 0000000..d2476f8 --- /dev/null +++ b/Coding/Quick/QuickContext.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Media.Imaging; + +namespace Froser.Quick +{ + internal struct QuickContext + { + public void ClearSubModel() + { + m_subModel = null; + } + + public QuickModel GetSubModel() + { + return m_subModel; + } + + public void ReplaceSubModel(QuickModel m) + { + m_subModel = m; + } + + // 有时候进入某些条目,需要替换掉当前的model + private QuickModel m_subModel; + } +} diff --git a/Coding/Quick/QuickListener.cs b/Coding/Quick/QuickListener.cs new file mode 100644 index 0000000..cc2ed1c --- /dev/null +++ b/Coding/Quick/QuickListener.cs @@ -0,0 +1,259 @@ +using Froser.Quick.UI; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using System.Windows.Forms.Integration; + +namespace Froser.Quick +{ + internal class QuickListener + { + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); + + public static QuickListener Listener + { + get{ + return s_listener ?? (s_listener = new QuickListener()); + } + } + + private QuickListener() + { + m_notify = Program.notify; + m_quickHotkey = new Hotkey(IntPtr.Zero); + m_contextHotkey = new Hotkey(IntPtr.Zero); + + Init(); + } + + public void Init() + { + QuickConfig.ThisConfig.Reload(); + QuickConfig.ThisConfig.CurrentVersion = Application.ProductVersion; + QuickConfig.ThisConfig.TrySave(); + + m_quickModels = new Dictionary(); + + var globalModel = QuickModel.GetModel(QuickModel.GlobalModelName + ".xml"); + m_quickModels.Add(QuickModel.GlobalModelName, globalModel); //添加全局Model + + foreach (var item in QuickConfig.ThisConfig.ModelName) + { + if (!m_quickModels.ContainsKey(item)) + { + m_quickModels.Add(item, QuickModel.GetModel(item + ".xml")); + } + } + + //装载插件 + QuickPluginLoader.AddAdditionQuickMethodTo(m_quickModels); + + m_quickContextWindowHandler = new QuickContextWindowHandler(); + m_quickContextWindow = new QuickContextWindow(m_quickContextWindowHandler); + ElementHost.EnableModelessKeyboardInterop(m_quickContextWindow); + } + + public void Run() + { + m_quickHotkey.RegisterHotkey(QuickConfig.ThisConfig.QuickHotKey, (Hotkey.KeyFlags)QuickConfig.ThisConfig.QuickHotKeyFlags); + m_quickHotkey.OnHotkey += QuickHotkey_OnHotkey; + + m_contextHotkey.RegisterHotkey(QuickConfig.ThisConfig.ContextMenuHotKey, (Hotkey.KeyFlags)QuickConfig.ThisConfig.ContextMenuHotKeyFlags); + m_contextHotkey.OnHotkey += ContextHotkey_OnHotkey; + } + + public void Reload() + { + m_quickHotkey.UnregisterHotkeys(); + m_contextHotkey.UnregisterHotkeys(); + m_quickHotkey = new Hotkey(IntPtr.Zero); + m_contextHotkey = new Hotkey(IntPtr.Zero); + Init(); + Run(); + } + + private void ContextHotkey_OnHotkey(int HotKeyID) + { + try + { + object obj = GetActiveObject(false); + if (QuickConfig.ThisConfig.ContextMenuToogle) + { + var textObject = QuickReflection.Invoke(m_currentModel.Search, obj); + if (textObject != null) + { + m_quickContextWindow.Show(textObject.ToString ()); + QuickVitality.UpdateVitality("context", m_currentModel.ProgramName, textObject.ToString()); + } + } + } + catch { } + } + + public void QuickHotkey_OnHotkey(int HotKeyID) + { + Trigger(false); + } + + private void Trigger(bool forceGetGlobalObject) + { + QuickContext quickContext = default(QuickContext); + bool isGlobal; + Process currentProcess; + IntPtr windowPtr; + object obj = GetActiveObject(forceGetGlobalObject, out isGlobal, out windowPtr, out currentProcess); + SetupQuickMainWindowAndHandler(obj, quickContext, windowPtr, isGlobal, currentProcess); + TriggerQuickMainWindow(isGlobal); + } + + private void TriggerQuickMainWindow(bool isGlobal) + { + if (m_quickMainWindow != null && m_quickMainWindow.IsVisible) + { + m_quickMainWindow.Close(); //如果窗体已存在并在显示状态,则触发FormClosing,Hide() + if (!isGlobal) + { + // 非公共窗口,再次触发快捷键会打开Global的window + Trigger(true); + } + return; + } + else + { + if (m_currentModel.MethodList.Count > 0) + { + QuickVitality.UpdateVitality("showlist", m_currentModel.ProgramName, ""); + m_quickMainWindow.Show(); + m_quickMainWindow.Activate(); + } + } + } + + private object GetGlobalObject(IntPtr windowPtr, bool isGlobal) + { + if (m_commonObject == null) + m_commonObject = new QuickCommonObject(windowPtr, isGlobal); //调用公共的Model + return m_commonObject; + } + + private object GetActiveObject(bool bForceGetGlobalObject) + { + bool isGlobal; + Process currentProcess; + IntPtr windowPtr; + return GetActiveObject(false, out isGlobal, out windowPtr, out currentProcess); + } + + private object GetActiveObject(bool bForceGetGlobalObject, out bool isGlobalModel, out IntPtr windowPtr, out Process currentProcess) + { + object currentActiveObject = null; + windowPtr = GetForegroundWindow(); + int currentPID; + GetWindowThreadProcessId(windowPtr, out currentPID); + currentProcess = Process.GetProcessById(currentPID); //获得活动窗口的进程 + + isGlobalModel = true; + string modelProcessName = string.Empty; + if (bForceGetGlobalObject || !m_quickModels.ContainsKey(currentProcess.ProcessName, true, out modelProcessName)) + { + modelProcessName = QuickModel.GlobalModelName; + } + + if (!isGlobalModel) + Validate(currentProcess.ProcessName); + m_currentModel = m_quickModels[modelProcessName]; + + if (m_currentModel.ProgramName.Trim() != "") + { + bool bFailed = true; + foreach (var name in m_currentModel.ProgramName.Split(',')) + { + try + { + currentActiveObject = Marshal.GetActiveObject(name.Trim()); //调用当前的Model + bFailed = false; + break; + } + catch { } + } + + if (!bFailed) + { + isGlobalModel = false; + } + else + { + m_currentModel = m_quickModels[QuickModel.GlobalModelName]; + currentActiveObject = GetGlobalObject(windowPtr, true); //调用公共的Model + } + } + else + { + currentActiveObject = GetGlobalObject(windowPtr, true); //调用公共的Model + } + + return currentActiveObject; + } + + private void SetupQuickMainWindowAndHandler(object obj, QuickContext quickContext, IntPtr windowPtr, bool isGlobal, Process currentProcess) + { + if (m_handlerMap == null) + m_handlerMap = new Dictionary(); + if (m_windowMap == null) + m_windowMap = new Dictionary(); + + QuickMainWindowHandler handler = null; + if (m_handlerMap.ContainsKey(m_currentModel)) + { + handler = m_handlerMap[m_currentModel]; + } + else + { + handler = new QuickMainWindowHandler(obj, m_currentModel, quickContext, windowPtr, isGlobal, currentProcess); + m_handlerMap.Add(m_currentModel, handler); + } + + if (m_windowMap.ContainsKey(handler)) + { + m_quickMainWindow = m_windowMap[handler]; + } + else + { + m_quickMainWindow = new QuickMainWindow(handler); + ElementHost.EnableModelessKeyboardInterop(m_quickMainWindow); + m_windowMap.Add(handler, m_quickMainWindow); + } + + System.Windows.Media.Color bgColor = System.Windows.Media.Color.FromRgb((byte)m_currentModel.BorderColorR, (byte)m_currentModel.BorderColorG, (byte)m_currentModel.BorderColorB); + m_quickMainWindow.SetBackgroundColor(bgColor); + } + + private void Validate(String processName) + { + Process[] processes = Process.GetProcessesByName(processName); + if (processes.Length > 1) + { + m_notify.ShowBalloonTip("您开启了多个" + processName + "进程,当您调用快捷菜单时,只能对第一个进程进行操作,如果要对其他" + processName + "进行操作,请关闭多余的此类进程。"); + } + } + + private static QuickListener s_listener; + private Dictionary m_quickModels; + private Hotkey m_quickHotkey; + private Hotkey m_contextHotkey; + private QuickContextWindow m_quickContextWindow; + private QuickContextWindowHandler m_quickContextWindowHandler; + private QuickModel m_currentModel; + private QuickMainWindow m_quickMainWindow; + private NotifyIcon m_notify; + private QuickCommonObject m_commonObject; + private Dictionary m_handlerMap; + private Dictionary m_windowMap; + } +} diff --git a/Coding/Quick/QuickMethod.cs b/Coding/Quick/QuickMethod.cs new file mode 100644 index 0000000..6711eba --- /dev/null +++ b/Coding/Quick/QuickMethod.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml.Serialization; + +namespace Froser.Quick +{ + public class QuickMethod + { + public String MethodName = "打开资源管理器 [dakaiziyuanguanliqi]"; + public String MethodScript = "Call(\"explorer.exe\",\"\")"; + public String MethodDescription = "打开资源管理器"; + public String MethodParamRegex = @""; // 可接参数的正则表达式匹配,如\d表示任意数字,.表示任意字符,+表示一个或多个,*表示0个或多个 + public String MethodDefArgs = ""; //动作执行的默认参数,用逗号分隔开 + public Int32 MethodPriority = 0; + [XmlIgnore] + public String Application = ""; //针对特定程序的方法,如wps、et、wpp,用于插件中 + + public override String ToString() + { + return Regex.Replace(MethodName, @"\[.*?\]|\{|\}", ""); + } + + public void SetAdditionMethod(IQuickPluginMethod method) + { + m_method = method; + } + + public IQuickPluginMethod GetPluginInterface() + { + if (m_method == null) + return null; + return new QuickSafePluginMethodRef(m_method); + } + + private IQuickPluginMethod m_method; + } + +} diff --git a/Coding/Quick/QuickModel.cs b/Coding/Quick/QuickModel.cs new file mode 100644 index 0000000..6c41f03 --- /dev/null +++ b/Coding/Quick/QuickModel.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml.Serialization; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Froser.Quick +{ + public class QuickModel + { + [XmlIgnore] + public static String GlobalModelName + { + get + { + return "__global"; + } + } + + public QuickModel() + { + MethodList = new List(); + } + + public QuickModel(QuickModel cloneProperty) + { + MethodList = new List(); + this.BorderColorB = cloneProperty.BorderColorB; + this.BorderColorG = cloneProperty.BorderColorG; + this.BorderColorR = cloneProperty.BorderColorR; + this.Left = cloneProperty.Left; + this.Search = cloneProperty.Search; + this.Top = cloneProperty.Top; + this.Width = cloneProperty.Width; + } + + public static void CreateTemplate() + { + var template = new QuickModel(); + + template.ProgramName = "kwps.application"; + template.MethodList.Add(new QuickMethod()); + + template.BorderColorR = 77; + template.BorderColorG = 130; + template.BorderColorB = 228; + using (var fs = File.Create(QuickUtilities.DirectoryFromDomain(@"config\template.xml"))) + { + new XmlSerializer(template.GetType()).Serialize(fs, template); + } + } + + public static QuickModel GetModel(String filename) + { + XmlSerializer ser = new XmlSerializer(typeof(QuickModel)); + QuickModel ret = null; + using (FileStream fs = + new FileStream(Path.Combine(QuickUtilities.DirectoryFromDomain(@"config\"), filename), FileMode.Open, + FileAccess.Read)) + { + ret = (QuickModel)ser.Deserialize(fs); + return ret; + } + } + + public void Save(String filename) + { + Save(this, filename); + } + + private static void Save(QuickModel instance, String filename) + { + XmlSerializer xmlsSave = new XmlSerializer(typeof(QuickModel)); + using (FileStream fs = new FileStream(Path.Combine(QuickUtilities.DirectoryFromDomain(@"config\"), filename), FileMode.Create, FileAccess.Write)) + { + xmlsSave.Serialize(fs, instance); + } + } + + public static String[] GetArguments(string input) + { + char quote = '"'; + char[] separator = new char[] { ' ', ',' }; + //state: + //-1: parameter with no quote + //0: start + //1: in quote + int state = 0; + List result = new List(); + string value = ""; + for (int i = 0; i < input.Length; i++) + { + char c = input[i]; + switch (state) + { + case -1: + if (separator.Contains(c)) + { + state = 0; + result.Add(value); + value = ""; + } + else + { + value += c; + } + break; + + case 0: + if (c == quote) + { + state = 1; + } + else + { + state = -1; + i--; + } + break; + + case 1: + if (c == quote) + { + state = 0; + result.Add(value); + value = ""; + if (i < input.Length - 1 && separator.Contains(input[i + 1])) + i++; + } + else + { + value += c; + } + break; + } + } + + if (value != "") + result.Add(value); + return result.ToArray(); + } + + public QuickModel GetFilteredModel(Func condition) + { + //condition为筛选条件,达到条件者被保留 + QuickModel model = new QuickModel(); + Action copyAction = (method) => + { + if (condition(method)) + { + model.MethodList.Add(method); + } + }; + MethodList.ForEach(copyAction); + return model; + } + + // meta,不要修改变量名 + public String ProgramName { get; set; } + + public int BorderColorR { get; set; } + public int BorderColorG { get; set; } + public int BorderColorB { get; set; } + public String Left { get; set; } + public String Width { get; set; } + public String Top { get; set; } + public String Search { get; set; } + public List MethodList { get; set; } + } +} \ No newline at end of file diff --git a/Coding/Quick/QuickMultiVersion.cs b/Coding/Quick/QuickMultiVersion.cs new file mode 100644 index 0000000..fbef695 --- /dev/null +++ b/Coding/Quick/QuickMultiVersion.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick +{ + internal static class QuickMultiVersion + { +#if KSO + public static string s_vitalityRequest = "http://10.20.133.13/vitality.aspx?action={0}&target={1}&api={2}"; + public static string s_homePage = "http://10.20.133.13"; + public static string s_commentPage = "http://10.20.133.13/comment.html"; +#else + public static string s_vitalityRequest = "http://quick.kd.net/vitality.aspx?action={0}&target={1}&api={2}"; + public static string s_homePage = "http://quick.kd.net"; + public static string s_commentPage = "http://quick.kd.net/comment.html"; +#endif + } +} diff --git a/Coding/Quick/QuickNotify.cs b/Coding/Quick/QuickNotify.cs new file mode 100644 index 0000000..aebfb2d --- /dev/null +++ b/Coding/Quick/QuickNotify.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Diagnostics; +using Froser.Quick.UI; +using System.Windows.Forms.Integration; +using Froser.Quick.Properties; + +namespace Froser.Quick +{ + internal abstract class QuickNotify + { + public static NotifyIcon GetNotify() + { + NotifyIcon notify = new NotifyIcon(); + notify.Text = "Quick"; + notify.Icon = Icon.FromHandle(Resources.quick.GetHicon()); + notify.MouseClick += (sender, e) => { if (e.Button == MouseButtons.Left) OnAbout(sender, e); }; + notify.ContextMenuStrip = new ContextMenuStrip(); + notify.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { + new ToolStripMenuItem(Application.ProductName + " " + Application.ProductVersion ), + new ToolStripSeparator(), + new ToolStripMenuItem("访问主页", null, (sender, e) => Process.Start (QuickMultiVersion.s_homePage )), + new ToolStripMenuItem("功能缺失反馈", null, (sender, e) => Process.Start (QuickMultiVersion.s_commentPage )), + new ToolStripSeparator(), + new ToolStripMenuItem("重新载入配置", null, (sender, e) => QuickListener.Listener.Reload()), + new ToolStripMenuItem("偏好设置", null, (sender, e) => ShowPreference(false)), + new ToolStripMenuItem("关于", null, OnAbout), + new ToolStripSeparator(), + new ToolStripMenuItem("退出", null, (sender, e) => Program.Quit()), + } + ); + return notify; + } + + private static void OnAbout(object sender, EventArgs e) + { + ShowPreference(true); + } + + private static void ShowPreference(bool about) + { + if (s_perferenceWindowHandler == null) + s_perferenceWindowHandler = new QuickPreferenceWindowHandler(); + + if (s_perferenceWindow == null) + { + s_perferenceWindow = new QuickPreferenceWindow(s_perferenceWindowHandler); + ElementHost.EnableModelessKeyboardInterop(s_perferenceWindow); + } + + if (about) + s_perferenceWindow.ShowAbout(); + else + s_perferenceWindow.Show(); + } + + static QuickPreferenceWindow s_perferenceWindow; + static QuickPreferenceWindowHandler s_perferenceWindowHandler; + } +} diff --git a/Coding/Quick/QuickPluginLoader.cs b/Coding/Quick/QuickPluginLoader.cs new file mode 100644 index 0000000..15180a2 --- /dev/null +++ b/Coding/Quick/QuickPluginLoader.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Froser.Quick +{ + internal static class QuickPluginLoader + { + public static void AddAdditionQuickMethodTo(Dictionary models) + { + // 从配置文件中读取出加载项,放入model中 + var plugins = QuickConfig.ThisConfig.Plugins; + if (!plugins.Contains(s_defaultPlugin)) + plugins.Insert(0, s_defaultPlugin); + List addedList = new List(); + foreach (var pluginPath in plugins) + { + if (addedList.Contains(pluginPath)) + continue; + addedList.Add(pluginPath); + string additionDir = QuickUtilities.DirectoryFromDomain(PLUGINS_PATH); + string addFullPath = Path.Combine(additionDir, pluginPath); + try + { + var methods = GetMethodsFromAssembly(addFullPath); + if (methods == null) + continue; + foreach (var method in methods) + AddToCorrectModel(models, method); + } + catch { } + } + } + + private static IQuickPluginMethod[] GetMethodsFromAssembly(string path) + { + // 加载到当前程序集 + Assembly asm = Assembly.LoadFrom(path); + object instance = asm.CreateInstance("Froser.Quick.QuickPlugin"); + IQuickPlugin addition = new QuickSafePluginRef((IQuickPlugin)instance); + return addition.GetMethods(); + } + + private static void AddToCorrectModel(Dictionary models, IQuickPluginMethod method) + { + QuickMethod coreMethod = new QuickMethod(); + coreMethod.MethodDefArgs = " "; + coreMethod.MethodName = method.GetName(); + coreMethod.MethodDescription = method.GetDescription(null); + bool acceptArgs = method.AcceptArgs(); + coreMethod.MethodParamRegex = acceptArgs ? "." : ""; + coreMethod.SetAdditionMethod(method); + + bool bAddedToSpecificModel = false; + foreach (var modelName in QuickConfig.ThisConfig.ModelName) + { + var availStr = method.AvailableApplicationName(); + string[] avails = availStr != null ? availStr.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) : null; + if (avails != null && avails.Contains(modelName, new ModelNameComparer())) + { + models[modelName].MethodList.Insert(0, coreMethod); + bAddedToSpecificModel = true; + } + } + if (!bAddedToSpecificModel) + { + // 如果没有加到特定的模块,则加到global中 + models[QuickModel.GlobalModelName].MethodList.Insert(0, coreMethod); + } + } + + private class ModelNameComparer : IEqualityComparer + { + public bool Equals(string x, string y) + { + return x.Trim().ToLower() == y.Trim().ToLower(); + } + + public int GetHashCode(string obj) + { + return obj.GetHashCode(); + } + } + + public const string PLUGINS_PATH = "plugins"; + private const string s_defaultPlugin = "quickplugin.dll"; + } +} diff --git a/Coding/Quick/QuickReflection.cs b/Coding/Quick/QuickReflection.cs new file mode 100644 index 0000000..47e08a1 --- /dev/null +++ b/Coding/Quick/QuickReflection.cs @@ -0,0 +1,261 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace Froser.Quick +{ + /// + /// 定义了一些反射方法的类 + /// + internal static class QuickReflection + { + /// + /// 通过调用一些符合C#语法的语句,给对象的成员赋值 + /// + /// 符合C#语法的语句 + /// 需要赋的值 + /// 需要赋值的对象 + public static void Set(String api, object value, object targetObj) + { + object last_obj; + string last_member_name; + object obj = Invoke(api, out last_obj, out last_member_name, targetObj); + last_obj.GetType().InvokeMember(last_member_name, BindingFlags.SetProperty, null, last_obj, new object[] { value }); + } + + /// + /// 调用某个对象的特定方法或返回特定属性成员 + /// + /// 符合C#语法的语句 + /// 需要赋值的对象 + /// 返回对象或属性的值 + public static object Invoke(String api, object targetObj) + { + string strUseless = ""; + object objUseless = null; + return Invoke(api, out objUseless, out strUseless, targetObj); + } + + private static object Invoke(String api, out object last_obj, out string last_member_name, object targetObj) + { + last_member_name = ""; + last_obj = null; + object _obj = targetObj; + string member_name; + object[] parameters; + BindingFlags flags; + bool loop = true; + try + { + //通过反射运行一段API,并获取返回值 + //API返回值大致这样分类: + // 1. 属性值 ( {Property.Property...} = {pi} ) + // 2. 方法返回值 ( {Property.Method (Param1, Param2 ...) ) + while (loop) + { + loop = GetNextMember(api, _obj, out member_name, out flags, out parameters, out api, targetObj); + last_obj = _obj; + _obj = _obj.GetType().InvokeMember(member_name, flags, null, _obj, parameters); + last_member_name = member_name; + } + } + catch (Exception e) + { + throw e; + } + return _obj; + } + + private static bool GetNextMember(string api_string, object COMObj, out string member_name, out BindingFlags flags, out object[] parameters, out string api_remaining_string, object top_obj) + { + Regex regIndexer = new Regex(@"\[(?(.*))\]"); + string s = api_string; + while (s[0] == '.') + { + s = s.Remove(0, 1); + } + String[] sections = s.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + Match mIndexer = regIndexer.Match(sections[0]); + while (mIndexer.Success) + { + string result = mIndexer.Result("${index}"); + sections[0] = sections[0].Replace("[" + result + "]", ".Item(" + result + ")"); + mIndexer = mIndexer.NextMatch(); + } + s = ""; + foreach (string frag in sections) + { + s += frag + "."; + } + s = s.Remove(s.Length - 1); + + string recorder = ""; + for (int i = 0; i < s.Length; i++) + { + if (char.IsWhiteSpace(s[i])) continue; + if (s[i] != '.' && s[i] != '(' && s[i] != '[') + { + recorder += s[i]; + } + else if (s[i] == '.') + { + flags = BindingFlags.GetProperty; + member_name = recorder; + parameters = null; + api_remaining_string = s.Substring(i); + if (api_remaining_string == "") return false; + return true; + } + else if (s[i] == '(') + { + i++; + string pstring = ""; + try + { + while (s[i] != ')' || s.Substring(0, i).CountOf('"') % 2 == 1) + { + pstring += s[i]; + i++; + } + i++; + List plist = new List(); + string tmp = ""; + Action actAddToList = new Action(() => + { + if (tmp != "") + { + double ifDouble; + int ifInt; + if (int.TryParse(tmp, out ifInt)) + { + plist.Add(ifInt); + } + else if (double.TryParse(tmp, out ifDouble)) + { + plist.Add(ifDouble); + } + else if (tmp.ToLower() == "true") + { + plist.Add(true); + } + else if (tmp.ToLower() == "false") + { + plist.Add(false); + } + else if (tmp[0] == '"' && tmp[tmp.Length - 1] == '"') + { + plist.Add(tmp); + } + else + { + plist.Add(Invoke(tmp, top_obj)); + } + } + tmp = ""; + }); + + for (int j = 0; j < pstring.Length; j++) + { + tmp += pstring[j]; + if (pstring[j] == '"') + { + j++; + while (pstring[j] != '"') + { + tmp += pstring[j]; + j++; + } + tmp += pstring[j]; + plist.Add(tmp.Replace("\"", "")); + tmp = ""; + } + else + { + if (char.IsWhiteSpace(pstring[j])) + { + //2014.4.24 + tmp = tmp.Remove(0); + //--------- + continue; + } + if (pstring[j] == ',') + { + tmp = tmp.Remove(tmp.Length - 1); + actAddToList.Invoke(); + } + } + } + + if (tmp != "") + { + actAddToList.Invoke(); + } + + parameters = plist.ToArray(); + flags = BindingFlags.InvokeMethod; + member_name = recorder; + api_remaining_string = s.Substring(i); + if (api_remaining_string == "") return false; + return true; + + } + catch (IndexOutOfRangeException) + { + throw new IndexOutOfRangeException("输入的语句不合法"); + } + catch (Exception) + { + throw; + } + } + } + + member_name = recorder; + flags = BindingFlags.GetProperty; + parameters = null; + api_remaining_string = ""; + return false; + } + + /// + /// 判断某个属性是否为字符串、布尔型、数字型或枚举型 + /// + /// 需要进行判断属性 + /// 返回判断结果 + private static bool IsValueType(PropertyInfo p) + { + Type t = p.PropertyType; + if (t == typeof(String) || + t == typeof(Int32) || + t == typeof(Int64) || + t == typeof(Single) || + t == typeof(Double) || + t == typeof(Boolean) || + t.IsEnum + ) + { + return true; + } + return false; + } + + /// + /// 计算在字符串内某个字符出现的次数 + /// + /// 需要进行判断的字符串 + /// 需要计算数量的字符 + /// 返回值: 字符个数 + private static int CountOf(this string str, char ch) + { + int count = 0; + foreach (char c in str) + { + if (c == ch) count++; + } + return count; + } + } +} diff --git a/Coding/Quick/QuickSafePluginRef.cs b/Coding/Quick/QuickSafePluginRef.cs new file mode 100644 index 0000000..023dad9 --- /dev/null +++ b/Coding/Quick/QuickSafePluginRef.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick +{ + // 会吞掉异常的引用代理 + internal class QuickSafePluginRef : IQuickPlugin + { + public QuickSafePluginRef(IQuickPlugin plugin) + { + m_plugin = plugin; + } + + public IQuickPluginMethod[] GetMethods() + { + try + { + return m_plugin.GetMethods(); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin", "plugin load error", "invoking: GetMethods() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + return null; + } + } + + private IQuickPlugin m_plugin; + } + + internal class QuickSafePluginMethodRef : IQuickPluginMethod + { + public QuickSafePluginMethodRef(IQuickPluginMethod method) + { + m_method = method; + } + + public string GetName() + { + try + { + return m_method.GetName(); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", "plugin GetName() error", "invoking: GetName() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + return null; + } + } + + public string GetDescription(IQuickWindow quickWindow) + { + try + { + return m_method.GetDescription(quickWindow); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: GetName() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + return null; + } + } + + public string AvailableApplicationName() + { + try + { + return m_method.AvailableApplicationName(); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: AvailableApplicationName() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + return null; + } + } + + public void Invoke(object sender, IQuickWindow quickWindow) + { + try + { + m_method.Invoke(sender, quickWindow); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: Invoke() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public bool AcceptArgs() + { + try + { + return m_method.AcceptArgs(); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: AcceptArgs() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + return false; + } + } + + public bool GetIcon(IQuickWindow quickWindow, out System.Windows.Media.ImageSource icon) + { + try + { + return m_method.GetIcon(quickWindow, out icon); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: GetIcon() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + icon = null; + return false; + } + } + + public void KeyDown(IQuickWindow quickWindow, System.Windows.Input.KeyEventArgs e) + { + try + { + m_method.KeyDown(quickWindow, e); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: KeyDown() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void TextChanged(IQuickWindow quickWindow, System.Windows.Controls.TextChangedEventArgs e) + { + try + { + m_method.TextChanged(quickWindow, e); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: TextChanged() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void Closed(IQuickWindow quickWindow) + { + try + { + m_method.Closed(quickWindow); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: Closed() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void PageDown(IQuickWindow quickWindow) + { + try + { + m_method.PageDown(quickWindow); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: PageDown() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void PageUp(IQuickWindow quickWindow) + { + try + { + m_method.PageUp(quickWindow); + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error in plugin method", m_method.GetName(), "invoking: PageUp() and caused " + ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + private IQuickPluginMethod m_method; + } +} diff --git a/Coding/Quick/QuickSafeReflection.cs b/Coding/Quick/QuickSafeReflection.cs new file mode 100644 index 0000000..4573d6c --- /dev/null +++ b/Coding/Quick/QuickSafeReflection.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick +{ + public static class QuickSafeReflection + { + public static void Set(String api, object value, object targetObj) + { + try + { + QuickReflection.Set(api, value, targetObj); + } + catch { } + } + + public static object Invoke(String api, object targetObj) + { + try + { + return QuickReflection.Invoke(api, targetObj); + } + catch + { + return null; + } + } + + } +} diff --git a/Coding/Quick/QuickUpdate.cs b/Coding/Quick/QuickUpdate.cs new file mode 100644 index 0000000..8ee1a0e --- /dev/null +++ b/Coding/Quick/QuickUpdate.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Windows.Forms; +using System.Xml.Linq; + +namespace Froser.Quick +{ + internal static class QuickUpdate + { + /// + /// 静默更新,有更新且换完成后返回true,否则返回false + /// + public static bool SilenceUpdate() + { + try + { + XDocument resp = null; + string latestVersion = null; + if (HasUpdate(out resp, out latestVersion)) + { + string updateUrlRoot = "http://10.20.133.13/download/update/"; + var filelist = resp.Element("info").Element("version").Element ("filelist").Descendants(); + + string updateDir = Path.Combine (AppDir, "update"); + + WebClient wc = new WebClient(); + foreach (var file in filelist) + { + string fileAddress = updateUrlRoot + file.Value; + string downloadPath = Path.Combine(updateDir, fileAddress.Replace(updateUrlRoot, "")); + string dir = Path.GetDirectoryName(downloadPath); + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + + wc.DownloadFile(fileAddress, downloadPath); + // 因为服务器设置,不能直接下载的文件类型加上.update + // 在配置服务器的时候,应该添加.update的MIME关联 + if (Path.GetExtension(downloadPath) == ".update") + File.Move(downloadPath, Path.Combine(Path.GetDirectoryName(downloadPath), Path.GetFileNameWithoutExtension(downloadPath))); + } + + // 下载完所有更新文件后,写updatenotify文件 + string notifyFilePath = Path.Combine(AppDir, "updatenotify"); + using (var writer = File.CreateText(notifyFilePath)) + { + writer.WriteLine(latestVersion); + } + + // 准备退出程序,调用QuickUpdate + + return true; + } + } + catch { } + return false; + } + + public static bool LocalUpdate() + { + try + { + if (NeedLocalUpdate()) + { + Process proc = Process.Start(UpdateAppPath); + return true; + } + } + catch { } + return false; + } + + private static bool NeedLocalUpdate() + { + if (File.Exists(NotifyFilePath)) + { + using (var reader = File.OpenText(NotifyFilePath)) + { + return !QuickUtilities.IsLatestVersion(Application.ProductVersion, reader.ReadToEnd().Trim()); + } + } + return false; + } + + private static bool HasUpdate(out XDocument resp, out string latestVersion) + { + try + { + resp = XDocument.Load(@"http://10.20.133.13/Download/Version.xml"); + String version = Application.ProductVersion; + latestVersion = resp.Element("info").Element("version").Attribute("value").Value; + return !QuickUtilities.IsLatestVersion(version, latestVersion); + } + catch + { + //先吞掉更新失败的问题 + resp = null; + latestVersion = null; + return false; + } + } + + private static string AppDir + { + get + { + return AppDomain.CurrentDomain.BaseDirectory; + } + } + + private static string NotifyFilePath + { + get + { + return Path.Combine(AppDir, s_notifyFile); + } + } + + private static string UpdateAppPath + { + get + { + return Path.Combine(AppDir, s_updateAppPath); + } + } + + private const string s_notifyFile = "updatenotify"; + private const string s_updateAppPath = "quickupdate.exe"; + } +} diff --git a/Coding/Quick/QuickVitality.cs b/Coding/Quick/QuickVitality.cs new file mode 100644 index 0000000..75a90c8 --- /dev/null +++ b/Coding/Quick/QuickVitality.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Net; +using System.Windows.Forms; +using System.Web; + +namespace Froser.Quick +{ + internal static class QuickVitality + { + public static void UpdateVitality(String action, String target, String api) + { +#if !DEBUG + Action update = () => + { + action = HttpUtility.UrlEncode(action); + target = HttpUtility.UrlEncode(target); + api = HttpUtility.UrlEncode(api); + + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(String.Format(QuickMultiVersion.s_vitalityRequest, action, target, api)); + try + { + request.Method = "GET"; + request.UserAgent = "Quick " + Application.ProductVersion; + request.BeginGetResponse(null, null); //只需要异步,无需知道结果 + } + catch { } + }; + update.BeginInvoke(null, null); +#endif + } + } +} diff --git a/Coding/Quick/UI/QuickContextWindowHandler.cs b/Coding/Quick/UI/QuickContextWindowHandler.cs new file mode 100644 index 0000000..1582e60 --- /dev/null +++ b/Coding/Quick/UI/QuickContextWindowHandler.cs @@ -0,0 +1,80 @@ +using Froser.Quick.UI; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Controls; + +namespace Froser.Quick.UI +{ + class QuickContextWindowHandler : IQuickContextWindowHandler + { + [DllImport("user32.dll", EntryPoint = "GetCursorPos")] + public static extern bool GetCursorPos(ref Point lpPoint); + + public void SetHost(QuickContextWindow host) + { + m_host = host; + } + + public void Init() + { + var list = m_host.GetList(); + foreach (var i in QuickConfig.ThisConfig.ContextMenuList) + { + QuickListItem item = new QuickListItem(i.Name, null, null); + item.Tag = i; + item.CreateListBoxItemTo(list); + } + list.ListItemClicked += itemClicked; + } + + private void itemClicked(object sender, EventArgs e) + { + ListBoxItem listItem = (ListBoxItem)sender; + QuickListItem rawItem = (QuickListItem)listItem.Tag; + var menuItem = (QuickConfig.ContextMenuItem)rawItem.Tag; + string concreteCmd = menuItem.Exec.Replace(QuickConfig.ContextMenuItem.Replacement, m_context.ToString()); + Process.Start(concreteCmd, menuItem.Argument); + } + + public void BeforeShow(string context) + { + m_context = context; + + Point mousePos = new Point(); + GetCursorPos(ref mousePos); + m_host.Left = mousePos.X; + m_host.Top = mousePos.Y; + m_host.Activate(); + } + + public void AfterShow() + { + if (!m_adjustedHeight) + { + var listItems = m_host.GetList().Items; + if (listItems.Count > 0) + { + ListBoxItem item = (ListBoxItem)m_host.GetList().Items[0]; + double eachHeight = item.ActualHeight; + const int OFFSET = 4; + m_host.Height = (eachHeight + OFFSET) * listItems.Count ; + } + m_adjustedHeight = true; + } + } + + public void OnDeactivate(object sender, EventArgs e) + { + m_host.Hide(); + } + + private QuickContextWindow m_host; + private bool m_adjustedHeight = false; + private string m_context; + } +} diff --git a/Coding/Quick/UI/QuickMainWindowHandler.cs b/Coding/Quick/UI/QuickMainWindowHandler.cs new file mode 100644 index 0000000..e0a1a0f --- /dev/null +++ b/Coding/Quick/UI/QuickMainWindowHandler.cs @@ -0,0 +1,748 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace Froser.Quick.UI +{ + internal class QuickMainWindowHandler : IQuickMainWindowHandler, IQuickWindow + { + [DllImport("user32.dll", SetLastError = true)] + private static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); + + public QuickMainWindowHandler(object comObject, QuickModel model, QuickContext context, IntPtr hostPtr) + { + m_comObject = comObject; + m_model = model; + m_hostPtr = hostPtr; + m_context = context; + m_utilities = new Utilities(comObject); + m_defaultIcon = null; + m_bitmapSourceCache = null; + m_isGlobalModel = true; + m_locked = false; + } + + ~QuickMainWindowHandler() + { + ReleaseObject(); + } + + public QuickMainWindowHandler(object comObject, QuickModel model, QuickContext context, IntPtr hostPtr, bool isGlobalModel, Process currentProcess) + : this(comObject, model, context, hostPtr) + { + m_isGlobalModel = isGlobalModel; + if (!isGlobalModel) + { + try + { + var icon = Icon.ExtractAssociatedIcon(currentProcess.MainModule.FileName); //获得主线程图标 + if (icon != null) + SetDefaultIcon(icon); + } + catch + { + } + } + } + + public void Init() + { + UpdateLockImage(); + } + + public void OnLockedClick(object sender, MouseButtonEventArgs e) + { + var config = QuickConfig.ThisConfig; + config.LockWindow = !config.LockWindow; + UpdateLockImage(); + config.TrySave(); + } + + public void OnClosing(object sender, System.ComponentModel.CancelEventArgs e) + { + e.Cancel = true; + try + { + m_hostWindow.Hide(); + + BlockTextBoxChangedEvent(); + NotifyPluginOnClosed(); + m_hostWindow.GetQueryTextBox().Document.Blocks.Clear(); + m_context.ClearSubModel(); + + FilterList(""); + ResetPage(); + RefreshList(); + } + catch { } + finally + { + UnblockTextBoxChangedEvent(); + } + + } + + public void OnShowing() + { + m_hostWindow.ResetOpacity(); + + if (m_bFirstLoad) + FirstLoad(); + else + AdjustPosition(); + m_hostWindow.GetQueryTextBox().Focus(); + } + + public void OnShowed() + { + if (m_bFirstLoad) + { + AdjustPosition(); + m_bFirstLoad = false; + } + } + + public void OnDeactivated(object sender, EventArgs e) + { + bool globalLock = QuickConfig.ThisConfig.LockWindow; + if (!m_locked && !globalLock) + JobDone(); + else + m_hostWindow.SetOpacity(0.3d); + } + + public void OnActivated(object sender, EventArgs e) + { + m_hostWindow.ResetOpacity(); + } + + public void OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e) + { + int idx = GetSelectedIndex(); + if (idx >= 0) + { + var plugin = m_availableMethods[idx].GetPluginInterface(); + if (plugin != null) + plugin.KeyDown(this, e); + } + + switch (e.Key) + { + case Key.Enter: + InvokeCommand(); + break; + case Key.Down: + m_hostWindow.SelectNext(); + break; + case Key.Up: + m_hostWindow.SelectPrevious(); + break; + case Key.PageDown: + PageDown(); + e.Handled = true; + break; + case Key.PageUp: + PageUp(); + e.Handled = true; + break; + case Key.End: + { + int itemCount = m_hostWindow.GetList().Items.Count; + if (itemCount > 0) + m_hostWindow.Select(itemCount - 1); + } + break; + case Key.Home: + { + int itemCount = m_hostWindow.GetList().Items.Count; + if (itemCount > 0) + m_hostWindow.Select(0); + } + break; + case Key.Escape: + JobDone(); + break; + } + } + + public void OnMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) + { + } + + public void OnTextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) + { + if (!m_textboxSelectionChangedBlock) + { + FilterList(GetQueryText()); + ResetPage(); + RefreshList(); + + // 全局Model下要筛选下,拿到正确的Method + m_hostWindow.GetList().SelectedIndex = 0; + var currentMethod = GetSelectedMethod(); + if (currentMethod != null) + { + var plugin = currentMethod.GetPluginInterface(); + if (plugin != null) + { + plugin.TextChanged(this, e); + ResetPage(); + return; + } + } + } + } + + public void OnListItemClicked(object sender, EventArgs e) + { + InvokeCommand(); + } + + public void OnListPageUp() + { + if (PageUp()) + m_hostWindow.Select(m_hostWindow.GetList().Items.Count - 1); + } + + public void OnListPageDown() + { + if (PageDown()) + m_hostWindow.Select(0); + } + + public void SetHostWindow(QuickMainWindow host) + { + m_hostWindow = host; + } + + public void BlockTextBoxChangedEvent() + { + m_textboxSelectionChangedBlock = true; + } + + public void UnblockTextBoxChangedEvent() + { + m_textboxSelectionChangedBlock = false; + } + + public string GetQueryText() + { + var textbox = m_hostWindow.GetQueryTextBox(); + TextRange txRange = new TextRange(textbox.Document.ContentStart, textbox.Document.ContentEnd); + return txRange.Text.Trim(); + } + + public void SetQueryText(string text) + { + var textbox = m_hostWindow.GetQueryTextBox(); + BlockTextBoxChangedEvent(); + textbox.Document.Blocks.Clear(); + UnblockTextBoxChangedEvent(); + var para = new Paragraph(); + Run r = new Run(text); + para.Inlines.Add(r); + textbox.Document.Blocks.Add(para); + } + + public RichTextBox GetQueryTextBox() + { + return m_hostWindow.GetQueryTextBox(); + } + + public string GetArgument() + { + return GetArgumentString(GetQueryText()); + } + + public void ReplaceMethods(IQuickPluginMethod[] methods) + { + QuickModel model = new QuickModel(m_model); + foreach (var m in methods) + { + QuickMethod qm = new QuickMethod(); + qm.Application = m.AvailableApplicationName(); + qm.MethodDefArgs = " "; + qm.MethodParamRegex = "."; //一定可以接受参数 + qm.MethodDescription = m.GetDescription(this); + qm.MethodName = m.GetName(); + qm.SetAdditionMethod(m); + model.MethodList.Add(qm); + } + m_context.ReplaceSubModel(model); + FilterList(GetQueryText()); + ResetPage(); + RefreshList(); + } + + public void ResetMethods() + { + m_context.ClearSubModel(); + FilterList(GetQueryText()); + ResetPage(); + RefreshList(); + } + + public void SetDefaultIcon(Icon icon) + { + m_defaultIcon = icon; + m_bitmapSourceCache = icon.ToBitmapSource(); + } + + public string GetPluginsPath() + { + return QuickPluginLoader.PLUGINS_PATH; + } + + public int GetCurrentPage() + { + return m_page; + } + + public void Refresh(int selectIndex) + { + FilterList(GetQueryText()); + RefreshList(); + var list = m_hostWindow.GetList(); + int count = list.Items.Count; + if (count > 0) + { + if (selectIndex < 0) + selectIndex = 0; + else if (selectIndex >= count) + m_hostWindow.Select(count - 1); + list.SelectedIndex = selectIndex; + } + } + + public void LockWindow() + { + m_locked = true; + } + + public void UnlockWindow() + { + m_locked = false; + } + + public void AsyncInvoke(Action action) + { + m_hostWindow.Dispatcher.BeginInvoke(action); + } + + private void AdjustPosition() + { + if (!m_isGlobalModel) + { + try + { + m_hostWindow.Left = (int)(QuickSafeReflection.Invoke(m_model.Left, m_comObject).Plus(QuickSafeReflection.Invoke(m_model.Width, m_comObject)) - 60); + m_hostWindow.Top = (int)(QuickSafeReflection.Invoke(m_model.Top, m_comObject).Plus(0)); + } + catch + { + foreach (var name in m_model.ProgramName.Split(',')) + { + try + { + m_comObject = Marshal.GetActiveObject(name); + m_hostWindow.Left = (int)(QuickSafeReflection.Invoke(m_model.Left, m_comObject).Plus(QuickSafeReflection.Invoke(m_model.Width, m_comObject)) - 60); + m_hostWindow.Top = (int)(QuickSafeReflection.Invoke(m_model.Top, m_comObject).Plus(0)); + break; + } + catch (Exception ex) + { + QuickVitality.UpdateVitality("error", m_model.ProgramName, "GetActiveObject error. " + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace); + } + } + } + } + else + { + var commonObj = m_comObject as QuickCommonObject; + if (m_comObject == null) + { + throw new Exception("公共对象并非CommonObject"); + } + else + { + m_hostWindow.Left = commonObj.GetWindowRect().Left + (commonObj.GetWindowRect().Right - commonObj.GetWindowRect().Left - m_hostWindow.Width) / 2; + m_hostWindow.Top = commonObj.GetWindowRect().Top + (commonObj.GetWindowRect().Bottom - commonObj.GetWindowRect().Top - m_hostWindow.Height) / 2; + } + } + } + + private void NotifyPluginOnClosed() + { + foreach (var method in m_model.MethodList) + { + var plugin = method.GetPluginInterface(); + if (plugin != null) + plugin.Closed(this); + } + } + + private QuickMethod GetSelectedMethod() + { + int idx = GetSelectedIndex(); + if (m_availableMethods.Count > 0 && idx >= 0) + return m_availableMethods[idx]; + return null; + } + + private int GetMaxPage() + { + // 获得从0开始算起的最大页码编号 + int totalCount = m_availableMethods.Count; + int max = (totalCount - 1) / MAX_DISPLAY_ACTION; + return max < 0 ? 0 : max; + } + + private bool PageUp() + { + bool result = false; + if (m_page > 0) + { + m_page--; + RefreshList(); + result = true; + } + + var plugin = GetSelectedMethod().GetPluginInterface(); + if (plugin != null) + plugin.PageUp(this); + return result; + } + + private bool PageDown() + { + bool result = false; + if (m_page < GetMaxPage()) + { + m_page++; + RefreshList(); + result = true; + } + + var plugin = GetSelectedMethod().GetPluginInterface(); + if (plugin != null) + plugin.PageDown(this); + return result; + } + + private void JobDone() + { + m_hostWindow.Close(); + } + + private void FirstLoad() + { + ResetPage(); + FilterList(""); + RefreshList(); + } + + private void ResetPage() + { + m_page = 0; + } + + private void FilterList(String queryText) + { + // 将符合条件的选项筛选进available list + m_availableMethods = new List(); + var subModel = m_context.GetSubModel(); + bool isSubModel = (subModel != null); + QuickModel currentModel = subModel ?? m_model; + + foreach (QuickMethod methodItem in currentModel.MethodList) + { + string query = queryText; + bool hasParams = false; + Regex reg_params = GetArgumentRegex(methodItem.MethodParamRegex); + Match m = reg_params.Match(query); + + if (m.Success) + { + query = reg_params.Replace(query, "").Trim(); //表示取出参数后的字符串 + hasParams = true; + } + else + { + hasParams = false; + } + + if (query.Trim() == "" || methodItem.MethodName.Replace(" ", "").HasString(query) || isSubModel) + { + if (hasParams) + { + //滤过不含参数的指令。含有参数的方法,其正则表达式不为空 + if (methodItem.MethodParamRegex == "") + { + continue; + } + } + m_availableMethods.Add(methodItem); + } + } + } + + private void RefreshList() + { + var list = m_hostWindow.GetList(); + list.Items.Clear(); + for (int i = 0; i < MAX_DISPLAY_ACTION; i++) + { + int idx = m_page * MAX_DISPLAY_ACTION + i; + if (idx == m_availableMethods.Count) + break; + + var currentMethod = m_availableMethods[idx]; + string title = Regex.Replace(currentMethod.MethodName, REG_TITLE_RULES, ""); + string description = null; + ImageSource icon = null; + IQuickPluginMethod plugin = currentMethod.GetPluginInterface(); + // 如果是一个加载项,可以调用其函数获取 + if (plugin != null) + { + description = plugin.GetDescription(this); + ImageSource tmp = null; + bool needIcon = plugin.GetIcon(this, out tmp); + if (needIcon) + icon = tmp; + else + icon = QuickUIResource.GetDefaultPluginIcon(); + } + else + { + description = currentMethod.MethodDescription; + if (!m_isGlobalModel) //非全局的情况下,使用当前应用程序的图标 + icon = m_bitmapSourceCache; + } + + QuickListItem item = new QuickListItem(title, description, icon); + item.CreateListBoxItemTo(m_hostWindow.GetList()); + } + if (GetSelectedIndex() == -1 && m_hostWindow.GetList().HasItems) + m_hostWindow.GetList().SelectedIndex = 0; + + AutoResize(); + } + + private void AutoResize() + { + m_hostWindow.AutoResize(); + } + + private String GetArgumentString(String queryText) + { + String methodParamRegex = GetSelectedIndex() == -1 ? "." : m_availableMethods[GetSelectedIndex()].MethodParamRegex; + Regex reg_params = GetArgumentRegex(methodParamRegex); + Match m = reg_params.Match(queryText); + + if (m.Success) + return m.Result("${PARAMS}"); + return null; + } + + private int GetSelectedIndex() + { + return m_hostWindow.GetList().SelectedIndex; + } + + private void InvokeCommand() + { + int idx = GetSelectedIndex(); + var list = m_hostWindow.GetList(); + if (idx == -1) + { + if (!list.HasItems) + return; + idx = 0; + } + + QuickMethod method = m_availableMethods[idx]; + String arguments = GetArgumentString(GetQueryText()); + String realMethod = "invalid"; + try + { + String[] args = arguments == null ? QuickModel.GetArguments(method.MethodDefArgs) : QuickModel.GetArguments(arguments); + if (method.GetPluginInterface() != null) + { + method.GetPluginInterface().Invoke(m_comObject, this); + } + else if (method.MethodParamRegex == "" || method.MethodParamRegex == "." || args.Length > 0) + { + //将参数塞进MethodScript中 + if (method.MethodScript.Trim()[0] == '!') + { + //!表示对布尔值进行切换 + realMethod = method.MethodScript.Trim().Substring(1); + object value = QuickSafeReflection.Invoke(realMethod, m_comObject); + if (value is bool) + { + QuickSafeReflection.Set(realMethod, !(bool)value, m_comObject); + } + } + else if (method.MethodScript.Trim()[0] == '@') + { + String utilityMethod = null; + //如果是@开头,表示调用Utilities中方法来赋值或将返回值传给方法中的{$1} + //可能存在!在引号内的风险 + if (method.MethodScript.Contains("!")) + { + utilityMethod = method.MethodScript.Substring(1, method.MethodScript.IndexOf('!') - 1); + utilityMethod = ReplaceAruguments(utilityMethod, args); + realMethod = method.MethodScript.Substring(method.MethodScript.IndexOf('!') + 1); + + if (method.MethodScript.Trim()[method.MethodScript.Length - 1] != ')') + { + QuickSafeReflection.Set(realMethod, QuickSafeReflection.Invoke(utilityMethod, m_utilities), m_comObject); + } + else + { + realMethod = ReplaceAruguments(realMethod, (String[])QuickSafeReflection.Invoke(utilityMethod, m_utilities)); + QuickSafeReflection.Invoke(realMethod, m_comObject); + } + } + else + { + utilityMethod = method.MethodScript.Substring(1); + realMethod = ReplaceAruguments(utilityMethod, args); + QuickSafeReflection.Invoke(realMethod, m_utilities); + } + } + else if (method.MethodScript.Trim()[method.MethodScript.Length - 1] != ')') + { + //如果不以)结尾,表示是一个赋值方法 + realMethod = method.MethodScript; + QuickSafeReflection.Set(realMethod, args[0], m_comObject); + } + else + { + realMethod = ReplaceAruguments(method.MethodScript, args); + QuickSafeReflection.Invoke(realMethod, m_comObject); + } + } + + QuickVitality.UpdateVitality("invoke", m_model.ProgramName, realMethod); + } + catch (Exception ex) + { + //在此插入异常 + QuickVitality.UpdateVitality("error", m_model.ProgramName, "invoking: " + realMethod + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace); + } + JobDone(); + } + + private Regex GetArgumentRegex(string methodParamRegex) + { + // 获得参数匹配的正则表达式 + return new Regex(@"\s+?(?(" + methodParamRegex + @"|,|\s)+)(\s*$)"); + } + + private string ReplaceAruguments(string script, string[] replacement) + { + //将{$1}、{$2}、{$n}以实际的参数代替 + //将{$_}替换为,以引号包围、逗号分隔的长串字符 + //将{$!}替换为,"replacement[0]","replacement[rest]"形式的字符串 + if (replacement == null) return script; + StringBuilder stringArgs = new StringBuilder(); + if (script.Contains("{$_}")) + { + foreach (var arg in replacement) + { + stringArgs.AppendFormat("\"{0}\",", arg); + } + stringArgs.Remove(stringArgs.Length - 1, 1); + script = script.Replace("{$_}", stringArgs.ToString()); + } + else if (script.Contains("{$!}")) + { + bool prefix = false; + for (int i = 0; i < replacement.Length; i++) + { + if (i == 0) + { + stringArgs.Append("\"" + replacement[i] + "\",\""); + } + else + { + stringArgs.Append(replacement[i] + " "); + if (!prefix) prefix = true; + } + } + if (prefix) stringArgs.Remove(stringArgs.Length - 1, 1); + stringArgs.Append("\""); + script = script.Replace("{$!}", stringArgs.ToString()); + } + + for (int i = 0; i < replacement.Length; i++) + { + string token = "{$" + (i + 1) + "}"; + if (script.Contains(token)) + { + script = script.Replace(token, replacement[i]); + } + } + return script; + } + + private ImageSource GetWindowLockImage(bool locked) + { + return locked + ? QuickUIResource.GetLockedIcon() + : QuickUIResource.GetUnlockedIcon(); + } + + private void UpdateLockImage() + { + var lockedButton = m_hostWindow.GetLockImageButton(); + bool windowLocked = QuickConfig.ThisConfig.LockWindow; + lockedButton.Source = GetWindowLockImage(windowLocked); + } + + /// + /// 彻底释放COM对象,防止进程残留 + /// + private void ReleaseObject() + { + if (!m_isGlobalModel) + { + try + { + System.Runtime.InteropServices.Marshal.FinalReleaseComObject(m_comObject); + GC.Collect(); + } + catch { } + } + } + + private const string REG_TITLE_RULES = @"\[.*?\]|\{|\}"; //标题规范 [] {},[]中的内容不会显示但是会被检索,{}中的内容会被显示但是不会被检索 + private const int MAX_DISPLAY_ACTION = 10; + + private bool m_bFirstLoad = true; + private QuickMainWindow m_hostWindow; + private object m_comObject; + private QuickContext m_context; + private QuickModel m_model; + private IntPtr m_hostPtr; + private Utilities m_utilities; + private List m_availableMethods; //第一部分为QuickMethod,第二部分为参数 + private int m_page; + private bool m_textboxSelectionChangedBlock = false; + + private Icon m_defaultIcon; + private BitmapSource m_bitmapSourceCache; + private bool m_isGlobalModel; + private bool m_locked; + } +} diff --git a/Coding/Quick/UI/QuickPreferenceWindowHandler.cs b/Coding/Quick/UI/QuickPreferenceWindowHandler.cs new file mode 100644 index 0000000..b1d4737 --- /dev/null +++ b/Coding/Quick/UI/QuickPreferenceWindowHandler.cs @@ -0,0 +1,394 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; + +namespace Froser.Quick.UI +{ + public class QuickPreferenceWindowHandler : IQuickPreferenceWindowHandler + { + public void LoadConfig() + { + LoadGeneral(); + LoadTemplate(); + LoadVersion(); + } + + public void SetHost(QuickPreferenceWindow host) + { + m_host = host; + } + + public void OnSave() + { + SaveGeneral(); + QuickConfig.ThisConfig.TrySave(); + QuickListener.Listener.Reload(); + } + + public void OnGeneralDefault() + { + QuickConfig.ThisConfig.SetDefaultConfig(); + LoadGeneral(); + } + + public void OnSaveMethod() + { + var list = m_host.GetMethodsListInTemplate(); + var item = (QuickMethod)list.SelectedItem; + if (item != null) + { + var methodName = m_host.GetMethodNameTextBoxInTemplate(); + var methodDescription = m_host.GetMethodDescriptionTextBoxInTemplate(); + var methodScript = m_host.GetMethodScriptTextBoxInTemplate(); + var methodDefArg = m_host.GetMethodDefaultArgumentTextBoxInTemplate(); + var methodRegex = m_host.GetMethodRegexTextBoxInTemplate(); + var filename = ((FrameworkElement)m_host.GetTemplateListInTemplate().SelectedItem).Tag.ToString(); + + item.MethodName = methodName.Text; + item.MethodDescription = methodDescription.Text; + item.MethodScript = methodScript.Text; + item.MethodDefArgs = methodDefArg.Text; + item.MethodParamRegex = methodRegex.Text; + item.MethodPriority = 0; + + SaveModel(); + } + } + + private void SaveModel() + { + var filename = ((FrameworkElement)m_host.GetTemplateListInTemplate().SelectedItem).Tag.ToString(); + try + { + m_currentModel.Save(filename); + QuickListener.Listener.Reload(); + } + catch (Exception) + { + // TODO: 在这里处理异常 + } + } + + private void ClearTextBoxInTemplate() + { + var methodName = m_host.GetMethodNameTextBoxInTemplate(); + var methodDescription = m_host.GetMethodDescriptionTextBoxInTemplate(); + var methodScript = m_host.GetMethodScriptTextBoxInTemplate(); + var methodDefArg = m_host.GetMethodDefaultArgumentTextBoxInTemplate(); + var methodRegex = m_host.GetMethodRegexTextBoxInTemplate(); + methodName.Clear(); + methodDescription.Clear(); + methodScript.Clear(); + methodDefArg.Clear(); + methodRegex.Clear(); + } + + public void OnCreateNewContext() + { + var list = m_host.GetContextMenuInGeneral(); + QuickConfig.ContextMenuItem newItem = new QuickConfig.ContextMenuItem(); + QuickConfig.ThisConfig.ContextMenuList.Add(newItem); + LoadContextMenu(); + } + + public void OnRemoveContext() + { + var list = m_host.GetContextMenuInGeneral(); + object selectedItem = list.SelectedItem; + if (selectedItem != null) + { + list.Items.Remove(selectedItem); + QuickConfig.ThisConfig.ContextMenuList.Remove((QuickConfig.ContextMenuItem)selectedItem); + LoadContextMenu(); + } + } + + public void OnModifyContext() + { + var list = m_host.GetContextMenuInGeneral(); + var item = (QuickConfig.ContextMenuItem)list.SelectedItem; + if (item == null) + return; + + QuickPerferenceContextEdit editor = new QuickPerferenceContextEdit(); + editor.Init += (() => { + editor.GetName().Text = item.Name; + editor.GetBehavior().Text = item.Exec; + editor.GetArgument().Text = item.Argument; + }); + editor.Done += (() => { + item.Name = editor.GetName().Text; + item.Exec = editor.GetBehavior().Text; + item.Argument = editor.GetArgument().Text; + QuickConfig.ThisConfig.TrySave(); + LoadContextMenu(); + }); + editor.Show(); + } + + public void OnRestoreMethod() + { + var list = m_host.GetMethodsListInTemplate(); + var item = (QuickMethod)list.SelectedItem; + if (item != null) + { + var methodName = m_host.GetMethodNameTextBoxInTemplate(); + var methodDescription = m_host.GetMethodDescriptionTextBoxInTemplate(); + var methodScript = m_host.GetMethodScriptTextBoxInTemplate(); + var methodDefArg = m_host.GetMethodDefaultArgumentTextBoxInTemplate(); + var methodRegex = m_host.GetMethodRegexTextBoxInTemplate(); + methodName.Text = item.MethodName; + methodDescription.Text = item.MethodDescription; + methodScript.Text = item.MethodScript; + methodDefArg.Text = item.MethodDefArgs; + methodRegex.Text = item.MethodParamRegex; + } + } + + public void OnMoveUpMethod() + { + var list = m_host.GetMethodsListInTemplate(); + var item = list.SelectedItem; + if (item != null) + { + int idx = list.SelectedIndex; + if (idx > 0) + { + m_currentModel.MethodList.Swap(list.Items[idx], list.Items[idx - 1]); + list.Items.Swap(list.Items[idx], list.Items[idx - 1]); + list.SelectedIndex = idx - 1; + SaveModel(); + } + } + } + + public void OnMoveDownMethod() + { + var list = m_host.GetMethodsListInTemplate(); + var item = list.SelectedItem; + if (item != null) + { + int idx = list.SelectedIndex; + if (idx < list.Items.Count - 1) + { + m_currentModel.MethodList.Swap(list.Items[idx], list.Items[idx + 1]); + list.Items.Swap(list.Items[idx], list.Items[idx + 1]); + list.SelectedIndex = idx + 1; + SaveModel(); + } + } + } + + public void OnCreateNewMethod() + { + var list = m_host.GetMethodsListInTemplate(); + var item = list.SelectedItem; + var method = new QuickMethod(); + if (item != null) + { + m_currentModel.MethodList.Insert(list.SelectedIndex, method); + list.Items.Insert(list.SelectedIndex, method); + } + else + { + m_currentModel.MethodList.Add(method); + list.Items.Insert(list.Items.Count, new QuickMethod()); + } + SaveModel(); + } + + public void OnDeleteMethod() + { + var list = m_host.GetMethodsListInTemplate(); + var item = list.SelectedItem; + if (item != null) + { + var method = new QuickMethod(); + m_currentModel.MethodList.Remove((QuickMethod)item); + list.Items.Remove(item); + SaveModel(); + } + } + + public void OnTemplateSelected(int index) + { + if (index < 0) + return; + + var item = m_host.GetTemplateListInTemplate().Items[index]; + string filename = ((FrameworkElement)item).Tag.ToString(); + var methodsList = m_host.GetMethodsListInTemplate(); + m_currentModel = QuickModel.GetModel(filename); + methodsList.Items.Clear(); + foreach (var i in m_currentModel.MethodList) + { + methodsList.Items.Add(i); + } + } + + private void LoadGeneral() + { + TextBox quickKey = m_host.GetQuickTextBoxInGeneral(); + CheckBox quickShift = m_host.GetQuickShiftInGeneral(); + CheckBox quickCtrl = m_host.GetQuickCtrlInGeneral(); + CheckBox quickAlt = m_host.GetQuickAltInGeneral(); + CheckBox quickWin = m_host.GetQuickWinInGeneral(); + + quickKey.Tag = QuickConfig.ThisConfig.QuickHotKey; + quickKey.Text = QuickConfig.ThisConfig.QuickHotKey.KeyToString(); + if ((QuickConfig.ThisConfig.QuickHotKeyFlags & (int)Hotkey.KeyFlags.MOD_ALT) != 0) + quickAlt.IsChecked = true; + if ((QuickConfig.ThisConfig.QuickHotKeyFlags & (int)Hotkey.KeyFlags.MOD_CONTROL) != 0) + quickCtrl.IsChecked = true; + if ((QuickConfig.ThisConfig.QuickHotKeyFlags & (int)Hotkey.KeyFlags.MOD_SHIFT) != 0) + quickShift.IsChecked = true; + if ((QuickConfig.ThisConfig.QuickHotKeyFlags & (int)Hotkey.KeyFlags.MOD_WIN) != 0) + quickWin.IsChecked = true; + + // ---- + TextBox contextKey = m_host.GetContextTextBoxInGeneral(); + CheckBox contextShift = m_host.GetContextShiftInGeneral(); + CheckBox contextCtrl = m_host.GetContextCtrlInGeneral(); + CheckBox contextAlt = m_host.GetContextAltInGeneral(); + CheckBox contextWin = m_host.GetContextWinInGeneral(); + CheckBox useContext = m_host.GetUseContext(); + + contextKey.Tag = QuickConfig.ThisConfig.ContextMenuHotKey; + contextKey.Text = QuickConfig.ThisConfig.ContextMenuHotKey.KeyToString(); + if ((QuickConfig.ThisConfig.ContextMenuHotKeyFlags & (int)Hotkey.KeyFlags.MOD_ALT) != 0) + contextAlt.IsChecked = true; + if ((QuickConfig.ThisConfig.ContextMenuHotKeyFlags & (int)Hotkey.KeyFlags.MOD_CONTROL) != 0) + contextCtrl.IsChecked = true; + if ((QuickConfig.ThisConfig.ContextMenuHotKeyFlags & (int)Hotkey.KeyFlags.MOD_SHIFT) != 0) + contextShift.IsChecked = true; + if ((QuickConfig.ThisConfig.ContextMenuHotKeyFlags & (int)Hotkey.KeyFlags.MOD_WIN) != 0) + contextWin.IsChecked = true; + + useContext.IsChecked = QuickConfig.ThisConfig.ContextMenuToogle; + + // --- + LoadContextMenu(); + } + + private void LoadContextMenu() + { + var contextMenu = m_host.GetContextMenuInGeneral(); + contextMenu.Items.Clear(); + var coreList = QuickConfig.ThisConfig.ContextMenuList; + foreach (var i in coreList) + contextMenu.Items.Add(i); + } + + private void SaveGeneral() + { + TextBox quickKey = m_host.GetQuickTextBoxInGeneral(); + CheckBox quickShift = m_host.GetQuickShiftInGeneral(); + CheckBox quickCtrl = m_host.GetQuickCtrlInGeneral(); + CheckBox quickAlt = m_host.GetQuickAltInGeneral(); + CheckBox quickWin = m_host.GetQuickWinInGeneral(); + Key qkey = (Key)quickKey.Tag; + Hotkey.KeyFlags quickFlags = Hotkey.KeyFlags.MOD_NONE; + if (quickAlt.IsChecked.HasValue && quickAlt.IsChecked.Value) quickFlags |= Hotkey.KeyFlags.MOD_ALT; + if (quickCtrl.IsChecked.HasValue && quickCtrl.IsChecked.Value) quickFlags |= Hotkey.KeyFlags.MOD_CONTROL; + if (quickShift.IsChecked.HasValue && quickShift.IsChecked.Value) quickFlags |= Hotkey.KeyFlags.MOD_SHIFT; + if (quickWin.IsChecked.HasValue && quickWin.IsChecked.Value) quickFlags |= Hotkey.KeyFlags.MOD_WIN; + + // ---- + TextBox contextKey = m_host.GetContextTextBoxInGeneral(); + CheckBox contextShift = m_host.GetContextShiftInGeneral(); + CheckBox contextCtrl = m_host.GetContextCtrlInGeneral(); + CheckBox contextAlt = m_host.GetContextAltInGeneral(); + CheckBox contextWin = m_host.GetContextWinInGeneral(); + CheckBox useContext = m_host.GetUseContext(); + + Key ckey = (Key)contextKey.Tag; + Hotkey.KeyFlags searchFlags = Hotkey.KeyFlags.MOD_NONE; + if (contextAlt.IsChecked.HasValue && contextAlt.IsChecked.Value) searchFlags |= Hotkey.KeyFlags.MOD_ALT; + if (contextCtrl.IsChecked.HasValue && contextCtrl.IsChecked.Value) searchFlags |= Hotkey.KeyFlags.MOD_CONTROL; + if (contextShift.IsChecked.HasValue && contextShift.IsChecked.Value) searchFlags |= Hotkey.KeyFlags.MOD_SHIFT; + if (contextWin.IsChecked.HasValue && contextWin.IsChecked.Value) searchFlags |= Hotkey.KeyFlags.MOD_WIN; + + QuickConfig.ThisConfig.QuickHotKey = qkey; + QuickConfig.ThisConfig.QuickHotKeyFlags = (int)quickFlags; + QuickConfig.ThisConfig.ContextMenuHotKey = ckey; + QuickConfig.ThisConfig.ContextMenuHotKeyFlags = (int)searchFlags; + QuickConfig.ThisConfig.ContextMenuToogle = useContext.IsChecked.HasValue && useContext.IsChecked.Value; + } + + private void LoadTemplate() + { + ClearTextBoxInTemplate(); + var list = m_host.GetTemplateListInTemplate(); + list.Items.Clear(); + + { + ComboBoxItem item = new ComboBoxItem(); + item.Content = "全局模板"; + item.Tag = QuickModel.GlobalModelName + ".xml"; + list.Items.Add(item); + } + + foreach (var i in QuickConfig.ThisConfig.ModelName) + { + ComboBoxItem item = new ComboBoxItem(); + item.Content = i + ".xml"; + item.Tag = i + ".xml"; + list.Items.Add(item); + } + + if (list.Items.Count > 0) + list.SelectedIndex = 0; + } + + private void LoadVersion() + { + var version = m_host.GetVersionTextBlockInAbout(); + StringBuilder str = new StringBuilder(); + str.AppendLine("Quick"); + str.AppendLine(System.Windows.Forms.Application.ProductVersion); + str.AppendLine(); + str.AppendLine("Froser, 2015年8月21日15:35:35"); + version.Text = str.ToString(); + } + + public void ShortcutTextBoxOnPreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) + { + if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl || + e.Key == Key.LeftShift || e.Key == Key.RightShift || + e.Key == Key.LeftAlt || e.Key == Key.RightAlt || + e.Key == Key.LWin || e.Key == Key.RWin) + return; + + TextBox tb = sender as TextBox; + tb.Tag = e.Key; + tb.Text = e.Key.KeyToString(); + e.Handled = true; + } + + public void OnTemplateMethodSelect(int index) + { + var methodsList = m_host.GetMethodsListInTemplate(); + var item = (QuickMethod)(methodsList).SelectedItem; + var methodName = m_host.GetMethodNameTextBoxInTemplate(); + var methodDescription = m_host.GetMethodDescriptionTextBoxInTemplate(); + var methodScript = m_host.GetMethodScriptTextBoxInTemplate(); + var methodDefArg = m_host.GetMethodDefaultArgumentTextBoxInTemplate(); + var methodRegex = m_host.GetMethodRegexTextBoxInTemplate(); + if (item != null) + { + methodName.Text = item.MethodName; + methodDescription.Text = item.MethodDescription; + methodScript.Text = item.MethodScript; + methodDefArg.Text = item.MethodDefArgs; + methodRegex.Text = item.MethodParamRegex; + } + } + + private QuickModel m_currentModel; + private QuickPreferenceWindow m_host; + } +} diff --git a/Coding/Quick/Utilities.cs b/Coding/Quick/Utilities.cs new file mode 100644 index 0000000..d70c976 --- /dev/null +++ b/Coding/Quick/Utilities.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Windows.Forms; + +namespace Froser.Quick +{ + public static class QuickUtilities + { + /// + /// 表示本程序目录下的一个目录的完整路径 + /// + /// 目录名 + /// 如果不存在,是否要创建一个新的目录 + /// + public static String DirectoryFromDomain(String dirname, bool create) + { + String dir = AppDomain.CurrentDomain.BaseDirectory; + String result = Path.Combine(dir, dirname); + if (create) + { + if (!Directory.Exists(result)) + Directory.CreateDirectory(result); + } + return result; + } + + public static String DirectoryFromDomain(String dirname) + { + return DirectoryFromDomain(dirname, false); + } + + public static bool IsRoot(String path) + { + try + { + if (char.IsLetter(path[0]) && path[1] == ':') + { + if (path.Length == 3 && path[2] == '\\') + { + return true; + } + else if (path.Length == 2) + { + return true; + } + } + return false; + } + catch + { + return false; + } + } + + public static bool IsLatestVersion(String current, String latest) + { + Version vc = new Version(current); + Version vl = new Version(latest); + + var result = vc.CompareTo(vl); + return result >= 0; + } + + } + + internal class Utilities + { + private object comObject; + public Utilities(object comObject) + { + this.comObject = comObject; + } + + //获得一个Win32颜色的整型数值 + public int Win32Color(string api) + { + int def = (int) double.Parse (QuickReflection.Invoke(api, comObject).ToString ()); + try + { + ColorDialog cd = new ColorDialog(); + cd.Color = ColorTranslator.FromWin32(def); + if (cd.ShowDialog() == DialogResult.OK) + { + return ColorTranslator.ToWin32(cd.Color); + } + return def; + } + catch { return def; } + } + + // Utilities的方法返回值一定要为String[] + public String[] AuthorAndContent(string api, String str) + { + return new String[] { QuickReflection.Invoke(api, comObject) + ":" + Environment.NewLine + str }; + } + + public object GetObject(string api) + { + return QuickReflection.Invoke(api, comObject); + } + + public String EmptyString() + { + return ""; + } + + public void RunFile(String cmd, String arg) + { + try + { + Process.Start(cmd, arg); + } + catch (Win32Exception) + { + Process.Start(Path.Combine(QuickUtilities.DirectoryFromDomain(""), cmd), arg); + } + } + } +} diff --git a/Coding/Quick/app.config b/Coding/Quick/app.config new file mode 100644 index 0000000..e365603 --- /dev/null +++ b/Coding/Quick/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Coding/Quick/quick.ico b/Coding/Quick/quick.ico new file mode 100644 index 0000000..4000195 Binary files /dev/null and b/Coding/Quick/quick.ico differ diff --git a/Coding/QuickPlugin/Calc/QuickCalc.cs b/Coding/QuickPlugin/Calc/QuickCalc.cs new file mode 100644 index 0000000..f4179f0 --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalc.cs @@ -0,0 +1,123 @@ +using Froser.Quick.Plugins.Calc; +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace Froser.Quick.Plugins +{ + internal class QuickCalc : IQuickPluginMethod + { + // 接口部分 + public virtual string GetName() + { + return "计算(calc)[jisuan]"; + } + + public virtual string GetDescription(IQuickWindow quickWindow) + { + if (!GetCache().HasCache()) + return "输入算式进行计算,回车粘贴到剪贴板"; + return GetCache().GetValue().ToString(); + } + + public virtual void Invoke(object sender, IQuickWindow quickWindow) + { + Process.Start("calc.exe"); + } + + public bool AcceptArgs() + { + return true; + } + + public string AvailableApplicationName() + { + return null; + } + + public virtual bool GetIcon(IQuickWindow quickWindow, out ImageSource icon) + { + icon = null; + return false; + } + + public void KeyDown(IQuickWindow quickWindow, KeyEventArgs e) + { + } + + public void TextChanged(IQuickWindow quickWindow, TextChangedEventArgs e) + { + var arg = quickWindow.GetArgument (); + if (arg == null) + { + GetCache().ClearCache(); + quickWindow.ResetMethods(); + return; + } + + CalcResult(quickWindow); + + QuickCalcItemType[] types = { QuickCalcItemType.ToDecimal, + QuickCalcItemType.ToHex, + QuickCalcItemType.ToBinary, + }; + List calcItemList = new List(); + foreach (var type in types) + { + QuickCalcItem item = new QuickCalcItem(GetRoot(), type); + calcItemList.Add(item); + } + if (calcItemList.Count > 0) + quickWindow.ReplaceMethods(calcItemList.ToArray()); + } + + public virtual QuickCalc GetRoot() + { + return this; + } + + public virtual QuickCalcCache GetCache() + { + return m_cache; + } + + private void CalcResult(IQuickWindow quickWindow) + { + QuickCalcScanner calc = new QuickCalcScanner(); + if (quickWindow != null) + { + var arg = quickWindow.GetArgument(); + if (arg != null) + { + try + { + var result = calc.Eval(arg); + GetCache().SetValue (result); + } + catch { } + return; + } + } + GetCache().ClearCache(); + } + + public void Closed(IQuickWindow quickWindow) + { + GetCache().ClearCache(); + quickWindow.Refresh(0); + } + + public void PageDown(IQuickWindow quickWindow) + { + } + + public void PageUp(IQuickWindow quickWindow) + { + } + + private QuickCalcCache m_cache = new QuickCalcCache(); + } + +} diff --git a/Coding/QuickPlugin/Calc/QuickCalcCache.cs b/Coding/QuickPlugin/Calc/QuickCalcCache.cs new file mode 100644 index 0000000..9ad69a5 --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalcCache.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick.Plugins.Calc +{ + internal class QuickCalcCache + { + public double GetValue() + { + return m_value; + } + + public void SetValue(double value) + { + m_value = value; + m_cached = true; + } + + public bool HasCache() + { + return m_cached; + } + + public void ClearCache() + { + m_cached = false; + } + + private bool m_cached = false; + private double m_value; + } +} diff --git a/Coding/QuickPlugin/Calc/QuickCalcException.cs b/Coding/QuickPlugin/Calc/QuickCalcException.cs new file mode 100644 index 0000000..3db4aa2 --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalcException.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick.Plugins.Calc +{ + internal class QuickCalcException : Exception + { + public QuickCalcException(string message) : base(message) + { + + } + } +} diff --git a/Coding/QuickPlugin/Calc/QuickCalcItem.cs b/Coding/QuickPlugin/Calc/QuickCalcItem.cs new file mode 100644 index 0000000..1d90a2f --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalcItem.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Windows; + +namespace Froser.Quick.Plugins.Calc +{ + enum QuickCalcItemType + { + ToDecimal, + ToHex, + ToBinary, + } + + internal class QuickCalcItem : QuickCalc + { + public QuickCalcItem(QuickCalc parent, QuickCalcItemType type) + { + m_parent = parent; + m_type = type; + } + + public override string GetName() + { + StringBuilder name = new StringBuilder("结果 "); + switch (m_type) + { + case QuickCalcItemType.ToDecimal: + break; + case QuickCalcItemType.ToHex: + name.Append("十六进制 "); + break; + case QuickCalcItemType.ToBinary: + name.Append("二进制 "); + break; + default: + Debug.Assert(false, "无有效类型"); + break; + } + return name.ToString (); + } + + public override string GetDescription(IQuickWindow quickWindow) + { + return Transform(GetCache().GetValue ()); + } + + public override QuickCalc GetRoot() + { + return m_parent; + } + + public override void Invoke(object sender, IQuickWindow quickWindow) + { + Clipboard.SetText(Transform(GetCache().GetValue())); + } + + public override QuickCalcCache GetCache() + { + return GetRoot().GetCache(); + } + + private string Transform(double n) + { + switch (m_type) + { + case QuickCalcItemType.ToDecimal: + return n.ToString (); + case QuickCalcItemType.ToHex: + return "0x" + Convert.ToString ((int)n, 16).ToUpper(); + case QuickCalcItemType.ToBinary: + return Convert.ToString((int)n, 2); + default: + Debug.Assert(false, "无有效类型"); + break; + } + return n.ToString (); + } + + private QuickCalc m_parent; + private QuickCalcItemType m_type; + } +} diff --git a/Coding/QuickPlugin/Calc/QuickCalcLog.cs b/Coding/QuickPlugin/Calc/QuickCalcLog.cs new file mode 100644 index 0000000..40c2eb3 --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalcLog.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick.Plugins.Calc +{ + internal static class QuickCalcLog + { + public static void Log(string msg) + { + + } + } +} diff --git a/Coding/QuickPlugin/Calc/QuickCalcParse.cs b/Coding/QuickPlugin/Calc/QuickCalcParse.cs new file mode 100644 index 0000000..cadfc2c --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalcParse.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick.Plugins.Calc +{ + internal class QuickCalcParse + { + public QuickCalcParse() + { + } + + public void Add(QuickCalcToken t, string i) + { + m_tokenList.Add(t); + m_symbolList.Add(i); + } + + public void ClearAll() + { + m_tokenList.Clear(); + m_symbolList.Clear(); + } + + public QuickCalcToken GetToken(int index) + { + return m_tokenList[index]; + } + + public string GetValue(int index) + { + return m_symbolList[index]; + } + + public double Parse() + { + m_parseProgress = 0; + return Stmt_legalexp(); + } + + private void Match(string expected) + { + if (m_symbolList[m_parseProgress] == expected) + { + m_parseProgress++; + } + else + { + QuickCalcLog.Log(""); + throw new QuickCalcException("不匹配的标记"); + } + } + + private double Stmt_legalexp() + { + return Stmt_assign(); + } + + private double Stmt_assign() + { + return Stmt_expcmp(); + } + + private double Stmt_expcmp() + { + double result = Stmt_termcmp(); + bool rA = true; + bool rB = true; + if ((int)result == 0) + rA = false; + else + rA = true; + + while (m_parseProgress < m_symbolList.Count() && m_symbolList[m_parseProgress] == ("&&")) + { + Match("&&"); + if ((int)Stmt_termcmp() != 0) + { + rB = true; + } + else + rB = false; + if (rA && rB) + return 1; + return 0; + } + + return result; + } + + private double Stmt_termcmp() + { + double result = Stmt_factorcmp(); + bool rA = false; + bool rB = false; + if ((int)result == 0) + rA = false; + else + rA = true; + + while (m_parseProgress < m_symbolList.Count() && m_symbolList[m_parseProgress] == "||") + { + Match("||"); + if ((int)Stmt_factorcmp() != 0) + { + rB = true; + } + else + rB = false; + + if (rA || rB) + return 1; + return 0; + } + + return result; + } + + private double Stmt_factorcmp() + { + double result = Stmt_exp(); + while (m_parseProgress < m_symbolList.Count() && + (m_symbolList[m_parseProgress] == ">" || + m_symbolList[m_parseProgress] == "<" || + m_symbolList[m_parseProgress] == "==" || + m_symbolList[m_parseProgress] == ">=" || + m_symbolList[m_parseProgress] == "<=" || + m_symbolList[m_parseProgress] == "!=")) + { + if (m_symbolList[m_parseProgress] == ">") + { + Match(">"); + if (result > Stmt_exp()) result = 1; else result = 0; + } + else if (m_symbolList[m_parseProgress] == "<") + { + Match("<"); + if (result < Stmt_exp()) result = 1; else result = 0; + } + else if (m_symbolList[m_parseProgress] == "==") + { + Match("=="); + if (result == Stmt_exp()) result = 1; else result = 0; + } + else if (m_symbolList[m_parseProgress] == ">=") + { + Match(">="); + if (result >= Stmt_exp()) result = 1; else result = 0; + } + else if (m_symbolList[m_parseProgress] == "<=") + { + Match("<="); + if (result <= Stmt_exp()) result = 1; else result = 0; + } + else if (m_symbolList[m_parseProgress] == "!=") + { + Match("!="); + if (result != Stmt_exp()) result = 1; else result = 0; + } + } + return result; + } + + private double Stmt_exp() + { + double result = Stmt_term(); + while (m_parseProgress < m_symbolList.Count() && + (m_symbolList[m_parseProgress] == "+" || m_symbolList[m_parseProgress] == "-")) + { + if (m_symbolList[m_parseProgress] == "+") + { + Match("+"); + result += Stmt_term(); + } + else if (m_symbolList[m_parseProgress] == "-") + { + Match("-"); + result -= Stmt_term(); + } + } + return result; + } + + private double Stmt_term() + { + double result = Stmt_power(); + while (m_parseProgress < m_symbolList.Count() && + (m_symbolList[m_parseProgress] == "*" || m_symbolList[m_parseProgress] == "/")) + { + if (m_symbolList[m_parseProgress] == "*") + { + Match("*"); + result *= Stmt_power(); + } + else if (m_symbolList[m_parseProgress] == "/") + { + Match("/"); + result /= Stmt_power(); + } + } + + return result; + } + + private double Stmt_power() + { + double _result; + _result = Stmt_definedfunction(); + while (m_parseProgress < m_symbolList.Count() && m_symbolList[m_parseProgress] == "^") + { + if (m_symbolList[m_parseProgress] == "^") + { + Match("^"); + _result = Math.Pow(_result, Stmt_definedfunction()); + } + } + + return _result; + } + + private double Stmt_definedfunction() + { + double result; + if (m_symbolList[m_parseProgress] == "sin") + { + Match("sin"); + Match("("); + result = Math.Sin(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "cos") + { + Match("cos"); + Match("("); + result = Math.Cos(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "tan") + { + Match("tan"); + Match("("); + result = Math.Tan(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "asin") + { + Match("asin"); + Match("("); + result = Math.Asin(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "acos") + { + Match("acos"); + Match("("); + result = Math.Acos(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "atan") + { + Match("atan"); + Match("("); + result = Math.Atan(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "ln") + { + Match("ln"); + Match("("); + result = Math.Log(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "sqrt") + { + Match("sqrt"); + Match("("); + result = Math.Sqrt(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "abs") + { + Match("abs"); + Match("("); + result = Math.Abs(Stmt_expcmp()); + Match(")"); + } + else if (m_symbolList[m_parseProgress] == "int") + { + Match("int"); + Match("("); + result = (int)(Stmt_expcmp()); + Match(")"); + } + else + { + result = Stmt_factor(); + } + return result; + } + + private double Stmt_factor() + { + double result; + if (m_tokenList[m_parseProgress] == QuickCalcToken.Numeric) + { + string symbol = m_symbolList[m_parseProgress]; + bool isHex = symbol.ToLower().StartsWith("0x"); + if (isHex) + result = Convert.ToInt16(symbol, 16); + else + result = Double.Parse(symbol); + m_parseProgress++; + } + else if (m_symbolList[m_parseProgress] == "-") + { + m_parseProgress++; + result = -Stmt_factor(); + } + else if (m_symbolList[m_parseProgress] == "+") + { + m_parseProgress++; + result = Stmt_factor(); + } + else if (m_symbolList[m_parseProgress] == "(") + { + Match("("); + result = Stmt_expcmp(); + Match(")"); + } + else + { + QuickCalcLog.Log(""); + throw new QuickCalcException("找不到标识符"); + } + return result; + } + + private List m_tokenList = new List(); + private List m_symbolList = new List(); + private int m_parseProgress; + } +} diff --git a/Coding/QuickPlugin/Calc/QuickCalcScanner.cs b/Coding/QuickPlugin/Calc/QuickCalcScanner.cs new file mode 100644 index 0000000..6b42b12 --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalcScanner.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick.Plugins.Calc +{ + internal class QuickCalcScanner + { + private enum DFAState { Start, InId, InInt, InDecimal, InHex, InSym, InCmp, Error } + private static readonly string[] KEYWORDS = new string[] { "sin", "cos", "tan", "asin", "acos", "atan", "sqrt", "ln", "abs" }; + private static readonly char[] ALL_AVAILABLE_OP = new char[] { '+', '-', '*', '/', '(', ')', '=', '^', ',', '>', '<', '!', '&', '|' }; + private static readonly char[] ALL_COMPARE_OP = { '>', '<', '=', '!', '&', '|' }; + + public QuickCalcScanner() + { + } + + public double Eval(string line) + { + QuickCalcParse parser = Scan(line); + return parser.Parse(); + } + + private QuickCalcParse Scan(string line) + { + QuickCalcParse parser = new QuickCalcParse(); + StringBuilder result = new StringBuilder(); + int index = 0; //获取形参s的每一个字符的索引 + + DFAState currentState = DFAState.Start; //当前DFA的状态 + + while (index < line.Length) + { //DFA循环 + switch (currentState) + { + case DFAState.Start: + if (char.IsWhiteSpace(line[index])) + { + } + else if (char.IsLetter(line[index])) + { + result.Append (line[index]); + currentState = DFAState.InId; + } + else if (char.IsDigit(line[index])) + { + result.Append(line[index]); + currentState = DFAState.InInt; + } + else if (line[index] == '.') + { + result.Append(line[index]); + currentState = DFAState.InDecimal; + } + else if (ALL_AVAILABLE_OP.Contains(line[index])) + { + result.Append(line[index]); + currentState = DFAState.InSym; + } + else + { + QuickCalcLog.Log(""); + parser.Add(QuickCalcToken.Error, line); + } + index++; + break; + case DFAState.InInt: + if (line[index] == '.') + { + result.Append(line[index]); + currentState = DFAState.InDecimal; + } + else if (result[0] == '0' && (line[index] == 'x' || line[index] == 'X')) + { + result.Append(line[index]); + currentState = DFAState.InHex; + } + else if (!char.IsDigit(line[index])) + { + parser.Add(QuickCalcToken.Numeric, result.ToString()); //写入语法分析表 + currentState = DFAState.Start; + result.Clear(); //清空字符串 + index--; //回退 + } + else if (char.IsDigit(line[index])) + { + result.Append(line[index]); + currentState = DFAState.InInt; + } + index++; + break; + case DFAState.InDecimal: + if (!char.IsDigit(line[index])) + { + parser.Add(QuickCalcToken.Numeric, result.ToString()); //写入语法分析表 + currentState = DFAState.Start; + result.Clear(); //清空字符串 + index--; //回退 + } + else if (char.IsDigit(line[index])) + { + result.Append(line[index]); + } + index++; + break; + case DFAState.InHex: + if (char.IsDigit(line[index]) || + (line[index] >= 'a' && line[index] <= 'f') || + (line[index] >= 'A' && line[index] <= 'F')) + { + result.Append(line[index]); + } + else if (!char.IsDigit(line[index])) + { + parser.Add(QuickCalcToken.Numeric, result.ToString()); //写入语法分析表 + currentState = DFAState.Start; + result.Clear(); //清空字符串 + index--; //回退 + } + index++; + break; + case DFAState.InId: + if (!char.IsLetter(line[index])) + { + if (isReserved(result.ToString())) //判断是否为关键字 + { + parser.Add(QuickCalcToken.Reserved, result.ToString()); + currentState = DFAState.Start; + result.Clear(); + index--; + } + else + { + QuickCalcLog.Log(""); + parser.Add(QuickCalcToken.Error, line); + } + } + else if (char.IsLetter(line[index])) + { + result.Append(line[index]); + currentState = DFAState.InId; + } + index++; + break; + case DFAState.InSym: + index--; + if (ALL_COMPARE_OP.Contains(line[index])) + { + currentState = DFAState.InCmp; + } + else + { + parser.Add(QuickCalcToken.Symbol, result.ToString()); + currentState = DFAState.Start; + result.Clear(); + } + index++; + break; + case DFAState.InCmp: + switch (line[index - 1]) + { //判断前一个字符是<,>,=还是!,他们只能后接=符号,否则将作为两个符号处理 + case '>': + case '<': + case '=': + case '!': + if (line[index] == '=') + { + result.Append(line[index]); + parser.Add(QuickCalcToken.Symbol, result.ToString()); + } + else + { //作为两个符号保存 + parser.Add(QuickCalcToken.Symbol, result.ToString()); + index--; + } + index++; + currentState = DFAState.Start; + break; + case '&': + if (line[index] == '&') + { + result.Append(line[index]); + parser.Add(QuickCalcToken.Symbol, result.ToString()); + index++; + } + else + { //作为两个符号保存 + parser.Add(QuickCalcToken.Symbol, result.ToString()); + } + currentState = DFAState.Start; + result.Clear(); + break; + case '|': + if (line[index] == '|') + { + result.Append(line[index]); + parser.Add(QuickCalcToken.Symbol, result.ToString()); + index++; + } + else + { //作为两个符号保存 + parser.Add(QuickCalcToken.Symbol, result.ToString()); + } + currentState = DFAState.Start; + result.Clear(); + break; + } + break; + } + } + + //处理字符串尾端的状态 + switch (currentState) + { + case DFAState.InInt: + case DFAState.InDecimal: + case DFAState.InHex: + parser.Add(QuickCalcToken.Numeric, result.ToString()); //写入语法分析表 + break; + case DFAState.InId: + if (isReserved(result.ToString())) + { //判断是否为关键字 + parser.Add(QuickCalcToken.Reserved, result.ToString()); + } + else + { + parser.Add(QuickCalcToken.Error, result.ToString()); + } + break; + case DFAState.InSym: + parser.Add(QuickCalcToken.Symbol, result.ToString()); + break; + } + + return parser; + } + + private bool isReserved(String s) + { //判断是否为关键字 + return KEYWORDS.Contains(s.ToLower()); + } + } +} diff --git a/Coding/QuickPlugin/Calc/QuickCalcToken.cs b/Coding/QuickPlugin/Calc/QuickCalcToken.cs new file mode 100644 index 0000000..ee8f923 --- /dev/null +++ b/Coding/QuickPlugin/Calc/QuickCalcToken.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Froser.Quick.Plugins.Calc +{ + internal enum QuickCalcToken + { + Reserved, + Numeric, + Symbol, + Error, + } +} diff --git a/Coding/QuickPlugin/Find/QuickEverything.cs b/Coding/QuickPlugin/Find/QuickEverything.cs new file mode 100644 index 0000000..6bf2ea7 --- /dev/null +++ b/Coding/QuickPlugin/Find/QuickEverything.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace Froser.Quick.Plugins.Find +{ + public enum EVERYTHING_RESULT + { + EVERYTHING_OK = 0, + EVERYTHING_ERROR_MEMORY = 1, + EVERYTHING_ERROR_IPC = 2, + EVERYTHING_ERROR_REGISTERCLASSEX = 3, + EVERYTHING_ERROR_CREATEWINDOW = 4, + EVERYTHING_ERROR_CREATETHREAD = 5, + EVERYTHING_ERROR_INVALIDINDEX = 6, + EVERYTHING_ERROR_INVALIDCALL = 7, + } + + internal class QuickEverything + { + private static bool s_is64Bit = false; + static QuickEverything() + { + s_is64Bit = Environment.Is64BitOperatingSystem; + } + public static int Everything_SetSearchW(string lpSearchString) + { + if (s_is64Bit) + return QuickEverything64.Everything_SetSearchW(lpSearchString); + else + return QuickEverything32.Everything_SetSearchW(lpSearchString); + } + + public static void Everything_SetMatchPath(bool bEnable) + { + if (s_is64Bit) + QuickEverything64.Everything_SetMatchPath(bEnable); + else + QuickEverything32.Everything_SetMatchPath(bEnable); + } + + public static void Everything_SetMatchCase(bool bEnable) + { + if (s_is64Bit) + QuickEverything64.Everything_SetMatchCase(bEnable); + else + QuickEverything32.Everything_SetMatchCase(bEnable); + } + + public static void Everything_SetMatchWholeWord(bool bEnable) + { + if (s_is64Bit) + QuickEverything64.Everything_SetMatchWholeWord(bEnable); + else + QuickEverything32.Everything_SetMatchWholeWord(bEnable); + } + + public static void Everything_SetRegex(bool bEnable) + { + if (s_is64Bit) + QuickEverything64.Everything_SetRegex(bEnable); + else + QuickEverything32.Everything_SetRegex(bEnable); + } + + public static void Everything_SetMax(int dwMax) + { + if (s_is64Bit) + QuickEverything64.Everything_SetMax(dwMax); + else + QuickEverything32.Everything_SetMax(dwMax); + } + + public static void Everything_SetOffset(int dwOffset) + { + if (s_is64Bit) + QuickEverything64.Everything_SetOffset(dwOffset); + else + QuickEverything32.Everything_SetOffset(dwOffset); + } + + public static bool Everything_GetMatchPath() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetMatchPath(); + else + return QuickEverything32.Everything_GetMatchPath(); + } + + public static bool Everything_GetMatchCase() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetMatchCase(); + else + return QuickEverything32.Everything_GetMatchCase(); + } + + public static bool Everything_GetMatchWholeWord() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetMatchWholeWord(); + else + return QuickEverything32.Everything_GetMatchWholeWord(); + } + + public static bool Everything_GetRegex() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetRegex(); + else + return QuickEverything32.Everything_GetRegex(); + } + + public static UInt32 Everything_GetMax() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetMax(); + else + return QuickEverything32.Everything_GetMax(); + } + + public static UInt32 Everything_GetOffset() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetOffset(); + else + return QuickEverything32.Everything_GetOffset(); + } + + public static string Everything_GetSearchW() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetSearchW(); + else + return QuickEverything32.Everything_GetSearchW(); + } + + public static int Everything_GetLastError() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetLastError(); + else + return QuickEverything32.Everything_GetLastError(); + } + + public static bool Everything_QueryW(bool bWait) + { + if (s_is64Bit) + return QuickEverything64.Everything_QueryW(bWait); + else + return QuickEverything32.Everything_QueryW(bWait); + } + + public static void Everything_SortResultsByPath() + { + if (s_is64Bit) + QuickEverything64.Everything_SortResultsByPath(); + else + QuickEverything32.Everything_SortResultsByPath(); + } + + public static int Everything_GetNumFileResults() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetNumFileResults(); + else + return QuickEverything32.Everything_GetNumFileResults(); + } + + public static int Everything_GetNumFolderResults() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetNumFolderResults(); + else + return QuickEverything32.Everything_GetNumFolderResults(); + } + + public static int Everything_GetNumResults() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetNumResults(); + else + return QuickEverything32.Everything_GetNumResults(); + } + + public static int Everything_GetTotFileResults() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetTotFileResults(); + else + return QuickEverything32.Everything_GetTotFileResults(); + } + + public static int Everything_GetTotFolderResults() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetTotFolderResults(); + else + return QuickEverything32.Everything_GetTotFolderResults(); + } + + public static int Everything_GetTotResults() + { + if (s_is64Bit) + return QuickEverything64.Everything_GetTotResults(); + else + return QuickEverything32.Everything_GetTotResults(); + } + + public static bool Everything_IsVolumeResult(int nIndex) + { + if (s_is64Bit) + return QuickEverything64.Everything_IsVolumeResult(nIndex); + else + return QuickEverything32.Everything_IsVolumeResult(nIndex); + } + + public static bool Everything_IsFolderResult(int nIndex) + { + if (s_is64Bit) + return QuickEverything64.Everything_IsFolderResult(nIndex); + else + return QuickEverything32.Everything_IsFolderResult(nIndex); + } + + public static bool Everything_IsFileResult(int nIndex) + { + if (s_is64Bit) + return QuickEverything64.Everything_IsFileResult(nIndex); + else + return QuickEverything32.Everything_IsFileResult(nIndex); + } + + public static void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount) + { + if (s_is64Bit) + QuickEverything64.Everything_GetResultFullPathNameW(nIndex, lpString, nMaxCount); + else + QuickEverything32.Everything_GetResultFullPathNameW(nIndex, lpString, nMaxCount); + } + + public static void Everything_Reset() + { + if (s_is64Bit) + QuickEverything64.Everything_Reset(); + else + QuickEverything32.Everything_Reset(); + } + } +} diff --git a/Coding/QuickPlugin/Find/QuickEverything32.cs b/Coding/QuickPlugin/Find/QuickEverything32.cs new file mode 100644 index 0000000..a6dc42a --- /dev/null +++ b/Coding/QuickPlugin/Find/QuickEverything32.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace Froser.Quick.Plugins.Find +{ + internal class QuickEverything32 + { + const String dllPath = "3rdparty/everything/everything32.dll"; + + [DllImport(dllPath, CharSet = CharSet.Unicode)] + public static extern int Everything_SetSearchW(string lpSearchString); + [DllImport(dllPath)] + public static extern void Everything_SetMatchPath(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetMatchCase(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetMatchWholeWord(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetRegex(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetMax(int dwMax); + [DllImport(dllPath)] + public static extern void Everything_SetOffset(int dwOffset); + + [DllImport(dllPath)] + public static extern bool Everything_GetMatchPath(); + [DllImport(dllPath)] + public static extern bool Everything_GetMatchCase(); + [DllImport(dllPath)] + public static extern bool Everything_GetMatchWholeWord(); + [DllImport(dllPath)] + public static extern bool Everything_GetRegex(); + [DllImport(dllPath)] + public static extern UInt32 Everything_GetMax(); + [DllImport(dllPath)] + public static extern UInt32 Everything_GetOffset(); + [DllImport(dllPath)] + public static extern string Everything_GetSearchW(); + [DllImport(dllPath)] + public static extern int Everything_GetLastError(); + + [DllImport(dllPath)] + public static extern bool Everything_QueryW(bool bWait); + + [DllImport(dllPath)] + public static extern void Everything_SortResultsByPath(); + + [DllImport(dllPath)] + public static extern int Everything_GetNumFileResults(); + [DllImport(dllPath)] + public static extern int Everything_GetNumFolderResults(); + [DllImport(dllPath)] + public static extern int Everything_GetNumResults(); + [DllImport(dllPath)] + public static extern int Everything_GetTotFileResults(); + [DllImport(dllPath)] + public static extern int Everything_GetTotFolderResults(); + [DllImport(dllPath)] + public static extern int Everything_GetTotResults(); + [DllImport(dllPath)] + public static extern bool Everything_IsVolumeResult(int nIndex); + [DllImport(dllPath)] + public static extern bool Everything_IsFolderResult(int nIndex); + [DllImport(dllPath)] + public static extern bool Everything_IsFileResult(int nIndex); + [DllImport(dllPath, CharSet = CharSet.Unicode)] + public static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount); + [DllImport(dllPath)] + public static extern void Everything_Reset(); + } +} diff --git a/Coding/QuickPlugin/Find/QuickEverything64.cs b/Coding/QuickPlugin/Find/QuickEverything64.cs new file mode 100644 index 0000000..d57023d --- /dev/null +++ b/Coding/QuickPlugin/Find/QuickEverything64.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace Froser.Quick.Plugins.Find +{ + internal class QuickEverything64 + { + const String dllPath = "3rdparty/everything/everything64.dll"; + + [DllImport(dllPath, CharSet = CharSet.Unicode)] + public static extern int Everything_SetSearchW(string lpSearchString); + [DllImport(dllPath)] + public static extern void Everything_SetMatchPath(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetMatchCase(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetMatchWholeWord(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetRegex(bool bEnable); + [DllImport(dllPath)] + public static extern void Everything_SetMax(int dwMax); + [DllImport(dllPath)] + public static extern void Everything_SetOffset(int dwOffset); + + [DllImport(dllPath)] + public static extern bool Everything_GetMatchPath(); + [DllImport(dllPath)] + public static extern bool Everything_GetMatchCase(); + [DllImport(dllPath)] + public static extern bool Everything_GetMatchWholeWord(); + [DllImport(dllPath)] + public static extern bool Everything_GetRegex(); + [DllImport(dllPath)] + public static extern UInt32 Everything_GetMax(); + [DllImport(dllPath)] + public static extern UInt32 Everything_GetOffset(); + [DllImport(dllPath)] + public static extern string Everything_GetSearchW(); + [DllImport(dllPath)] + public static extern int Everything_GetLastError(); + + [DllImport(dllPath)] + public static extern bool Everything_QueryW(bool bWait); + + [DllImport(dllPath)] + public static extern void Everything_SortResultsByPath(); + + [DllImport(dllPath)] + public static extern int Everything_GetNumFileResults(); + [DllImport(dllPath)] + public static extern int Everything_GetNumFolderResults(); + [DllImport(dllPath)] + public static extern int Everything_GetNumResults(); + [DllImport(dllPath)] + public static extern int Everything_GetTotFileResults(); + [DllImport(dllPath)] + public static extern int Everything_GetTotFolderResults(); + [DllImport(dllPath)] + public static extern int Everything_GetTotResults(); + [DllImport(dllPath)] + public static extern bool Everything_IsVolumeResult(int nIndex); + [DllImport(dllPath)] + public static extern bool Everything_IsFolderResult(int nIndex); + [DllImport(dllPath)] + public static extern bool Everything_IsFileResult(int nIndex); + [DllImport(dllPath, CharSet = CharSet.Unicode)] + public static extern void Everything_GetResultFullPathNameW(int nIndex, StringBuilder lpString, int nMaxCount); + [DllImport(dllPath)] + public static extern void Everything_Reset(); + } +} diff --git a/Coding/QuickPlugin/Find/QuickFind.cs b/Coding/QuickPlugin/Find/QuickFind.cs new file mode 100644 index 0000000..2e7720a --- /dev/null +++ b/Coding/QuickPlugin/Find/QuickFind.cs @@ -0,0 +1,328 @@ +using Froser.Quick.Plugins.Find; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.ServiceProcess; +using System.Text; +using System.Threading; +using System.Windows.Threading; + +namespace Froser.Quick.Plugins +{ + internal class QuickFind : IQuickPluginMethod + { + private enum SearchOption + { + All, + File, + Folder + } + + private string EverythingExePath + { + get + { + return m_everythingExePath; + } + } + + private string m_everythingExePath = null; + + public virtual string GetName() + { + return "查找(find)[chazhao] 任何文件"; + } + + public virtual string GetDescription(IQuickWindow quickWindow) + { + switch (CurrentDescriptionType) + { + case DescriptionType.NoResult: + return NO_RESULT_DESCRIPTION; + case DescriptionType.NotInited: + return NOT_INITED_YET; + default: + return DEFAULT_DESCRIPTION; + } + } + + public string AvailableApplicationName() + { + return null; + } + + public virtual void Invoke(object sender, IQuickWindow quickWindow) + { + } + + public bool AcceptArgs() + { + return true; + } + + public virtual bool GetIcon(IQuickWindow quickWindow, out System.Windows.Media.ImageSource icon) + { + icon = null; + return false; + } + + public virtual void KeyDown(IQuickWindow quickWindow, System.Windows.Input.KeyEventArgs e) + { + if (quickWindow != null && m_everythingExePath == null) + m_everythingExePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, + quickWindow.GetPluginsPath(), + "3rdparty/everything/everything.exe"); + } + + public void TextChanged(IQuickWindow quickWindow, System.Windows.Controls.TextChangedEventArgs e) + { + ResetPage(); + + var timer = GetTimer(quickWindow); + timer.Stop(); + + var arg = quickWindow.GetArgument(); + if (arg == null) + { + quickWindow.ResetMethods(); + CurrentDescriptionType = DescriptionType.Default; + return; + } + + timer.Start(); + } + + public void Closed(IQuickWindow quickWindow) + { + ResetPage(); + CurrentDescriptionType = DescriptionType.Default; + quickWindow.Refresh(0); + } + + public void PageDown(IQuickWindow quickWindow) + { + UpdatePage(quickWindow, true); + } + + public void PageUp(IQuickWindow quickWindow) + { + UpdatePage(quickWindow, false); + } + + public virtual int GetPage() + { + return m_page; + } + + public virtual void SetPage(int p) + { + m_page = p; + } + + public virtual QuickFind GetRoot() + { + return this; + } + + public virtual DispatcherTimer GetTimer(IQuickWindow quickWindow) + { + if (m_timer == null) + { + m_timer = new DispatcherTimer(DispatcherPriority.Normal); + m_timer.Interval = TimeSpan.FromMilliseconds(COUNT_DOWN_TIMEOUT); + m_timer.Tick += QueryOnTick; + m_timer.Tag = quickWindow; + } + return m_timer; + } + + private void QueryOnTick(object sender, EventArgs e) + { + DispatcherTimer timer = (DispatcherTimer)sender; + IQuickWindow quickWindow = (IQuickWindow)timer.Tag; + AsyncQuery(quickWindow); + timer.Stop(); + } + + private void UpdatePage(IQuickWindow quickWindow, bool isPageDown) + { + int backupPage = GetPage(); + if (isPageDown) + { + SetPage(GetPage() + 1); + } + else + { + if (GetPage() > 0) + SetPage(GetPage() - 1); + else + return; + } + + bool success = Query(quickWindow); + if (!success) + { + SetPage(backupPage); + return; + } + + if (isPageDown) + quickWindow.Refresh(0); + else + quickWindow.Refresh(MAX_FILE_NUMBER_IN_ONE_QUERY); + } + + private void ResetPage() + { + SetPage(0); + } + + private void AsyncQuery(IQuickWindow quickWindow) + { + quickWindow.AsyncInvoke( + () => + { + Query(quickWindow); + quickWindow.Refresh(0); + } + ); + } + + private bool Query(IQuickWindow quickWindow) + { + bool bInited = TestEverything(quickWindow); + if (!bInited) + { + CurrentDescriptionType = DescriptionType.NotInited; + quickWindow.Refresh(0); + return false; + } + + QuickEverything.Everything_Reset(); + QuickEverything.Everything_SetMax(MAX_FILE_NUMBER_IN_ONE_QUERY); + QuickEverything.Everything_SetOffset(GetPage() * MAX_FILE_NUMBER_IN_ONE_QUERY); + + string arg = quickWindow.GetArgument(); + if (arg == null) + return false; + + //改善易用性,将/视为\ + arg = arg.Replace('/', '\\'); + SearchOption option = SearchOption.File; + string a = arg.Trim().ToLower(); + if (a.StartsWith("folder:")) + option = SearchOption.Folder; + else if (a.StartsWith("all:")) + option = SearchOption.All; + + string realQueryText = arg; + if (option == SearchOption.File) + realQueryText = "file:" + arg; + else if (option == SearchOption.Folder) + realQueryText = "folder:" + arg; + + QuickEverything.Everything_SetSearchW(realQueryText); + QuickEverything.Everything_QueryW(true); + int count = QuickEverything.Everything_GetNumResults(); + EVERYTHING_RESULT result = (EVERYTHING_RESULT)QuickEverything.Everything_GetLastError(); + if (result == EVERYTHING_RESULT.EVERYTHING_OK && count > 0) + { + ReplaceMethods(quickWindow, count); + return true; + } + CurrentDescriptionType = DescriptionType.NoResult; + return false; + } + + private bool TestEverything(IQuickWindow quickWindow) + { + // 返回引擎是否已经初始化 + QuickEverything.Everything_Reset(); + QuickEverything.Everything_SetMax(1); + QuickEverything.Everything_SetOffset(0); + QuickEverything.Everything_SetSearchW("*"); + bool success = false; + bool startServer = false; + int times = 0; + do + { + success = QuickEverything.Everything_QueryW(true); + if (success) + { + quickWindow.UnlockWindow(); + int count = QuickEverything.Everything_GetNumResults(); + return count > 0 ? true : false; + } + else + { + quickWindow.LockWindow(); + if (!startServer) + { + StartService(); + startServer = true; + } + Thread.Sleep(COUNT_DOWN_TIMEOUT); + times++; + if (times > MAX_TRYING_TIMES) + return false; + } + } while (!success); + Debug.Assert(false, "应该在success的时候就返回了"); + return false; + } + + private void ReplaceMethods(IQuickWindow quickWindow, int count) + { + const int bufsize = 260; + StringBuilder buf = new StringBuilder(bufsize); + List findItemList = new List(); + for (int i = 0; i < count; i++ ) + { + QuickEverything.Everything_GetResultFullPathNameW(i, buf, bufsize); + EVERYTHING_RESULT result = (EVERYTHING_RESULT)QuickEverything.Everything_GetLastError(); + if (result != EVERYTHING_RESULT.EVERYTHING_OK) + continue; + + QuickFindItem item = new QuickFindItem(GetRoot(), buf.ToString ()); + findItemList.Add(item); + } + + quickWindow.ReplaceMethods(findItemList.ToArray()); + } + + private void StartService() + { + const string serviceName = "Everything"; + Process.Start(EverythingExePath, "-startup -admin"); + if (!IsServiceExisted(serviceName)) + { + var service = Process.Start(EverythingExePath, "-install-client-service"); + service.WaitForExit(); + } + } + + private bool IsServiceExisted(string serviceName) + { + ServiceController[] services = ServiceController.GetServices(); + foreach (ServiceController s in services) + { + if (s.ServiceName == serviceName) + return true; + } + return false; + } + + private const string DEFAULT_DESCRIPTION = "使用Everything服务秒查全盘的文件,Ctrl+Enter打开其所在的文件夹"; + private const string NO_RESULT_DESCRIPTION = "没有找到结果"; + private const string NOT_INITED_YET = "引擎正在初始化,请稍后再重新搜索"; + private const int MAX_FILE_NUMBER_IN_ONE_QUERY = 10; + private const int COUNT_DOWN_TIMEOUT = 500; + private const int MAX_TRYING_TIMES = 50; + public enum DescriptionType { Default, NoResult, NotInited }; + public virtual DescriptionType CurrentDescriptionType { get; set; } + private DispatcherTimer m_timer ; + private int m_page = 0; + } +} diff --git a/Coding/QuickPlugin/Find/QuickFindItem.cs b/Coding/QuickPlugin/Find/QuickFindItem.cs new file mode 100644 index 0000000..221562d --- /dev/null +++ b/Coding/QuickPlugin/Find/QuickFindItem.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Windows.Input; +using System.Windows.Threading; + +namespace Froser.Quick.Plugins.Find +{ + internal class QuickFindItem : QuickFind + { + public QuickFindItem(QuickFind parent, string fullpath) + { + m_parent = parent; + m_fullpath = fullpath; + } + + public override string GetName() + { + return Path.GetFileName(m_fullpath); + } + + public override string GetDescription(IQuickWindow quickWindow) + { + return m_fullpath; + } + + public override int GetPage() + { + return GetRoot().GetPage(); + } + + public override void SetPage(int p) + { + GetRoot().SetPage(p); + } + + public override void Invoke(object sender, IQuickWindow quickWindow) + { + if (m_directoryOpenedToogle) + { + m_directoryOpenedToogle = false; + return; + } + Execute(false); + } + + public override QuickFind GetRoot() + { + return m_parent; + } + + public override bool GetIcon(IQuickWindow quickWindow, out System.Windows.Media.ImageSource icon) + { + try + { + var tmp = Icon.ExtractAssociatedIcon(m_fullpath); //获得主线程图标 + icon = tmp.ToBitmapSource(); + return true; + } + catch { } + icon = null; + return false; + } + + + public override void KeyDown(IQuickWindow quickWindow, System.Windows.Input.KeyEventArgs e) + { + switch (e.Key) + { + case Key.Enter: + // Ctrl+Enter 打开文件夹 + if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) + OpenDirectory(); + break; + } + } + + public override DispatcherTimer GetTimer(IQuickWindow quickWindow) + { + return GetRoot().GetTimer(quickWindow); + } + + private void Execute(bool openDirectoryOnly) + { + var path = openDirectoryOnly ? Path.GetDirectoryName(m_fullpath) : m_fullpath; + Process.Start(path); + } + + private void OpenDirectory() + { + m_directoryOpenedToogle = true; + Execute(true); + } + + public override DescriptionType CurrentDescriptionType + { + get + { + return GetRoot().CurrentDescriptionType; + } + set + { + GetRoot().CurrentDescriptionType = value; + } + } + + private QuickFind m_parent; + private string m_fullpath; + private bool m_directoryOpenedToogle = false; + } +} diff --git a/Coding/QuickPlugin/Properties/AssemblyInfo.cs b/Coding/QuickPlugin/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b5227ce --- /dev/null +++ b/Coding/QuickPlugin/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过以下 +// 特性集控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("QuickAddition")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("QuickAddition")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("178eccf2-6e6d-405f-a28a-2260a17b46e0")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Coding/QuickPlugin/QuickPlugin.cs b/Coding/QuickPlugin/QuickPlugin.cs new file mode 100644 index 0000000..c148e42 --- /dev/null +++ b/Coding/QuickPlugin/QuickPlugin.cs @@ -0,0 +1,25 @@ +using Froser.Quick.Plugins; + +namespace Froser.Quick +{ + internal class QuickPlugin : IQuickPlugin + { + public QuickPlugin() + { + m_additionMethod = new IQuickPluginMethod[] + { + new QuickCalc(), + new QuickRun(), + new QuickFind(), + }; + } + + public IQuickPluginMethod[] GetMethods() + { + return m_additionMethod; + } + + private IQuickPluginMethod[] m_additionMethod; + } + +} diff --git a/Coding/QuickPlugin/QuickPlugin.csproj b/Coding/QuickPlugin/QuickPlugin.csproj new file mode 100644 index 0000000..b75dbc2 --- /dev/null +++ b/Coding/QuickPlugin/QuickPlugin.csproj @@ -0,0 +1,123 @@ + + + + + Debug + AnyCPU + {EA358646-8755-4A40-AABC-200C03CF86CC} + Library + Properties + Froser.Quick.Plugins + QuickPlugin + v4.0 + 512 + + + + true + full + false + ..\..\Bin\Debug\plugins\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\Bin\Release\plugins\ + TRACE + prompt + 4 + + + true + ..\..\Bin\Debug4KSO\plugins\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + ..\..\Bin\Release4KSO\plugins\ + TRACE + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resource.resx + + + + + + + ResXFileCodeGenerator + Resource.Designer.cs + + + + + {d26b7bea-d131-4801-a19b-e0afc6740322} + Quick + + + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + + + + + \ No newline at end of file diff --git a/Coding/QuickPlugin/Resource.Designer.cs b/Coding/QuickPlugin/Resource.Designer.cs new file mode 100644 index 0000000..5a6a3c6 --- /dev/null +++ b/Coding/QuickPlugin/Resource.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.18408 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick.Plugins { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 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 Resource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resource() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Froser.Quick.Plugins.Resource", typeof(Resource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap folder { + get { + object obj = ResourceManager.GetObject("folder", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Coding/QuickPlugin/Resource.resx b/Coding/QuickPlugin/Resource.resx new file mode 100644 index 0000000..683dac1 --- /dev/null +++ b/Coding/QuickPlugin/Resource.resx @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsSAAALEgHS3X78AAAABmJL + R0QA/wD/AP+gvaeTAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE1LTA3LTI1VDIxOjQ5OjMyKzA4OjAweTsV + 0AAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMS0xMC0wOVQwMDoyNDo1OCswODowMEssx3wAAABOdEVYdHNv + ZnR3YXJlAEltYWdlTWFnaWNrIDYuOC44LTEwIFExNiB4ODZfNjQgMjAxNS0wNy0xOSBodHRwOi8vd3d3 + LmltYWdlbWFnaWNrLm9yZwUMnDUAAAAYdEVYdFRodW1iOjpEb2N1bWVudDo6UGFnZXMAMaf/uy8AAAAX + dEVYdFRodW1iOjpJbWFnZTo6SGVpZ2h0ADQ4h2CHLQAAABZ0RVh0VGh1bWI6OkltYWdlOjpXaWR0aAA0 + OH/PR6AAAAAZdEVYdFRodW1iOjpNaW1ldHlwZQBpbWFnZS9wbmc/slZOAAAAF3RFWHRUaHVtYjo6TVRp + bWUAMTMxODA5MTA5ON1oQroAAAATdEVYdFRodW1iOjpTaXplADEuMTdLQkLU1pG4AAAAWHRFWHRUaHVt + Yjo6VVJJAGZpbGU6Ly8vaG9tZS93d3dyb290L3d3dy5lYXN5aWNvbi5uZXQvY2RuLWltZy5lYXN5aWNv + bi5jbi9zcmMvNTYzNS81NjM1NDkucG5n8QhtwwAABNJJREFUWEftlltsVFUUhmdCVCjSdkrbaQE1AuHS + gsiDBqkgAUVC6oNRmmJCfDDGBKKImpjo8ACiwRAvifGFJ5NGkOkM0/sVWjqlYrkoWGqBYostLaXAtJS2 + yL79/mfmtAwEE2oyjQ/8yZcz55x11v5n77X2OY4HeqD/jYQvjaRPED73NOGd+ozwJj1Psm7jyhK+xCzh + T8iS+0kgPksWxC+VhYmzZVHyZBlwO2Rhip1tjIoMnjaRg7/D4xlROCckihf0ieJMHkkJKc0IybL5IVkx + LyQrLeb2yco5vJbeI0tce2Rp0mxZkmRnHIPswR0iP3W5CDzRpU5uhempgblcT4IRem2uWNRFuBpBd+ZB + BZ+FKpuyS5VNd6jKeDvzfeq2gZT3+K9hhrswVumzH0NVx1eoqrgEHu3M9ynbgJMz4BElC4Gbvcx4C/qv + vdAtnzM5ad0Bff4zmD9J23ayDaZjF2Pbwgasc30o/qA+ODFZB+McuiLRKctcTi6LUxS5nCKQ4pQ+t1N4 + 053CN51wPI777wbkINQvuWACqPIEqKop0Aceha6ZzIEmQQcfgTmSBvRVRwx074ZpSDhnghM2mUMPv6Vr + Jnr0gTiPqpzs4dJ4ZHGCRxa4PMI/1cOZttgcXnJf2qR7GzAapu8EE/tJPswl0uNlPXiB3n3kJyBUDqjr + YQO42Q5zdgPM7ytgTq2E+W0V9IkXoY+9BNX4MtSRNVCH10IGsyFrX4GsWgFRMLOLRf/BPQxcjiQdkwzN + 3ODM9d0b0X8nf1+FOr0Twj/tim2A62JNTekC3vwvBsYu3VMLUTQPEQN7Z7AoUjyyPHPcDFhtbnWdQ/jd + DpH3mFP4kz+R5RnjaCBoG/ClP8RiWMoKDciyWSy6Aphrh2BCtazyGqD/IHCdx4F64EYjMPgrMNQEDLeQ + c6SVnOW1Zt47RY4z7mc+Uxd5ljlMyILnwxesoe824H5N7H+8TVYthWrIhjqxHvrkG9BNuTDNOTBnXgda + c4G2t4ELHwKd24Cur4FLu4HLeeRH8gPQ/T1w8Uug41Og/V3g/JvAuXUwLeugT+ewI1ZCH13Djiq8y0B+ + 6h5Zz8GGOuwqDd1GRqFYzVbbqQEyyCoaIsNR8NzqhPB95rHio58fbodu3sJt+zmYgWZu7Q0jBlLy5OEN + DOLDsRaXQNUuhm7jxjVahGw/WbmcxXfNjoqh+CdVYw7Uyc3Q3VU0sDBsYJ0ozhg0/SyqWMso6D+2Q9Wt + 5lu0aNTAMlEwu11fLLGjYivTFYCsWATVuhvWzmsZmCn8M46olm/tkNjKhI5BHngB6tj7NPBU2ECc8CYX + quNb7JDYygx3Q9a9Clm5LGor3pf4laxfz9ZjC8VarAPVuBEcV/BldDRiwOvaJKtX3TID3NnGQarlG74J + pzdxD1piG0haLUoWXTdXuIWOg8JvwsI5nVz+lRED+amzOB2XdGeBHRJbmaFOiNLFhgY2Rgz40lw00aia + dtCetMNiqFv9kDXZoIEvRgxMEPnuj9gWQ+rMd5wivg3v/iyP/iSP+iwfJfper4X93EiOUeqhO/wQ5Us4 + A6lboz9Mp/LCTi5FyGoPa58epTQTsiwDsnw+22cev+ks5kJW21i/Lax7FYyx4koz2OeZd+YZIfAku8Dd + IHxpT/8DJjHvqdR8hdwAAAAASUVORK5CYII= + + + \ No newline at end of file diff --git a/Coding/QuickPlugin/Run/QuickRun.cs b/Coding/QuickPlugin/Run/QuickRun.cs new file mode 100644 index 0000000..91d4cc8 --- /dev/null +++ b/Coding/QuickPlugin/Run/QuickRun.cs @@ -0,0 +1,453 @@ +using Froser.Quick.Plugins.Run; +using IWshRuntimeLibrary; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Interop; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace Froser.Quick.Plugins +{ + internal class QuickRun : IQuickPluginMethod + { + public QuickRun() + { + Init(); + } + + // 接口部分 + public virtual string GetName() + { + return "运行(run)[yunxing] 文件"; + } + + public virtual string GetDescription(IQuickWindow quickWindow) + { + return "运行文件,按Tab可以自动补全文件路径,Ctrl+Enter打开其所在的文件夹"; + } + + public void Invoke(object sender, IQuickWindow quickWindow) + { + if (m_directoryOpenedToogle) + { + m_directoryOpenedToogle = false; + return; + } + Execute(false, quickWindow); + } + + public bool AcceptArgs() + { + return true; + } + + public string AvailableApplicationName() + { + return null; + } + + public virtual bool GetIcon(IQuickWindow quickWindow, out ImageSource icon) + { + icon = null; + return false; + } + + public void KeyDown(IQuickWindow quickWindow, KeyEventArgs e) + { + switch (e.Key) + { + case Key.Tab: + TabKeyPressed = true; + CompletePathInTextbox(quickWindow, e); + return; + case Key.LeftShift: + case Key.RightShift: + case Key.LeftCtrl: + case Key.RightCtrl: + case Key.LeftAlt: + case Key.RightAlt: + break; + case Key.Enter: + // Ctrl+Enter 打开文件夹 + if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) + OpenDirectory(quickWindow); + break; + } + } + + public void TextChanged(IQuickWindow quickWindow, TextChangedEventArgs e) + { + if (TabKeyPressed) + { + TabKeyPressed = false; + TextDirty = false; + } + else + { + TextDirty = true; + } + + // 在没有参数传进来的时候,因为已经退出了SubModel + var arg = quickWindow.GetArgument (); + if (arg == null) + { + quickWindow.ResetMethods(); + return; + } + + List matchedFiles = new List(); + matchedFiles = GetCurrentPathFileNames(arg); + + List runItemList = new List(); + foreach (var r in matchedFiles) + { + QuickRunItem item = new QuickRunItem(GetRoot(), Path.GetFileNameWithoutExtension(r), MatchCommonShortcutPath(r) ?? r); + runItemList.Add (item); + } + + if (runItemList.Count > 0) + quickWindow.ReplaceMethods(runItemList.ToArray()); + else + quickWindow.ResetMethods(); + } + + public void Closed(IQuickWindow quickWindow) + { + quickWindow.Refresh(0); + } + + public void PageDown(IQuickWindow quickWindow) + { + } + + public void PageUp(IQuickWindow quickWindow) + { + } + + // 内部实现 + public virtual List GetCommonShortcuts() + { + return CommonShortcuts; + } + + public virtual Dictionary GetCommonShortcutsPath() + { + return CommonShortcutsPath; + } + + protected virtual QuickRun GetRoot() + { + return this; + } + + protected virtual void Init() + { + CommonShortcutsPath = new Dictionary(); + CommonShortcuts = new List(); + ResultList = new List(); + AutoSearchIndex = 0; + TabKeyPressed = false; + + GetDrives(); + + try + { + IntPtr hFolderBitmap = Resource.folder.GetHbitmap(); + DefaultFolderIcon = Imaging.CreateBitmapSourceFromHBitmap(hFolderBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); + } + catch { } + + //来自注册表 + try + { + RegistryKey regkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default); + var appKey = regkey.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\App Paths"); + if (appKey != null) + FillCommonShortcutsInfo(appKey); + + regkey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default); + appKey = regkey.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\App Paths"); + if (appKey != null) + FillCommonShortcutsInfo(appKey); + } + catch { } + + // 考虑用一种O(logN)的数据结构代替 + FillSysEnvPATHShortcutsInfo(); + FillAllProgramInfo(); + CommonShortcuts.Sort(); + } + + protected virtual void Execute(bool openDirectoryOnly, IQuickWindow quickWindow) + { + string arg = quickWindow.GetArgument(); + if (arg == null) + return; + + string[] splits = arg.Split(new char[] { ' ', '\t', '\r', '\n' }, 2); + string path = splits[0]; + + if (openDirectoryOnly) + { + string tmpPath = Path.GetDirectoryName(path); + if (!Directory.Exists(tmpPath)) + { + tmpPath = MatchCommonShortcutPath(path); + if (tmpPath != null) + { + tmpPath = Path.GetDirectoryName(tmpPath); + if (!Directory.Exists(tmpPath)) + return; + path = tmpPath; + } + } + } + + string shellarg = splits.Length > 1 ? splits[1] : null; + Process.Start(path, shellarg ?? ""); + } + + protected string MatchCommonShortcutPath(string shortcutName) + { + string pathKey = RemoveExeExtension(shortcutName); + if (GetCommonShortcutsPath().ContainsKey(pathKey.ToLower())) + return GetCommonShortcutsPath()[pathKey.ToLower()]; + return null; + } + + private List GetCurrentPathFileNames(string queryPath) + { + List resultList = new List(); + try + { + resultList.Clear(); + if (queryPath.Length > 0) + { + if (Path.IsPathRooted(queryPath)) + { + string nearestPath = null; + // 获得最接近的路径 + if (QuickUtilities.IsRoot(queryPath)) + { + resultList.AddRange(GetDrives()); + nearestPath = Path.GetPathRoot(queryPath); + if (!nearestPath.EndsWith(@"\")) + nearestPath += @"\"; + } + else + { + nearestPath = Path.GetDirectoryName(queryPath); + } + resultList.AddRange(Directory.GetDirectories(nearestPath)); + resultList.AddRange(Directory.GetFiles(nearestPath)); + } + else + { + // 全局路径 + resultList.AddRange(GetCommonShortcuts()); + } + } + } + catch { } + + resultList.RemoveAll((item) => + { + if (Path.IsPathRooted(item)) + { + return !item.StartsWith(queryPath, true, CultureInfo.CurrentCulture); + } + else + { + return !Path.GetFileName(item).StartsWith(queryPath, true, CultureInfo.CurrentCulture); + } + }); + + return resultList; + } + + private void CompletePathInTextbox(IQuickWindow quickWindow, KeyEventArgs e) + { + var modifiers = e.KeyboardDevice.Modifiers; + string queryPath = quickWindow.GetArgument(); + + if (queryPath.Length == 0) + return; + + if (TextDirty) + ResultList = GetCurrentPathFileNames(queryPath); + + if (ResultList.Count == 0) + return; + + if (modifiers != ModifierKeys.Shift) + { + AutoSearchIndex = ++AutoSearchIndex % ResultList.Count; + } + else if (modifiers == ModifierKeys.Shift) + { + AutoSearchIndex = --AutoSearchIndex < 0 ? ResultList.Count - 1 : AutoSearchIndex; + } + + string content = quickWindow.GetQueryText(); + string replaced = content.Replace(queryPath, ResultList[AutoSearchIndex]); + quickWindow.SetQueryText(replaced); + var textbox = quickWindow.GetQueryTextBox(); + textbox.CaretPosition = textbox.Document.ContentEnd; + } + + private void FillCommonShortcutsInfo(RegistryKey key) + { + var names = key.GetSubKeyNames(); + foreach (var name in names) + { + var subkey = key.OpenSubKey(name); + var value = subkey.GetValue(""); + var fullpath = value == null ? "" : value.ToString(); + if (fullpath.Trim() == "") + continue; + + // 只加载有效项 + try + { + fullpath = Path.GetFullPath(fullpath.Replace ("\"", "")); + } + catch + { + continue; + } + if (!System.IO.File.Exists(fullpath) || Path.GetExtension(fullpath).ToLower() != ".exe") + continue; + + CommonShortcuts.Add(name); + string pathKey = RemoveExeExtension(name); + if (!CommonShortcutsPath.ContainsKey(pathKey.ToLower())) + CommonShortcutsPath.Add(pathKey.ToLower(), fullpath); + } + } + + private void FillSysEnvPATHShortcutsInfo() + { + var envPaths = Environment.GetEnvironmentVariable("path").Split(';'); + foreach (var p in envPaths) + { + try + { + foreach (var fullpath in Directory.GetFiles(p, "*.exe")) + { + if (!CommonShortcuts.Contains(fullpath)) + { + string filename = Path.GetFileNameWithoutExtension(fullpath).ToLower(); + if (!CommonShortcutsPath.ContainsValue(fullpath)) + { + CommonShortcuts.Add(filename); + CommonShortcutsPath.Add(filename, fullpath); + } + } + } + } + catch { } + } + } + + private void FillAllProgramInfo() + { + string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms); + string[] allPrograms = Directory.GetFiles(path, "*.lnk", SearchOption.AllDirectories); + foreach (var link in allPrograms) + { + WshShell shell = new WshShell(); + IWshShortcut sc = (IWshShortcut)shell.CreateShortcut(link); + string targetPath = sc.TargetPath; + if (Path.GetExtension(targetPath).ToLower () == ".exe") + { + string filename = Path.GetFileNameWithoutExtension(link).ToLower(); + if (!CommonShortcuts.Contains(filename)) + CommonShortcuts.Add(filename); + if (!CommonShortcutsPath.ContainsKey(filename)) + CommonShortcutsPath.Add(filename, link); + } + } + } + + private List GetDrives() + { + var driveList = new List(); + + DriveInfo[] drives = DriveInfo.GetDrives(); + foreach (var drive in drives) + { + // TODO: 当isReady改变的时候,应该重新初始化一次 + if (!drive.IsReady) + continue; + string caption = drive.Name ; + if (drive.VolumeLabel.Trim() != "") + caption += " (" + drive.VolumeLabel + ")"; + string directory = drive.RootDirectory.Name; + driveList.Add(caption); + if (!m_driveInited) + { + CommonShortcuts.Add(caption); + CommonShortcutsPath.Add(caption, directory); + m_driveInited = true; + } + } + + return driveList; + } + + private string RemoveExeExtension(string strIn) + { + const string targetString = ".exe"; + if (strIn.EndsWith(targetString, StringComparison.OrdinalIgnoreCase)) + return strIn.Substring(0, strIn.Length - targetString.Length); + return strIn; + } + + private void OpenDirectory(IQuickWindow quickWindow) + { + m_directoryOpenedToogle = true; + Execute(true, quickWindow); + } + + // 文件名自动搜索 + public virtual bool TextDirty + { + get + { + return m_editedByHand; + } + set + { + m_editedByHand = value; + if (value) + AutoSearchIndex = 0; + } + } + private bool m_editedByHand = true; + public virtual Dictionary CommonShortcutsPath { get; set; } + + // 不带exe结尾的文件名 + public virtual List CommonShortcuts { get; set; } + + // 文件名和其完整路径组成的关系容器 + public virtual List ResultList { get; set; } + + // Tab键保存路径时的路径索引 + public virtual int AutoSearchIndex { get; set; } + + // 是否按下了Tab导致TextChanged + public virtual bool TabKeyPressed { get; set; } + + public ImageSource DefaultFolderIcon { get; set; } + private bool m_directoryOpenedToogle = false; + private bool m_driveInited = false; + } + +} diff --git a/Coding/QuickPlugin/Run/QuickRunItem.cs b/Coding/QuickPlugin/Run/QuickRunItem.cs new file mode 100644 index 0000000..8b8aadc --- /dev/null +++ b/Coding/QuickPlugin/Run/QuickRunItem.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Windows.Media.Imaging; + +namespace Froser.Quick.Plugins.Run +{ + internal class QuickRunItem : QuickRun + { + public QuickRunItem(QuickRun parent, string progName, string fullpath) + { + m_progName = progName; + m_fullpath = fullpath; + m_parent = parent; + } + + public override string GetName() + { + return "运行(run)[yunxing] " + m_progName; + } + + public override string GetDescription(IQuickWindow quickWindow) + { + return m_fullpath; + } + + protected override void Execute(bool openDirectoryOnly, IQuickWindow quickWindow) + { + string arg = quickWindow.GetArgument(); + if (arg == null) + return; + + string[] splits = arg.Split(new char[] { ' ', '\t', '\r', '\n' }, 2); + string path = m_fullpath; + + if (openDirectoryOnly) + path = Path.GetDirectoryName(m_fullpath); + + string shellarg = splits.Length > 1 ? splits[1] : null; + Process.Start(path, shellarg ?? ""); + } + + public override bool GetIcon(IQuickWindow quickWindow, out System.Windows.Media.ImageSource icon) + { + try + { + if (Directory.Exists(m_fullpath)) + { + icon = GetRoot().DefaultFolderIcon; + } + else + { + string dest = m_fullpath; + if (!Path.IsPathRooted(m_fullpath)) + dest = MatchCommonShortcutPath(m_fullpath); + + var tmp = Icon.ExtractAssociatedIcon(dest); //获得主线程图标 + icon = tmp.ToBitmapSource(); + } + return true; + } + catch { } + icon = null; + return false; + } + + protected override QuickRun GetRoot() + { + return m_parent; + } + + protected override void Init() + { + // C#中是允许在构造的时候调用派生类虚函数的 + } + + public override List GetCommonShortcuts() + { + return m_parent.GetCommonShortcuts(); + } + + public override Dictionary GetCommonShortcutsPath() + { + return m_parent.GetCommonShortcutsPath(); + } + + public override bool TextDirty + { + get + { + return GetRoot().TextDirty; + } + set + { + GetRoot().TextDirty = value; + } + } + + public override Dictionary CommonShortcutsPath + { + get + { + return GetRoot().CommonShortcutsPath; + } + set + { + GetRoot().CommonShortcutsPath = value; + } + } + + public override List CommonShortcuts + { + get + { + return GetRoot().CommonShortcuts; + } + set + { + GetRoot().CommonShortcuts = value; + } + } + + public override List ResultList + { + get + { + return GetRoot().ResultList; + } + set + { + GetRoot().ResultList = value; + } + } + + public override int AutoSearchIndex + { + get + { + return GetRoot().AutoSearchIndex; + } + set + { + GetRoot().AutoSearchIndex = value; + } + } + + public override bool TabKeyPressed + { + get + { + return GetRoot().TabKeyPressed; + } + set + { + GetRoot().TabKeyPressed = value; + } + } + + private string m_progName; + private string m_fullpath; + private QuickRun m_parent; + } +} diff --git a/Coding/QuickUI/IQuickContextWindowHandler.cs b/Coding/QuickUI/IQuickContextWindowHandler.cs new file mode 100644 index 0000000..eefec1c --- /dev/null +++ b/Coding/QuickUI/IQuickContextWindowHandler.cs @@ -0,0 +1,12 @@ +using System; +namespace Froser.Quick.UI +{ + public interface IQuickContextWindowHandler + { + void SetHost(QuickContextWindow host); + void Init(); + void AfterShow(); + void BeforeShow(string context); + void OnDeactivate(object sender, EventArgs e); + } +} diff --git a/Coding/QuickUI/IQuickMainWindowHandler.cs b/Coding/QuickUI/IQuickMainWindowHandler.cs new file mode 100644 index 0000000..3bbd246 --- /dev/null +++ b/Coding/QuickUI/IQuickMainWindowHandler.cs @@ -0,0 +1,26 @@ +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; + +namespace Froser.Quick.UI +{ + public interface IQuickMainWindowHandler + { + void Init(); + void SetHostWindow(QuickMainWindow host); + void OnClosing(object sender, CancelEventArgs e); + void OnDeactivated(object sender, EventArgs e); + void OnActivated(object sender, EventArgs e); + void OnKeyDown(object sender, KeyEventArgs e); + void OnMouseWheel(object sender, MouseWheelEventArgs e); + void OnTextChanged(object sender, TextChangedEventArgs e); + void OnListItemClicked(object sender, EventArgs e); + void OnLockedClick(object sender, MouseButtonEventArgs e); + void OnListPageUp(); + void OnListPageDown(); + void OnShowing(); + void OnShowed(); + } +} diff --git a/Coding/QuickUI/IQuickPreferenceWindowHandler.cs b/Coding/QuickUI/IQuickPreferenceWindowHandler.cs new file mode 100644 index 0000000..f462c4c --- /dev/null +++ b/Coding/QuickUI/IQuickPreferenceWindowHandler.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Input; + +namespace Froser.Quick.UI +{ + public interface IQuickPreferenceWindowHandler + { + void SetHost(QuickPreferenceWindow host); + void LoadConfig(); + void ShortcutTextBoxOnPreviewKeyDown(object sender, KeyEventArgs e); + void OnSave(); + void OnTemplateSelected(int index); + void OnTemplateMethodSelect(int index); + void OnGeneralDefault(); + void OnSaveMethod(); + void OnRestoreMethod(); + void OnMoveUpMethod(); + void OnMoveDownMethod(); + void OnCreateNewMethod(); + void OnDeleteMethod(); + void OnCreateNewContext(); + void OnRemoveContext(); + void OnModifyContext(); + } +} diff --git a/Coding/QuickUI/Properties/AssemblyInfo.cs b/Coding/QuickUI/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..69aa465 --- /dev/null +++ b/Coding/QuickUI/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 有关程序集的常规信息通过以下 +// 特性集控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("QuickUI")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Froser")] +[assembly: AssemblyProduct("QuickUI")] +[assembly: AssemblyCopyright("Froser")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +//若要开始生成可本地化的应用程序,请在 +// 中的 .csproj 文件中 +//设置 CultureYouAreCodingWith。 例如,如果您在源文件中 +//使用的是美国英语,请将 设置为 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")] diff --git a/Coding/QuickUI/Properties/Resources.Designer.cs b/Coding/QuickUI/Properties/Resources.Designer.cs new file mode 100644 index 0000000..487e9fa --- /dev/null +++ b/Coding/QuickUI/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.18408 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick.UI.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 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() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Froser.Quick.UI.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Coding/QuickUI/Properties/Resources.resx b/Coding/QuickUI/Properties/Resources.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Coding/QuickUI/Properties/Resources.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Coding/QuickUI/Properties/Settings.Designer.cs b/Coding/QuickUI/Properties/Settings.Designer.cs new file mode 100644 index 0000000..398960e --- /dev/null +++ b/Coding/QuickUI/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.18408 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick.UI.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.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; + } + } + } +} diff --git a/Coding/QuickUI/Properties/Settings.settings b/Coding/QuickUI/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/Coding/QuickUI/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Coding/QuickUI/QuickContextWindow.xaml b/Coding/QuickUI/QuickContextWindow.xaml new file mode 100644 index 0000000..37a6d92 --- /dev/null +++ b/Coding/QuickUI/QuickContextWindow.xaml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding/QuickUI/QuickContextWindow.xaml.cs b/Coding/QuickUI/QuickContextWindow.xaml.cs new file mode 100644 index 0000000..33a8fb7 --- /dev/null +++ b/Coding/QuickUI/QuickContextWindow.xaml.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +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.Shapes; + +namespace Froser.Quick.UI +{ + /// + /// QuickContextWindow.xaml 的交互逻辑 + /// + public partial class QuickContextWindow : Window + { + public QuickContextWindow(IQuickContextWindowHandler handler) + { + InitializeComponent(); + + handler.SetHost(this); + m_handler = handler; + this.Deactivated += handler.OnDeactivate; + + handler.Init(); + } + + public void Show(string context) + { + WindowStartupLocation = System.Windows.WindowStartupLocation.Manual; + m_handler.BeforeShow(context); + Show(); + m_handler.AfterShow(); + } + + public QuickListBox GetList() + { + return quickContextList; + } + + private IQuickContextWindowHandler m_handler; + } +} diff --git a/Coding/QuickUI/QuickListBox.cs b/Coding/QuickUI/QuickListBox.cs new file mode 100644 index 0000000..748ccb6 --- /dev/null +++ b/Coding/QuickUI/QuickListBox.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls; + +namespace Froser.Quick.UI +{ + public class QuickListBox : ListBox + { + public event EventHandler ListItemClicked; + + public void ActivateListItemClickedEvent(ListBoxItem sender) + { + if (ListItemClicked != null) + ListItemClicked(sender, new EventArgs()); + } + } +} diff --git a/Coding/QuickUI/QuickListItem.cs b/Coding/QuickUI/QuickListItem.cs new file mode 100644 index 0000000..9aa344d --- /dev/null +++ b/Coding/QuickUI/QuickListItem.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +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; + +namespace Froser.Quick.UI +{ + public class QuickListItem + { + private const int IMAGE_SIZE = 32; + private const int IMAGE_SIZE_SIMPLE = 24; + + public QuickListItem(string title, string description, ImageSource imgSrc) + { + m_title = title; + m_description = description; + m_iconImageSource = imgSrc; + m_type = description == null ? ListType.Simple : ListType.Full; + } + + public ListBoxItem CreateListBoxItemTo(QuickListBox list) + { + ListBoxItem item = new ListBoxItem(); + item.Focusable = false; + item.SetResourceReference(ListBoxItem.StyleProperty, "quickListItemStyle"); + + InitGrid(); + InitImage(); + InitTextGrid(); + InitTitle(); + InitDescription(); + + item.Content = m_grid; + list.Items.Add(item); + + item.MouseEnter += (sender, e) => { list.SelectedItem = item; }; + item.PreviewMouseDown += (sender, e) => { list.ActivateListItemClickedEvent(item); }; + item.Tag = this; + + return item; + } + + private void InitGrid() + { + GridLength length ; + if (m_type == ListType.Full) + length = new GridLength(IMAGE_SIZE, GridUnitType.Pixel); + else + length = new GridLength(IMAGE_SIZE_SIMPLE, GridUnitType.Pixel); + ColumnDefinition gcd1 = new ColumnDefinition(); + ColumnDefinition gcd2 = new ColumnDefinition(); + gcd1.Width = length; + m_grid = new Grid(); + m_grid.ColumnDefinitions.Add(gcd1); + m_grid.ColumnDefinitions.Add(gcd2); + } + + private void InitImage() + { + m_img = new Image(); + if (m_iconImageSource != null) + m_img.Source = m_iconImageSource; + else + m_img.Source = QuickUIResource.GetDefaultIcon(); + Grid.SetColumn(m_img, 0); + m_grid.Children.Add(m_img); + } + + private void InitTextGrid() + { + m_textGrid = new Grid(); + if (m_type == ListType.Full) + { + RowDefinition tgcd1 = new RowDefinition(); + RowDefinition tgcd2 = new RowDefinition(); + tgcd1.Height = new GridLength(4, GridUnitType.Star); + tgcd2.Height = new GridLength(2, GridUnitType.Star); + m_textGrid.RowDefinitions.Add(tgcd1); + m_textGrid.RowDefinitions.Add(tgcd2); + } + m_grid.Children.Add(m_textGrid); + Grid.SetColumn(m_textGrid, 1); + } + + private void InitTitle() + { + m_lbTitle = new Label(); + m_lbTitle.Content = m_title.Replace("_", "__"); + m_lbTitle.FontFamily = DEFAULT_FONT_FAMILTY; + m_lbTitle.FontWeight = FontWeights.Bold; + m_lbTitle.FontSize = 16; + m_textGrid.Children.Add(m_lbTitle); + Grid.SetRow(m_lbTitle, 0); + } + + private void InitDescription() + { + if (m_type == ListType.Full) + { + m_lbDescription = new Label(); + m_lbDescription.Content = m_description.Replace("_", "__"); + m_lbDescription.FontFamily = DEFAULT_FONT_FAMILTY; + m_lbDescription.FontSize = 12; + m_textGrid.Children.Add(m_lbDescription); + Grid.SetRow(m_lbDescription, 1); + } + } + + public object Tag { get; set; } + + private readonly FontFamily DEFAULT_FONT_FAMILTY = new FontFamily("Consolas, Microsoft YaHei"); + private Grid m_grid; + private Image m_img; + private Grid m_textGrid; + private Label m_lbTitle; + private Label m_lbDescription; + + private ImageSource m_iconImageSource; + private string m_title; + private string m_description; + private enum ListType {Simple, Full} + private ListType m_type; + } +} diff --git a/Coding/QuickUI/QuickMainWindow.xaml b/Coding/QuickUI/QuickMainWindow.xaml new file mode 100644 index 0000000..aab606e --- /dev/null +++ b/Coding/QuickUI/QuickMainWindow.xaml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding/QuickUI/QuickMainWindow.xaml.cs b/Coding/QuickUI/QuickMainWindow.xaml.cs new file mode 100644 index 0000000..26ed73d --- /dev/null +++ b/Coding/QuickUI/QuickMainWindow.xaml.cs @@ -0,0 +1,123 @@ +using System; +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace Froser.Quick.UI +{ + /// + /// QuickMainWindow.xaml 的交互逻辑 + /// + public partial class QuickMainWindow : Window + { + public QuickMainWindow(IQuickMainWindowHandler handler) + { + InitializeComponent(); + + m_handler = handler; + handler.SetHostWindow(this); + + Closing += handler.OnClosing; + Deactivated += handler.OnDeactivated; + Activated += handler.OnActivated; + GetQueryTextBox().CaptureMouse(); + GetQueryTextBox().TextChanged += handler.OnTextChanged; + GetQueryTextBox().MouseWheel += handler.OnMouseWheel; + GetQueryTextBox().PreviewKeyDown += handler.OnKeyDown; + GetList().ListItemClicked += handler.OnListItemClicked; + GetList().KeyDown += handler.OnKeyDown; + GetList().MouseWheel += handler.OnMouseWheel; + GetLockImageButton().PreviewMouseDown += handler.OnLockedClick; + + handler.Init(); + + backgroundBorder.PreviewMouseDown += dragMove; + innerBorder.PreviewMouseDown += dragMove; + } + + public new void Show() + { + m_handler.OnShowing(); + base.Show(); + m_handler.OnShowed(); + } + + public void SetOpacity(double o) + { + mainWindow.Opacity = o; + } + + public void ResetOpacity() + { + mainWindow.Opacity = 1.0; + } + + public RichTextBox GetQueryTextBox() + { + return searchTextBox; + } + + public QuickListBox GetList() + { + return quickListBox; + } + + public Image GetLockImageButton() + { + return iconLock; + } + + public void SelectNext() + { + var list = GetList(); + int nextIndex = list.SelectedIndex + 1; + if (nextIndex >= list.Items.Count) + m_handler.OnListPageDown(); + else + list.SelectedIndex = nextIndex; + } + + public void SelectPrevious() + { + var list = GetList(); + int nextIndex = list.SelectedIndex - 1; + if (nextIndex < 0) + m_handler.OnListPageUp(); + else + list.SelectedIndex = nextIndex; + } + + public void Select(int index) + { + var list = GetList(); + list.SelectedIndex = index; + } + + public void AutoResize() + { + int itemsHeight = GetList().Items.Count * UNIT_HEIGHT; + if (itemsHeight < MIN_LIST_HEIGHT) + itemsHeight = MIN_LIST_HEIGHT; + Height = itemsHeight + WINDOW_OFFSET; + } + + public void SetBackgroundColor(Color c) + { + backgroundBorder.Background = new SolidColorBrush(c); + } + + private void dragMove(object sender, MouseButtonEventArgs e) + { + if (e.LeftButton == MouseButtonState.Pressed) + DragMove(); + } + + private const int UNIT_HEIGHT = 55; + private const int WINDOW_OFFSET = 68; + private const int MIN_LIST_HEIGHT = 3 * UNIT_HEIGHT; + + private IQuickMainWindowHandler m_handler; + } +} diff --git a/Coding/QuickUI/QuickPerferenceContextEdit.xaml b/Coding/QuickUI/QuickPerferenceContextEdit.xaml new file mode 100644 index 0000000..f93be06 --- /dev/null +++ b/Coding/QuickUI/QuickPerferenceContextEdit.xaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + 上下文编辑 + 名称 + + 行为 + + 运行参数 + + + + diff --git a/Coding/QuickUI/QuickPerferenceContextEdit.xaml.cs b/Coding/QuickUI/QuickPerferenceContextEdit.xaml.cs new file mode 100644 index 0000000..08a281f --- /dev/null +++ b/Coding/QuickUI/QuickPerferenceContextEdit.xaml.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +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.Shapes; + +namespace Froser.Quick.UI +{ + /// + /// QuickPerferenceContextEdit.xaml 的交互逻辑。不使用接口,因为功能简单 + /// + public partial class QuickPerferenceContextEdit : Window + { + public QuickPerferenceContextEdit() + { + InitializeComponent(); + btn_done.Click += btn_done_Click; + } + + void btn_done_Click(object sender, RoutedEventArgs e) + { + if (Done != null) + Done(); + Close(); + } + + public new void Show() + { + if (Init != null) + Init(); + base.ShowDialog(); + } + + public TextBox GetName() + { + return tb_name; + } + + public TextBox GetBehavior() + { + return tb_behavior; + } + + public TextBox GetArgument() + { + return tb_argument; + } + + public event Action Init; + public event Action Done; + + public object m_data; + } +} diff --git a/Coding/QuickUI/QuickPreferenceWindow.xaml b/Coding/QuickUI/QuickPreferenceWindow.xaml new file mode 100644 index 0000000..d531ebc --- /dev/null +++ b/Coding/QuickUI/QuickPreferenceWindow.xaml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + 快捷键 + + + + + + + + + + + + + + + + + + + 上下文菜单 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 方法名称 + 中括号中表示的为注音,它可以被检索出来,但是不会再界面上显示。尖括号{}中表示参数名称,它会被显示出来,但是不会被检索 + + 描述 + + 脚本 + + 接受参数正则表达式 + 如 . 表示接受任意字符串,\d表示接收数字,为空且默认参数为空表示不接受任何参数 + + 默认参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + diff --git a/Coding/QuickUI/QuickPreferenceWindow.xaml.cs b/Coding/QuickUI/QuickPreferenceWindow.xaml.cs new file mode 100644 index 0000000..3f186b7 --- /dev/null +++ b/Coding/QuickUI/QuickPreferenceWindow.xaml.cs @@ -0,0 +1,244 @@ +using System.Windows; +using System.Windows.Controls; + +namespace Froser.Quick.UI +{ + /// + /// Window1.xaml 的交互逻辑 + /// + public partial class QuickPreferenceWindow : Window + { + public QuickPreferenceWindow(IQuickPreferenceWindowHandler handler) + { + InitializeComponent(); + handler.SetHost(this); + this.Closing += QuickPreferenceWindow_Closing; + + GetQuickTextBoxInGeneral().PreviewKeyDown += handler.ShortcutTextBoxOnPreviewKeyDown; + GetContextTextBoxInGeneral().PreviewKeyDown += handler.ShortcutTextBoxOnPreviewKeyDown; + GetSaveInTemplate().Click += QuickPreferenceWindow_SaveTemplate_Click; + GetRestoreInTemplate().Click +=QuickPreferenceWindow_RestoreTemplate_Click; + GetMoveUpInTemplate().Click += QuickPreferenceWindow_moveUp_Click; + GetMoveDownInTemplate().Click += QuickPreferenceWindow_moveDown_Click; + GetDeleteItemInTemplate().Click += QuickPreferenceWindow_delItem_Click; + GetCreateItemInTemplate().Click += QuickPreferenceWindow_newItem_Click; + GetSetToDefaultInGeneral().Click += QuickPreferenceWindow_default_Click; + m_handler = handler; + } + void QuickPreferenceWindow_default_Click(object sender, RoutedEventArgs e) + { + m_handler.OnGeneralDefault(); + } + + void QuickPreferenceWindow_moveUp_Click(object sender, RoutedEventArgs e) + { + m_handler.OnMoveUpMethod(); + } + + void QuickPreferenceWindow_moveDown_Click(object sender, RoutedEventArgs e) + { + m_handler.OnMoveDownMethod(); + } + + void QuickPreferenceWindow_delItem_Click(object sender, RoutedEventArgs e) + { + m_handler.OnDeleteMethod(); + } + + void QuickPreferenceWindow_newItem_Click(object sender, RoutedEventArgs e) + { + m_handler.OnCreateNewMethod(); + } + + void QuickPreferenceWindow_SaveTemplate_Click(object sender, RoutedEventArgs e) + { + m_handler.OnSaveMethod(); + } + + void QuickPreferenceWindow_RestoreTemplate_Click(object sender, RoutedEventArgs e) + { + m_handler.OnRestoreMethod(); + } + + private void QuickPreferenceWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + e.Cancel = true; + Hide(); + m_handler.OnSave(); + } + + private void template_list_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + m_handler.OnTemplateSelected(GetTemplateListInTemplate().SelectedIndex); + } + + private void template_methods_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + m_handler.OnTemplateMethodSelect(GetMethodsListInTemplate().SelectedIndex); + } + + public void ShowAbout() + { + about.IsSelected = true; + Show(); + } + + public new void Show() + { + m_handler.LoadConfig(); + base.Show(); + } + + public TextBox GetContextTextBoxInGeneral() + { + return general_contextShortcutTx; + } + + public TextBox GetQuickTextBoxInGeneral() + { + return general_quickShortcutTx; + } + + public CheckBox GetContextShiftInGeneral() + { + return general_contextShift; + } + + public CheckBox GetContextCtrlInGeneral() + { + return general_contextCtrl; + } + + public CheckBox GetContextAltInGeneral() + { + return general_contextAlt; + } + + public CheckBox GetContextWinInGeneral() + { + return general_contextWin; + } + + public CheckBox GetUseContext() + { + return general_useContext; + } + + public CheckBox GetQuickShiftInGeneral() + { + return general_quickShift; + } + + public CheckBox GetQuickCtrlInGeneral() + { + return general_quickCtrl; + } + + public CheckBox GetQuickAltInGeneral() + { + return general_quickAlt; + } + + public CheckBox GetQuickWinInGeneral() + { + return general_quickWin; + } + + public Button GetSetToDefaultInGeneral() + { + return general_setToDefault; + } + + public ListView GetContextMenuInGeneral() + { + return general_contextMenu; + } + + public ComboBox GetTemplateListInTemplate() + { + return template_list; + } + + public ListBox GetMethodsListInTemplate() + { + return template_methods; + } + + public TextBox GetMethodNameTextBoxInTemplate() + { + return tmp_methodname; + } + + public TextBox GetMethodDescriptionTextBoxInTemplate() + { + return tmp_methoddesc; + } + + public TextBox GetMethodScriptTextBoxInTemplate() + { + return tmp_methodscpt; + } + + public TextBox GetMethodRegexTextBoxInTemplate() + { + return tmp_methodreg; + } + + public TextBox GetMethodDefaultArgumentTextBoxInTemplate() + { + return tmp_methoddefarg; + } + + public Button GetRestoreInTemplate() + { + return tmp_restore; + } + + public Button GetSaveInTemplate() + { + return tmp_save; + } + + public Button GetMoveUpInTemplate() + { + return tmp_moveUp; + } + + public Button GetMoveDownInTemplate() + { + return tmp_moveDown; + } + + public Button GetDeleteItemInTemplate() + { + return tmp_delItem; + } + + public Button GetCreateItemInTemplate() + { + return tmp_newItem; + } + + public TextBlock GetVersionTextBlockInAbout() + { + return tb_version; + } + + private void newContextMenu_Click(object sender, RoutedEventArgs e) + { + m_handler.OnCreateNewContext(); + } + + private void removeContextMenu_Click(object sender, RoutedEventArgs e) + { + m_handler.OnRemoveContext(); + } + + private void modifyContextMenu_Click(object sender, RoutedEventArgs e) + { + m_handler.OnModifyContext(); + } + + private IQuickPreferenceWindowHandler m_handler; + } +} diff --git a/Coding/QuickUI/QuickUI.csproj b/Coding/QuickUI/QuickUI.csproj new file mode 100644 index 0000000..ae44a7e --- /dev/null +++ b/Coding/QuickUI/QuickUI.csproj @@ -0,0 +1,167 @@ + + + + + Debug + AnyCPU + {F36B622E-4F74-4D69-912C-FB9DE8915362} + library + Properties + Froser.Quick.UI + QuickUI + v4.0 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + + true + full + false + ..\..\Bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\Bin\Release\ + TRACE + prompt + 4 + + + true + ..\..\Bin\Debug4KSO\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + ..\..\Bin\Release4KSO\ + TRACE + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + 4.0 + + + + + + + + + + + QuickContextWindow.xaml + + + QuickPerferenceContextEdit.xaml + + + + QuickPreferenceWindow.xaml + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + + QuickMainWindow.xaml + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Coding/QuickUI/QuickUIResource.cs b/Coding/QuickUI/QuickUIResource.cs new file mode 100644 index 0000000..0711b4d --- /dev/null +++ b/Coding/QuickUI/QuickUIResource.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media.Imaging; + +namespace Froser.Quick.UI +{ + public static class QuickUIResource + { + public static BitmapImage GetDefaultIcon() + { + if (s_defaultIcon == null) + { + string uri = "resources/icons/quick.png"; + s_defaultIcon = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute)); + } + return s_defaultIcon; + } + + public static BitmapImage GetDefaultPluginIcon() + { + if (s_defaultPluginIcon == null) + { + string uri = "resources/icons/plugin.png"; + s_defaultPluginIcon = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute)); + } + return s_defaultPluginIcon; + } + + public static BitmapImage GetLockedIcon() + { + if (m_iconLocked == null) + { + string uri = "resources/icons/locked.png"; + m_iconLocked = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute)); + } + return m_iconLocked; + } + + public static BitmapImage GetUnlockedIcon() + { + if (m_iconUnlocked == null) + { + string uri = "resources/icons/unlocked.png"; + m_iconUnlocked = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute)); + } + return m_iconUnlocked; + } + + private static BitmapImage s_defaultIcon; + private static BitmapImage s_defaultPluginIcon; + private static BitmapImage m_iconLocked; + private static BitmapImage m_iconUnlocked; + } +} diff --git a/Coding/QuickUI/Resources/icons/config_about.png b/Coding/QuickUI/Resources/icons/config_about.png new file mode 100644 index 0000000..28f6f7f Binary files /dev/null and b/Coding/QuickUI/Resources/icons/config_about.png differ diff --git a/Coding/QuickUI/Resources/icons/config_behaviors.png b/Coding/QuickUI/Resources/icons/config_behaviors.png new file mode 100644 index 0000000..4b01b28 Binary files /dev/null and b/Coding/QuickUI/Resources/icons/config_behaviors.png differ diff --git a/Coding/QuickUI/Resources/icons/config_general.png b/Coding/QuickUI/Resources/icons/config_general.png new file mode 100644 index 0000000..c89ffc5 Binary files /dev/null and b/Coding/QuickUI/Resources/icons/config_general.png differ diff --git a/Coding/QuickUI/Resources/icons/locked.png b/Coding/QuickUI/Resources/icons/locked.png new file mode 100644 index 0000000..7690f1a Binary files /dev/null and b/Coding/QuickUI/Resources/icons/locked.png differ diff --git a/Coding/QuickUI/Resources/icons/plugin.png b/Coding/QuickUI/Resources/icons/plugin.png new file mode 100644 index 0000000..3425a97 Binary files /dev/null and b/Coding/QuickUI/Resources/icons/plugin.png differ diff --git a/Coding/QuickUI/Resources/icons/quick.png b/Coding/QuickUI/Resources/icons/quick.png new file mode 100644 index 0000000..37d9f80 Binary files /dev/null and b/Coding/QuickUI/Resources/icons/quick.png differ diff --git a/Coding/QuickUI/Resources/icons/quick128.png b/Coding/QuickUI/Resources/icons/quick128.png new file mode 100644 index 0000000..f2e10fe Binary files /dev/null and b/Coding/QuickUI/Resources/icons/quick128.png differ diff --git a/Coding/QuickUI/Resources/icons/unlocked.png b/Coding/QuickUI/Resources/icons/unlocked.png new file mode 100644 index 0000000..e08e47c Binary files /dev/null and b/Coding/QuickUI/Resources/icons/unlocked.png differ diff --git a/Coding/QuickUI/Themes/Generic.xaml b/Coding/QuickUI/Themes/Generic.xaml new file mode 100644 index 0000000..34fe906 --- /dev/null +++ b/Coding/QuickUI/Themes/Generic.xaml @@ -0,0 +1,5 @@ + + diff --git a/Coding/QuickUI/app.config b/Coding/QuickUI/app.config new file mode 100644 index 0000000..49cc43e --- /dev/null +++ b/Coding/QuickUI/app.config @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Coding/QuickUpdate/App.config b/Coding/QuickUpdate/App.config new file mode 100644 index 0000000..74ade9d --- /dev/null +++ b/Coding/QuickUpdate/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/Coding/QuickUpdate/Program.cs b/Coding/QuickUpdate/Program.cs new file mode 100644 index 0000000..ee5fffd --- /dev/null +++ b/Coding/QuickUpdate/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Froser.Quick.QuickUpdate +{ + static class Program + { + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + SilenceUpdate.Update(); + } + } +} diff --git a/Coding/QuickUpdate/Properties/AssemblyInfo.cs b/Coding/QuickUpdate/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9497817 --- /dev/null +++ b/Coding/QuickUpdate/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过以下 +// 特性集控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("QuickUpdate")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Froser")] +[assembly: AssemblyProduct("Quick")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("c3de8738-6b18-4a26-927c-db482c1975e6")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Coding/QuickUpdate/Properties/Resources.Designer.cs b/Coding/QuickUpdate/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9d31441 --- /dev/null +++ b/Coding/QuickUpdate/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.18408 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick.QuickUpdate.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 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() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Froser.Quick.QuickUpdate.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Coding/QuickUpdate/Properties/Resources.resx b/Coding/QuickUpdate/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Coding/QuickUpdate/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Coding/QuickUpdate/Properties/Settings.Designer.cs b/Coding/QuickUpdate/Properties/Settings.Designer.cs new file mode 100644 index 0000000..f2fd54f --- /dev/null +++ b/Coding/QuickUpdate/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.18408 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Froser.Quick.QuickUpdate.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.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; + } + } + } +} diff --git a/Coding/QuickUpdate/Properties/Settings.settings b/Coding/QuickUpdate/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Coding/QuickUpdate/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Coding/QuickUpdate/QuickUpdate.csproj b/Coding/QuickUpdate/QuickUpdate.csproj new file mode 100644 index 0000000..139454e --- /dev/null +++ b/Coding/QuickUpdate/QuickUpdate.csproj @@ -0,0 +1,138 @@ + + + + + Debug + AnyCPU + {E197A7E7-B3E0-4ECF-AC0A-459BC80D2A28} + WinExe + Properties + Froser.Quick.QuickUpdate + QuickUpdate + v4.0 + 512 + false + + 发布\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + AnyCPU + true + full + false + ..\..\Bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + ..\..\Bin\Release\ + TRACE + prompt + 4 + + + ..\..\Bin\Debug4KSO\ + true + TRACE;DEBUG;KSO + full + true + + + ..\..\Bin\Release4KSO\ + TRACE + true + pdbonly + true + + + LocalIntranet + + + false + + + + Froser.Quick.QuickUpdate.Program + + + + + + + + + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + False + Microsoft .NET Framework 4.5 %28x86 和 x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + + + \ No newline at end of file diff --git a/Coding/QuickUpdate/SilenceUpdate.cs b/Coding/QuickUpdate/SilenceUpdate.cs new file mode 100644 index 0000000..daea995 --- /dev/null +++ b/Coding/QuickUpdate/SilenceUpdate.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Froser.Quick.QuickUpdate +{ + public static class SilenceUpdate + { + public static void Update() + { + while (IsQuickRunning()) + { + Thread.Sleep(100); + } + + if (HasNotifyFile()) + { + try + { + // 准备更新,将文件全部都拷贝出来,然后运行Quick.exe,然后删除updatenotify和update文件夹 + CopyFile(); + Clear(); + Exec(); + Done(); + } + catch + { + // Swallow exceptions + } + } + } + + private static bool IsQuickRunning() + { + Process[] proc = Process.GetProcessesByName(s_processName); + return proc.Length > 0; + } + + private static bool HasNotifyFile() + { + + return File.Exists(NotifyFilePath); + } + + private static void CopyFile() + { + string[] files = Directory.GetFiles(UpdateDir, "*", SearchOption.AllDirectories); + foreach (var file in files) + { + string relPath = file.Replace(UpdateDir, ""); + string dest = Path.Combine(AppDir, relPath); + File.Copy(file, dest, true); + } + } + + private static void Clear() + { + File.Delete(NotifyFilePath); + Directory.Delete(UpdateDir, true); + } + + private static void Exec() + { + Debug.Assert(File.Exists(AppPath)); + Process.Start(AppPath); + } + + private static void Done() + { + } + + private static string AppDir + { + get + { + return AppDomain.CurrentDomain.BaseDirectory; + } + } + + private static string UpdateDir + { + get + { + return Path.Combine(AppDir, s_updateDirName) + @"\"; + } + } + + private static string NotifyFilePath + { + get + { + return Path.Combine(AppDir, s_notifyFile); + } + } + + private static string AppPath + { + get + { + return Path.Combine(AppDir, s_appName); + } + } + + private const string s_notifyFile = "updatenotify"; + private const string s_appName = "quick.exe"; + private const string s_updateDirName = "update"; + private const string s_processName = "Quick"; + } +} diff --git a/Coding/Resources/icons/folder16.png b/Coding/Resources/icons/folder16.png new file mode 100644 index 0000000..5b13f84 Binary files /dev/null and b/Coding/Resources/icons/folder16.png differ diff --git a/Coding/Resources/icons/folder24.png b/Coding/Resources/icons/folder24.png new file mode 100644 index 0000000..aeb70e4 Binary files /dev/null and b/Coding/Resources/icons/folder24.png differ diff --git a/Coding/Resources/icons/folder32.png b/Coding/Resources/icons/folder32.png new file mode 100644 index 0000000..a565a35 Binary files /dev/null and b/Coding/Resources/icons/folder32.png differ diff --git a/Coding/Resources/icons/folder48.png b/Coding/Resources/icons/folder48.png new file mode 100644 index 0000000..b208c97 Binary files /dev/null and b/Coding/Resources/icons/folder48.png differ diff --git a/Coding/Resources/icons/locked16.png b/Coding/Resources/icons/locked16.png new file mode 100644 index 0000000..7690f1a Binary files /dev/null and b/Coding/Resources/icons/locked16.png differ diff --git a/Coding/Resources/icons/locked24.png b/Coding/Resources/icons/locked24.png new file mode 100644 index 0000000..8b1295f Binary files /dev/null and b/Coding/Resources/icons/locked24.png differ diff --git a/Coding/Resources/icons/plugin32.png b/Coding/Resources/icons/plugin32.png new file mode 100644 index 0000000..3425a97 Binary files /dev/null and b/Coding/Resources/icons/plugin32.png differ diff --git a/Coding/Resources/icons/plugin48.png b/Coding/Resources/icons/plugin48.png new file mode 100644 index 0000000..9ab2777 Binary files /dev/null and b/Coding/Resources/icons/plugin48.png differ diff --git a/Coding/Resources/icons/quick128.png b/Coding/Resources/icons/quick128.png new file mode 100644 index 0000000..f2e10fe Binary files /dev/null and b/Coding/Resources/icons/quick128.png differ diff --git a/Coding/Resources/icons/quick16.png b/Coding/Resources/icons/quick16.png new file mode 100644 index 0000000..717bd83 Binary files /dev/null and b/Coding/Resources/icons/quick16.png differ diff --git a/Coding/Resources/icons/quick24.png b/Coding/Resources/icons/quick24.png new file mode 100644 index 0000000..4dfb956 Binary files /dev/null and b/Coding/Resources/icons/quick24.png differ diff --git a/Coding/Resources/icons/quick32.png b/Coding/Resources/icons/quick32.png new file mode 100644 index 0000000..37d9f80 Binary files /dev/null and b/Coding/Resources/icons/quick32.png differ diff --git a/Coding/Resources/icons/quick48.png b/Coding/Resources/icons/quick48.png new file mode 100644 index 0000000..28f6f7f Binary files /dev/null and b/Coding/Resources/icons/quick48.png differ diff --git a/Coding/Resources/icons/quick64.png b/Coding/Resources/icons/quick64.png new file mode 100644 index 0000000..06034a3 Binary files /dev/null and b/Coding/Resources/icons/quick64.png differ diff --git a/Coding/Resources/icons/quick72.png b/Coding/Resources/icons/quick72.png new file mode 100644 index 0000000..06edd24 Binary files /dev/null and b/Coding/Resources/icons/quick72.png differ diff --git a/Coding/Resources/icons/unlocked16.png b/Coding/Resources/icons/unlocked16.png new file mode 100644 index 0000000..e08e47c Binary files /dev/null and b/Coding/Resources/icons/unlocked16.png differ diff --git a/Coding/Resources/icons/unlocked24.png b/Coding/Resources/icons/unlocked24.png new file mode 100644 index 0000000..59c4558 Binary files /dev/null and b/Coding/Resources/icons/unlocked24.png differ