commit d8e0f01af1f15dd7c24eacc431eee0cc1339e39a Author: 如果当时 <1017848709@qq.com> Date: Sat Nov 28 15:03:28 2020 +0800 初始备份。 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..758c1ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +Publish/ +Res/ +**/obj +*.pdb +**/dcu +*.dcu \ No newline at end of file diff --git a/Bin/Debug/CommonControls/.NET4 示例/Itrycn_Project.exe b/Bin/Debug/CommonControls/.NET4 示例/Itrycn_Project.exe new file mode 100644 index 0000000..fdb54d4 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/Itrycn_Project.exe differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/Itrycn_Project2.exe b/Bin/Debug/CommonControls/.NET4 示例/Itrycn_Project2.exe new file mode 100644 index 0000000..b42a4c1 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/Itrycn_Project2.exe differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/MyDb.dll b/Bin/Debug/CommonControls/.NET4 示例/MyDb.dll new file mode 100644 index 0000000..f87a598 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/MyDb.dll differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/MyDb_SQLite.dll b/Bin/Debug/CommonControls/.NET4 示例/MyDb_SQLite.dll new file mode 100644 index 0000000..14e223b Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/MyDb_SQLite.dll differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/RyPrint.dll b/Bin/Debug/CommonControls/.NET4 示例/RyPrint.dll new file mode 100644 index 0000000..eae4273 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/RyPrint.dll differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/RyWeb.dll b/Bin/Debug/CommonControls/.NET4 示例/RyWeb.dll new file mode 100644 index 0000000..423e97c Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/RyWeb.dll differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/System.Data.SQLite.dll b/Bin/Debug/CommonControls/.NET4 示例/System.Data.SQLite.dll new file mode 100644 index 0000000..e15c908 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/System.Data.SQLite.dll differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/UserDb/Win.dat b/Bin/Debug/CommonControls/.NET4 示例/UserDb/Win.dat new file mode 100644 index 0000000..72643e4 --- /dev/null +++ b/Bin/Debug/CommonControls/.NET4 示例/UserDb/Win.dat @@ -0,0 +1,2 @@ +[Money_Op] +hwnd=4533362 diff --git a/Bin/Debug/CommonControls/.NET4 示例/XPTable.dll b/Bin/Debug/CommonControls/.NET4 示例/XPTable.dll new file mode 100644 index 0000000..4ac2f2e Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/XPTable.dll differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/cUpdate.dat b/Bin/Debug/CommonControls/.NET4 示例/cUpdate.dat new file mode 100644 index 0000000..e16f597 --- /dev/null +++ b/Bin/Debug/CommonControls/.NET4 示例/cUpdate.dat @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Bin/Debug/CommonControls/.NET4 示例/ryControls.dll b/Bin/Debug/CommonControls/.NET4 示例/ryControls.dll new file mode 100644 index 0000000..7a4385b Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/ryControls.dll differ diff --git a/Bin/Debug/CommonControls/.NET4 示例/ryControls.xml b/Bin/Debug/CommonControls/.NET4 示例/ryControls.xml new file mode 100644 index 0000000..eb3c402 --- /dev/null +++ b/Bin/Debug/CommonControls/.NET4 示例/ryControls.xml @@ -0,0 +1,11247 @@ + + + + ryControls + + + + + 控件状态 + + + + + 无 + + + + + 获得焦点 + + + + + 失去焦点 + + + + + 鼠标指针进入控件 + + + + + Toolbar控件 + + + + + + + + + + + + + + + 获取或设置控件显示的图片 + + + + + 重写控件焦点属性 + + + + + 自定义绘制 + + + + + + 焦点进入 + + + + + + 失去焦点 + + + + + + 禁止调整大小 + + + + + + + + + + + + + + + + + + 只响应单击鼠标左键事件 + + + + + + 按比例缩放图片 + + + + + + + 图片缩放 + + 源图片 + 缩放图片的宽度 + 缩放图片的高度 + 缩放的图片 + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 绘图对像 + + 绘图对像 + 图片 + 绘置的图片大小、坐标 + 绘置的图片边界 + 当前状态 + 状态总数 + + + + 绘图对像 + + 绘图对像 + 图片对像 + 绘置的图片大小、坐标 + 当前状态 + 状态总数 + + + + + + + + + 得到要绘置的图片对像 + + 图像在程序集中的地址 + + + + + 得到要绘置的图片对像 + + 图像在程序集中的路径 + 图像在程序集中的地址 + + + + + 获取资源图标 + + + + + + + 得到图程序集中的图片对像 + + 图像在程序集中的地址 + + + + + 得到图程序集中的图片对像 + + 图像在程序集中的路径 + 图像在程序集中的地址 + + + + + 控件的状态。 + + + + + 正常 + + + + + 鼠标经过 + + + + + 鼠标按下 + + + + + 鼠标的当前位置 + + + + + + + + + + + + + + + + + + + + 美化按钮 + + + + + 普通按钮矩形位置 + + + + + 美化按钮 + + + + + 分割按钮的宽度 + + + + + 是否启用分割按钮 + + + + + 优先使用默认皮肤 + + + + + 按钮基础背景色 + + + + + 按钮字体颜色 + + + + + 图片宽度,默认值为18px,最小12px + + + + + 圆角的位置,默认全部都是圆角 + + + + + 设置圆角半径 + + + + + 背景色是否渐变 + + + + + 图片高度 + + + + + 图片与文字之间的间距 + + + + + 当鼠标按下时图片和文字是否产生偏移 + + + + + 鼠标进入时 + + + + + + 鼠标离开 + + + + + + 鼠标按下 + + + + + + 鼠标弹起 + + + + + + 鼠标当前所在位置 + + + + + 获取图像以及文字的位置 + + + + + + + + + + + + + + + + + + + + + + + + 添加菜单分隔线 + + + + + + 添加菜单 + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + RichTextBox + + + + + 在自带菜单弹出前激发 + + + + + 根据标签获得菜单项 + + + + + + + 只允许输入文本(只对设置之后的人工输入有效) + + + + + 按下按键 + + + + + + + + + + + + + + + + + + + + + + + + 鼠标按下 + + + + + + + + + + + + 当文本框为空时,显示的内容。 + + + + + 添加菜单分隔线 + + + + + + 添加菜单 + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + 消息列表控件 + + + + + 最大高度 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 建立圆角路径的样式。 + + + + + 四个角都不是圆角。 + + + + + 四个角都为圆角。 + + + + + 左边两个角为圆角。 + + + + + 右边两个角为圆角。 + + + + + 上边两个角为圆角。 + + + + + 下边两个角为圆角。 + + + + + 左下角为圆角。 + + + + + 右下角为圆角。 + + + + + 画图相关API + + + + + 建立带有圆角样式的路径。 + + 用来建立路径的矩形。 + 圆角的大小。 + 圆角的样式。 + 是否把矩形长宽减 1,以便画出边框。 + 建立的路径。 + + + + 窗体皮肤 + + + + + 窗体皮肤 + + + + + 标题属性 + + + + + 是否使用父窗口的图标 + + + + + 点击最小化按钮是最小化还是隐藏 + + + + + 最大化按钮 + + + + + 最小化按钮 + + + + + 标题栏关闭按钮是否显示 + + + + + 当窗口位于后台时,是否标注显示。 + + + + + + + + + + 标题栏字体颜色 + + + + + 标题栏不处于活动状态时的字体颜色 + + + + + 标题栏背景颜色 + + + + + 标题栏不处于活动状态时的背景颜色 + + + + + 是否允许拖拉窗体边缘来改变窗体大小 + + + + + + + + + + + 画边框 + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + 热键文本框 + + + + + 热键文本框 + + + + + 在控件大小变化时发生 + + + + + + 此属性无效 + + + + + 载入热键配置 + + + + + + 保存热键 + + + + + + 是否含义热键 + + + + + 读取或设置热键 + + + + + 功能键 + + + + + 热键按键 + + + + + KeyDown事件 + + + + + + KeyDown事件 + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 最大高度 + + + + + 标题 + + + + + 是否显示时间 + + + + + 添加时间 + + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 最大高度 + + + + + 标题 + + + + + 是否显示时间 + + + + + 添加时间 + + + + + 内容 + + + + + 网址 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 图标 + + + + + 标题 + + + + + 悬浮提示 + + + + + 标题颜色 + + + + + 设置按钮 + + + + + + + 判断和设置是否选择 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 绘制边框 + + 消息 + + + + 类说明:CContextMenuStrip控件的实现用来代替系统的ContextMenuStrip控件 + + + + + + + + + + + + + + + + 重写OnCreateControl + + + + + 重写OnPaint事件 + + + + + + CreateRoundedRectanglePath + + Rectangle + + + + + + 系统热键数据类。 + + + + + 系统热键数据类 + + + + + 使多行属性失效掉 + + + + + 使只读属性失效掉 + + + + + 获取热键文本 + + + + + 功能键 + + + + + 热键按键 + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 增强时间控件 + + + + + 增强时间控件 + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 选择文本框 + + + + + 选择文本框 + + + + + 按钮基础背景色 + + + + + 优先使用默认皮肤 + + + + + 选择的id + + + + + 选择的名称 + + + + + 选择的名称 + + + + + 字体 + + + + + 重新设置大小 + + + + + 在选择时激发 + + + + + 点击选择 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 可以改变文本行距(行间距)的Label + + + + + 行间距 + + + + + 可以改变文本行距(行间距)的Label + + + + + + + + + + 字体高度 + + + + + + + + + + 文本 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 计算两个日期的时间间隔,返回的是日期值+ + + 时间值,将显示在返回的值里 + 参照时间 + + + + + + + + + + + + + + + 控件边框颜色 + + + + + 控件背景颜色 + + + + + 圆角弧度大小 + + + + + 圆角风格 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + 在搜索时激发 + + + + + 文本变化时激发 + + + + + 文本变化时激发 + + + + + 双击时激发 + + + + + + + + + + + + + + + 文本为空时的显示效果 + + + + + 文本不选中 + + + + + 有内容时的显示效果 + + + + + 当文本框为空时,显示的内容。 + + + + + 字体 + + + + + 优先使用默认皮肤 + + + + + 按钮基础背景色 + + + + + + + + + + 重新设置大小 + + + + + 点击搜索按钮 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 使用公共皮肤 + + + + + 按钮颜色 + + + + + + + + + + + + + + + + + + + + + + + + + + + 皮肤公共类 + + + + + 是否使用默认皮肤 + + + + + 按钮皮肤 + + + + + 按钮皮肤类 + + + + + 背景颜色 + + + + + 字体颜色 + + + + + 类说明:帮助类 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 修改控件或窗体的边框,例如Textbox或是Form窗体 + + 消息 + 控件对象 + 边框像素 + 边框颜色 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 超级图片控件,支持加载工程内部图片、异步加载网络图片 + + + + + 超级图片控件,支持加载工程内部图片、异步加载网络图片 + + + + + 图片所在上级域名 + + + + + 图片资源所在上级文件夹 + + + + + 根据不同前缀,加载不同格式图片。i:表示工程内置图片;s:表示T_ImageDomain域名下的图片,u:表示指定url的图片;f:表示本地图片 + + + + + + 加载本地图片,加载完毕不会占用本地图片 + + + + + + 加载指定url图片 + + url位置 + 是否异步 + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 多标签控件 + + + + + + + + + + 选项发生变化时激发 + + + + + 标签选择的序号 + + + + + + + + + + 选择的颜色 + + + + + 多标签控件颜色 + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 多标签控件 + + + + + + + + + + 获取对应的标签 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 美化文本框控件 + + + + + 文本变化时激发 + + + + + 文本变化时激发 + + + + + 双击时激发 + + + + + + + + + + 是否只能输入数字 + + + + + 是否多行 + + + + + 是否在显示不下时换行 + + + + + 最大长度 + + + + + + + + + + 背景颜色 + + + + + 右键菜单 + + + + + 字体颜色 + + + + + 选择的开始位置 + + + + + 选择的长度 + + + + + 选择的文本 + + + + + 提示文本 + + + + + 选择全部 + + + + + 密码 + + + + + 是否只读 + + + + + + + + + + + 文本为空时的显示效果 + + + + + 字体 + + + + + 有内容时的显示效果 + + + + + 当文本框为空时,显示的内容。 + + + + + + + + + + 选择文本框中的文本范围 + + 文本框中当前选定文本的第一个字符的位置。 + 要选择的字符数 + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + Define some Windows message constants + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This class adds to the functionality provided in System.Windows.Forms.MenuStrip. + + It allows you to "ClickThrough" to the MenuStrip so that you don't have to click once to + bring the form into focus and once more to take the desired action + + It also implements a SuppressHighlighting property to turn off the highlighting + that occures on mouseover when the form is not active + + + + + Gets or sets whether the control honors item clicks when its containing form does + not have input focus. + + + Default value is false, which is the same behavior provided by the base ToolStrip class. + + + + + Gets or sets whether the control shows highlighting on mouseover + + + Default value is true, which is the same behavior provided by the base MenuStrip class. + + + + + This method overrides the procedure that responds to Windows messages. + + It intercepts the WM_MOUSEMOVE message + and ignores it if SuppressHighlighting is on and the TopLevelControl does not contain the focus. + Otherwise, it calls the base class procedure to handle the message. + + It also intercepts the WM_MOUSEACTIVATE message and replaces an "Activate and Eat" result with + an "Activate" result if ClickThrough is enabled. + + + + + + This class adds to the functionality provided in System.Windows.Forms.ToolStrip. + + It allows you to "ClickThrough" to the MenuStrip so that you don't have to click once to + bring the form into focus and once more to take the desired action + + It also implements a SuppressHighlighting property to turn off the highlighting + that occures on mouseover when the form is not active + + + + + Gets or sets whether the control honors item clicks when its containing form does + not have input focus. + + + Default value is false, which is the same behavior provided by the base ToolStrip class. + + + + + Gets or sets whether the control shows highlighting on mouseover + + + Default value is true, which is the same behavior provided by the base MenuStrip class. + + + + + This method overrides the procedure that responds to Windows messages. + + It intercepts the WM_MOUSEMOVE message + and ignores it if SuppressHighlighting is on and the TopLevelControl does not contain the focus. + Otherwise, it calls the base class procedure to handle the message. + + It also intercepts the WM_MOUSEACTIVATE message and replaces an "Activate and Eat" result with + an "Activate" result if ClickThrough is enabled. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 还原 + + + + + 移动 + + + + + 大小 + + + + + 最小化 + + + + + 最大化 + + + + + 关闭 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 透明图片控件 + + + + + 是否使用透明,默认为True + + + + + 设置透明度 + + + + + 要绑定的控件 + + + + + 透明图片控件 + + + + + 图片 + + + + + 初始化加载控件 + + 透明度 + 是否显示加载图片 + 图片 + + + + + + + + + + + + + + + 显示加载 + + + + + 隐藏加载 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 一个强类型的资源类,用于查找本地化的字符串等。 + + + + + 返回此类使用的缓存的 ResourceManager 实例。 + + + + + 使用此强类型资源类,为所有资源查找 + 重写当前线程的 CurrentUICulture 属性。 + + + + + 查找 System.Drawing.Bitmap 类型的本地化资源。 + + + + + 查找 System.Drawing.Bitmap 类型的本地化资源。 + + + + + + + + + + 获得当前进程,以便重绘控件 + + + + + + + 是否启用热点效果 + + + + + 边框颜色 + + + + + 热点边框颜色 + + + + + 是否鼠标MouseOver状态 + + + + + 是否启用热点效果 + + + + + 边框颜色 + + + + + 热点时边框颜色 + + + + + + + + + + 鼠标移动到该控件上时 + + + + + + 当鼠标从该控件移开时 + + + + + + 当该控件获得焦点时 + + + + + + 当该控件失去焦点时 + + + + + + 获得操作系统消息 + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 日控件 + + + + + 日控件 + + + + + 当前日期 + + + + + 在发生页码变化前激发 + + + + + 设置休息状态,1为休息,-1为上班,其它为不显示 + + + + + + 日期 + + + + + 农历 + + + + + 阳历日期字体颜色 + + + + + 阳历日期字体 + + + + + 农历日期字体 + + + + + 农历部分字体颜色 + + + + + 是否选中 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 日历控件 + + + + + 单击事件 + + + + + + + 单击某个日期事件 + + + + + 日历控件 + + + + + 设置日期 + + + + + 放假数据表 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 设置管理类,快速添加设置。 + + + + + 设置管理类,快速添加设置。 + + + + + 设置管理类,快速添加设置。 + + + + + + 存储类型 + + + + + 配置存储路径 + + + + + 设置XML内容 + + + + + 添加控件 + + + + + + + + 设置值 + + + + + + + + 添加控件 + + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 读取配置 + + + + + 保存配置 + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + 类 名:ColorHSL + 功 能:H 色相 \ S 饱和度(纯度) \ L 亮度 颜色模型 + 日 期:2015-02-08 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + HSL颜色 + + + + + + + + 色相 + + + + + 饱和度(纯度) + + + + + 饱和度 + + + + + 类 名:ColorHSV + 功 能:H 色相 \ S 饱和度(纯度) \ V 明度 颜色模型 + 日 期:2015-01-22 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + 构造方法 + + + + + + + + 色相 + + + + + 饱和度(纯度) + + + + + 明度 + + + + + 类 名:ColorRGB + 功 能:R 红色 \ G 绿色 \ B 蓝色 颜色模型 + 所有颜色模型的基类,RGB是用于输出到屏幕的颜色模式,所以所有模型都将转换成RGB输出 + 日 期:2015-01-22 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + 构造方法 + + + + + + + + + + + + + + 红色 + + + + + 绿色 + + + + + 蓝色 + + + + + 获取实际颜色 + + + + + + 类 名:ColorHelper + 功 能:提供从RGB到HSV/HSL色彩空间的相互转换 + 日 期:2015-02-08 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + RGB转换HSV + + + + + + + HSV转换RGB + + + + + + + RGB转换HSL + + + + + + + HSL转换RGB + + H, S and L input range = 0 -1.0 + + + + + RGB转CMYK + + + + + + + + + + RGB转CMYK + + + + + + + + + + + + CMYK转RGB + + + + + + + + + + Standard-RGB → XYZ,X、Y、Z 使用 D65/2°标准光源. + + + + + + + + + XYZ → Standard-RGB,X、Y、Z 使用 D65/2°标准光源. + + + + + + + + + XYZ → Adobe-RGB,X、Y、Z 使用 D65/2°标准光源.RGB Adobe 1998 + + + + + + + + + Adobe-RGB → XYZ,X、Y、Z 使用 D65/2°标准光源.RGB Adobe 1998 + + + + + + + + + Yxy转RGB + + + + + + + + + RGB转Yxy + + + + + + + + + 超级颜色选择控件 + + + + + + + + + + + + + + + + + + + + + + + + + + 获取网页颜色 + + + + + 超级颜色选择控件 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + Chrome风格的多标签控件 + + + + + 设置选项卡处于选中状态时第一背景色. + + + + + 设置选项卡处于选中状态时第二背景色. + + + + + 设置选项卡处于非选中状态时第一背景色. + + + + + 设置选项卡处于非选中状态时第二背景色. + + + + + 设置鼠标移动到非选中状态选项卡时第一背景色. + + + + + 设置鼠标移动到非选中状态选项卡时第二背景色. + + + + + 设置选项卡工作区背景色. + + + + + 设置选项卡工作区背景图. + + + + + 是否显示关闭按钮 + + + + + 是否显示新增按钮 + + + + + 是否允许拖拽标签 + + + + + 标签最大宽度 + + + + + 标签右键菜单 + + + + + 鼠标按下标签时激发 + + + + + 鼠标放开标签时激发 + + + + + Chrome风格的多标签控件 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 画标签文字 + + + + + + + + + 画标签图标 + + + + + + + 画关闭按钮 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 添加新标签 + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + The position is not over a tab. + + + + + The position is over a tab's icon. + + + + + The position is over a tab's text. + + + + + The position is over a tab but not over its icon or its text. For owner-drawn tab controls, this value is specified if the position is anywhere over a tab. + TCHT_ONITEM is a bitwise-OR operation on TCHT_ONITEMICON and TCHT_ONITEMLABEL. + + + + + Specifies values from SetWindowPosZ enumeration. + + + + + Specified HWND_TOP enumeration value. + + + + + Specified HWND_BOTTOM enumeration value. + + + + + Specified HWND_TOPMOST enumeration value. + + + + + Specified HWND_NOTOPMOST enumeration value. + + + + + Invalidates the rectangle or region that you specify in lprcUpdate or hrgnUpdate. + You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_INVALIDATE invalidates the entire window. + + + + Causes the OS to post a WM_PAINT message to the window regardless of whether a portion of the window is invalid. + + + + Causes the window to receive a WM_ERASEBKGND message when the window is repainted. + Specify this value in combination with the RDW_INVALIDATE value; otherwise, RDW_ERASE has no effect. + + + + + Validates the rectangle or region that you specify in lprcUpdate or hrgnUpdate. + You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_VALIDATE validates the entire window. + This value does not affect internal WM_PAINT messages. + + + + Suppresses any pending WM_ERASEBKGND messages. + + + Excludes child windows, if any, from the repainting operation. + + + Includes child windows, if any, in the repainting operation. + + + Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values, to receive WM_ERASEBKGND and WM_PAINT messages before the RedrawWindow returns, if necessary. + + + + Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values, to receive WM_ERASEBKGND messages before RedrawWindow returns, if necessary. + The affected windows receive WM_PAINT messages at the ordinary time. + + + + + Specifies values from Msgs enumeration. + + + + + Specified WM_NULL enumeration value. + + + + + Specified WM_CREATE enumeration value. + + + + + Specified WM_DESTROY enumeration value. + + + + + Specified WM_MOVE enumeration value. + + + + + Specified WM_SIZE enumeration value. + + + + + Specified WM_ACTIVATE enumeration value. + + + + + Specified WM_SETFOCUS enumeration value. + + + + + Specified WM_KILLFOCUS enumeration value. + + + + + Specified WM_ENABLE enumeration value. + + + + + Specified WM_SETREDRAW enumeration value. + + + + + Specified WM_SETTEXT enumeration value. + + + + + Specified WM_GETTEXT enumeration value. + + + + + Specified WM_GETTEXTLENGTH enumeration value. + + + + + Specified WM_PAINT enumeration value. + + + + + Specified WM_CLOSE enumeration value. + + + + + Specified WM_QUERYENDSESSION enumeration value. + + + + + Specified WM_QUIT enumeration value. + + + + + Specified WM_QUERYOPEN enumeration value. + + + + + Specified WM_ERASEBKGND enumeration value. + + + + + Specified WM_SYSCOLORCHANGE enumeration value. + + + + + Specified WM_ENDSESSION enumeration value. + + + + + Specified WM_SHOWWINDOW enumeration value. + + + + + Specified WM_WININICHANGE enumeration value. + + + + + Specified WM_SETTINGCHANGE enumeration value. + + + + + Specified WM_DEVMODECHANGE enumeration value. + + + + + Specified WM_ACTIVATEAPP enumeration value. + + + + + Specified WM_FONTCHANGE enumeration value. + + + + + Specified WM_TIMECHANGE enumeration value. + + + + + Specified WM_CANCELMODE enumeration value. + + + + + Specified WM_SETCURSOR enumeration value. + + + + + Specified WM_MOUSEACTIVATE enumeration value. + + + + + Specified WM_CHILDACTIVATE enumeration value. + + + + + Specified WM_QUEUESYNC enumeration value. + + + + + Specified WM_GETMINMAXINFO enumeration value. + + + + + Specified WM_PAINTICON enumeration value. + + + + + Specified WM_ICONERASEBKGND enumeration value. + + + + + Specified WM_NEXTDLGCTL enumeration value. + + + + + Specified WM_SPOOLERSTATUS enumeration value. + + + + + Specified WM_DRAWITEM enumeration value. + + + + + Specified WM_MEASUREITEM enumeration value. + + + + + Specified WM_DELETEITEM enumeration value. + + + + + Specified WM_VKEYTOITEM enumeration value. + + + + + Specified WM_CHARTOITEM enumeration value. + + + + + Specified WM_SETFONT enumeration value. + + + + + Specified WM_GETFONT enumeration value. + + + + + Specified WM_SETHOTKEY enumeration value. + + + + + Specified WM_GETHOTKEY enumeration value. + + + + + Specified WM_QUERYDRAGICON enumeration value. + + + + + Specified WM_COMPAREITEM enumeration value. + + + + + Specified WM_GETOBJECT enumeration value. + + + + + Specified WM_COMPACTING enumeration value. + + + + + Specified WM_COMMNOTIFY enumeration value. + + + + + Specified WM_WINDOWPOSCHANGING enumeration value. + + + + + Specified WM_WINDOWPOSCHANGED enumeration value. + + + + + Specified WM_POWER enumeration value. + + + + + Specified WM_COPYDATA enumeration value. + + + + + Specified WM_CANCELJOURNAL enumeration value. + + + + + Specified WM_NOTIFY enumeration value. + + + + + Specified WM_INPUTLANGCHANGEREQUEST enumeration value. + + + + + Specified WM_INPUTLANGCHANGE enumeration value. + + + + + Specified WM_TCARD enumeration value. + + + + + Specified WM_HELP enumeration value. + + + + + Specified WM_USERCHANGED enumeration value. + + + + + Specified WM_NOTIFYFORMAT enumeration value. + + + + + Specified WM_CONTEXTMENU enumeration value. + + + + + Specified WM_STYLECHANGING enumeration value. + + + + + Specified WM_STYLECHANGED enumeration value. + + + + + Specified WM_DISPLAYCHANGE enumeration value. + + + + + Specified WM_GETICON enumeration value. + + + + + Specified WM_SETICON enumeration value. + + + + + Specified WM_NCCREATE enumeration value. + + + + + Specified VK_RMENU enumeration value. + + + + + Specified WM_NCCALCSIZE enumeration value. + + + + + Specified WM_NCHITTEST enumeration value. + + + + + Specified WM_NCPAINT enumeration value. + + + + + Specified WM_NCACTIVATE enumeration value. + + + + + Specified WM_GETDLGCODE enumeration value. + + + + + Specified WM_SYNCPAINT enumeration value. + + + + + Specified WM_NCMOUSEMOVE enumeration value. + + + + + Specified WM_NCLBUTTONDOWN enumeration value. + + + + + Specified WM_NCLBUTTONUP enumeration value. + + + + + Specified WM_NCLBUTTONDBLCLK enumeration value. + + + + + Specified WM_NCRBUTTONDOWN enumeration value. + + + + + Specified WM_NCRBUTTONUP enumeration value. + + + + + Specified WM_NCRBUTTONDBLCLK enumeration value. + + + + + Specified WM_NCMBUTTONDOWN enumeration value. + + + + + Specified WM_NCMBUTTONUP enumeration value. + + + + + Specified WM_NCMBUTTONDBLCLK enumeration value. + + + + + Specified WM_NCXBUTTONDOWN enumeration value. + + + + + Specified WM_NCXBUTTONUP enumeration value. + + + + + Specified WM_KEYDOWN enumeration value. + + + + + Specified WM_KEYUP enumeration value. + + + + + Specified WM_CHAR enumeration value. + + + + + Specified WM_DEADCHAR enumeration value. + + + + + Specified WM_SYSKEYDOWN enumeration value. + + + + + Specified WM_SYSKEYUP enumeration value. + + + + + Specified WM_SYSCHAR enumeration value. + + + + + Specified WM_SYSDEADCHAR enumeration value. + + + + + Specified WM_KEYLAST enumeration value. + + + + + Specified WM_IME_STARTCOMPOSITION enumeration value. + + + + + Specified WM_IME_ENDCOMPOSITION enumeration value. + + + + + Specified WM_IME_COMPOSITION enumeration value. + + + + + Specified WM_IME_KEYLAST enumeration value. + + + + + Specified WM_INITDIALOG enumeration value. + + + + + Specified WM_COMMAND enumeration value. + + + + + Specified WM_SYSCOMMAND enumeration value. + + + + + Specified WM_TIMER enumeration value. + + + + + Specified WM_HSCROLL enumeration value. + + + + + Specified WM_VSCROLL enumeration value. + + + + + Specified WM_INITMENU enumeration value. + + + + + Specified WM_INITMENUPOPUP enumeration value. + + + + + Specified WM_MENUSELECT enumeration value. + + + + + Specified WM_MENUCHAR enumeration value. + + + + + Specified WM_ENTERIDLE enumeration value. + + + + + Specified WM_MENURBUTTONUP enumeration value. + + + + + Specified WM_MENUDRAG enumeration value. + + + + + Specified WM_MENUGETOBJECT enumeration value. + + + + + Specified WM_UNINITMENUPOPUP enumeration value. + + + + + Specified WM_MENUCOMMAND enumeration value. + + + + + Specified WM_CTLCOLORMSGBOX enumeration value. + + + + + Specified WM_CTLCOLOREDIT enumeration value. + + + + + Specified WM_CTLCOLORLISTBOX enumeration value. + + + + + Specified WM_CTLCOLORBTN enumeration value. + + + + + Specified WM_CTLCOLORDLG enumeration value. + + + + + Specified WM_CTLCOLORSCROLLBAR enumeration value. + + + + + Specified WM_CTLCOLORSTATIC enumeration value. + + + + + Specified WM_MOUSEMOVE enumeration value. + + + + + Specified WM_LBUTTONDOWN enumeration value. + + + + + Specified WM_LBUTTONUP enumeration value. + + + + + Specified WM_LBUTTONDBLCLK enumeration value. + + + + + Specified WM_RBUTTONDOWN enumeration value. + + + + + Specified WM_RBUTTONUP enumeration value. + + + + + Specified WM_RBUTTONDBLCLK enumeration value. + + + + + Specified WM_MBUTTONDOWN enumeration value. + + + + + Specified WM_MBUTTONUP enumeration value. + + + + + Specified WM_MBUTTONDBLCLK enumeration value. + + + + + Specified WM_MOUSEWHEEL enumeration value. + + + + + Specified WM_XBUTTONDOWN enumeration value. + + + + + Specified WM_XBUTTONUP enumeration value. + + + + + Specified WM_XBUTTONDBLCLK enumeration value. + + + + + Specified WM_PARENTNOTIFY enumeration value. + + + + + Specified WM_ENTERMENULOOP enumeration value. + + + + + Specified WM_EXITMENULOOP enumeration value. + + + + + Specified WM_NEXTMENU enumeration value. + + + + + Specified WM_SIZING enumeration value. + + + + + Specified WM_CAPTURECHANGED enumeration value. + + + + + Specified WM_MOVING enumeration value. + + + + + Specified WM_DEVICECHANGE enumeration value. + + + + + Specified WM_MDICREATE enumeration value. + + + + + Specified WM_MDIDESTROY enumeration value. + + + + + Specified WM_MDIACTIVATE enumeration value. + + + + + Specified WM_MDIRESTORE enumeration value. + + + + + Specified WM_MDINEXT enumeration value. + + + + + Specified WM_MDIMAXIMIZE enumeration value. + + + + + Specified WM_MDITILE enumeration value. + + + + + Specified WM_MDICASCADE enumeration value. + + + + + Specified WM_MDIICONARRANGE enumeration value. + + + + + Specified WM_MDIGETACTIVE enumeration value. + + + + + Specified WM_MDISETMENU enumeration value. + + + + + Specified WM_ENTERSIZEMOVE enumeration value. + + + + + Specified WM_EXITSIZEMOVE enumeration value. + + + + + Specified WM_DROPFILES enumeration value. + + + + + Specified WM_MDIREFRESHMENU enumeration value. + + + + + Specified WM_IME_SETCONTEXT enumeration value. + + + + + Specified WM_IME_NOTIFY enumeration value. + + + + + Specified WM_IME_CONTROL enumeration value. + + + + + Specified WM_IME_COMPOSITIONFULL enumeration value. + + + + + Specified WM_IME_SELECT enumeration value. + + + + + Specified WM_IME_CHAR enumeration value. + + + + + Specified WM_IME_REQUEST enumeration value. + + + + + Specified WM_IME_KEYDOWN enumeration value. + + + + + Specified WM_IME_KEYUP enumeration value. + + + + + Specified WM_MOUSEHOVER enumeration value. + + + + + Specified WM_UNDO enumeration value. + + + + + Specified WM_RENDERFORMAT enumeration value. + + + + + Specified WM_RENDERALLFORMATS enumeration value. + + + + + Specified WM_DESTROYCLIPBOARD enumeration value. + + + + + Specified WM_DRAWCLIPBOARD enumeration value. + + + + + Specified WM_PAINTCLIPBOARD enumeration value. + + + + + Specified WM_VSCROLLCLIPBOARD enumeration value. + + + + + Specified WM_SIZECLIPBOARD enumeration value. + + + + + Specified WM_ASKCBFORMATNAME enumeration value. + + + + + Specified WM_CHANGECBCHAIN enumeration value. + + + + + Specified WM_HSCROLLCLIPBOARD enumeration value. + + + + + Specified WM_QUERYNEWPALETTE enumeration value. + + + + + Specified WM_PALETTEISCHANGING enumeration value. + + + + + Specified WM_PALETTECHANGED enumeration value. + + + + + Specified WM_HOTKEY enumeration value. + + + + + Specified WM_PRINT enumeration value. + + + + + Specified WM_PRINTCLIENT enumeration value. + + + + + Specified WM_HANDHELDFIRST enumeration value. + + + + + Specified WM_HANDHELDLAST enumeration value. + + + + + Specified WM_AFXFIRST enumeration value. + + + + + Specified WM_AFXLAST enumeration value. + + + + + Specified WM_PENWINFIRST enumeration value. + + + + + Specified WM_PENWINLAST enumeration value. + + + + + Specified WM_APP enumeration value. + + + + + Specified WM_USER enumeration value. + + + + + Specified WM_REFLECT enumeration value. + + + + + Specified WM_THEMECHANGED enumeration value. + + + + + The GetParent function retrieves a handle to the specified window's parent or owner. + + Handle to the window whose parent window handle is to be retrieved. + If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is a handle to the owner window. If the window is a top-level unowned window or if the function fails, the return value is NULL. + + + + The FindWindowEx function retrieves a handle to a window whose class name and window name match the specified strings. The function searches child windows, beginning with the one following the specified child window. + + Handle to the parent window whose child windows are to be searched. + Handle to a child window. + Specifies class name. + Pointer to a null-terminated string that specifies the window name (the window's title). + If the function succeeds, the return value is a handle to the window that has the specified class and window names.If the function fails, the return value is NULL. + + + + The InvalidateRect function adds a rectangle to the specified window's update region. + + Handle to window. + Rectangle coordinates. + Erase state. + If the function succeeds, the return value is true.If the function fails, the return value is false. + + + + The ValidateRect function validates the client area within a rectangle by removing the rectangle from the update region of the specified window. + + Handle to window. + Validation rectangle coordinates. + If the function succeeds, the return value is true.If the function fails, the return value is false. + + + + Changes the size, position, and Z order of a child, pop-up, or top-level window. + These windows are ordered according to their appearance on the screen. + The topmost window receives the highest rank and is the first window in the Z order. + + A handle to the window. + A handle to the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values. + Specifies the new position of the left side of the window, in client coordinates. + Specifies the new position of the top of the window, in client coordinates. + Specifies the new width of the window, in pixels. + Specifies the new height of the window, in pixels. + Specifies the window sizing and positioning flags. This parameter can be a combination of the following values. + If the function succeeds, the return value is nonzero, if the function fails, the return value is zero. + + + + + + + + + 关键词 + + + + + 密码 + + + + + 权限用户id + + + + + + + + + + + + + 返回关键词 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 树形控件,用于分类用 + + + + + 显示在第一位的名称 + + + + + 是否显示菜单 + + + + + 树形控件 + + + + + 判断指定节点是否是目标节点的子节点 + + + + + + + + + 判断当前节点,当前用户是否有权限访问 + + + + + + + + + 权限事件 + + + + + + + + 选择权限用户时发生 + + + + + 数据变化时发生 + + + + + 数据变化前发生 + + + + + 操作事件 + + + + + + + 在添加分组前发生 + + + + + 在修改分组前发生 + + + + + 在删除分组前发生 + + + + + 在设置密码前发生 + + + + + 在设置权限前发生 + + + + + 获取新的关键词分类 + + + + + + 根据id获取节点 + + + + + + + 根据节点获取节点信息 + + + + + + + 设置节点信息 + + + + + + + 设置节点关键词和密码 + + + + + + + + 设置节点密码 + + + + + + + 设置节点关键词 + + + + + + + 设置节点用户 + + + + + + + RecursionTreeControl:表示将XML文件的内容显示在TreeView控件中 + + 将要加载的XML文件中的节点元素 + 将要加载的XML文件中的节点集合 + + + + 把XML文本载入到列表中 + + + + + + 把XML文件载入到列表中 + + + + + + 将列表保存为xml文本 + + + + + + 改变所有子节点的状态 + + + + + + + 反选子节点 + + + + + + 根据关键词来选中列表 + + + + + + 根据关键词来选中列表 + + + + + + 格式化关键字(会去除重复项),以便存入数据库 + + + + + + + 去除掉重复项 + + + + + + + 获取当前选中项以及所有父项的关键词组合 + + + + + + 获取选中的 + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + 是否为添加 + + + + + 选择的文本 + + + + + 选择的Tag + + + + + 选择的图片序号 + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + + + + + + + + + + + 旧密码 + + + + + 新密码 + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + 颜色标签 + + + + + 行间距 + + + + + 颜色标签 + + + + + 更新 + + + + + 字体高度 + + + + + 控件高 + + + + + 控件文本 + + + + + 获取过滤掉颜色的字 + + + + + + + 改变字体 + + + + + + + + + + + + + + 分页控件 + + + + + 首页文本 + + + + + 上一页文本 + + + + + 下一页文本 + + + + + 末页文本 + + + + + 跳页文本 + + + + + 页面信息文本 + + + + + 存储SQL参数 + + + + + 最后一页的页码 + + + + + 在发生页码变化时激发 + + + + + 在发生页码变化前激发 + + + + + 设置/返回每页显示的量大小 + + + + + 设置/返回记录总数 + + + + + 设置/返回分页SQL语句,{pagecount}表示页数,{recordcount}表示记录总数,{pagesize}表示页面大小, + {pageindex}表示当前页数,{recordnum}表示当前页记录数,{pageendnum}表示当前页最后一条记录的记录数 + + + + + 设置/返回当{recordnum}小于等于0时的分页SQL语句(比如第一页),如果为空,则默认使用SQLText值。{pagecount}表示页数, + {recordcount}表示记录总数,{pagesize}表示页面大小,{pageindex}表示当前页数,{recordnum}表示当前页记录数,{pageendnum}表示当前页最后一条记录的记录数 + + + + + 获取当前页码 + + + + + + 设置分页语句为MSSQL分页语句 + + 表名 + 条件判断sql语句,注意不包含where,以及不包含排序语句;,如果不存在条件判断语句,请为空 + 排序语句,必须包含Order By;,如果不存在排序语句,请为空 + + + + + 获取MSSQL数据库指定条件的记录总数 + + 表名 + 条件判断sql语句,注意不包含where,以及不包含排序语句;,如果不存在条件判断语句,请为空 + 排序语句,必须包含Order By;,如果不存在排序语句,请为空 + + + + + 设置分页语句为SQLite分页语句 + + 表名 + 条件判断sql语句,注意不包含where,可包含order by,如果不存在条件判断语句,请为空 + + + + + 获取SQLite数据库指定条件的记录总数 + + 表名 + 条件判断sql语句,注意不包含where,可包含order by,如果不存在条件判断语句,请为空 + + + + + 返回分页SQL语句 + + + + + 分页控件 + + + + + 设置当前页为指定页 + + + + + + 下一页 + + + + + 上一页 + + + + + 末页 + + + + + 首页 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 自动排列控件 + + + + + 最大列数 + + + + + 开始排列的坐标 + + + + + 下一项的位置 + + + + + 下一项的右下角坐标 + + + + + 竖向间隔像素 + + + + + 横向间隔像素 + + + + + 最小保留右边距,只对ReDraw2有效 + + + + + 自动排列控件构造函数 + + + + + + 自动排列控件构造函数 + + + + + + + + 开始排列控件 + + + + + 开始排列控件,当列数超过显示空间时,自动换行 + + + + + 加入的控件列表 + + + + + 初始化添加,自动将容器设置为滚动条自动显示 + + + + + + 添加控件 + + + + + + + 删除控件 + + + + + + 删除控件 + + + + + + 清空所有控件 + + + + + An object list displays 'aspects' of a collection of objects in a listview control. + + + + The intelligence for this control is in the columns. OLVColumns are + extended so they understand how to fetch an 'aspect' from each row + object. They also understand how to sort by their aspect, and + how to group them. + + + Aspects are extracted by giving the name of a method to be called or a + property to be fetched. These names can be simple names or they can be dotted + to chain property access e.g. "Owner.Address.Postcode". + Aspects can also be extracted by installing a delegate. + + + Sorting by column clicking and grouping by column are handled automatically. + + + Right clicking on the column header should present a popup menu that allows the user to + choose which columns will be visible in the list. This behaviour can be disabled by + setting SelectColumnsOnRightClick to false. + + + This list puts sort indicators in the column headers to show the column sorting direction. + On Windows XP and later, the system standard images are used. + If you wish to replace the standard images with your own images, put entries in the small image list + with the key values "sort-indicator-up" and "sort-indicator-down". + + + For these classes to build correctly, the project must have references to these assemblies: + + System.Data + System.Design + System.Drawing + System.Windows.Forms (obviously) + + + + + + + Create an ObjectListView + + + + + Get or set all the columns that this control knows about. + Only those columns where IsVisible is true will be seen by the user. + + If you want to add new columns programmatically, add them to + AllColumns and then call RebuildColumns(). Normally, you do not have to + deal with this property directly. Just use the IDE. + + + + If every second row has a background different to the control, what color should it be? + + + + + Return the alternate row background color that has been set, or the default color + + + + + This property forces the ObjectListView to always group items by the given column. + + + + + If AlwaysGroupByColumn is not null, this property will be used to decide how + those groups are sorted. If this property has the value SortOrder.None, then + the sort order will toggle according to the users last header click. + + + + + Give access to the image list that is actually being used by the control + + + + + How does a user indicate that they want to edit cells? + + + + + This list cannot be edited. F2 does nothing. + + + + + A single click on a subitem will edit the value. Single clicking the primary column, + selects the row just like normal. The user must press F2 to edit the primary column. + + + + + Double clicking a subitem or the primary column will edit that cell. + F2 will edit the primary column. + + + + + Pressing F2 is the only way to edit the cells. Once the primary column is being edited, + the other cells in the row can be edited by pressing Tab. + + + + + How does the user indicate that they want to edit a cell? + None means that the listview cannot be edited. + + Columns can also be marked as editable. + + + + Return the model object of the row that is checked or null if no row is checked + or more than one row is checked + + + + + Get or set the collection of model objects that are checked. + When setting this property, any row whose model object isn't + in the given collection will be unchecked. Setting to null is + equivilent to unchecking all. + + + + This property returns a simple collection. Changes made to the returned + collection do NOT affect the list. This is different to the behaviour of + CheckedIndicies collection. + + + The CheckedItems property is not helpful. It is just a short-hand for + iterating through the list looking for items that are checked. + + + The performance of this method is O(n). Be careful on long lists. + + + + + + Get/set the list of columns that should be used when the list switches to tile view. + + If no list of columns has been installed, this value will default to the + first column plus any column where IsTileViewColumn is true. + + + + Return the visible columns in the order they are displayed to the user + + + + + If there are no items in this list view, what message should be drawn onto the control? + + + + + What font should the 'list empty' message be drawn in? + + + + + Return the font for the 'list empty' message or a default + + + + + Get or set whether or not the listview is frozen. When the listview is + frozen, it will not update itself. + + The Frozen property is similar to the methods Freeze()/Unfreeze() + except that changes to the Frozen property do not nest. + objectListView1.Frozen = false; // unfreeze the control regardless of the number of Freeze() calls + + + + + When a group title has an item count, how should the lable be formatted? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group + + + "{0} [{1} items]" + + + + Return this.GroupWithItemCountFormat or a reasonable default + + + + + When a group title has an item count, how should the lable be formatted if + there is only one item in the group? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group (always 1) + + + "{0} [{1} item]" + + + + Return this.GroupWithItemCountSingularFormat or a reasonable default + + + + + Does this listview have a message that should be drawn when the list is empty? + + + + + What color should be used for the background of selected rows? + + Windows does not give the option of changing the selection background. + So this color is only used when control is owner drawn and when columns have a + renderer installed -- a basic new BaseRenderer() will suffice. + + + + Return the color should be used for the background of selected rows or a reasonable default + + + + + Setup the list so it will draw selected rows using custom colours. + + + This method makes the list owner drawn, and ensures that all columns have at + least a BaseRender installed. + + + + + What color should be used for the foreground of selected rows? + + Windows does not give the option of changing the selection foreground (text color). + So this color is only used when control is owner drawn and when columns have a + renderer installed -- a basic new BaseRenderer() will suffice. + + + + Return the color should be used for the foreground of selected rows or a reasonable default + + + + + Return true if a cell edit operation is currently happening + + + + + Get/set the collection of objects that this list will show + + The contents of the control will be updated immediately after setting this property + + + + Take ownership of the 'objects' collection. This separats our collection from the source. + + + + This method + separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject + calls will modify our collection and not the original colleciton. + + + This method has the intentional side-effect of converting our list of objects to an ArrayList. + + + + + + Specify the height of each row in the control in pixels. + + The row height in a listview is normally determined by the font size and the small image list size. + This setting allows that calculation to be overridden (within reason: you still cannot set the line height to be + less than the line height of the font used in the control). + Setting it to -1 means use the normal calculation method. + This feature is experiemental! Strange things may happen to your program, + your spouse or your pet if you use it. + + + + + Get/set the column that will be used to resolve comparisons that are equal when sorting. + + There is no user interface for this setting. It must be set programmatically. + The default is the first column. + + + + When the SecondarySortColumn is used, in what order will it compare results? + + + + + When the user right clicks on the column headers, should a menu be presented which will allow + them to choose which columns will be shown in the view? + + + + + When the column select menu is open, should it stay open after an item is selected? + Staying open allows the user to turn more than one column on or off at a time. + + + + + Return the index of the row that is currently selected. If no row is selected, + or more than one is selected, return -1. + + + + + Get the ListViewItem that is currently selected . If no row is selected, or more than one is selected, return null. + + + + + Get the model object from the currently selected row. If no row is selected, or more than one is selected, return null. + Select the row that is displaying the given model object. All other rows are deselected. + + + + + Get the model objects from the currently selected rows. If no row is selected, the returned List will be empty. + When setting this value, select the rows that is displaying the given model objects. All other rows are deselected. + + + + + Should the list view show a bitmap in the column header to show the sort direction? + + + The only reason for not wanting to have sort indicators is that, on pre-XP versions of + Windows, having sort indicators required the ListView to have a small image list, and + as soon as you give a ListView a SmallImageList, the text of column 0 is bumped 16 + pixels to the right, even if you never used an image. + + + + + Should the list view show images on subitems? + + + Under Windows, this works by sending messages to the underlying + Windows control. To make this work under Mono, we would have to owner drawing the items :-( + + + + This property controls whether group labels will be suffixed with a count of items. + + + The format of the suffix is controlled by GroupWithItemCountFormat/GroupWithItemCountSingularFormat properties + + + + + Override the SmallImageList property so we can correctly shadow its operations. + + If you use the RowHeight property to specify the row height, the SmallImageList + must be fully initialised before setting/changing the RowHeight. If you add new images to the image + list after setting the RowHeight, you must assign the imagelist to the control again. Something as simple + as this will work: + listView1.SmallImageList = listView1.SmallImageList; + + + + + When the listview is grouped, should the items be sorted by the primary column? + If this is false, the items will be sorted by the same column as they are grouped. + + + + + When resizing a column by dragging its divider, should any space filling columns be + resized at each mouse move? If this is false, the filling columns will be + updated when the mouse is released. + + + I think that this looks very ugly, but it does give more immediate feedback. + It looks ugly because every + column to the right of the divider being dragged gets updated twice: once when + the column be resized changes size (this moves + all the columns slightly to the right); then again when the filling columns are updated, but they will be shrunk + so that the combined width is not more than the control, so everything jumps slightly back to the left again. + + + + + Should the list give a different background color to every second row? + + The color of the alternate rows is given by AlternateRowBackColor. + There is a "feature" in .NET for listviews in non-full-row-select mode, where + selected rows are not drawn with their correct background color. + + + + Get/set the style of view that this listview is using + + Switching to tile or details view installs the columns appropriate to that view. + Confusingly, in tile view, every column is shown as a row of information. + + + + This delegate can be used to sort the table in a custom fasion. + + + + What the delegate has to do depends on the type of ObjectListView it is sorting: + + + + If it is sorting a normal ObjectListView, the delegate must install a ListViewItemSorter on the ObjectListView. This install ItemSorter will actually do the work of sorting the ListViewItems. See ColumnComparer in the code for an example of what an ItemSorter has to do. + + + If the delegate is sorting a VirtualObjectListView or a FastObjectListView, the delegate must sort the model objects that are sourcing the list (remember, in a virtual list, the application holds the model objects and the list just askes for them as it needs them). + + + + + + + This delegate can be used to format a OLVListItem before it is added to the control. + + + The model object for the row can be found through the RowObject property of the OLVListItem object. + All subitems normally have the same style as list item, so setting the forecolor on one + subitem changes the forecolor of all subitems. + To allow subitems to have different attributes, do this:myListViewItem.UseItemStyleForSubItems = false;. + + If UseAlternatingBackColors is true, the backcolor of the listitem will be calculated + by the control and cannot be controlled by the RowFormatter delegate. In general, trying to use a RowFormatter + when UseAlternatingBackColors is true does not work well. + + + + This delegate will be called whenever the ObjectListView needs to know the check state + of the row associated with a given model object + + + + + This delegate will be called whenever the user tries to change the check state + of a row. The delegate should return the value that the listview should actuall + use, which may be different to the one given to the delegate. + + + + + Set the collection of objects that will be shown in this list view. + + This method can safely be called from background threads. + The list is updated immediately + The objects to be displayed + + + + Add the given model object to this control. + + The model object to be displayed + See AddObjects() for more details + + + + Add the given collection of model objects to this control. + + A collection of model objects + + The added objects will appear in their correct sort position, if sorting + is active. Otherwise, they will appear at the end of the list. + No check is performed to see if any of the objects are already in the ListView. + The method uses the ObjectsAsList property. See that property for a + description of what is does. + Null objects are silently ignored. + + + + + Remove the given model object from the ListView + + The model to be removed + See RemoveObjects() for more details + + + + Remove all of the given objects from the control + + Collection of objects to be removed + + Nulls and model objects that are not in the ListView are silently ignored. + + + + + Update the list to reflect the contents of the given collection, without affecting + the scrolling position, selection or sort order. + + The objects to be displayed + + This method is about twice as slow as SetObjects(). + This method is experimental -- it may disappear in later versions of the code. + There has to be a better way to do this! JPP 15/1/2008 + In most situations, if you need this functionality, use a FastObjectListView instead. JPP 2/2/2008 + + + + + Remove all items from this list + + This method can safely be called from background threads. + + + + Build/rebuild all the list view items in the list + + + + + Build/rebuild all the list view items in the list + + If this is true, the control will try to preserve the selection + and the scroll position (see Remarks) + + + + Use this method in situations were the contents of the list is basically the same + as previously. + + + Due to limitations in .NET's ListView, the scroll position is only preserved if + the control is in Details view AND it is not showing groups. + + + + + + Get or set the index of the top item of this listview + + + + This property only works when the listview is in Details view and not showing groups. + + + The reason that it does not work when showing groups is that, when groups are enabled, + the Windows message LVM_GETTOPINDEX always returns 0, regardless of the + scroll position. + + + + + + Sort the items by the last sort column + + + + + Organise the view items into groups, based on the last sort column or the first column + if there is no last sort column + + + + + Organise the view items into groups, based on the given column + + If the AlwaysGroupByColumn property is not null, + the list view items will be organisd by that column, + and the 'column' parameter will be ignored. + The column whose values should be used for sorting. + + + + Pause (or unpause) all animations in the list + + true to pause, false to unpause + + + + Give the listview a reasonable size of its tiles, based on the number of lines of + information that each tile is going to display. + + + + + Rebuild this list for the given view + + + + + + Rebuild the columns based upon its current view and column visibility settings + + + + + Copy a text and html representation of the selected rows onto the clipboard. + + Be careful when using this with virtual lists. If the user has selected + 10,000,000 rows, this method will faithfully try to copy all of them to the clipboard. + From the user's point of view, your program will appear to have hung. + + + + Copy a text and html representation of the given objects onto the clipboard. + + + + + Convert the fragment of HTML into the Clipboards HTML format. + + The HTML format is found here http://msdn2.microsoft.com/en-us/library/aa767917.aspx + + The HTML to put onto the clipboard. It must be valid HTML! + A string that can be put onto the clipboard and will be recognized as HTML + + + + Return a byte array that represents the current state of the ObjectListView, such + that the state can be restored by RestoreState() + + + The state of an ObjectListView includes the attributes that the user can modify: + + current view (i.e. Details, Tile, Large Icon...) + sort column and direction + column order + column widths + column visibility + + + + It does not include selection or the scroll position. + + + A byte array representing the state of the ObjectListView + + + + Restore the state of the control from the given string, which must have been + produced by SaveState() + + A byte array returned from SaveState() + Returns true if the state was restored + + + + Instances of this class are used to store the state of an ObjectListView. + + + + + Event handler for the column click event + + + + + Handle when a user checks/unchecks a row + + + + + Override the basic message pump for this control + + + + + + Perform any steps needed before painting the control + + + + + Perform any steps needed after painting the control + + + + + When the control is created capture the messages for the header. + + + + + Class used to capture window messages for the header of the list view + control. + + We only need this class in order to not change the cursor + when the cursor is over the divider of a fixed width column. It + really is a little too perfectionist even for me. + + + + Return the Windows handle behind this control + + + When an ObjectListView is initialized as part of a UserControl, the + GetHeaderControl() method returns 0 until the UserControl is + completely initialized. So the AssignHandle() call in the constructor + doesn't work. So we override the Handle property so value is always + current. + + + + + Return the index of the column under the current cursor position, + or -1 if the cursor is not over a column + + Index of the column under the cursor, or -1 + + + + The user wants to see the context menu. + + The windows message + A bool indicating if this message has been handled + + We want to ignore context menu requests that are triggered by right clicks on the header + + + + + In the notification messages, we handle attempts to change the width of our columns + + The msg to be processed + bool to indicate if the msg has been handled + + + + The user has right clicked on the column headers. Do whatever is required + + Return true if this event has been handle + + + + The user has right clicked on the column headers. Do whatever is required + + Return true if this event has been handle + + + + Tell the world when a cell is about to finish being edited. + + + + + The callbacks for RightColumnClick events + + + + + Triggered when a column header is right clicked. + + + + + Show a popup menu at the given point which will allow the user to choose which columns + are visible on this listview + + Where should the menu be placed + + + + Append the column selection menu items to the given menu strip. + + The menu to which the items will be added. If this is null, a new + ContextMenuStrip will be created + Return the menu to which the items were added + + + + Override the OnColumnReordered method to do what we want + + + + + + Resize our space filling columns so they fill any unoccupied width in the control + + + + + Change the given item from the old check value to a new one + + The item to be change + The old value of the check + The new value of the check + + + + Change the given item from the old check value to a new one + + The item to be change + The old value of the check + The new value of the check + + + + Return true of the given object is checked + + The model object whose checkedness is returned + Is the given object checked? + If the given object is not in the list, this method returns false. + + + + Return the OLVListItem that displays the given model object + + The modelObject whose item is to be found + The OLVListItem that displays the model, or null + This method has O(n) performance. + + + + Toggle the checkedness of the given object + + The model object to be checked + + + + Mark the given object as checked in the list + + The model object to be checked + + + + Mark the given object as unchecked in the list + + The model object to be unchecked + + + + Return the column at the given index + + Index of the column to be returned + An OLVColumn + + + + Return the column at the given title. + + Name of the column to be returned + An OLVColumn + + + + Return the number of items in the list + + the number of items in the list + + + + Return the item at the given index + + Index of the item to be returned + An OLVListItem + + + + Return the model object at the given index + + Index of the model object to be returned + A model object + + + + Find the item and column that are under the given co-ords + + X co-ord + Y co-ord + The column under the given point + The item under the given point. Can be null. + + + + Select all rows in the listview + + + + + Deselect all rows in the listview + + + + + Return the model object of the row that is selected or null if there is no selection or more than one selection + + Model object or null + + + + Return the model objects of the rows that are selected or an empty collection if there is no selection + + ArrayList + + + + Return the model object of the row that is checked or null if no row is checked + or more than one row is checked + + Model object or null + Use CheckedObject property instead of this method + + + + Get the collection of model objects that are checked. + + Use CheckedObjects property instead of this method + + + + Select the row that is displaying the given model object. All other rows are deselected. + + The object to be selected or null to deselect all + + + + Select the rows that is displaying any of the given model object. All other rows are deselected. + + A collection of model objects + + + + Update the ListViewItem with the data from its associated model. + + This method does not resort or regroup the view. It simply updates + the displayed data of the given item + + + + Update the rows that are showing the given objects + + This method does not resort or regroup the view. + + + + Update the rows that are showing the given objects + + + This method does not resort or regroup the view. + This method can safely be called from background threads. + + + + + Update the rows that are selected + + This method does not resort or regroup the view. + + + + Find the given model object within the listview and return its index + + Technically, this method will work with virtual lists, but it will + probably be very slow. + The model object to be found + The index of the object. -1 means the object was not present + + + + Return the ListViewItem that appears immediately after the given item. + If the given item is null, the first item in the list will be returned. + Return null if the given item is the last item. + + The item that is before the item that is returned, or null + A ListViewItem + + + + Return the ListViewItem that appears immediately before the given item. + If the given item is null, the last item in the list will be returned. + Return null if the given item is the first item. + + The item that is before the item that is returned + A ListViewItem + + + + Freeze the listview so that it no longer updates itself. + + Freeze()/Unfreeze() calls nest correctly + + + + Unfreeze the listview. If this call is the outermost Unfreeze(), + the contents of the listview will be rebuilt. + + Freeze()/Unfreeze() calls nest correctly + + + + Do the actual work required when the listview is unfrozen + + + + + Sort the items in the list view by the values in the given column. + If ShowGroups is true, the rows will be grouped by the given column, + otherwise, it will be a straight sort. + + The name of the column whose values will be used for the sorting + + + + Sort the items in the list view by the values in the given column. + If ShowGroups is true, the rows will be grouped by the given column, + otherwise, it will be a straight sort. + + The index of the column whose values will be used for the sorting + + + + Sort the items in the list view by the values in the given column. + If ShowGroups is true, the rows will be grouped by the given column, + otherwise, it will be a straight sort. + + The column whose values will be used for the sorting + + + + Put a sort indicator next to the text of the sort column + + + + + Put a sort indicator next to the text of the given given column + + The column to be marked + The sort order in effect on that column + + + + The name of the image used when a column is sorted ascending + + This image is only used on pre-XP systems. System images are used for XP and later + + + + The name of the image used when a column is sorted descending + + This image is only used on pre-XP systems. System images are used for XP and later + + + + If the sort indicator images don't already exist, this method will make and install them + + + + + Fill in the given OLVListItem with values of the given row + + the OLVListItem that is to be stuff with values + the model object from which values will be taken + + + + Setup all subitem images on all rows + + + + + Tell the underlying list control which images to show against the subitems + + the index at which the item occurs + the item whose subitems are to be set + + + + Tell the underlying list control which images to show against the subitems + + the index at which the item occurs + the item whose subitems are to be set + will existing images be cleared if no new image is provided? + + + + Prepare the listview to show alternate row backcolors + + We cannot rely on lvi.Index in this method. + In a straight list, lvi.Index is the display index, and can be used to determine + whether the row should be colored. But when organised by groups, lvi.Index is not + useable because it still refers to the position in the overall list, not the display order. + + + + + For some reason, UseItemStyleForSubItems doesn't work for the colors + when owner drawing the list, so we have to specifically give each subitem + the desired colors + + The item whose subitems are to be corrected + + + + Convert the given image selector to an index into our image list. + Return -1 if that's not possible + + + Index of the image in the imageList, or -1 + + + + Make sure the ListView has the extended style that says to display subitem images. + + This method must be called after any .NET call that update the extended styles + since they seem to erase this setting. + + + + For the given item and subitem, make it display the given image + + row number (0 based) + subitem (0 is the item itself) + index into the image list + + + + Update our externally visible image list so it holds the same images as our shadow list, but sized correctly + + + + + Return a copy of the given source image list, where each image has been resized to be height x height in size. + If source is null, an empty image list of the given size is returned + + Height and width of the new images + Source of the images (can be null) + A new image list + + + + Return a bitmap of the given height x height, which shows the given image, centred. + + Height and width of new bitmap + Image to be centred + The background color + A new bitmap + + + + Owner draw the column header + + + + + + Owner draw the item + + + + + + Owner draw a single subitem + + + + + + This method is called every time a row is selected or deselected. This can be + a pain if the user shift-clicks 100 rows. We override this method so we can + trigger one event for any number of select/deselects that come from one user action + + + + + + The application is idle. Trigger a SelectionChanged event. + + + + + + + This event is triggered once per user action that changes the selection state + of one or more rows. + + + + + Trigger the SelectionChanged event + + + + + + We need the click count in the mouse up event, but that is always 1. + So we have to remember the click count from the preceding mouse down event. + + + + + + Check to see if we need to start editing a cell + + + + + + Should we start editing the cell? + + + + + + + Handle a key press on this control. We specifically look for F2 which edits the primary column, + or a Tab character during an edit operation, which tries to start editing on the next (or previous) cell. + + + + + + + Begin an edit operation on the given cell. + + This performs various sanity checks and passes off the real work to StartCellEdit(). + The row to be edited + The index of the cell to be edited + + + + Really start an edit operation on a given cell. The parameters are assumed to be sane. + + The row to be edited + The index of the cell to be edited + + + + Try to give the given value to the provided control. Fall back to assigning a string + if the value assignment fails. + + A control + The value to be given to the control + The string to be given if the value doesn't work + + + + Setup the given control to be a cell editor + + + + + Return the value that the given control is showing + + + + + + + Called when the cell editor could be about to lose focus. Time to commit the change + + + + + + + Return the bounds of the given cell + + The row to be edited + The index of the cell to be edited + A Rectangle + + + + Return a control that can be used to edit the value of the given cell. + + The row to be edited + The index of the cell to be edited + + + + + Return a TextBox that can be used as a default cell editor. + + What column does the cell belong to? + + + + + Stop editing a cell and throw away any changes. + + + + + If a cell edit is in progress, finish the edit + + Returns false if the finishing process was cancelled + (i.e. the cell editor is still on screen) + + + + Finish the cell edit operation, writing changed data back to the model object + + + + + Remove all trace of any existing cell edit operation + + + + + The callbacks for CellEditing events + + + + + Triggered when a cell is about to be edited. + + Set Cancel to true to prevent the cell being edited. + You can change the the Control to be something completely different. + + + + Triggered when a cell editor needs to be validated + + + If this event is cancelled, focus will remain on the cell editor. + + + + + Triggered when a cell is about to finish being edited. + + If Cancel is already true, the user is cancelling the edit operation. + Set Cancel to true to prevent the value from the cell being written into the model. + You cannot prevent the editing from finishing. + + + + Tell the world when a cell is about to be edited. + + + + + Tell the world when a cell is about to finish being edited. + + + + + Tell the world when a cell is about to finish being edited. + + + + + Let the world know that a cell edit operation is beginning or ending + + + + + Create an event args + + + + + + + + + + Change this to true to cancel the cell editing operation. + + + During the CellEditStarting event, setting this to true will prevent the cell from being edited. + During the CellEditFinishing event, if this value is already true, this indicates that the user has + cancelled the edit operation and that the handler should perform cleanup only. Setting this to true, + will prevent the ObjectListView from trying to write the new value into the model object. + + + + + During the CellEditStarting event, this can be modified to be the control that you want + to edit the value. You must fully configure the control before returning from the event, + including its bounds and the value it is showing. + During the CellEditFinishing event, you can use this to get the value that the user + entered and commit that value to the model. Changing the control during the finishing + event has no effect. + + + + + The column of the cell that is going to be or has been edited. + + + + + The model object of the row of the cell that is going to be or has been edited. + + + + + The listview item of the cell that is going to be or has been edited. + + + + + The index of the cell that is going to be or has been edited. + + + + + The data value of the cell before the edit operation began. + + + + + The bounds of the cell that is going to be or has been edited. + + + + + This editor simply shows and edits integer values. + + + + + This editor simply shows and edits unsigned integer values. + + + + + This editor simply shows and edits boolean values. + + You can intercept the CellEditStarting event if you want + to change the characteristics of the editor. For example, by changing + the labels to "No" and "Yes". The false value must come first. + + + + This editor simply shows and edits floating point values. + + You can intercept the CellEditStarting event if you want + to change the characteristics of the editor. For example, by increasing + the number of decimal places. + + + + This editor shows and auto completes values from the given listview column. + + + + + Return a collection of columns that are appropriate to the given view. + Only Tile and Details have columns; all other views have 0 columns. + + Which view are the columns being calculate for? + A list of columns + + + + This class works in conjunction with the OLVColumns property to allow OLVColumns + to be added to the ObjectListView. + + + + + Return Columns for this list. We hide the original so we can associate + a specialised editor with it. + + + + + Which column did we last sort by + + + + + Which direction did we last sort + + + + + Wrapper for all native method calls on ListView controls + + + + + Notify message header structure. + + + + + Make sure the ListView has the extended style that says to display subitem images. + + This method must be called after any .NET call that update the extended styles + since they seem to erase this setting. + The listview to send a message to + + + + For the given item and subitem, make it display the given image + + The listview to send a message to + row number (0 based) + subitem (0 is the item itself) + index into the image list + + + + Setup the given column of the listview to show the given image to the right of the text. + If the image index is -1, any previous image is cleared + + The listview to send a message to + Index of the column to modifiy + + Index into the small image list + + + + Does this version of the operating system have builtin sort indicators? + + Are there builtin sort indicators + XP and later have these + + + + Return the bounds of the update region on the given control. + + The BeginPaint() system call validates the update region, effectively wiping out this information. + So this call has to be made before the BeginPaint() call. + The control whose update region is be calculated + A rectangle + + + + Validate an area of the given control. A validated area will not be repainted at the next redraw. + + The control to be validated + The area of the control to be validated + + + + Select all rows on the given listview + + The listview whose items are to be selected + + + + Deselect all rows on the given listview + + The listview whose items are to be deselected + + + + Set the item state on the given item + + The listview whose item's state is to be changed + The index of the item to be changed + Which bits of the value are to be set? + The value to be set + + + + Return the handle to the header control on the given list + + The listview whose header control is to be returned + The handle to the header control + + + + Return the index of the divider under the given point. Return -1 if no divider is under the pt + + The list we are interested in + The client co-ords + The index of the divider under the point, or -1 if no divider is under that point + + + + Return the index of the column of the header that is under the given point. + Return -1 if no column is under the pt + + The list we are interested in + The client co-ords + The index of the column under the point, or -1 if no column header is under that point + + + + Get the scroll position of the given scroll bar + + + + + + + + A virtual object list view operates in virtual mode, that is, it only gets model objects for + a row when it is needed. This gives it the ability to handle very large numbers of rows with + minimal resources. + + A listview is not a great user interface for a large number of items. But if you've + ever wanted to have a list with 10 million items, go ahead, knock yourself out. + Virtual lists can never iterate their contents. That would defeat the whole purpose. + Given the above, grouping and sorting are not possible on virtual lists. But if the backing data store has + a sorting mechanism, a CustomSorter can be installed which will be called when the sorting is required. + For the same reason, animate GIFs should not be used in virtual lists. Animated GIFs require some state + information to be stored for each animation, but virtual lists specifically do not keep any state information. + You really do not want to keep state information for 10 million animations! + + + + + Create a VirtualObjectListView + + + + + This delegate is used to fetch a rowObject, given it's index within the list + + + + + Return the number of items in the list + + the number of items in the list + + + + Return the item at the given index + + Index of the item to be returned + An OLVListItem + + + + Return the model object at the given index + + Index of the model object to be returned + A model object + + + + Remove all items from this list + + This method can safely be called from background threads. + + + + Select the row that is displaying the given model object. + This does nothing in virtual lists. + + This is a no-op for virtual lists, since there is no way to map the model + object back to the ListViewItem that represents it. + The object that gave data + + + + Select the rows that is displaying any of the given model object. + This does nothing in virtual lists. + + This is a no-op for virtual lists, since there is no way to map the model + objects back to the ListViewItem that represents them. + A collection of model objects + + + + Update the rows that are showing the given objects + + This is a no-op for virtual lists, since there is no way to map the model + objects back to the ListViewItem that represents them. + + + + Add the given collection of model objects to this control. + + A collection of model objects + This is a no-op for virtual lists, since the control + does not have a list of model objects to which it can add this new one. + All model object management is done by the application. + + + + Remove all of the given objects from the control + + Collection of objects to be removed + This is a no-op for virtual lists, since the control + does not have a list of model objects from which it can remove these ones. + All model object management is done by the application. + + + + Invalidate any cached information when we rebuild the list. + + + + + Prepare the listview to show alternate row backcolors + + Alternate colored backrows can't be handle in the same way as our base class. + With virtual lists, they are handled at RetrieveVirtualItem time. + + + + Refresh the given item in the list + + The item to refresh + + + + Handle a mouse down event + + + + + + Handle a RetrieveVirtualItem + + + + + + + Create a OLVListItem for given row index + + The index of the row that is needed + An OLVListItem + + + + Return the row object for the given row index + + index of the row whose object is to be fetched + A model object or null if no delegate is installed + + + + Clear any cached info this list may have been using + + + + + A FastObjectListView trades function for speed. + + + On my mid-range laptop, this view builds a list of 10,000 objects in 0.1 seconds, + as opposed to a normal ObjectListView which takes 10-15 seconds. Lists of up to 50,000 items should be + able to be handled with sub-second response times even on low end machines. + + A FastObjectListView is implemented as a virtual list with some of the virtual modes limits (e.g. no sorting) + fixed through coding. There are some functions that simply cannot be provided. Specifically, a FastObjectListView cannot: + + shows groups + use Tile view + display images on subitems + + + You can circumvent the limit on subitem images by making the list owner drawn, and giving the column + a Renderer of BaseRenderer, e.g. myColumnWithImage.Renderer = new BaseRenderer(); + + Although it isn't documented, virtual lists cannot have checkboxes. A FastObjectListView codes around this limitation, + but you must use the functions provided by FastObjectListView. If you call the normal "CheckedItems", it will throw an + exception. If you use CheckedObjects and its friends (declared in ObjectListView), you should not have any trouble. + The only exception is the "CheckBoxes" property itself. Once this is set, trying to unset it will throw an exception, + since the list is a virtual list. + + + + + + Make a FastObjectListView + + + + + Get/set the list of objects that are shown by the control. + + + This method preserves selection, if possible. Use SetObjects() if + you do not want to preserve the selection. Preserving selection is the slowest part of this + code and performance is O(n) where n is the number of selected rows. + This method is not thread safe. + + + + + When the user types into a list, should the values in the current sort column be searched to find a match? + If this is false, the primary column will always be used regardless of the sort column. + + When this is true, the behavior is like that of ITunes. + + + + Set the collection of objects that this control will show. + + + This method can safely be called from background threads. + + + + Add the given collection of model objects to this control. + + A collection of model objects + + The added objects will appear in their correct sort position, if sorting + is active. Otherwise, they will appear at the end of the list. + No check is performed to see if any of the objects are already in the ListView. + Null objects are silently ignored. + + + + + Remove all of the given objects from the control + + Collection of objects to be removed + + Nulls and model objects that are not in the ListView are silently ignored. + + + + + Take ownership of the 'objects' collection. This separats our collection from the source. + + + + This method + separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject + calls will modify our collection and not the original colleciton. + + + FastObjectListViews always own their collections, so this is a no-op. + + + + + + Event handler for the column click event + + + This differs from its base version by trying to preserve selection. The base class, + being a pure virtual list, cannot maintain selection since it cannot map a + model objects to the row that is responsible for displaying it. This class can do that. + + + + + Select the row that is displaying the given model object. + + The object that gave data + + + + Select the rows that is displaying any of the given model object. + + A collection of model objects + + + + Update the rows that are showing the given objects + + + + + Rebuild the map that remembers which model object is displayed at which line + + + + + Return the row object for the given row index + + index of the row whose object is to be fetched + A model object or null if no delegate is installed + + + + A DataListView is a ListView that can be bound to a datasource (which would normally be a DataTable or DataView). + + + This listview keeps itself in sync with its source datatable by listening for change events. + If the listview has no columns when given a data source, it will automatically create columns to show all of the datatables columns. + This will be only the simplest view of the world, and would look more interesting with a few delegates installed. + This listview will also automatically generate missing aspect getters to fetch the values from the data view. + Changing data sources is possible, but error prone. Before changing data sources, the programmer is responsible for modifying/resetting + the column collection to be valid for the new data source. + + + + + Make a DataListView + + + + + Get or set the DataSource that will be displayed in this list view. + + The DataSource should implement either , , + or . Some common examples are the following types of objects: + + + + + + + + When binding to a list container (i.e. one that implements the + interface, such as ) + you must also set the property in order + to identify which particular list you would like to display. You + may also set the property even when + DataSource refers to a list, since can + also be used to navigate relations between lists. + + + + + Gets or sets the name of the list or table in the data source for which the DataListView is displaying data. + + If the data source is not a DataSet or DataViewManager, this property has no effect + + + + Our data source has changed. Figure out how to handle the new source + + + + + Our data source has changed. Figure out how to handle the new source + + + + + The data source for this control has changed. Reconfigure the control for the new source + + + + + Create columns for the listview based on what properties are available in the data source + + + This method will not replace existing columns. + + + + + Generate aspect getters and putters for any columns that are missing them (and for which we have + enough information to actually generate a getter) + + + + + Add the given collection of model objects to this control. + + A collection of model objects + This is a no-op for data lists, since the data + is controlled by the DataSource. Manipulate the data source + rather than this view of the data source. + + + + Remove the given collection of model objects from this control. + + This is a no-op for data lists, since the data + is controlled by the DataSource. Manipulate the data source + rather than this view of the data source. + + + + What should we do when the list is unfrozen + + + + + Handles binding context changes + + The EventArgs that will be passed to any handlers + of the BindingContextChanged event. + + + + Handles parent binding context changes + + Unused EventArgs. + + + + Handle a SelectedIndexChanged event + + The event + + Called by Windows Forms when the currently selected index of the + control changes. This usually happens because the user clicked on + the control. In this case we want to notify the CurrencyManager so + that any other bound controls will remain in sync. This method will + also be called when we changed our index as a result of a + notification that originated from the CurrencyManager, and in that + case we avoid notifying the CurrencyManager back! + + + + + These delegates are used to extract an aspect from a row object + + + + + These delegates are used to put a changed value back into a model object + + + + + These delegates can be used to convert an aspect value to a display string, + instead of using the default ToString() + + + + + These delegates are used to the state of the checkbox for a row object. + + For reasons known only to someone in Microsoft, we can only set + a boolean on the ListViewItem to indicate it's "checked-ness", but when + we receive update events, we have to use a tristate CheckState. So we can + be told about an indeterminate state, but we can't set it ourselves. + + + + These delegates are used to put a changed check state back into a model object + + + + + These delegates are used to retrieve the object that is the key of the group to which the given row belongs. + + + + + These delegates are used to convert a group key into a title for the group + + + + + These delegates are used to fetch the image selector that should be used + to choose an image for this column. + + + + + These delegates are used to draw a cell + + + + + These delegates are used to fetch a row object for virtual lists + + + + + These delegates are used to format a listviewitem before it is added to the control. + + + + + These delegates are used to sort the listview in some custom fashion + + + + + An OLVColumn knows which aspect of an object it should present. + + + The column knows how to: + + extract its aspect from the row object + convert an aspect to a string + calculate the image for the row object + extract a group "key" from the row object + convert a group "key" into a title for the group + + For sorting to work correctly, aspects from the same column + must be of the same type, that is, the same aspect cannot sometimes + return strings and other times integers. + + + + + Create an OLVColumn + + + + + Initialize a column to have the given title, and show the given aspect + + The title of the column + The aspect to be shown in the column + + + + The name of the property or method that should be called to get the value to display in this column. + This is only used if a ValueGetterDelegate has not been given. + + This name can be dotted to chain references to properties or methods. + "DateOfBirth" + "Owner.HomeAddress.Postcode" + + + + This format string will be used to convert an aspect to its string representation. + + + This string is passed as the first parameter to the String.Format() method. + This is only used if ToStringDelegate has not been set. + "{0:C}" to convert a number to currency + + + + Group objects by the initial letter of the aspect of the column + + + One common pattern is to group column by the initial letter of the value for that group. + The aspect must be a string (obviously). + + + + + Get/set whether this column should be used when the view is switched to tile view. + + Column 0 is always included in tileview regardless of this setting. + Tile views do not work well with many "columns" of information, 2 or 3 works best. + + + + This delegate will be used to extract a value to be displayed in this column. + + + If this is set, AspectName is ignored. + + + + + The delegate that will be used to translate the aspect to display in this column into a string. + + If this value is set, ValueToStringFormat will be ignored. + + + + This delegate is called to get the image selector of the image that should be shown in this column. + It can return an int, string, Image or null. + + This delegate can use these return value to identify the image: + + null or -1 -- indicates no image + an int -- the int value will be used as an index into the image list + a String -- the string value will be used as a key into the image list + an Image -- the Image will be drawn directly (only in OwnerDrawn mode) + + + + + + This delegate is called to get the object that is the key for the group + to which the given row belongs. + + + + + This delegate is called to convert a group key into a title for that group. + + + + + This delegate is called when a cell needs to be drawn in OwnerDrawn mode. + + + + + Get/set the renderer that will be invoked when a cell needs to be redrawn + + + + + Remember if this aspect getter for this column was generated internally, and can therefore + be regenerated at will + + + + + When the listview is grouped by this column and group title has an item count, + how should the lable be formatted? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group + + If this value is not set, the values from the list view will be used + + "{0} [{1} items]" + + + + Return this.GroupWithItemCountFormat or a reasonable default + + + + + When the listview is grouped by this column and a group title has an item count, + how should the lable be formatted if there is only one item in the group? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group (always 1) + + If this value is not set, the values from the list view will be used + + "{0} [{1} item]" + + + + Return this.GroupWithItemCountSingularFormat or a reasonable default + + + + + What is the minimum width that the user can give to this column? + + -1 means there is no minimum width. Give this the same value as MaximumWidth to make a fixed width column. + + + + What is the maximum width that the user can give to this column? + + -1 means there is no maximum width. Give this the same value as MinimumWidth to make a fixed width column. + + + + Is this column a fixed width column? + + + + + What proportion of the unoccupied horizontal space in the control should be given to this column? + + + + There are situations where it would be nice if a column (normally the rightmost one) would expand as + the list view expands, so that as much of the column was visible as possible without having to scroll + horizontally (you should never, ever make your users have to scroll anything horizontally!). + + + A space filling column is resized to occupy a proportion of the unoccupied width of the listview (the + unoccupied width is the width left over once all the the non-filling columns have been given their space). + This property indicates the relative proportion of that unoccupied space that will be given to this column. + The actual value of this property is not important -- only its value relative to the value in other columns. + For example: + + + If there is only one space filling column, it will be given all the free space, regardless of the value in FreeSpaceProportion. + + + If there are two or more space filling columns and they all have the same value for FreeSpaceProportion, + they will share the free space equally. + + + If there are three space filling columns with values of 3, 2, and 1 + for FreeSpaceProportion, then the first column with occupy half the free space, the second will + occupy one-third of the free space, and the third column one-sixth of the free space. + + + + + + + + Should this column resize to fill the free space in the listview? + + + + If you want two (or more) columns to equally share the available free space, set this property to True. + If you want this column to have a larger or smaller share of the free space, you must + set the FreeSpaceProportion property explicitly. + + + Space filling columns are still governed by the MinimumWidth and MaximumWidth properties. + + /// + + + + This delegate will be used to put an edited value back into the model object. + + + This does nothing if IsEditable == false. + + + + + Can the values shown in this column be edited? + + This defaults to true, since the primary means to control the editability of a listview + is on the listview itself. Once a listview is editable, all the columns are too, unless the + programmer explicitly marks them as not editable + + + + Return the control that should be used to edit cells in this column + + + + + Can this column be seen by the user? + + After changing this value, you must call RebuildColumns() before the changes will be effected. + + + + Where was this column last positioned within the Detail view columns + + DisplayIndex is volatile. Once a column is removed from the control, + there is no way to discover where it was in the display order. This property + guards that information even when the column is not in the listview's active columns. + + + + For a given row object, return the object that is to be displayed in this column. + + The row object that is being displayed + An object, which is the aspect to be displayed + + + + For a given row object, extract the value indicated by the AspectName property of this column. + + The row object that is being displayed + An object, which is the aspect named by AspectName + + + + Update the given model object with the given value + + The model object to be updated + The value to be put into the model + + + + Update the given model object with the given value using the column's + AspectName. + + The model object to be updated + The value to be put into the model + + + + For a given row object, return the string representation of the value shown in this column. + + + For aspects that are string (e.g. aPerson.Name), the aspect and its string representation are the same. + For non-strings (e.g. aPerson.DateOfBirth), the string representation is very different. + + + + + + + Convert the aspect object to its string representation. + + + If the column has been given a ToStringDelegate, that will be used to do + the conversion, otherwise just use ToString(). Nulls are always converted + to empty strings. + + The value of the aspect that should be displayed + A string representation of the aspect + + + + For a given row object, return the image selector of the image that should displayed in this column. + + The row object that is being displayed + int or string or Image. int or string will be used as index into image list. null or -1 means no image + + + + For a given row object, return the object that is the key of the group that this row belongs to. + + The row object that is being displayed + Group key object + + + + For a given group value, return the string that should be used as the groups title. + + The group key that is being converted to a title + string + + + + Install delegates that will group the columns aspects into progressive partitions. + If an aspect is less than value[n], it will be grouped with description[n]. + If an aspect has a value greater than the last element in "values", it will be grouped + with the last element in "descriptions". + + Array of values. Values must be able to be + compared to the aspect (using IComparable) + The description for the matching value. The last element is the default description. + If there are n values, there must be n+1 descriptions. + + this.salaryColumn.MakeGroupies( + new UInt32[] { 20000, 100000 }, + new string[] { "Lowly worker", "Middle management", "Rarified elevation"}); + + + + + OLVListItems are specialized ListViewItems that know which row object they came from, + and the row index at which they are displayed, even when in group view mode. They + also know the image they should draw against themselves + + + + + Create a OLVListItem for the given row object + + + + + Create a OLVListItem for the given row object, represented by the given string and image + + + + + RowObject is the model object that is source of the data for this list item. + + + + + DisplayIndex is the index of the row where this item is displayed. For flat lists, + this is the same as ListViewItem.Index, but for grouped views, it is different. + + + + + Get or set the image that should be shown against this item + + This can be an Image, a string or an int. A string or an int will + be used as an index into the small image list. + + + + A ListViewSubItem that knows which image should be drawn against it. + + + + + Create a OLVListSubItem + + + + + Create a OLVListSubItem that shows the given string and image + + + + + Get or set the image that should be shown against this item + + This can be an Image, a string or an int. A string or an int will + be used as an index into the small image list. + + + + Return the state of the animatation of the image on this subitem. + Null means there is either no image, or it is not an animation + + + + + This comparer sort list view groups. + It does this on the basis of the values in the Tags, if we can figure out how to compare + objects of that type. Failing that, it uses a case insensitive compare on the group header. + + + + + ColumnComparer is the workhorse for all comparison between two values of a particular column. + If the column has a specific comparer, use that to compare the values. Otherwise, do + a case insensitive string compare of the string representations of the values. + + This class inherits from both IComparer and its generic counterpart + so that it can be used on untyped and typed collections. + + + + Renderers are responsible for drawing a single cell within an owner drawn ObjectListView. + + + Methods on this class are called during the DrawItem or DrawSubItemEvent. + Subclasses can tell which type of event they are handling by examining DrawItemEvent: if this + is not null, it is a DrawItem event. + Subclasses will normally override the RenderWithDefault or Render method, and use the other + methods as helper functions. + If a renderer is installed on the primary column (column 0), it will be given a chance + to draw the whole item in all views (Details, Tile, etc.). If the renderer returns true, + default processing will continue. If it returns false, no other rendering will happen. + This means that when an ObjectListView is in Details view, the renderer on column 0 + will be called twice: once to handle the DrawItem event, and then again to draw only the + first cell. Subclasses must distinguish between these two very different events (using + the "this.DrawItemEvent == null" test). + + + + + Make a simple renderer + + + + + Get/set the event that caused this renderer to be called + + + + + Get/set the event that caused this renderer to be called + + + + + Get/set the listview for which the drawing is to be done + + + + + Get or set the OLVColumn that this renderer will draw + + + + + Get or set the model object that this renderer should draw + + + + + Get or set the aspect of the model object that this renderer should draw + + + + + Get or set the listitem that this renderer will be drawing + + + + + Get or set the list subitem that this renderer will be drawing + + + + + Get the specialized OLVSubItem that this renderer is drawing + + This returns null for column 0. + + + + Cache whether or not our item is selected + + + + + Return the font to be used for text in this cell + + The font of the subitem + + + + The brush that will be used to paint the text + + + + + Should this renderer fill in the background before drawing? + + + + + Can the renderer wrap lines that do not fit completely within the cell? + + This value is currently only used when printing a list view using ListViewPrinter. + + + + When rendering multiple images, how many pixels should be between each image? + + + + + Return the string that should be drawn within this + + + + + + Return the image that should be drawn against this subitem + + An Image or null if no image should be drawn. + + + + Return the actual image that should be drawn when keyed by the given image selector. + An image selector can be: + an int, giving the index into the image list + a string, giving the image key into the image list + an Image, being the image itself + + + The value that indicates the image to be used + An Image or null + + + + Return the Color that is the background color for this item's cell + + The background color of the subitem + + + + Return the Color that is the background color for this item's text + + The background color of the subitem's text + + + + Return the color to be used for text in this cell + + The text color of the subitem + + + + Align the second rectangle with the first rectangle, + according to the alignment of the column + + The cell's bounds + The rectangle to be aligned within the bounds + An aligned rectangle + + + + Draw the given image aligned horizontally within the column. + + + Over tall images are scaled to fit. Over-wide images are + truncated. This is by design! + + Graphics context to use for drawing + Bounds of the cell + The image to be drawn + + + + Fill in the background of this cell + + Graphics context to use for drawing + Bounds of the cell + + + + The delegate that is called from the list view. This is the main entry point, but + subclasses should override Render instead of this method. + + The event that caused this redraw + The context that our drawing should be done using + The bounds of the cell within which the renderer can draw + The model object for this row + A boolean indicating whether the default process should occur + + + + Draw our data into the given rectangle using the given graphics context. + + + Subclasses should override this method. + The graphics context that should be used for drawing + The bounds of the subitem cell + Returns whether the renderering has already taken place. + If this returns false, the default processing will take over. + + + + + Draw our data into the given rectangle using the given graphics context. + + + Subclasses should override this method if they never want + to fall back on the default processing + The graphics context that should be used for drawing + The bounds of the subitem cell + + + + Draw our subitems image and text + + Graphics context to use for drawing + Bounds of the cell + + + + Draw the given text and optional image in the "normal" fashion + + Graphics context to use for drawing + Bounds of the cell + The string to be drawn + The optional image to be drawn + + + + This class maps a data value to an image that should be drawn for that value. + + It is useful for drawing data that is represented as an enum or boolean. + + + + Return a renderer that draw boolean values using the given images + + Draw this when our data value is true + Draw this when our data value is false + A Renderer + + + + Return a renderer that draw tristate boolean values using the given images + + Draw this when our data value is true + Draw this when our data value is false + Draw this when our data value is null + A Renderer + + + + Make a new empty renderer + + + + + Make a new renderer that will show the given image when the given key is the aspect value + + The data value to be matched + The image to be shown when the key is matched + + + + Make a new renderer that will show the given images when it receives the given keys + + + + + + + + + Build a renderer from the given array of keys and their matching images + + An array of key/image pairs + + + + Register the image that should be drawn when our Aspect has the data value. + + Value that the Aspect must match + An ImageSelector -- an int, string or image + + + + Render our value + + + + + + + Render an image that comes from our data source. + + The image can be sourced from: + + a byte-array (normally when the image to be shown is + stored as a value in a database) + an int, which is treated as an index into the image list + a string, which is treated first as a file name, and failing that as an index into the image list + + If an image is an animated GIF, it's state is stored in the SubItem object. + By default, the image renderer does not render animations (it begins life with animations paused). + To enable animations, you must call Unpause(). + + + + + Make an empty image renderer + + + + + Make an empty image renderer that begins life ready for animations + + + + + Draw our image + + + + + + + Translate our Aspect into an image. + + The strategy is: + If its a byte array, we treat it as an in-memory image + If it's an int, we use that as an index into our image list + If it's a string, we try to load a file by that name. If we can't, we use the string as an index into our image list. + + An image + + + + Should the animations in this renderer be paused? + + + + + Pause any animations + + + + + Unpause any animations + + + + + This is the method that is invoked by the timer. It basically switches control to the listview thread. + + not used + + + + This is the OnTimer callback, but invoked in the same thread as the creator of the ListView. + This method can use all of ListViews methods without creating a CrossThread exception. + + + + + Instances of this class kept track of the animation state of a single image. + + + + + Is the given image an animation + + The image to be tested + Is the image an animation? + + + + Create an AnimationState in a quiet state + + + + + Create an animation state for the given image, which may or may not + be an animation + + The image to be rendered + + + + Does this state represent a valid animation + + + + + Advance our images current frame and calculate when it will expire + + + + + Render our Aspect as a progress bar + + + + + Make a BarRenderer + + + + + Make a BarRenderer for the given range of data values + + + + + Make a BarRenderer using a custom bar scheme + + + + + Make a BarRenderer using a custom bar scheme + + + + + Make a BarRenderer that uses a horizontal gradient + + + + + Make a BarRenderer that uses a horizontal gradient + + + + + Should this bar be drawn in the system style + + + + + How many pixels in from our cell border will this bar be drawn + + + + + The Pen that will draw the frame surrounding this bar + + + + + The brush that will be used to fill the bar + + + + + The brush that will be used to fill the background of the bar + + + + + The first color when a gradient is used to fill the bar + + + + + The end color when a gradient is used to fill the bar + + + + + Regardless of how wide the column become the progress bar will never be wider than this + + + + + Regardless of how high the cell is the progress bar will never be taller than this + + + + + The minimum data value expected. Values less than this will given an empty bar + + + + + The maximum value for the range. Values greater than this will give a full bar + + + + + Draw this progress bar using a gradient + + + + + + + Draw our aspect + + + + + + + An ImagesRenderer draws zero or more images depending on the data returned by its Aspect. + + This renderer's Aspect must return a ICollection of ints, strings or Images, + each of which will be drawn horizontally one after the other. + + + + Draw our data value + + + + + + + A MultiImageRenderer draws the same image a number of times based on our data value + + The stars in the Rating column of iTunes is a good example of this type of renderer. + + + + Make a quiet rendererer + + + + + Make an image renderer that will draw the indicated image, at most maxImages times. + + + + + + + + + The image selector that will give the image to be drawn + + + + + What is the maximum number of images that this renderer should draw? + + + + + Values less than or equal to this will have 0 images drawn + + + + + Values greater than or equal to this will have MaxNumberImages images drawn + + + + + Draw our data value + + + + + + + A class to render a value that contains a bitwise-OR'ed collection of values. + + The type of value that holds the bit-OR'ed flag + + + + Register the given image to the given value + + When this flag is present... + ...draw this image + + + + Draw the flags + + + + + + + 鼠标的当前位置 + + + + + + + + + + + + + + + + + + + + 控件的状态。 + + + + + 正常 + + + + + 鼠标经过 + + + + + 鼠标按下 + + + + + 建立圆角路径的样式。 + + + + + 四个角都不是圆角。 + + + + + 四个角都为圆角。 + + + + + 左边两个角为圆角。 + + + + + 右边两个角为圆角。 + + + + + 上边两个角为圆角。 + + + + + 下边两个角为圆角。 + + + + + 左下角为圆角。 + + + + + 右下角为圆角。 + + + + + + + + + + 普通按钮按下事件 + + + + + 分割按钮按下事件 + + + + + + + + + + 下拉菜单与按钮的距离 + + + + + 图片高度 + + + + + 分割按钮的宽度 + + + + + 当鼠标按下时图片和文字是否产生偏移 + + + + + 是否一直显示按钮边框,设置为false则只在鼠标经过和按下时显示边框 + + + + + 当显示分割按钮时,分割按钮的箭头颜色 + + + + + 按钮的边框颜色 + + + + + 按钮内边框颜色 + + + + + 鼠标经过和按下时按钮的渐变背景颜色 + + + + + 鼠标经过和按下时按钮的渐变背景颜色 + + + + + 图片宽度 + + + + + 图片高度 + + + + + 按钮圆角样式 + + + + + 按钮圆角弧度 + + + + + 图片与文字之间的间距 + + + + + 按钮当前状态 + + + + + 鼠标当前所在位置 + + + + + 普通按钮矩形位置 + + + + + 分割按钮矩形位置 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取图像以及文字的位置 + + + + + + + + 画边框与背景 + + + + + 画分割按钮 + + + + + + + + + + + + 建立带有圆角样式的矩形路径 + + 用来建立路径的矩形。 + 圆角的大小 + 圆角的样式 + 是否把矩形长宽减 1,以便画出边框 + 建立的路径 + + + + This enum represents the possible browser commands + + + + + Used when no commans are available + + + + + Used in the new navigation events + + + + + The URL to navigate to + + + + + The name of the frame to navigate to + + + + + The flags when opening a new window + + + + + The pointer to ppDisp + + + + + Creates a new instance of WebBrowserExtendedNavigatingEventArgs + + Pointer to the automation object of the browser + The URL to go to + The name of the frame + The new window flags + + + + + + + + + Used in the new navigation events + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 查看源码 + + + + + 复制当前选中区 + + + + + 粘贴当前选中区 + + + + + 剪切当前选中区 + + + + + 全选 + + + + + 清除当前选中区的选中状态。 + + + + + 从当前选中区中删除全部超级链接。 + + + + + 从当前选中区中删除全部书签。 + + + + + 删除当前选中区 + + + + + 重做 + + + + + 撤销 + + + + + 从当前选中区中删除格式化标签。 + + + + + 点击节点 + + + + + + + + 点击节点 + + + + + + + + + 点击元素 + + 节点名 + 属性 + 属性值 + 等待毫秒数 + 第几个符合的元素,从1开始 + + + + 等待多时毫秒 + + + + + + Represents event information for the main form, when the command state of the active browser changes + + + + + Creates a new instance of the class + + A list of commands that are available + + + + Gets a list of commands that are available + + + + + An extended version of the control. + + + + + + + + + + + + 在页面弹出消息对话框时激发 + + + + + + + + + + + + + + + + + + + + + + 打开页面并等待页面加载完毕 + + 要打开的页面地址 + 小于等于0,则表示一直等待,否则表示等待指定秒后,如果依然没有加载完毕,就直接返回 + + + + 等待页面加载完毕 + + 小于等于0,则表示一直等待,否则表示等待指定秒后,如果依然没有加载完毕,就直接返回 + + + + 等待指定毫秒 + + 等待指定毫秒 + + + + 获取网页源代码,可以自动去除乱码 + + + + + + 加载html文本到浏览器中 + + + + + + + 加载html文本到浏览器中 + + + + + + 强制用本窗体打开新链接 + + + + + + + + + + + This method supports the .NET Framework infrastructure and is not intended to be used directly from your code. + Called by the control when the underlying ActiveX control is created. + + + + + + This method supports the .NET Framework infrastructure and is not intended to be used directly from your code. + Called by the control when the underlying ActiveX control is discarded. + + + + + Returns the automation object for the web browser + + + + + This method will be called to give you a chance to create your own event sink + + + + + Detaches the event sink + + + + + 在文档下载开始时激发 + + + + + Raises the event + + Empty + + You could start an animation or a notification that downloading is starting + + + + + 下载完成后触发 + + + Here you could start monitoring for script errors. + + + + + Raises the event + + Empty + + + + 在开始浏览新网页时激发. + + + + + 在打开新的网页窗口时激发 + + + + + Raises the event + + Thrown when BrowserExtendedNavigatingEventArgs is null + + + + Raises the event + + Thrown when BrowserExtendedNavigatingEventArgs is null + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 新窗口事件,只限Window XP SP2或以上系统支持 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overridden + + The send to this procedure + + + + A list of all the available window messages + + + + + Raises the event + + + + + 在网页窗口关闭时激发 + + + Do not confuse this with DWebBrowserEvents2.Quit... That's something else. + + + + + Flags used by INewWindowManager::EvaluateNewWindow. + These values are taken into account in the decision of whether to display a pop-up window. + + + + + No information Present + + + + + The page is unloading. This flag is set in response to the onbeforeunload and onunload events. + Some pages load pop-up windows when you leave them rather than when you enter. This flag is used to identify those situations. + + + + + The call to INewWindowManager::EvaluateNewWindow is the result of a user-initiated action + (a mouse click or key press). Use this flag in conjunction with the NWMF_FIRST_USERINITED flag + to determine whether the call is a direct or indirect result of the user-initiated action. + + + + + When NWMF_USERINITED is present, this flag indicates that the call to + INewWindowManager::EvaluateNewWindow is the first query that results from this user-initiated action. + Always use this flag in conjunction with NWMF_USERINITED. + + + + + The override key (ALT) was pressed. The override key is used to bypass the pop-up manager梐llowing + all pop-up windows to display梐nd must be held down at the time that INewWindowManager::EvaluateNewWindow is called. + + + + + The new window attempting to load is the result of a call to the showHelp method. Help is sometimes displayed in a separate window, + and this flag is valuable in those cases. + + + + + The new window is a dialog box that displays HTML content. + + + + + Indicates that the EvaluateNewWindow method is being called through a marshalled Component Object Model (COM) proxy + from another thread. In this situation, the method should make a decision and return immediately without performing + blocking operations such as showing modal user interface (UI). Lengthy operations will cause the calling thread to + appear unresponsive. + + + + + HRESULT constants + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 线条图 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + 画值 + + 画布 + X轴数据 + + + + 走势图 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + 初始化参数 + + + + + 返回或设置X轴间隔 + + + + + 标题 + + + + + 返回图片的宽度 + + + + + 返回或设置图片的高度 + + + + + X轴的间距 + + + + + Y轴的间距 + + + + + 标题的颜色 + + + + + 标题的字体 + + + + + 背景颜色 + + + + + X轴的颜色 + + + + + Y轴的颜色 + + + + + 返回X轴数据的最大值(供给Painter调用) + + + + + 返回图片数据 + + + + + 画布 + + + + + 作图器 + + + + + 释放内容资源 + + + + + 获取X轴中的最大值 + + + + + + + 获取所有X轴列中的最大值 + + + + + + + 初始化图片 + + X轴的数据 + + + + + 画一条走势图 + + + + + + 画多条走势图 + + + + + + 作图器的基础类 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + 返回此作图器的相关链走势图 + + + + + 获取某值在Y轴上的位置 + + 当前点的值 + 点坐标 + + + + 画XY轴线 + + 画布 + X轴的数据 + + + + 画标题 + + + + + + 画走势线 + + 画布 + X轴数据 + + + + 方块图 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + 画值 + + 画布 + X轴数据 + + + + 走势图的X轴数据 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + + + + + + + + 标题 + + + + + 值 + + + + + 标题的颜色 + + + + + 标题的字体 + + + + + 值的颜色 + + + + + 值的字体 + + + + + 绘制颜色 + + + + + 值是否可见 + + + + + 克隆自身 + + + + + + 定义X轴的数据集合 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + + + + + + 添加一批数据 + + 轴的标题 + + + + 添加一批数据 + + 轴的标题 + 轴的值 + + + + 重置轴的值 + + 轴的值 + + + + 克隆数据 + + + + + + 获取颜色 + + + + + + + + + + + + + 颜色变化时激发 + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + diff --git a/Bin/Debug/CommonControls/.NET4 示例/ryUpdate.dll b/Bin/Debug/CommonControls/.NET4 示例/ryUpdate.dll new file mode 100644 index 0000000..f1456bc Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4 示例/ryUpdate.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/MyDb.dll b/Bin/Debug/CommonControls/.NET4/MyDb.dll new file mode 100644 index 0000000..f87a598 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/MyDb.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/MyDb_MSSQL.dll b/Bin/Debug/CommonControls/.NET4/MyDb_MSSQL.dll new file mode 100644 index 0000000..43d9407 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/MyDb_MSSQL.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/MyDb_MySQL.dll b/Bin/Debug/CommonControls/.NET4/MyDb_MySQL.dll new file mode 100644 index 0000000..07867a3 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/MyDb_MySQL.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/MyDb_SQLite.dll b/Bin/Debug/CommonControls/.NET4/MyDb_SQLite.dll new file mode 100644 index 0000000..14e223b Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/MyDb_SQLite.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/MySql.Data.dll b/Bin/Debug/CommonControls/.NET4/MySql.Data.dll new file mode 100644 index 0000000..b732da4 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/MySql.Data.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/RyPrint.dll b/Bin/Debug/CommonControls/.NET4/RyPrint.dll new file mode 100644 index 0000000..eae4273 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/RyPrint.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/RyWeb.dll b/Bin/Debug/CommonControls/.NET4/RyWeb.dll new file mode 100644 index 0000000..9bdb7b4 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/RyWeb.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/System.Data.SQLite.dll b/Bin/Debug/CommonControls/.NET4/System.Data.SQLite.dll new file mode 100644 index 0000000..e15c908 Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/System.Data.SQLite.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/XPTable.dll b/Bin/Debug/CommonControls/.NET4/XPTable.dll new file mode 100644 index 0000000..4ac2f2e Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/XPTable.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/ryControls.dll b/Bin/Debug/CommonControls/.NET4/ryControls.dll new file mode 100644 index 0000000..7a4385b Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/ryControls.dll differ diff --git a/Bin/Debug/CommonControls/.NET4/ryControls.xml b/Bin/Debug/CommonControls/.NET4/ryControls.xml new file mode 100644 index 0000000..eb3c402 --- /dev/null +++ b/Bin/Debug/CommonControls/.NET4/ryControls.xml @@ -0,0 +1,11247 @@ + + + + ryControls + + + + + 控件状态 + + + + + 无 + + + + + 获得焦点 + + + + + 失去焦点 + + + + + 鼠标指针进入控件 + + + + + Toolbar控件 + + + + + + + + + + + + + + + 获取或设置控件显示的图片 + + + + + 重写控件焦点属性 + + + + + 自定义绘制 + + + + + + 焦点进入 + + + + + + 失去焦点 + + + + + + 禁止调整大小 + + + + + + + + + + + + + + + + + + 只响应单击鼠标左键事件 + + + + + + 按比例缩放图片 + + + + + + + 图片缩放 + + 源图片 + 缩放图片的宽度 + 缩放图片的高度 + 缩放的图片 + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 绘图对像 + + 绘图对像 + 图片 + 绘置的图片大小、坐标 + 绘置的图片边界 + 当前状态 + 状态总数 + + + + 绘图对像 + + 绘图对像 + 图片对像 + 绘置的图片大小、坐标 + 当前状态 + 状态总数 + + + + + + + + + 得到要绘置的图片对像 + + 图像在程序集中的地址 + + + + + 得到要绘置的图片对像 + + 图像在程序集中的路径 + 图像在程序集中的地址 + + + + + 获取资源图标 + + + + + + + 得到图程序集中的图片对像 + + 图像在程序集中的地址 + + + + + 得到图程序集中的图片对像 + + 图像在程序集中的路径 + 图像在程序集中的地址 + + + + + 控件的状态。 + + + + + 正常 + + + + + 鼠标经过 + + + + + 鼠标按下 + + + + + 鼠标的当前位置 + + + + + + + + + + + + + + + + + + + + 美化按钮 + + + + + 普通按钮矩形位置 + + + + + 美化按钮 + + + + + 分割按钮的宽度 + + + + + 是否启用分割按钮 + + + + + 优先使用默认皮肤 + + + + + 按钮基础背景色 + + + + + 按钮字体颜色 + + + + + 图片宽度,默认值为18px,最小12px + + + + + 圆角的位置,默认全部都是圆角 + + + + + 设置圆角半径 + + + + + 背景色是否渐变 + + + + + 图片高度 + + + + + 图片与文字之间的间距 + + + + + 当鼠标按下时图片和文字是否产生偏移 + + + + + 鼠标进入时 + + + + + + 鼠标离开 + + + + + + 鼠标按下 + + + + + + 鼠标弹起 + + + + + + 鼠标当前所在位置 + + + + + 获取图像以及文字的位置 + + + + + + + + + + + + + + + + + + + + + + + + 添加菜单分隔线 + + + + + + 添加菜单 + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + RichTextBox + + + + + 在自带菜单弹出前激发 + + + + + 根据标签获得菜单项 + + + + + + + 只允许输入文本(只对设置之后的人工输入有效) + + + + + 按下按键 + + + + + + + + + + + + + + + + + + + + + + + + 鼠标按下 + + + + + + + + + + + + 当文本框为空时,显示的内容。 + + + + + 添加菜单分隔线 + + + + + + 添加菜单 + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + 消息列表控件 + + + + + 最大高度 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 建立圆角路径的样式。 + + + + + 四个角都不是圆角。 + + + + + 四个角都为圆角。 + + + + + 左边两个角为圆角。 + + + + + 右边两个角为圆角。 + + + + + 上边两个角为圆角。 + + + + + 下边两个角为圆角。 + + + + + 左下角为圆角。 + + + + + 右下角为圆角。 + + + + + 画图相关API + + + + + 建立带有圆角样式的路径。 + + 用来建立路径的矩形。 + 圆角的大小。 + 圆角的样式。 + 是否把矩形长宽减 1,以便画出边框。 + 建立的路径。 + + + + 窗体皮肤 + + + + + 窗体皮肤 + + + + + 标题属性 + + + + + 是否使用父窗口的图标 + + + + + 点击最小化按钮是最小化还是隐藏 + + + + + 最大化按钮 + + + + + 最小化按钮 + + + + + 标题栏关闭按钮是否显示 + + + + + 当窗口位于后台时,是否标注显示。 + + + + + + + + + + 标题栏字体颜色 + + + + + 标题栏不处于活动状态时的字体颜色 + + + + + 标题栏背景颜色 + + + + + 标题栏不处于活动状态时的背景颜色 + + + + + 是否允许拖拉窗体边缘来改变窗体大小 + + + + + + + + + + + 画边框 + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + 热键文本框 + + + + + 热键文本框 + + + + + 在控件大小变化时发生 + + + + + + 此属性无效 + + + + + 载入热键配置 + + + + + + 保存热键 + + + + + + 是否含义热键 + + + + + 读取或设置热键 + + + + + 功能键 + + + + + 热键按键 + + + + + KeyDown事件 + + + + + + KeyDown事件 + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 最大高度 + + + + + 标题 + + + + + 是否显示时间 + + + + + 添加时间 + + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 最大高度 + + + + + 标题 + + + + + 是否显示时间 + + + + + 添加时间 + + + + + 内容 + + + + + 网址 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 图标 + + + + + 标题 + + + + + 悬浮提示 + + + + + 标题颜色 + + + + + 设置按钮 + + + + + + + 判断和设置是否选择 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 绘制边框 + + 消息 + + + + 类说明:CContextMenuStrip控件的实现用来代替系统的ContextMenuStrip控件 + + + + + + + + + + + + + + + + 重写OnCreateControl + + + + + 重写OnPaint事件 + + + + + + CreateRoundedRectanglePath + + Rectangle + + + + + + 系统热键数据类。 + + + + + 系统热键数据类 + + + + + 使多行属性失效掉 + + + + + 使只读属性失效掉 + + + + + 获取热键文本 + + + + + 功能键 + + + + + 热键按键 + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 增强时间控件 + + + + + 增强时间控件 + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 选择文本框 + + + + + 选择文本框 + + + + + 按钮基础背景色 + + + + + 优先使用默认皮肤 + + + + + 选择的id + + + + + 选择的名称 + + + + + 选择的名称 + + + + + 字体 + + + + + 重新设置大小 + + + + + 在选择时激发 + + + + + 点击选择 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 可以改变文本行距(行间距)的Label + + + + + 行间距 + + + + + 可以改变文本行距(行间距)的Label + + + + + + + + + + 字体高度 + + + + + + + + + + 文本 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 计算两个日期的时间间隔,返回的是日期值+ + + 时间值,将显示在返回的值里 + 参照时间 + + + + + + + + + + + + + + + 控件边框颜色 + + + + + 控件背景颜色 + + + + + 圆角弧度大小 + + + + + 圆角风格 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + 在搜索时激发 + + + + + 文本变化时激发 + + + + + 文本变化时激发 + + + + + 双击时激发 + + + + + + + + + + + + + + + 文本为空时的显示效果 + + + + + 文本不选中 + + + + + 有内容时的显示效果 + + + + + 当文本框为空时,显示的内容。 + + + + + 字体 + + + + + 优先使用默认皮肤 + + + + + 按钮基础背景色 + + + + + + + + + + 重新设置大小 + + + + + 点击搜索按钮 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + + + + + + 使用公共皮肤 + + + + + 按钮颜色 + + + + + + + + + + + + + + + + + + + + + + + + + + + 皮肤公共类 + + + + + 是否使用默认皮肤 + + + + + 按钮皮肤 + + + + + 按钮皮肤类 + + + + + 背景颜色 + + + + + 字体颜色 + + + + + 类说明:帮助类 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 修改控件或窗体的边框,例如Textbox或是Form窗体 + + 消息 + 控件对象 + 边框像素 + 边框颜色 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 超级图片控件,支持加载工程内部图片、异步加载网络图片 + + + + + 超级图片控件,支持加载工程内部图片、异步加载网络图片 + + + + + 图片所在上级域名 + + + + + 图片资源所在上级文件夹 + + + + + 根据不同前缀,加载不同格式图片。i:表示工程内置图片;s:表示T_ImageDomain域名下的图片,u:表示指定url的图片;f:表示本地图片 + + + + + + 加载本地图片,加载完毕不会占用本地图片 + + + + + + 加载指定url图片 + + url位置 + 是否异步 + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 多标签控件 + + + + + + + + + + 选项发生变化时激发 + + + + + 标签选择的序号 + + + + + + + + + + 选择的颜色 + + + + + 多标签控件颜色 + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 多标签控件 + + + + + + + + + + 获取对应的标签 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 美化文本框控件 + + + + + 文本变化时激发 + + + + + 文本变化时激发 + + + + + 双击时激发 + + + + + + + + + + 是否只能输入数字 + + + + + 是否多行 + + + + + 是否在显示不下时换行 + + + + + 最大长度 + + + + + + + + + + 背景颜色 + + + + + 右键菜单 + + + + + 字体颜色 + + + + + 选择的开始位置 + + + + + 选择的长度 + + + + + 选择的文本 + + + + + 提示文本 + + + + + 选择全部 + + + + + 密码 + + + + + 是否只读 + + + + + + + + + + + 文本为空时的显示效果 + + + + + 字体 + + + + + 有内容时的显示效果 + + + + + 当文本框为空时,显示的内容。 + + + + + + + + + + 选择文本框中的文本范围 + + 文本框中当前选定文本的第一个字符的位置。 + 要选择的字符数 + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + Define some Windows message constants + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This class adds to the functionality provided in System.Windows.Forms.MenuStrip. + + It allows you to "ClickThrough" to the MenuStrip so that you don't have to click once to + bring the form into focus and once more to take the desired action + + It also implements a SuppressHighlighting property to turn off the highlighting + that occures on mouseover when the form is not active + + + + + Gets or sets whether the control honors item clicks when its containing form does + not have input focus. + + + Default value is false, which is the same behavior provided by the base ToolStrip class. + + + + + Gets or sets whether the control shows highlighting on mouseover + + + Default value is true, which is the same behavior provided by the base MenuStrip class. + + + + + This method overrides the procedure that responds to Windows messages. + + It intercepts the WM_MOUSEMOVE message + and ignores it if SuppressHighlighting is on and the TopLevelControl does not contain the focus. + Otherwise, it calls the base class procedure to handle the message. + + It also intercepts the WM_MOUSEACTIVATE message and replaces an "Activate and Eat" result with + an "Activate" result if ClickThrough is enabled. + + + + + + This class adds to the functionality provided in System.Windows.Forms.ToolStrip. + + It allows you to "ClickThrough" to the MenuStrip so that you don't have to click once to + bring the form into focus and once more to take the desired action + + It also implements a SuppressHighlighting property to turn off the highlighting + that occures on mouseover when the form is not active + + + + + Gets or sets whether the control honors item clicks when its containing form does + not have input focus. + + + Default value is false, which is the same behavior provided by the base ToolStrip class. + + + + + Gets or sets whether the control shows highlighting on mouseover + + + Default value is true, which is the same behavior provided by the base MenuStrip class. + + + + + This method overrides the procedure that responds to Windows messages. + + It intercepts the WM_MOUSEMOVE message + and ignores it if SuppressHighlighting is on and the TopLevelControl does not contain the focus. + Otherwise, it calls the base class procedure to handle the message. + + It also intercepts the WM_MOUSEACTIVATE message and replaces an "Activate and Eat" result with + an "Activate" result if ClickThrough is enabled. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 还原 + + + + + 移动 + + + + + 大小 + + + + + 最小化 + + + + + 最大化 + + + + + 关闭 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 透明图片控件 + + + + + 是否使用透明,默认为True + + + + + 设置透明度 + + + + + 要绑定的控件 + + + + + 透明图片控件 + + + + + 图片 + + + + + 初始化加载控件 + + 透明度 + 是否显示加载图片 + 图片 + + + + + + + + + + + + + + + 显示加载 + + + + + 隐藏加载 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 一个强类型的资源类,用于查找本地化的字符串等。 + + + + + 返回此类使用的缓存的 ResourceManager 实例。 + + + + + 使用此强类型资源类,为所有资源查找 + 重写当前线程的 CurrentUICulture 属性。 + + + + + 查找 System.Drawing.Bitmap 类型的本地化资源。 + + + + + 查找 System.Drawing.Bitmap 类型的本地化资源。 + + + + + + + + + + 获得当前进程,以便重绘控件 + + + + + + + 是否启用热点效果 + + + + + 边框颜色 + + + + + 热点边框颜色 + + + + + 是否鼠标MouseOver状态 + + + + + 是否启用热点效果 + + + + + 边框颜色 + + + + + 热点时边框颜色 + + + + + + + + + + 鼠标移动到该控件上时 + + + + + + 当鼠标从该控件移开时 + + + + + + 当该控件获得焦点时 + + + + + + 当该控件失去焦点时 + + + + + + 获得操作系统消息 + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 日控件 + + + + + 日控件 + + + + + 当前日期 + + + + + 在发生页码变化前激发 + + + + + 设置休息状态,1为休息,-1为上班,其它为不显示 + + + + + + 日期 + + + + + 农历 + + + + + 阳历日期字体颜色 + + + + + 阳历日期字体 + + + + + 农历日期字体 + + + + + 农历部分字体颜色 + + + + + 是否选中 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 日历控件 + + + + + 单击事件 + + + + + + + 单击某个日期事件 + + + + + 日历控件 + + + + + 设置日期 + + + + + 放假数据表 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + 设置管理类,快速添加设置。 + + + + + 设置管理类,快速添加设置。 + + + + + 设置管理类,快速添加设置。 + + + + + + 存储类型 + + + + + 配置存储路径 + + + + + 设置XML内容 + + + + + 添加控件 + + + + + + + + 设置值 + + + + + + + + 添加控件 + + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 添加控件 + + + + + + + + + 读取配置 + + + + + 保存配置 + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + 类 名:ColorHSL + 功 能:H 色相 \ S 饱和度(纯度) \ L 亮度 颜色模型 + 日 期:2015-02-08 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + HSL颜色 + + + + + + + + 色相 + + + + + 饱和度(纯度) + + + + + 饱和度 + + + + + 类 名:ColorHSV + 功 能:H 色相 \ S 饱和度(纯度) \ V 明度 颜色模型 + 日 期:2015-01-22 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + 构造方法 + + + + + + + + 色相 + + + + + 饱和度(纯度) + + + + + 明度 + + + + + 类 名:ColorRGB + 功 能:R 红色 \ G 绿色 \ B 蓝色 颜色模型 + 所有颜色模型的基类,RGB是用于输出到屏幕的颜色模式,所以所有模型都将转换成RGB输出 + 日 期:2015-01-22 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + 构造方法 + + + + + + + + + + + + + + 红色 + + + + + 绿色 + + + + + 蓝色 + + + + + 获取实际颜色 + + + + + + 类 名:ColorHelper + 功 能:提供从RGB到HSV/HSL色彩空间的相互转换 + 日 期:2015-02-08 + 修 改:2015-03-20 + 作 者:ls9512 + + + + + RGB转换HSV + + + + + + + HSV转换RGB + + + + + + + RGB转换HSL + + + + + + + HSL转换RGB + + H, S and L input range = 0 -1.0 + + + + + RGB转CMYK + + + + + + + + + + RGB转CMYK + + + + + + + + + + + + CMYK转RGB + + + + + + + + + + Standard-RGB → XYZ,X、Y、Z 使用 D65/2°标准光源. + + + + + + + + + XYZ → Standard-RGB,X、Y、Z 使用 D65/2°标准光源. + + + + + + + + + XYZ → Adobe-RGB,X、Y、Z 使用 D65/2°标准光源.RGB Adobe 1998 + + + + + + + + + Adobe-RGB → XYZ,X、Y、Z 使用 D65/2°标准光源.RGB Adobe 1998 + + + + + + + + + Yxy转RGB + + + + + + + + + RGB转Yxy + + + + + + + + + 超级颜色选择控件 + + + + + + + + + + + + + + + + + + + + + + + + + + 获取网页颜色 + + + + + 超级颜色选择控件 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要修改 + 使用代码编辑器修改此方法的内容。 + + + + + Chrome风格的多标签控件 + + + + + 设置选项卡处于选中状态时第一背景色. + + + + + 设置选项卡处于选中状态时第二背景色. + + + + + 设置选项卡处于非选中状态时第一背景色. + + + + + 设置选项卡处于非选中状态时第二背景色. + + + + + 设置鼠标移动到非选中状态选项卡时第一背景色. + + + + + 设置鼠标移动到非选中状态选项卡时第二背景色. + + + + + 设置选项卡工作区背景色. + + + + + 设置选项卡工作区背景图. + + + + + 是否显示关闭按钮 + + + + + 是否显示新增按钮 + + + + + 是否允许拖拽标签 + + + + + 标签最大宽度 + + + + + 标签右键菜单 + + + + + 鼠标按下标签时激发 + + + + + 鼠标放开标签时激发 + + + + + Chrome风格的多标签控件 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 画标签文字 + + + + + + + + + 画标签图标 + + + + + + + 画关闭按钮 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 添加新标签 + + + + + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + The position is not over a tab. + + + + + The position is over a tab's icon. + + + + + The position is over a tab's text. + + + + + The position is over a tab but not over its icon or its text. For owner-drawn tab controls, this value is specified if the position is anywhere over a tab. + TCHT_ONITEM is a bitwise-OR operation on TCHT_ONITEMICON and TCHT_ONITEMLABEL. + + + + + Specifies values from SetWindowPosZ enumeration. + + + + + Specified HWND_TOP enumeration value. + + + + + Specified HWND_BOTTOM enumeration value. + + + + + Specified HWND_TOPMOST enumeration value. + + + + + Specified HWND_NOTOPMOST enumeration value. + + + + + Invalidates the rectangle or region that you specify in lprcUpdate or hrgnUpdate. + You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_INVALIDATE invalidates the entire window. + + + + Causes the OS to post a WM_PAINT message to the window regardless of whether a portion of the window is invalid. + + + + Causes the window to receive a WM_ERASEBKGND message when the window is repainted. + Specify this value in combination with the RDW_INVALIDATE value; otherwise, RDW_ERASE has no effect. + + + + + Validates the rectangle or region that you specify in lprcUpdate or hrgnUpdate. + You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_VALIDATE validates the entire window. + This value does not affect internal WM_PAINT messages. + + + + Suppresses any pending WM_ERASEBKGND messages. + + + Excludes child windows, if any, from the repainting operation. + + + Includes child windows, if any, in the repainting operation. + + + Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values, to receive WM_ERASEBKGND and WM_PAINT messages before the RedrawWindow returns, if necessary. + + + + Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values, to receive WM_ERASEBKGND messages before RedrawWindow returns, if necessary. + The affected windows receive WM_PAINT messages at the ordinary time. + + + + + Specifies values from Msgs enumeration. + + + + + Specified WM_NULL enumeration value. + + + + + Specified WM_CREATE enumeration value. + + + + + Specified WM_DESTROY enumeration value. + + + + + Specified WM_MOVE enumeration value. + + + + + Specified WM_SIZE enumeration value. + + + + + Specified WM_ACTIVATE enumeration value. + + + + + Specified WM_SETFOCUS enumeration value. + + + + + Specified WM_KILLFOCUS enumeration value. + + + + + Specified WM_ENABLE enumeration value. + + + + + Specified WM_SETREDRAW enumeration value. + + + + + Specified WM_SETTEXT enumeration value. + + + + + Specified WM_GETTEXT enumeration value. + + + + + Specified WM_GETTEXTLENGTH enumeration value. + + + + + Specified WM_PAINT enumeration value. + + + + + Specified WM_CLOSE enumeration value. + + + + + Specified WM_QUERYENDSESSION enumeration value. + + + + + Specified WM_QUIT enumeration value. + + + + + Specified WM_QUERYOPEN enumeration value. + + + + + Specified WM_ERASEBKGND enumeration value. + + + + + Specified WM_SYSCOLORCHANGE enumeration value. + + + + + Specified WM_ENDSESSION enumeration value. + + + + + Specified WM_SHOWWINDOW enumeration value. + + + + + Specified WM_WININICHANGE enumeration value. + + + + + Specified WM_SETTINGCHANGE enumeration value. + + + + + Specified WM_DEVMODECHANGE enumeration value. + + + + + Specified WM_ACTIVATEAPP enumeration value. + + + + + Specified WM_FONTCHANGE enumeration value. + + + + + Specified WM_TIMECHANGE enumeration value. + + + + + Specified WM_CANCELMODE enumeration value. + + + + + Specified WM_SETCURSOR enumeration value. + + + + + Specified WM_MOUSEACTIVATE enumeration value. + + + + + Specified WM_CHILDACTIVATE enumeration value. + + + + + Specified WM_QUEUESYNC enumeration value. + + + + + Specified WM_GETMINMAXINFO enumeration value. + + + + + Specified WM_PAINTICON enumeration value. + + + + + Specified WM_ICONERASEBKGND enumeration value. + + + + + Specified WM_NEXTDLGCTL enumeration value. + + + + + Specified WM_SPOOLERSTATUS enumeration value. + + + + + Specified WM_DRAWITEM enumeration value. + + + + + Specified WM_MEASUREITEM enumeration value. + + + + + Specified WM_DELETEITEM enumeration value. + + + + + Specified WM_VKEYTOITEM enumeration value. + + + + + Specified WM_CHARTOITEM enumeration value. + + + + + Specified WM_SETFONT enumeration value. + + + + + Specified WM_GETFONT enumeration value. + + + + + Specified WM_SETHOTKEY enumeration value. + + + + + Specified WM_GETHOTKEY enumeration value. + + + + + Specified WM_QUERYDRAGICON enumeration value. + + + + + Specified WM_COMPAREITEM enumeration value. + + + + + Specified WM_GETOBJECT enumeration value. + + + + + Specified WM_COMPACTING enumeration value. + + + + + Specified WM_COMMNOTIFY enumeration value. + + + + + Specified WM_WINDOWPOSCHANGING enumeration value. + + + + + Specified WM_WINDOWPOSCHANGED enumeration value. + + + + + Specified WM_POWER enumeration value. + + + + + Specified WM_COPYDATA enumeration value. + + + + + Specified WM_CANCELJOURNAL enumeration value. + + + + + Specified WM_NOTIFY enumeration value. + + + + + Specified WM_INPUTLANGCHANGEREQUEST enumeration value. + + + + + Specified WM_INPUTLANGCHANGE enumeration value. + + + + + Specified WM_TCARD enumeration value. + + + + + Specified WM_HELP enumeration value. + + + + + Specified WM_USERCHANGED enumeration value. + + + + + Specified WM_NOTIFYFORMAT enumeration value. + + + + + Specified WM_CONTEXTMENU enumeration value. + + + + + Specified WM_STYLECHANGING enumeration value. + + + + + Specified WM_STYLECHANGED enumeration value. + + + + + Specified WM_DISPLAYCHANGE enumeration value. + + + + + Specified WM_GETICON enumeration value. + + + + + Specified WM_SETICON enumeration value. + + + + + Specified WM_NCCREATE enumeration value. + + + + + Specified VK_RMENU enumeration value. + + + + + Specified WM_NCCALCSIZE enumeration value. + + + + + Specified WM_NCHITTEST enumeration value. + + + + + Specified WM_NCPAINT enumeration value. + + + + + Specified WM_NCACTIVATE enumeration value. + + + + + Specified WM_GETDLGCODE enumeration value. + + + + + Specified WM_SYNCPAINT enumeration value. + + + + + Specified WM_NCMOUSEMOVE enumeration value. + + + + + Specified WM_NCLBUTTONDOWN enumeration value. + + + + + Specified WM_NCLBUTTONUP enumeration value. + + + + + Specified WM_NCLBUTTONDBLCLK enumeration value. + + + + + Specified WM_NCRBUTTONDOWN enumeration value. + + + + + Specified WM_NCRBUTTONUP enumeration value. + + + + + Specified WM_NCRBUTTONDBLCLK enumeration value. + + + + + Specified WM_NCMBUTTONDOWN enumeration value. + + + + + Specified WM_NCMBUTTONUP enumeration value. + + + + + Specified WM_NCMBUTTONDBLCLK enumeration value. + + + + + Specified WM_NCXBUTTONDOWN enumeration value. + + + + + Specified WM_NCXBUTTONUP enumeration value. + + + + + Specified WM_KEYDOWN enumeration value. + + + + + Specified WM_KEYUP enumeration value. + + + + + Specified WM_CHAR enumeration value. + + + + + Specified WM_DEADCHAR enumeration value. + + + + + Specified WM_SYSKEYDOWN enumeration value. + + + + + Specified WM_SYSKEYUP enumeration value. + + + + + Specified WM_SYSCHAR enumeration value. + + + + + Specified WM_SYSDEADCHAR enumeration value. + + + + + Specified WM_KEYLAST enumeration value. + + + + + Specified WM_IME_STARTCOMPOSITION enumeration value. + + + + + Specified WM_IME_ENDCOMPOSITION enumeration value. + + + + + Specified WM_IME_COMPOSITION enumeration value. + + + + + Specified WM_IME_KEYLAST enumeration value. + + + + + Specified WM_INITDIALOG enumeration value. + + + + + Specified WM_COMMAND enumeration value. + + + + + Specified WM_SYSCOMMAND enumeration value. + + + + + Specified WM_TIMER enumeration value. + + + + + Specified WM_HSCROLL enumeration value. + + + + + Specified WM_VSCROLL enumeration value. + + + + + Specified WM_INITMENU enumeration value. + + + + + Specified WM_INITMENUPOPUP enumeration value. + + + + + Specified WM_MENUSELECT enumeration value. + + + + + Specified WM_MENUCHAR enumeration value. + + + + + Specified WM_ENTERIDLE enumeration value. + + + + + Specified WM_MENURBUTTONUP enumeration value. + + + + + Specified WM_MENUDRAG enumeration value. + + + + + Specified WM_MENUGETOBJECT enumeration value. + + + + + Specified WM_UNINITMENUPOPUP enumeration value. + + + + + Specified WM_MENUCOMMAND enumeration value. + + + + + Specified WM_CTLCOLORMSGBOX enumeration value. + + + + + Specified WM_CTLCOLOREDIT enumeration value. + + + + + Specified WM_CTLCOLORLISTBOX enumeration value. + + + + + Specified WM_CTLCOLORBTN enumeration value. + + + + + Specified WM_CTLCOLORDLG enumeration value. + + + + + Specified WM_CTLCOLORSCROLLBAR enumeration value. + + + + + Specified WM_CTLCOLORSTATIC enumeration value. + + + + + Specified WM_MOUSEMOVE enumeration value. + + + + + Specified WM_LBUTTONDOWN enumeration value. + + + + + Specified WM_LBUTTONUP enumeration value. + + + + + Specified WM_LBUTTONDBLCLK enumeration value. + + + + + Specified WM_RBUTTONDOWN enumeration value. + + + + + Specified WM_RBUTTONUP enumeration value. + + + + + Specified WM_RBUTTONDBLCLK enumeration value. + + + + + Specified WM_MBUTTONDOWN enumeration value. + + + + + Specified WM_MBUTTONUP enumeration value. + + + + + Specified WM_MBUTTONDBLCLK enumeration value. + + + + + Specified WM_MOUSEWHEEL enumeration value. + + + + + Specified WM_XBUTTONDOWN enumeration value. + + + + + Specified WM_XBUTTONUP enumeration value. + + + + + Specified WM_XBUTTONDBLCLK enumeration value. + + + + + Specified WM_PARENTNOTIFY enumeration value. + + + + + Specified WM_ENTERMENULOOP enumeration value. + + + + + Specified WM_EXITMENULOOP enumeration value. + + + + + Specified WM_NEXTMENU enumeration value. + + + + + Specified WM_SIZING enumeration value. + + + + + Specified WM_CAPTURECHANGED enumeration value. + + + + + Specified WM_MOVING enumeration value. + + + + + Specified WM_DEVICECHANGE enumeration value. + + + + + Specified WM_MDICREATE enumeration value. + + + + + Specified WM_MDIDESTROY enumeration value. + + + + + Specified WM_MDIACTIVATE enumeration value. + + + + + Specified WM_MDIRESTORE enumeration value. + + + + + Specified WM_MDINEXT enumeration value. + + + + + Specified WM_MDIMAXIMIZE enumeration value. + + + + + Specified WM_MDITILE enumeration value. + + + + + Specified WM_MDICASCADE enumeration value. + + + + + Specified WM_MDIICONARRANGE enumeration value. + + + + + Specified WM_MDIGETACTIVE enumeration value. + + + + + Specified WM_MDISETMENU enumeration value. + + + + + Specified WM_ENTERSIZEMOVE enumeration value. + + + + + Specified WM_EXITSIZEMOVE enumeration value. + + + + + Specified WM_DROPFILES enumeration value. + + + + + Specified WM_MDIREFRESHMENU enumeration value. + + + + + Specified WM_IME_SETCONTEXT enumeration value. + + + + + Specified WM_IME_NOTIFY enumeration value. + + + + + Specified WM_IME_CONTROL enumeration value. + + + + + Specified WM_IME_COMPOSITIONFULL enumeration value. + + + + + Specified WM_IME_SELECT enumeration value. + + + + + Specified WM_IME_CHAR enumeration value. + + + + + Specified WM_IME_REQUEST enumeration value. + + + + + Specified WM_IME_KEYDOWN enumeration value. + + + + + Specified WM_IME_KEYUP enumeration value. + + + + + Specified WM_MOUSEHOVER enumeration value. + + + + + Specified WM_UNDO enumeration value. + + + + + Specified WM_RENDERFORMAT enumeration value. + + + + + Specified WM_RENDERALLFORMATS enumeration value. + + + + + Specified WM_DESTROYCLIPBOARD enumeration value. + + + + + Specified WM_DRAWCLIPBOARD enumeration value. + + + + + Specified WM_PAINTCLIPBOARD enumeration value. + + + + + Specified WM_VSCROLLCLIPBOARD enumeration value. + + + + + Specified WM_SIZECLIPBOARD enumeration value. + + + + + Specified WM_ASKCBFORMATNAME enumeration value. + + + + + Specified WM_CHANGECBCHAIN enumeration value. + + + + + Specified WM_HSCROLLCLIPBOARD enumeration value. + + + + + Specified WM_QUERYNEWPALETTE enumeration value. + + + + + Specified WM_PALETTEISCHANGING enumeration value. + + + + + Specified WM_PALETTECHANGED enumeration value. + + + + + Specified WM_HOTKEY enumeration value. + + + + + Specified WM_PRINT enumeration value. + + + + + Specified WM_PRINTCLIENT enumeration value. + + + + + Specified WM_HANDHELDFIRST enumeration value. + + + + + Specified WM_HANDHELDLAST enumeration value. + + + + + Specified WM_AFXFIRST enumeration value. + + + + + Specified WM_AFXLAST enumeration value. + + + + + Specified WM_PENWINFIRST enumeration value. + + + + + Specified WM_PENWINLAST enumeration value. + + + + + Specified WM_APP enumeration value. + + + + + Specified WM_USER enumeration value. + + + + + Specified WM_REFLECT enumeration value. + + + + + Specified WM_THEMECHANGED enumeration value. + + + + + The GetParent function retrieves a handle to the specified window's parent or owner. + + Handle to the window whose parent window handle is to be retrieved. + If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is a handle to the owner window. If the window is a top-level unowned window or if the function fails, the return value is NULL. + + + + The FindWindowEx function retrieves a handle to a window whose class name and window name match the specified strings. The function searches child windows, beginning with the one following the specified child window. + + Handle to the parent window whose child windows are to be searched. + Handle to a child window. + Specifies class name. + Pointer to a null-terminated string that specifies the window name (the window's title). + If the function succeeds, the return value is a handle to the window that has the specified class and window names.If the function fails, the return value is NULL. + + + + The InvalidateRect function adds a rectangle to the specified window's update region. + + Handle to window. + Rectangle coordinates. + Erase state. + If the function succeeds, the return value is true.If the function fails, the return value is false. + + + + The ValidateRect function validates the client area within a rectangle by removing the rectangle from the update region of the specified window. + + Handle to window. + Validation rectangle coordinates. + If the function succeeds, the return value is true.If the function fails, the return value is false. + + + + Changes the size, position, and Z order of a child, pop-up, or top-level window. + These windows are ordered according to their appearance on the screen. + The topmost window receives the highest rank and is the first window in the Z order. + + A handle to the window. + A handle to the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values. + Specifies the new position of the left side of the window, in client coordinates. + Specifies the new position of the top of the window, in client coordinates. + Specifies the new width of the window, in pixels. + Specifies the new height of the window, in pixels. + Specifies the window sizing and positioning flags. This parameter can be a combination of the following values. + If the function succeeds, the return value is nonzero, if the function fails, the return value is zero. + + + + + + + + + 关键词 + + + + + 密码 + + + + + 权限用户id + + + + + + + + + + + + + 返回关键词 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 树形控件,用于分类用 + + + + + 显示在第一位的名称 + + + + + 是否显示菜单 + + + + + 树形控件 + + + + + 判断指定节点是否是目标节点的子节点 + + + + + + + + + 判断当前节点,当前用户是否有权限访问 + + + + + + + + + 权限事件 + + + + + + + + 选择权限用户时发生 + + + + + 数据变化时发生 + + + + + 数据变化前发生 + + + + + 操作事件 + + + + + + + 在添加分组前发生 + + + + + 在修改分组前发生 + + + + + 在删除分组前发生 + + + + + 在设置密码前发生 + + + + + 在设置权限前发生 + + + + + 获取新的关键词分类 + + + + + + 根据id获取节点 + + + + + + + 根据节点获取节点信息 + + + + + + + 设置节点信息 + + + + + + + 设置节点关键词和密码 + + + + + + + + 设置节点密码 + + + + + + + 设置节点关键词 + + + + + + + 设置节点用户 + + + + + + + RecursionTreeControl:表示将XML文件的内容显示在TreeView控件中 + + 将要加载的XML文件中的节点元素 + 将要加载的XML文件中的节点集合 + + + + 把XML文本载入到列表中 + + + + + + 把XML文件载入到列表中 + + + + + + 将列表保存为xml文本 + + + + + + 改变所有子节点的状态 + + + + + + + 反选子节点 + + + + + + 根据关键词来选中列表 + + + + + + 根据关键词来选中列表 + + + + + + 格式化关键字(会去除重复项),以便存入数据库 + + + + + + + 去除掉重复项 + + + + + + + 获取当前选中项以及所有父项的关键词组合 + + + + + + 获取选中的 + + + + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + + + + + + 是否为添加 + + + + + 选择的文本 + + + + + 选择的Tag + + + + + 选择的图片序号 + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + + + + + + + + + + + 旧密码 + + + + + 新密码 + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + + 颜色标签 + + + + + 行间距 + + + + + 颜色标签 + + + + + 更新 + + + + + 字体高度 + + + + + 控件高 + + + + + 控件文本 + + + + + 获取过滤掉颜色的字 + + + + + + + 改变字体 + + + + + + + + + + + + + + 分页控件 + + + + + 首页文本 + + + + + 上一页文本 + + + + + 下一页文本 + + + + + 末页文本 + + + + + 跳页文本 + + + + + 页面信息文本 + + + + + 存储SQL参数 + + + + + 最后一页的页码 + + + + + 在发生页码变化时激发 + + + + + 在发生页码变化前激发 + + + + + 设置/返回每页显示的量大小 + + + + + 设置/返回记录总数 + + + + + 设置/返回分页SQL语句,{pagecount}表示页数,{recordcount}表示记录总数,{pagesize}表示页面大小, + {pageindex}表示当前页数,{recordnum}表示当前页记录数,{pageendnum}表示当前页最后一条记录的记录数 + + + + + 设置/返回当{recordnum}小于等于0时的分页SQL语句(比如第一页),如果为空,则默认使用SQLText值。{pagecount}表示页数, + {recordcount}表示记录总数,{pagesize}表示页面大小,{pageindex}表示当前页数,{recordnum}表示当前页记录数,{pageendnum}表示当前页最后一条记录的记录数 + + + + + 获取当前页码 + + + + + + 设置分页语句为MSSQL分页语句 + + 表名 + 条件判断sql语句,注意不包含where,以及不包含排序语句;,如果不存在条件判断语句,请为空 + 排序语句,必须包含Order By;,如果不存在排序语句,请为空 + + + + + 获取MSSQL数据库指定条件的记录总数 + + 表名 + 条件判断sql语句,注意不包含where,以及不包含排序语句;,如果不存在条件判断语句,请为空 + 排序语句,必须包含Order By;,如果不存在排序语句,请为空 + + + + + 设置分页语句为SQLite分页语句 + + 表名 + 条件判断sql语句,注意不包含where,可包含order by,如果不存在条件判断语句,请为空 + + + + + 获取SQLite数据库指定条件的记录总数 + + 表名 + 条件判断sql语句,注意不包含where,可包含order by,如果不存在条件判断语句,请为空 + + + + + 返回分页SQL语句 + + + + + 分页控件 + + + + + 设置当前页为指定页 + + + + + + 下一页 + + + + + 上一页 + + + + + 末页 + + + + + 首页 + + + + + 必需的设计器变量。 + + + + + 清理所有正在使用的资源。 + + 如果应释放托管资源,为 true;否则为 false。 + + + + 设计器支持所需的方法 - 不要 + 使用代码编辑器修改此方法的内容。 + + + + + 自动排列控件 + + + + + 最大列数 + + + + + 开始排列的坐标 + + + + + 下一项的位置 + + + + + 下一项的右下角坐标 + + + + + 竖向间隔像素 + + + + + 横向间隔像素 + + + + + 最小保留右边距,只对ReDraw2有效 + + + + + 自动排列控件构造函数 + + + + + + 自动排列控件构造函数 + + + + + + + + 开始排列控件 + + + + + 开始排列控件,当列数超过显示空间时,自动换行 + + + + + 加入的控件列表 + + + + + 初始化添加,自动将容器设置为滚动条自动显示 + + + + + + 添加控件 + + + + + + + 删除控件 + + + + + + 删除控件 + + + + + + 清空所有控件 + + + + + An object list displays 'aspects' of a collection of objects in a listview control. + + + + The intelligence for this control is in the columns. OLVColumns are + extended so they understand how to fetch an 'aspect' from each row + object. They also understand how to sort by their aspect, and + how to group them. + + + Aspects are extracted by giving the name of a method to be called or a + property to be fetched. These names can be simple names or they can be dotted + to chain property access e.g. "Owner.Address.Postcode". + Aspects can also be extracted by installing a delegate. + + + Sorting by column clicking and grouping by column are handled automatically. + + + Right clicking on the column header should present a popup menu that allows the user to + choose which columns will be visible in the list. This behaviour can be disabled by + setting SelectColumnsOnRightClick to false. + + + This list puts sort indicators in the column headers to show the column sorting direction. + On Windows XP and later, the system standard images are used. + If you wish to replace the standard images with your own images, put entries in the small image list + with the key values "sort-indicator-up" and "sort-indicator-down". + + + For these classes to build correctly, the project must have references to these assemblies: + + System.Data + System.Design + System.Drawing + System.Windows.Forms (obviously) + + + + + + + Create an ObjectListView + + + + + Get or set all the columns that this control knows about. + Only those columns where IsVisible is true will be seen by the user. + + If you want to add new columns programmatically, add them to + AllColumns and then call RebuildColumns(). Normally, you do not have to + deal with this property directly. Just use the IDE. + + + + If every second row has a background different to the control, what color should it be? + + + + + Return the alternate row background color that has been set, or the default color + + + + + This property forces the ObjectListView to always group items by the given column. + + + + + If AlwaysGroupByColumn is not null, this property will be used to decide how + those groups are sorted. If this property has the value SortOrder.None, then + the sort order will toggle according to the users last header click. + + + + + Give access to the image list that is actually being used by the control + + + + + How does a user indicate that they want to edit cells? + + + + + This list cannot be edited. F2 does nothing. + + + + + A single click on a subitem will edit the value. Single clicking the primary column, + selects the row just like normal. The user must press F2 to edit the primary column. + + + + + Double clicking a subitem or the primary column will edit that cell. + F2 will edit the primary column. + + + + + Pressing F2 is the only way to edit the cells. Once the primary column is being edited, + the other cells in the row can be edited by pressing Tab. + + + + + How does the user indicate that they want to edit a cell? + None means that the listview cannot be edited. + + Columns can also be marked as editable. + + + + Return the model object of the row that is checked or null if no row is checked + or more than one row is checked + + + + + Get or set the collection of model objects that are checked. + When setting this property, any row whose model object isn't + in the given collection will be unchecked. Setting to null is + equivilent to unchecking all. + + + + This property returns a simple collection. Changes made to the returned + collection do NOT affect the list. This is different to the behaviour of + CheckedIndicies collection. + + + The CheckedItems property is not helpful. It is just a short-hand for + iterating through the list looking for items that are checked. + + + The performance of this method is O(n). Be careful on long lists. + + + + + + Get/set the list of columns that should be used when the list switches to tile view. + + If no list of columns has been installed, this value will default to the + first column plus any column where IsTileViewColumn is true. + + + + Return the visible columns in the order they are displayed to the user + + + + + If there are no items in this list view, what message should be drawn onto the control? + + + + + What font should the 'list empty' message be drawn in? + + + + + Return the font for the 'list empty' message or a default + + + + + Get or set whether or not the listview is frozen. When the listview is + frozen, it will not update itself. + + The Frozen property is similar to the methods Freeze()/Unfreeze() + except that changes to the Frozen property do not nest. + objectListView1.Frozen = false; // unfreeze the control regardless of the number of Freeze() calls + + + + + When a group title has an item count, how should the lable be formatted? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group + + + "{0} [{1} items]" + + + + Return this.GroupWithItemCountFormat or a reasonable default + + + + + When a group title has an item count, how should the lable be formatted if + there is only one item in the group? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group (always 1) + + + "{0} [{1} item]" + + + + Return this.GroupWithItemCountSingularFormat or a reasonable default + + + + + Does this listview have a message that should be drawn when the list is empty? + + + + + What color should be used for the background of selected rows? + + Windows does not give the option of changing the selection background. + So this color is only used when control is owner drawn and when columns have a + renderer installed -- a basic new BaseRenderer() will suffice. + + + + Return the color should be used for the background of selected rows or a reasonable default + + + + + Setup the list so it will draw selected rows using custom colours. + + + This method makes the list owner drawn, and ensures that all columns have at + least a BaseRender installed. + + + + + What color should be used for the foreground of selected rows? + + Windows does not give the option of changing the selection foreground (text color). + So this color is only used when control is owner drawn and when columns have a + renderer installed -- a basic new BaseRenderer() will suffice. + + + + Return the color should be used for the foreground of selected rows or a reasonable default + + + + + Return true if a cell edit operation is currently happening + + + + + Get/set the collection of objects that this list will show + + The contents of the control will be updated immediately after setting this property + + + + Take ownership of the 'objects' collection. This separats our collection from the source. + + + + This method + separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject + calls will modify our collection and not the original colleciton. + + + This method has the intentional side-effect of converting our list of objects to an ArrayList. + + + + + + Specify the height of each row in the control in pixels. + + The row height in a listview is normally determined by the font size and the small image list size. + This setting allows that calculation to be overridden (within reason: you still cannot set the line height to be + less than the line height of the font used in the control). + Setting it to -1 means use the normal calculation method. + This feature is experiemental! Strange things may happen to your program, + your spouse or your pet if you use it. + + + + + Get/set the column that will be used to resolve comparisons that are equal when sorting. + + There is no user interface for this setting. It must be set programmatically. + The default is the first column. + + + + When the SecondarySortColumn is used, in what order will it compare results? + + + + + When the user right clicks on the column headers, should a menu be presented which will allow + them to choose which columns will be shown in the view? + + + + + When the column select menu is open, should it stay open after an item is selected? + Staying open allows the user to turn more than one column on or off at a time. + + + + + Return the index of the row that is currently selected. If no row is selected, + or more than one is selected, return -1. + + + + + Get the ListViewItem that is currently selected . If no row is selected, or more than one is selected, return null. + + + + + Get the model object from the currently selected row. If no row is selected, or more than one is selected, return null. + Select the row that is displaying the given model object. All other rows are deselected. + + + + + Get the model objects from the currently selected rows. If no row is selected, the returned List will be empty. + When setting this value, select the rows that is displaying the given model objects. All other rows are deselected. + + + + + Should the list view show a bitmap in the column header to show the sort direction? + + + The only reason for not wanting to have sort indicators is that, on pre-XP versions of + Windows, having sort indicators required the ListView to have a small image list, and + as soon as you give a ListView a SmallImageList, the text of column 0 is bumped 16 + pixels to the right, even if you never used an image. + + + + + Should the list view show images on subitems? + + + Under Windows, this works by sending messages to the underlying + Windows control. To make this work under Mono, we would have to owner drawing the items :-( + + + + This property controls whether group labels will be suffixed with a count of items. + + + The format of the suffix is controlled by GroupWithItemCountFormat/GroupWithItemCountSingularFormat properties + + + + + Override the SmallImageList property so we can correctly shadow its operations. + + If you use the RowHeight property to specify the row height, the SmallImageList + must be fully initialised before setting/changing the RowHeight. If you add new images to the image + list after setting the RowHeight, you must assign the imagelist to the control again. Something as simple + as this will work: + listView1.SmallImageList = listView1.SmallImageList; + + + + + When the listview is grouped, should the items be sorted by the primary column? + If this is false, the items will be sorted by the same column as they are grouped. + + + + + When resizing a column by dragging its divider, should any space filling columns be + resized at each mouse move? If this is false, the filling columns will be + updated when the mouse is released. + + + I think that this looks very ugly, but it does give more immediate feedback. + It looks ugly because every + column to the right of the divider being dragged gets updated twice: once when + the column be resized changes size (this moves + all the columns slightly to the right); then again when the filling columns are updated, but they will be shrunk + so that the combined width is not more than the control, so everything jumps slightly back to the left again. + + + + + Should the list give a different background color to every second row? + + The color of the alternate rows is given by AlternateRowBackColor. + There is a "feature" in .NET for listviews in non-full-row-select mode, where + selected rows are not drawn with their correct background color. + + + + Get/set the style of view that this listview is using + + Switching to tile or details view installs the columns appropriate to that view. + Confusingly, in tile view, every column is shown as a row of information. + + + + This delegate can be used to sort the table in a custom fasion. + + + + What the delegate has to do depends on the type of ObjectListView it is sorting: + + + + If it is sorting a normal ObjectListView, the delegate must install a ListViewItemSorter on the ObjectListView. This install ItemSorter will actually do the work of sorting the ListViewItems. See ColumnComparer in the code for an example of what an ItemSorter has to do. + + + If the delegate is sorting a VirtualObjectListView or a FastObjectListView, the delegate must sort the model objects that are sourcing the list (remember, in a virtual list, the application holds the model objects and the list just askes for them as it needs them). + + + + + + + This delegate can be used to format a OLVListItem before it is added to the control. + + + The model object for the row can be found through the RowObject property of the OLVListItem object. + All subitems normally have the same style as list item, so setting the forecolor on one + subitem changes the forecolor of all subitems. + To allow subitems to have different attributes, do this:myListViewItem.UseItemStyleForSubItems = false;. + + If UseAlternatingBackColors is true, the backcolor of the listitem will be calculated + by the control and cannot be controlled by the RowFormatter delegate. In general, trying to use a RowFormatter + when UseAlternatingBackColors is true does not work well. + + + + This delegate will be called whenever the ObjectListView needs to know the check state + of the row associated with a given model object + + + + + This delegate will be called whenever the user tries to change the check state + of a row. The delegate should return the value that the listview should actuall + use, which may be different to the one given to the delegate. + + + + + Set the collection of objects that will be shown in this list view. + + This method can safely be called from background threads. + The list is updated immediately + The objects to be displayed + + + + Add the given model object to this control. + + The model object to be displayed + See AddObjects() for more details + + + + Add the given collection of model objects to this control. + + A collection of model objects + + The added objects will appear in their correct sort position, if sorting + is active. Otherwise, they will appear at the end of the list. + No check is performed to see if any of the objects are already in the ListView. + The method uses the ObjectsAsList property. See that property for a + description of what is does. + Null objects are silently ignored. + + + + + Remove the given model object from the ListView + + The model to be removed + See RemoveObjects() for more details + + + + Remove all of the given objects from the control + + Collection of objects to be removed + + Nulls and model objects that are not in the ListView are silently ignored. + + + + + Update the list to reflect the contents of the given collection, without affecting + the scrolling position, selection or sort order. + + The objects to be displayed + + This method is about twice as slow as SetObjects(). + This method is experimental -- it may disappear in later versions of the code. + There has to be a better way to do this! JPP 15/1/2008 + In most situations, if you need this functionality, use a FastObjectListView instead. JPP 2/2/2008 + + + + + Remove all items from this list + + This method can safely be called from background threads. + + + + Build/rebuild all the list view items in the list + + + + + Build/rebuild all the list view items in the list + + If this is true, the control will try to preserve the selection + and the scroll position (see Remarks) + + + + Use this method in situations were the contents of the list is basically the same + as previously. + + + Due to limitations in .NET's ListView, the scroll position is only preserved if + the control is in Details view AND it is not showing groups. + + + + + + Get or set the index of the top item of this listview + + + + This property only works when the listview is in Details view and not showing groups. + + + The reason that it does not work when showing groups is that, when groups are enabled, + the Windows message LVM_GETTOPINDEX always returns 0, regardless of the + scroll position. + + + + + + Sort the items by the last sort column + + + + + Organise the view items into groups, based on the last sort column or the first column + if there is no last sort column + + + + + Organise the view items into groups, based on the given column + + If the AlwaysGroupByColumn property is not null, + the list view items will be organisd by that column, + and the 'column' parameter will be ignored. + The column whose values should be used for sorting. + + + + Pause (or unpause) all animations in the list + + true to pause, false to unpause + + + + Give the listview a reasonable size of its tiles, based on the number of lines of + information that each tile is going to display. + + + + + Rebuild this list for the given view + + + + + + Rebuild the columns based upon its current view and column visibility settings + + + + + Copy a text and html representation of the selected rows onto the clipboard. + + Be careful when using this with virtual lists. If the user has selected + 10,000,000 rows, this method will faithfully try to copy all of them to the clipboard. + From the user's point of view, your program will appear to have hung. + + + + Copy a text and html representation of the given objects onto the clipboard. + + + + + Convert the fragment of HTML into the Clipboards HTML format. + + The HTML format is found here http://msdn2.microsoft.com/en-us/library/aa767917.aspx + + The HTML to put onto the clipboard. It must be valid HTML! + A string that can be put onto the clipboard and will be recognized as HTML + + + + Return a byte array that represents the current state of the ObjectListView, such + that the state can be restored by RestoreState() + + + The state of an ObjectListView includes the attributes that the user can modify: + + current view (i.e. Details, Tile, Large Icon...) + sort column and direction + column order + column widths + column visibility + + + + It does not include selection or the scroll position. + + + A byte array representing the state of the ObjectListView + + + + Restore the state of the control from the given string, which must have been + produced by SaveState() + + A byte array returned from SaveState() + Returns true if the state was restored + + + + Instances of this class are used to store the state of an ObjectListView. + + + + + Event handler for the column click event + + + + + Handle when a user checks/unchecks a row + + + + + Override the basic message pump for this control + + + + + + Perform any steps needed before painting the control + + + + + Perform any steps needed after painting the control + + + + + When the control is created capture the messages for the header. + + + + + Class used to capture window messages for the header of the list view + control. + + We only need this class in order to not change the cursor + when the cursor is over the divider of a fixed width column. It + really is a little too perfectionist even for me. + + + + Return the Windows handle behind this control + + + When an ObjectListView is initialized as part of a UserControl, the + GetHeaderControl() method returns 0 until the UserControl is + completely initialized. So the AssignHandle() call in the constructor + doesn't work. So we override the Handle property so value is always + current. + + + + + Return the index of the column under the current cursor position, + or -1 if the cursor is not over a column + + Index of the column under the cursor, or -1 + + + + The user wants to see the context menu. + + The windows message + A bool indicating if this message has been handled + + We want to ignore context menu requests that are triggered by right clicks on the header + + + + + In the notification messages, we handle attempts to change the width of our columns + + The msg to be processed + bool to indicate if the msg has been handled + + + + The user has right clicked on the column headers. Do whatever is required + + Return true if this event has been handle + + + + The user has right clicked on the column headers. Do whatever is required + + Return true if this event has been handle + + + + Tell the world when a cell is about to finish being edited. + + + + + The callbacks for RightColumnClick events + + + + + Triggered when a column header is right clicked. + + + + + Show a popup menu at the given point which will allow the user to choose which columns + are visible on this listview + + Where should the menu be placed + + + + Append the column selection menu items to the given menu strip. + + The menu to which the items will be added. If this is null, a new + ContextMenuStrip will be created + Return the menu to which the items were added + + + + Override the OnColumnReordered method to do what we want + + + + + + Resize our space filling columns so they fill any unoccupied width in the control + + + + + Change the given item from the old check value to a new one + + The item to be change + The old value of the check + The new value of the check + + + + Change the given item from the old check value to a new one + + The item to be change + The old value of the check + The new value of the check + + + + Return true of the given object is checked + + The model object whose checkedness is returned + Is the given object checked? + If the given object is not in the list, this method returns false. + + + + Return the OLVListItem that displays the given model object + + The modelObject whose item is to be found + The OLVListItem that displays the model, or null + This method has O(n) performance. + + + + Toggle the checkedness of the given object + + The model object to be checked + + + + Mark the given object as checked in the list + + The model object to be checked + + + + Mark the given object as unchecked in the list + + The model object to be unchecked + + + + Return the column at the given index + + Index of the column to be returned + An OLVColumn + + + + Return the column at the given title. + + Name of the column to be returned + An OLVColumn + + + + Return the number of items in the list + + the number of items in the list + + + + Return the item at the given index + + Index of the item to be returned + An OLVListItem + + + + Return the model object at the given index + + Index of the model object to be returned + A model object + + + + Find the item and column that are under the given co-ords + + X co-ord + Y co-ord + The column under the given point + The item under the given point. Can be null. + + + + Select all rows in the listview + + + + + Deselect all rows in the listview + + + + + Return the model object of the row that is selected or null if there is no selection or more than one selection + + Model object or null + + + + Return the model objects of the rows that are selected or an empty collection if there is no selection + + ArrayList + + + + Return the model object of the row that is checked or null if no row is checked + or more than one row is checked + + Model object or null + Use CheckedObject property instead of this method + + + + Get the collection of model objects that are checked. + + Use CheckedObjects property instead of this method + + + + Select the row that is displaying the given model object. All other rows are deselected. + + The object to be selected or null to deselect all + + + + Select the rows that is displaying any of the given model object. All other rows are deselected. + + A collection of model objects + + + + Update the ListViewItem with the data from its associated model. + + This method does not resort or regroup the view. It simply updates + the displayed data of the given item + + + + Update the rows that are showing the given objects + + This method does not resort or regroup the view. + + + + Update the rows that are showing the given objects + + + This method does not resort or regroup the view. + This method can safely be called from background threads. + + + + + Update the rows that are selected + + This method does not resort or regroup the view. + + + + Find the given model object within the listview and return its index + + Technically, this method will work with virtual lists, but it will + probably be very slow. + The model object to be found + The index of the object. -1 means the object was not present + + + + Return the ListViewItem that appears immediately after the given item. + If the given item is null, the first item in the list will be returned. + Return null if the given item is the last item. + + The item that is before the item that is returned, or null + A ListViewItem + + + + Return the ListViewItem that appears immediately before the given item. + If the given item is null, the last item in the list will be returned. + Return null if the given item is the first item. + + The item that is before the item that is returned + A ListViewItem + + + + Freeze the listview so that it no longer updates itself. + + Freeze()/Unfreeze() calls nest correctly + + + + Unfreeze the listview. If this call is the outermost Unfreeze(), + the contents of the listview will be rebuilt. + + Freeze()/Unfreeze() calls nest correctly + + + + Do the actual work required when the listview is unfrozen + + + + + Sort the items in the list view by the values in the given column. + If ShowGroups is true, the rows will be grouped by the given column, + otherwise, it will be a straight sort. + + The name of the column whose values will be used for the sorting + + + + Sort the items in the list view by the values in the given column. + If ShowGroups is true, the rows will be grouped by the given column, + otherwise, it will be a straight sort. + + The index of the column whose values will be used for the sorting + + + + Sort the items in the list view by the values in the given column. + If ShowGroups is true, the rows will be grouped by the given column, + otherwise, it will be a straight sort. + + The column whose values will be used for the sorting + + + + Put a sort indicator next to the text of the sort column + + + + + Put a sort indicator next to the text of the given given column + + The column to be marked + The sort order in effect on that column + + + + The name of the image used when a column is sorted ascending + + This image is only used on pre-XP systems. System images are used for XP and later + + + + The name of the image used when a column is sorted descending + + This image is only used on pre-XP systems. System images are used for XP and later + + + + If the sort indicator images don't already exist, this method will make and install them + + + + + Fill in the given OLVListItem with values of the given row + + the OLVListItem that is to be stuff with values + the model object from which values will be taken + + + + Setup all subitem images on all rows + + + + + Tell the underlying list control which images to show against the subitems + + the index at which the item occurs + the item whose subitems are to be set + + + + Tell the underlying list control which images to show against the subitems + + the index at which the item occurs + the item whose subitems are to be set + will existing images be cleared if no new image is provided? + + + + Prepare the listview to show alternate row backcolors + + We cannot rely on lvi.Index in this method. + In a straight list, lvi.Index is the display index, and can be used to determine + whether the row should be colored. But when organised by groups, lvi.Index is not + useable because it still refers to the position in the overall list, not the display order. + + + + + For some reason, UseItemStyleForSubItems doesn't work for the colors + when owner drawing the list, so we have to specifically give each subitem + the desired colors + + The item whose subitems are to be corrected + + + + Convert the given image selector to an index into our image list. + Return -1 if that's not possible + + + Index of the image in the imageList, or -1 + + + + Make sure the ListView has the extended style that says to display subitem images. + + This method must be called after any .NET call that update the extended styles + since they seem to erase this setting. + + + + For the given item and subitem, make it display the given image + + row number (0 based) + subitem (0 is the item itself) + index into the image list + + + + Update our externally visible image list so it holds the same images as our shadow list, but sized correctly + + + + + Return a copy of the given source image list, where each image has been resized to be height x height in size. + If source is null, an empty image list of the given size is returned + + Height and width of the new images + Source of the images (can be null) + A new image list + + + + Return a bitmap of the given height x height, which shows the given image, centred. + + Height and width of new bitmap + Image to be centred + The background color + A new bitmap + + + + Owner draw the column header + + + + + + Owner draw the item + + + + + + Owner draw a single subitem + + + + + + This method is called every time a row is selected or deselected. This can be + a pain if the user shift-clicks 100 rows. We override this method so we can + trigger one event for any number of select/deselects that come from one user action + + + + + + The application is idle. Trigger a SelectionChanged event. + + + + + + + This event is triggered once per user action that changes the selection state + of one or more rows. + + + + + Trigger the SelectionChanged event + + + + + + We need the click count in the mouse up event, but that is always 1. + So we have to remember the click count from the preceding mouse down event. + + + + + + Check to see if we need to start editing a cell + + + + + + Should we start editing the cell? + + + + + + + Handle a key press on this control. We specifically look for F2 which edits the primary column, + or a Tab character during an edit operation, which tries to start editing on the next (or previous) cell. + + + + + + + Begin an edit operation on the given cell. + + This performs various sanity checks and passes off the real work to StartCellEdit(). + The row to be edited + The index of the cell to be edited + + + + Really start an edit operation on a given cell. The parameters are assumed to be sane. + + The row to be edited + The index of the cell to be edited + + + + Try to give the given value to the provided control. Fall back to assigning a string + if the value assignment fails. + + A control + The value to be given to the control + The string to be given if the value doesn't work + + + + Setup the given control to be a cell editor + + + + + Return the value that the given control is showing + + + + + + + Called when the cell editor could be about to lose focus. Time to commit the change + + + + + + + Return the bounds of the given cell + + The row to be edited + The index of the cell to be edited + A Rectangle + + + + Return a control that can be used to edit the value of the given cell. + + The row to be edited + The index of the cell to be edited + + + + + Return a TextBox that can be used as a default cell editor. + + What column does the cell belong to? + + + + + Stop editing a cell and throw away any changes. + + + + + If a cell edit is in progress, finish the edit + + Returns false if the finishing process was cancelled + (i.e. the cell editor is still on screen) + + + + Finish the cell edit operation, writing changed data back to the model object + + + + + Remove all trace of any existing cell edit operation + + + + + The callbacks for CellEditing events + + + + + Triggered when a cell is about to be edited. + + Set Cancel to true to prevent the cell being edited. + You can change the the Control to be something completely different. + + + + Triggered when a cell editor needs to be validated + + + If this event is cancelled, focus will remain on the cell editor. + + + + + Triggered when a cell is about to finish being edited. + + If Cancel is already true, the user is cancelling the edit operation. + Set Cancel to true to prevent the value from the cell being written into the model. + You cannot prevent the editing from finishing. + + + + Tell the world when a cell is about to be edited. + + + + + Tell the world when a cell is about to finish being edited. + + + + + Tell the world when a cell is about to finish being edited. + + + + + Let the world know that a cell edit operation is beginning or ending + + + + + Create an event args + + + + + + + + + + Change this to true to cancel the cell editing operation. + + + During the CellEditStarting event, setting this to true will prevent the cell from being edited. + During the CellEditFinishing event, if this value is already true, this indicates that the user has + cancelled the edit operation and that the handler should perform cleanup only. Setting this to true, + will prevent the ObjectListView from trying to write the new value into the model object. + + + + + During the CellEditStarting event, this can be modified to be the control that you want + to edit the value. You must fully configure the control before returning from the event, + including its bounds and the value it is showing. + During the CellEditFinishing event, you can use this to get the value that the user + entered and commit that value to the model. Changing the control during the finishing + event has no effect. + + + + + The column of the cell that is going to be or has been edited. + + + + + The model object of the row of the cell that is going to be or has been edited. + + + + + The listview item of the cell that is going to be or has been edited. + + + + + The index of the cell that is going to be or has been edited. + + + + + The data value of the cell before the edit operation began. + + + + + The bounds of the cell that is going to be or has been edited. + + + + + This editor simply shows and edits integer values. + + + + + This editor simply shows and edits unsigned integer values. + + + + + This editor simply shows and edits boolean values. + + You can intercept the CellEditStarting event if you want + to change the characteristics of the editor. For example, by changing + the labels to "No" and "Yes". The false value must come first. + + + + This editor simply shows and edits floating point values. + + You can intercept the CellEditStarting event if you want + to change the characteristics of the editor. For example, by increasing + the number of decimal places. + + + + This editor shows and auto completes values from the given listview column. + + + + + Return a collection of columns that are appropriate to the given view. + Only Tile and Details have columns; all other views have 0 columns. + + Which view are the columns being calculate for? + A list of columns + + + + This class works in conjunction with the OLVColumns property to allow OLVColumns + to be added to the ObjectListView. + + + + + Return Columns for this list. We hide the original so we can associate + a specialised editor with it. + + + + + Which column did we last sort by + + + + + Which direction did we last sort + + + + + Wrapper for all native method calls on ListView controls + + + + + Notify message header structure. + + + + + Make sure the ListView has the extended style that says to display subitem images. + + This method must be called after any .NET call that update the extended styles + since they seem to erase this setting. + The listview to send a message to + + + + For the given item and subitem, make it display the given image + + The listview to send a message to + row number (0 based) + subitem (0 is the item itself) + index into the image list + + + + Setup the given column of the listview to show the given image to the right of the text. + If the image index is -1, any previous image is cleared + + The listview to send a message to + Index of the column to modifiy + + Index into the small image list + + + + Does this version of the operating system have builtin sort indicators? + + Are there builtin sort indicators + XP and later have these + + + + Return the bounds of the update region on the given control. + + The BeginPaint() system call validates the update region, effectively wiping out this information. + So this call has to be made before the BeginPaint() call. + The control whose update region is be calculated + A rectangle + + + + Validate an area of the given control. A validated area will not be repainted at the next redraw. + + The control to be validated + The area of the control to be validated + + + + Select all rows on the given listview + + The listview whose items are to be selected + + + + Deselect all rows on the given listview + + The listview whose items are to be deselected + + + + Set the item state on the given item + + The listview whose item's state is to be changed + The index of the item to be changed + Which bits of the value are to be set? + The value to be set + + + + Return the handle to the header control on the given list + + The listview whose header control is to be returned + The handle to the header control + + + + Return the index of the divider under the given point. Return -1 if no divider is under the pt + + The list we are interested in + The client co-ords + The index of the divider under the point, or -1 if no divider is under that point + + + + Return the index of the column of the header that is under the given point. + Return -1 if no column is under the pt + + The list we are interested in + The client co-ords + The index of the column under the point, or -1 if no column header is under that point + + + + Get the scroll position of the given scroll bar + + + + + + + + A virtual object list view operates in virtual mode, that is, it only gets model objects for + a row when it is needed. This gives it the ability to handle very large numbers of rows with + minimal resources. + + A listview is not a great user interface for a large number of items. But if you've + ever wanted to have a list with 10 million items, go ahead, knock yourself out. + Virtual lists can never iterate their contents. That would defeat the whole purpose. + Given the above, grouping and sorting are not possible on virtual lists. But if the backing data store has + a sorting mechanism, a CustomSorter can be installed which will be called when the sorting is required. + For the same reason, animate GIFs should not be used in virtual lists. Animated GIFs require some state + information to be stored for each animation, but virtual lists specifically do not keep any state information. + You really do not want to keep state information for 10 million animations! + + + + + Create a VirtualObjectListView + + + + + This delegate is used to fetch a rowObject, given it's index within the list + + + + + Return the number of items in the list + + the number of items in the list + + + + Return the item at the given index + + Index of the item to be returned + An OLVListItem + + + + Return the model object at the given index + + Index of the model object to be returned + A model object + + + + Remove all items from this list + + This method can safely be called from background threads. + + + + Select the row that is displaying the given model object. + This does nothing in virtual lists. + + This is a no-op for virtual lists, since there is no way to map the model + object back to the ListViewItem that represents it. + The object that gave data + + + + Select the rows that is displaying any of the given model object. + This does nothing in virtual lists. + + This is a no-op for virtual lists, since there is no way to map the model + objects back to the ListViewItem that represents them. + A collection of model objects + + + + Update the rows that are showing the given objects + + This is a no-op for virtual lists, since there is no way to map the model + objects back to the ListViewItem that represents them. + + + + Add the given collection of model objects to this control. + + A collection of model objects + This is a no-op for virtual lists, since the control + does not have a list of model objects to which it can add this new one. + All model object management is done by the application. + + + + Remove all of the given objects from the control + + Collection of objects to be removed + This is a no-op for virtual lists, since the control + does not have a list of model objects from which it can remove these ones. + All model object management is done by the application. + + + + Invalidate any cached information when we rebuild the list. + + + + + Prepare the listview to show alternate row backcolors + + Alternate colored backrows can't be handle in the same way as our base class. + With virtual lists, they are handled at RetrieveVirtualItem time. + + + + Refresh the given item in the list + + The item to refresh + + + + Handle a mouse down event + + + + + + Handle a RetrieveVirtualItem + + + + + + + Create a OLVListItem for given row index + + The index of the row that is needed + An OLVListItem + + + + Return the row object for the given row index + + index of the row whose object is to be fetched + A model object or null if no delegate is installed + + + + Clear any cached info this list may have been using + + + + + A FastObjectListView trades function for speed. + + + On my mid-range laptop, this view builds a list of 10,000 objects in 0.1 seconds, + as opposed to a normal ObjectListView which takes 10-15 seconds. Lists of up to 50,000 items should be + able to be handled with sub-second response times even on low end machines. + + A FastObjectListView is implemented as a virtual list with some of the virtual modes limits (e.g. no sorting) + fixed through coding. There are some functions that simply cannot be provided. Specifically, a FastObjectListView cannot: + + shows groups + use Tile view + display images on subitems + + + You can circumvent the limit on subitem images by making the list owner drawn, and giving the column + a Renderer of BaseRenderer, e.g. myColumnWithImage.Renderer = new BaseRenderer(); + + Although it isn't documented, virtual lists cannot have checkboxes. A FastObjectListView codes around this limitation, + but you must use the functions provided by FastObjectListView. If you call the normal "CheckedItems", it will throw an + exception. If you use CheckedObjects and its friends (declared in ObjectListView), you should not have any trouble. + The only exception is the "CheckBoxes" property itself. Once this is set, trying to unset it will throw an exception, + since the list is a virtual list. + + + + + + Make a FastObjectListView + + + + + Get/set the list of objects that are shown by the control. + + + This method preserves selection, if possible. Use SetObjects() if + you do not want to preserve the selection. Preserving selection is the slowest part of this + code and performance is O(n) where n is the number of selected rows. + This method is not thread safe. + + + + + When the user types into a list, should the values in the current sort column be searched to find a match? + If this is false, the primary column will always be used regardless of the sort column. + + When this is true, the behavior is like that of ITunes. + + + + Set the collection of objects that this control will show. + + + This method can safely be called from background threads. + + + + Add the given collection of model objects to this control. + + A collection of model objects + + The added objects will appear in their correct sort position, if sorting + is active. Otherwise, they will appear at the end of the list. + No check is performed to see if any of the objects are already in the ListView. + Null objects are silently ignored. + + + + + Remove all of the given objects from the control + + Collection of objects to be removed + + Nulls and model objects that are not in the ListView are silently ignored. + + + + + Take ownership of the 'objects' collection. This separats our collection from the source. + + + + This method + separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject + calls will modify our collection and not the original colleciton. + + + FastObjectListViews always own their collections, so this is a no-op. + + + + + + Event handler for the column click event + + + This differs from its base version by trying to preserve selection. The base class, + being a pure virtual list, cannot maintain selection since it cannot map a + model objects to the row that is responsible for displaying it. This class can do that. + + + + + Select the row that is displaying the given model object. + + The object that gave data + + + + Select the rows that is displaying any of the given model object. + + A collection of model objects + + + + Update the rows that are showing the given objects + + + + + Rebuild the map that remembers which model object is displayed at which line + + + + + Return the row object for the given row index + + index of the row whose object is to be fetched + A model object or null if no delegate is installed + + + + A DataListView is a ListView that can be bound to a datasource (which would normally be a DataTable or DataView). + + + This listview keeps itself in sync with its source datatable by listening for change events. + If the listview has no columns when given a data source, it will automatically create columns to show all of the datatables columns. + This will be only the simplest view of the world, and would look more interesting with a few delegates installed. + This listview will also automatically generate missing aspect getters to fetch the values from the data view. + Changing data sources is possible, but error prone. Before changing data sources, the programmer is responsible for modifying/resetting + the column collection to be valid for the new data source. + + + + + Make a DataListView + + + + + Get or set the DataSource that will be displayed in this list view. + + The DataSource should implement either , , + or . Some common examples are the following types of objects: + + + + + + + + When binding to a list container (i.e. one that implements the + interface, such as ) + you must also set the property in order + to identify which particular list you would like to display. You + may also set the property even when + DataSource refers to a list, since can + also be used to navigate relations between lists. + + + + + Gets or sets the name of the list or table in the data source for which the DataListView is displaying data. + + If the data source is not a DataSet or DataViewManager, this property has no effect + + + + Our data source has changed. Figure out how to handle the new source + + + + + Our data source has changed. Figure out how to handle the new source + + + + + The data source for this control has changed. Reconfigure the control for the new source + + + + + Create columns for the listview based on what properties are available in the data source + + + This method will not replace existing columns. + + + + + Generate aspect getters and putters for any columns that are missing them (and for which we have + enough information to actually generate a getter) + + + + + Add the given collection of model objects to this control. + + A collection of model objects + This is a no-op for data lists, since the data + is controlled by the DataSource. Manipulate the data source + rather than this view of the data source. + + + + Remove the given collection of model objects from this control. + + This is a no-op for data lists, since the data + is controlled by the DataSource. Manipulate the data source + rather than this view of the data source. + + + + What should we do when the list is unfrozen + + + + + Handles binding context changes + + The EventArgs that will be passed to any handlers + of the BindingContextChanged event. + + + + Handles parent binding context changes + + Unused EventArgs. + + + + Handle a SelectedIndexChanged event + + The event + + Called by Windows Forms when the currently selected index of the + control changes. This usually happens because the user clicked on + the control. In this case we want to notify the CurrencyManager so + that any other bound controls will remain in sync. This method will + also be called when we changed our index as a result of a + notification that originated from the CurrencyManager, and in that + case we avoid notifying the CurrencyManager back! + + + + + These delegates are used to extract an aspect from a row object + + + + + These delegates are used to put a changed value back into a model object + + + + + These delegates can be used to convert an aspect value to a display string, + instead of using the default ToString() + + + + + These delegates are used to the state of the checkbox for a row object. + + For reasons known only to someone in Microsoft, we can only set + a boolean on the ListViewItem to indicate it's "checked-ness", but when + we receive update events, we have to use a tristate CheckState. So we can + be told about an indeterminate state, but we can't set it ourselves. + + + + These delegates are used to put a changed check state back into a model object + + + + + These delegates are used to retrieve the object that is the key of the group to which the given row belongs. + + + + + These delegates are used to convert a group key into a title for the group + + + + + These delegates are used to fetch the image selector that should be used + to choose an image for this column. + + + + + These delegates are used to draw a cell + + + + + These delegates are used to fetch a row object for virtual lists + + + + + These delegates are used to format a listviewitem before it is added to the control. + + + + + These delegates are used to sort the listview in some custom fashion + + + + + An OLVColumn knows which aspect of an object it should present. + + + The column knows how to: + + extract its aspect from the row object + convert an aspect to a string + calculate the image for the row object + extract a group "key" from the row object + convert a group "key" into a title for the group + + For sorting to work correctly, aspects from the same column + must be of the same type, that is, the same aspect cannot sometimes + return strings and other times integers. + + + + + Create an OLVColumn + + + + + Initialize a column to have the given title, and show the given aspect + + The title of the column + The aspect to be shown in the column + + + + The name of the property or method that should be called to get the value to display in this column. + This is only used if a ValueGetterDelegate has not been given. + + This name can be dotted to chain references to properties or methods. + "DateOfBirth" + "Owner.HomeAddress.Postcode" + + + + This format string will be used to convert an aspect to its string representation. + + + This string is passed as the first parameter to the String.Format() method. + This is only used if ToStringDelegate has not been set. + "{0:C}" to convert a number to currency + + + + Group objects by the initial letter of the aspect of the column + + + One common pattern is to group column by the initial letter of the value for that group. + The aspect must be a string (obviously). + + + + + Get/set whether this column should be used when the view is switched to tile view. + + Column 0 is always included in tileview regardless of this setting. + Tile views do not work well with many "columns" of information, 2 or 3 works best. + + + + This delegate will be used to extract a value to be displayed in this column. + + + If this is set, AspectName is ignored. + + + + + The delegate that will be used to translate the aspect to display in this column into a string. + + If this value is set, ValueToStringFormat will be ignored. + + + + This delegate is called to get the image selector of the image that should be shown in this column. + It can return an int, string, Image or null. + + This delegate can use these return value to identify the image: + + null or -1 -- indicates no image + an int -- the int value will be used as an index into the image list + a String -- the string value will be used as a key into the image list + an Image -- the Image will be drawn directly (only in OwnerDrawn mode) + + + + + + This delegate is called to get the object that is the key for the group + to which the given row belongs. + + + + + This delegate is called to convert a group key into a title for that group. + + + + + This delegate is called when a cell needs to be drawn in OwnerDrawn mode. + + + + + Get/set the renderer that will be invoked when a cell needs to be redrawn + + + + + Remember if this aspect getter for this column was generated internally, and can therefore + be regenerated at will + + + + + When the listview is grouped by this column and group title has an item count, + how should the lable be formatted? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group + + If this value is not set, the values from the list view will be used + + "{0} [{1} items]" + + + + Return this.GroupWithItemCountFormat or a reasonable default + + + + + When the listview is grouped by this column and a group title has an item count, + how should the lable be formatted if there is only one item in the group? + + + The given format string can/should have two placeholders: + + {0} - the original group title + {1} - the number of items in the group (always 1) + + If this value is not set, the values from the list view will be used + + "{0} [{1} item]" + + + + Return this.GroupWithItemCountSingularFormat or a reasonable default + + + + + What is the minimum width that the user can give to this column? + + -1 means there is no minimum width. Give this the same value as MaximumWidth to make a fixed width column. + + + + What is the maximum width that the user can give to this column? + + -1 means there is no maximum width. Give this the same value as MinimumWidth to make a fixed width column. + + + + Is this column a fixed width column? + + + + + What proportion of the unoccupied horizontal space in the control should be given to this column? + + + + There are situations where it would be nice if a column (normally the rightmost one) would expand as + the list view expands, so that as much of the column was visible as possible without having to scroll + horizontally (you should never, ever make your users have to scroll anything horizontally!). + + + A space filling column is resized to occupy a proportion of the unoccupied width of the listview (the + unoccupied width is the width left over once all the the non-filling columns have been given their space). + This property indicates the relative proportion of that unoccupied space that will be given to this column. + The actual value of this property is not important -- only its value relative to the value in other columns. + For example: + + + If there is only one space filling column, it will be given all the free space, regardless of the value in FreeSpaceProportion. + + + If there are two or more space filling columns and they all have the same value for FreeSpaceProportion, + they will share the free space equally. + + + If there are three space filling columns with values of 3, 2, and 1 + for FreeSpaceProportion, then the first column with occupy half the free space, the second will + occupy one-third of the free space, and the third column one-sixth of the free space. + + + + + + + + Should this column resize to fill the free space in the listview? + + + + If you want two (or more) columns to equally share the available free space, set this property to True. + If you want this column to have a larger or smaller share of the free space, you must + set the FreeSpaceProportion property explicitly. + + + Space filling columns are still governed by the MinimumWidth and MaximumWidth properties. + + /// + + + + This delegate will be used to put an edited value back into the model object. + + + This does nothing if IsEditable == false. + + + + + Can the values shown in this column be edited? + + This defaults to true, since the primary means to control the editability of a listview + is on the listview itself. Once a listview is editable, all the columns are too, unless the + programmer explicitly marks them as not editable + + + + Return the control that should be used to edit cells in this column + + + + + Can this column be seen by the user? + + After changing this value, you must call RebuildColumns() before the changes will be effected. + + + + Where was this column last positioned within the Detail view columns + + DisplayIndex is volatile. Once a column is removed from the control, + there is no way to discover where it was in the display order. This property + guards that information even when the column is not in the listview's active columns. + + + + For a given row object, return the object that is to be displayed in this column. + + The row object that is being displayed + An object, which is the aspect to be displayed + + + + For a given row object, extract the value indicated by the AspectName property of this column. + + The row object that is being displayed + An object, which is the aspect named by AspectName + + + + Update the given model object with the given value + + The model object to be updated + The value to be put into the model + + + + Update the given model object with the given value using the column's + AspectName. + + The model object to be updated + The value to be put into the model + + + + For a given row object, return the string representation of the value shown in this column. + + + For aspects that are string (e.g. aPerson.Name), the aspect and its string representation are the same. + For non-strings (e.g. aPerson.DateOfBirth), the string representation is very different. + + + + + + + Convert the aspect object to its string representation. + + + If the column has been given a ToStringDelegate, that will be used to do + the conversion, otherwise just use ToString(). Nulls are always converted + to empty strings. + + The value of the aspect that should be displayed + A string representation of the aspect + + + + For a given row object, return the image selector of the image that should displayed in this column. + + The row object that is being displayed + int or string or Image. int or string will be used as index into image list. null or -1 means no image + + + + For a given row object, return the object that is the key of the group that this row belongs to. + + The row object that is being displayed + Group key object + + + + For a given group value, return the string that should be used as the groups title. + + The group key that is being converted to a title + string + + + + Install delegates that will group the columns aspects into progressive partitions. + If an aspect is less than value[n], it will be grouped with description[n]. + If an aspect has a value greater than the last element in "values", it will be grouped + with the last element in "descriptions". + + Array of values. Values must be able to be + compared to the aspect (using IComparable) + The description for the matching value. The last element is the default description. + If there are n values, there must be n+1 descriptions. + + this.salaryColumn.MakeGroupies( + new UInt32[] { 20000, 100000 }, + new string[] { "Lowly worker", "Middle management", "Rarified elevation"}); + + + + + OLVListItems are specialized ListViewItems that know which row object they came from, + and the row index at which they are displayed, even when in group view mode. They + also know the image they should draw against themselves + + + + + Create a OLVListItem for the given row object + + + + + Create a OLVListItem for the given row object, represented by the given string and image + + + + + RowObject is the model object that is source of the data for this list item. + + + + + DisplayIndex is the index of the row where this item is displayed. For flat lists, + this is the same as ListViewItem.Index, but for grouped views, it is different. + + + + + Get or set the image that should be shown against this item + + This can be an Image, a string or an int. A string or an int will + be used as an index into the small image list. + + + + A ListViewSubItem that knows which image should be drawn against it. + + + + + Create a OLVListSubItem + + + + + Create a OLVListSubItem that shows the given string and image + + + + + Get or set the image that should be shown against this item + + This can be an Image, a string or an int. A string or an int will + be used as an index into the small image list. + + + + Return the state of the animatation of the image on this subitem. + Null means there is either no image, or it is not an animation + + + + + This comparer sort list view groups. + It does this on the basis of the values in the Tags, if we can figure out how to compare + objects of that type. Failing that, it uses a case insensitive compare on the group header. + + + + + ColumnComparer is the workhorse for all comparison between two values of a particular column. + If the column has a specific comparer, use that to compare the values. Otherwise, do + a case insensitive string compare of the string representations of the values. + + This class inherits from both IComparer and its generic counterpart + so that it can be used on untyped and typed collections. + + + + Renderers are responsible for drawing a single cell within an owner drawn ObjectListView. + + + Methods on this class are called during the DrawItem or DrawSubItemEvent. + Subclasses can tell which type of event they are handling by examining DrawItemEvent: if this + is not null, it is a DrawItem event. + Subclasses will normally override the RenderWithDefault or Render method, and use the other + methods as helper functions. + If a renderer is installed on the primary column (column 0), it will be given a chance + to draw the whole item in all views (Details, Tile, etc.). If the renderer returns true, + default processing will continue. If it returns false, no other rendering will happen. + This means that when an ObjectListView is in Details view, the renderer on column 0 + will be called twice: once to handle the DrawItem event, and then again to draw only the + first cell. Subclasses must distinguish between these two very different events (using + the "this.DrawItemEvent == null" test). + + + + + Make a simple renderer + + + + + Get/set the event that caused this renderer to be called + + + + + Get/set the event that caused this renderer to be called + + + + + Get/set the listview for which the drawing is to be done + + + + + Get or set the OLVColumn that this renderer will draw + + + + + Get or set the model object that this renderer should draw + + + + + Get or set the aspect of the model object that this renderer should draw + + + + + Get or set the listitem that this renderer will be drawing + + + + + Get or set the list subitem that this renderer will be drawing + + + + + Get the specialized OLVSubItem that this renderer is drawing + + This returns null for column 0. + + + + Cache whether or not our item is selected + + + + + Return the font to be used for text in this cell + + The font of the subitem + + + + The brush that will be used to paint the text + + + + + Should this renderer fill in the background before drawing? + + + + + Can the renderer wrap lines that do not fit completely within the cell? + + This value is currently only used when printing a list view using ListViewPrinter. + + + + When rendering multiple images, how many pixels should be between each image? + + + + + Return the string that should be drawn within this + + + + + + Return the image that should be drawn against this subitem + + An Image or null if no image should be drawn. + + + + Return the actual image that should be drawn when keyed by the given image selector. + An image selector can be: + an int, giving the index into the image list + a string, giving the image key into the image list + an Image, being the image itself + + + The value that indicates the image to be used + An Image or null + + + + Return the Color that is the background color for this item's cell + + The background color of the subitem + + + + Return the Color that is the background color for this item's text + + The background color of the subitem's text + + + + Return the color to be used for text in this cell + + The text color of the subitem + + + + Align the second rectangle with the first rectangle, + according to the alignment of the column + + The cell's bounds + The rectangle to be aligned within the bounds + An aligned rectangle + + + + Draw the given image aligned horizontally within the column. + + + Over tall images are scaled to fit. Over-wide images are + truncated. This is by design! + + Graphics context to use for drawing + Bounds of the cell + The image to be drawn + + + + Fill in the background of this cell + + Graphics context to use for drawing + Bounds of the cell + + + + The delegate that is called from the list view. This is the main entry point, but + subclasses should override Render instead of this method. + + The event that caused this redraw + The context that our drawing should be done using + The bounds of the cell within which the renderer can draw + The model object for this row + A boolean indicating whether the default process should occur + + + + Draw our data into the given rectangle using the given graphics context. + + + Subclasses should override this method. + The graphics context that should be used for drawing + The bounds of the subitem cell + Returns whether the renderering has already taken place. + If this returns false, the default processing will take over. + + + + + Draw our data into the given rectangle using the given graphics context. + + + Subclasses should override this method if they never want + to fall back on the default processing + The graphics context that should be used for drawing + The bounds of the subitem cell + + + + Draw our subitems image and text + + Graphics context to use for drawing + Bounds of the cell + + + + Draw the given text and optional image in the "normal" fashion + + Graphics context to use for drawing + Bounds of the cell + The string to be drawn + The optional image to be drawn + + + + This class maps a data value to an image that should be drawn for that value. + + It is useful for drawing data that is represented as an enum or boolean. + + + + Return a renderer that draw boolean values using the given images + + Draw this when our data value is true + Draw this when our data value is false + A Renderer + + + + Return a renderer that draw tristate boolean values using the given images + + Draw this when our data value is true + Draw this when our data value is false + Draw this when our data value is null + A Renderer + + + + Make a new empty renderer + + + + + Make a new renderer that will show the given image when the given key is the aspect value + + The data value to be matched + The image to be shown when the key is matched + + + + Make a new renderer that will show the given images when it receives the given keys + + + + + + + + + Build a renderer from the given array of keys and their matching images + + An array of key/image pairs + + + + Register the image that should be drawn when our Aspect has the data value. + + Value that the Aspect must match + An ImageSelector -- an int, string or image + + + + Render our value + + + + + + + Render an image that comes from our data source. + + The image can be sourced from: + + a byte-array (normally when the image to be shown is + stored as a value in a database) + an int, which is treated as an index into the image list + a string, which is treated first as a file name, and failing that as an index into the image list + + If an image is an animated GIF, it's state is stored in the SubItem object. + By default, the image renderer does not render animations (it begins life with animations paused). + To enable animations, you must call Unpause(). + + + + + Make an empty image renderer + + + + + Make an empty image renderer that begins life ready for animations + + + + + Draw our image + + + + + + + Translate our Aspect into an image. + + The strategy is: + If its a byte array, we treat it as an in-memory image + If it's an int, we use that as an index into our image list + If it's a string, we try to load a file by that name. If we can't, we use the string as an index into our image list. + + An image + + + + Should the animations in this renderer be paused? + + + + + Pause any animations + + + + + Unpause any animations + + + + + This is the method that is invoked by the timer. It basically switches control to the listview thread. + + not used + + + + This is the OnTimer callback, but invoked in the same thread as the creator of the ListView. + This method can use all of ListViews methods without creating a CrossThread exception. + + + + + Instances of this class kept track of the animation state of a single image. + + + + + Is the given image an animation + + The image to be tested + Is the image an animation? + + + + Create an AnimationState in a quiet state + + + + + Create an animation state for the given image, which may or may not + be an animation + + The image to be rendered + + + + Does this state represent a valid animation + + + + + Advance our images current frame and calculate when it will expire + + + + + Render our Aspect as a progress bar + + + + + Make a BarRenderer + + + + + Make a BarRenderer for the given range of data values + + + + + Make a BarRenderer using a custom bar scheme + + + + + Make a BarRenderer using a custom bar scheme + + + + + Make a BarRenderer that uses a horizontal gradient + + + + + Make a BarRenderer that uses a horizontal gradient + + + + + Should this bar be drawn in the system style + + + + + How many pixels in from our cell border will this bar be drawn + + + + + The Pen that will draw the frame surrounding this bar + + + + + The brush that will be used to fill the bar + + + + + The brush that will be used to fill the background of the bar + + + + + The first color when a gradient is used to fill the bar + + + + + The end color when a gradient is used to fill the bar + + + + + Regardless of how wide the column become the progress bar will never be wider than this + + + + + Regardless of how high the cell is the progress bar will never be taller than this + + + + + The minimum data value expected. Values less than this will given an empty bar + + + + + The maximum value for the range. Values greater than this will give a full bar + + + + + Draw this progress bar using a gradient + + + + + + + Draw our aspect + + + + + + + An ImagesRenderer draws zero or more images depending on the data returned by its Aspect. + + This renderer's Aspect must return a ICollection of ints, strings or Images, + each of which will be drawn horizontally one after the other. + + + + Draw our data value + + + + + + + A MultiImageRenderer draws the same image a number of times based on our data value + + The stars in the Rating column of iTunes is a good example of this type of renderer. + + + + Make a quiet rendererer + + + + + Make an image renderer that will draw the indicated image, at most maxImages times. + + + + + + + + + The image selector that will give the image to be drawn + + + + + What is the maximum number of images that this renderer should draw? + + + + + Values less than or equal to this will have 0 images drawn + + + + + Values greater than or equal to this will have MaxNumberImages images drawn + + + + + Draw our data value + + + + + + + A class to render a value that contains a bitwise-OR'ed collection of values. + + The type of value that holds the bit-OR'ed flag + + + + Register the given image to the given value + + When this flag is present... + ...draw this image + + + + Draw the flags + + + + + + + 鼠标的当前位置 + + + + + + + + + + + + + + + + + + + + 控件的状态。 + + + + + 正常 + + + + + 鼠标经过 + + + + + 鼠标按下 + + + + + 建立圆角路径的样式。 + + + + + 四个角都不是圆角。 + + + + + 四个角都为圆角。 + + + + + 左边两个角为圆角。 + + + + + 右边两个角为圆角。 + + + + + 上边两个角为圆角。 + + + + + 下边两个角为圆角。 + + + + + 左下角为圆角。 + + + + + 右下角为圆角。 + + + + + + + + + + 普通按钮按下事件 + + + + + 分割按钮按下事件 + + + + + + + + + + 下拉菜单与按钮的距离 + + + + + 图片高度 + + + + + 分割按钮的宽度 + + + + + 当鼠标按下时图片和文字是否产生偏移 + + + + + 是否一直显示按钮边框,设置为false则只在鼠标经过和按下时显示边框 + + + + + 当显示分割按钮时,分割按钮的箭头颜色 + + + + + 按钮的边框颜色 + + + + + 按钮内边框颜色 + + + + + 鼠标经过和按下时按钮的渐变背景颜色 + + + + + 鼠标经过和按下时按钮的渐变背景颜色 + + + + + 图片宽度 + + + + + 图片高度 + + + + + 按钮圆角样式 + + + + + 按钮圆角弧度 + + + + + 图片与文字之间的间距 + + + + + 按钮当前状态 + + + + + 鼠标当前所在位置 + + + + + 普通按钮矩形位置 + + + + + 分割按钮矩形位置 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取图像以及文字的位置 + + + + + + + + 画边框与背景 + + + + + 画分割按钮 + + + + + + + + + + + + 建立带有圆角样式的矩形路径 + + 用来建立路径的矩形。 + 圆角的大小 + 圆角的样式 + 是否把矩形长宽减 1,以便画出边框 + 建立的路径 + + + + This enum represents the possible browser commands + + + + + Used when no commans are available + + + + + Used in the new navigation events + + + + + The URL to navigate to + + + + + The name of the frame to navigate to + + + + + The flags when opening a new window + + + + + The pointer to ppDisp + + + + + Creates a new instance of WebBrowserExtendedNavigatingEventArgs + + Pointer to the automation object of the browser + The URL to go to + The name of the frame + The new window flags + + + + + + + + + Used in the new navigation events + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 查看源码 + + + + + 复制当前选中区 + + + + + 粘贴当前选中区 + + + + + 剪切当前选中区 + + + + + 全选 + + + + + 清除当前选中区的选中状态。 + + + + + 从当前选中区中删除全部超级链接。 + + + + + 从当前选中区中删除全部书签。 + + + + + 删除当前选中区 + + + + + 重做 + + + + + 撤销 + + + + + 从当前选中区中删除格式化标签。 + + + + + 点击节点 + + + + + + + + 点击节点 + + + + + + + + + 点击元素 + + 节点名 + 属性 + 属性值 + 等待毫秒数 + 第几个符合的元素,从1开始 + + + + 等待多时毫秒 + + + + + + Represents event information for the main form, when the command state of the active browser changes + + + + + Creates a new instance of the class + + A list of commands that are available + + + + Gets a list of commands that are available + + + + + An extended version of the control. + + + + + + + + + + + + 在页面弹出消息对话框时激发 + + + + + + + + + + + + + + + + + + + + + + 打开页面并等待页面加载完毕 + + 要打开的页面地址 + 小于等于0,则表示一直等待,否则表示等待指定秒后,如果依然没有加载完毕,就直接返回 + + + + 等待页面加载完毕 + + 小于等于0,则表示一直等待,否则表示等待指定秒后,如果依然没有加载完毕,就直接返回 + + + + 等待指定毫秒 + + 等待指定毫秒 + + + + 获取网页源代码,可以自动去除乱码 + + + + + + 加载html文本到浏览器中 + + + + + + + 加载html文本到浏览器中 + + + + + + 强制用本窗体打开新链接 + + + + + + + + + + + This method supports the .NET Framework infrastructure and is not intended to be used directly from your code. + Called by the control when the underlying ActiveX control is created. + + + + + + This method supports the .NET Framework infrastructure and is not intended to be used directly from your code. + Called by the control when the underlying ActiveX control is discarded. + + + + + Returns the automation object for the web browser + + + + + This method will be called to give you a chance to create your own event sink + + + + + Detaches the event sink + + + + + 在文档下载开始时激发 + + + + + Raises the event + + Empty + + You could start an animation or a notification that downloading is starting + + + + + 下载完成后触发 + + + Here you could start monitoring for script errors. + + + + + Raises the event + + Empty + + + + 在开始浏览新网页时激发. + + + + + 在打开新的网页窗口时激发 + + + + + Raises the event + + Thrown when BrowserExtendedNavigatingEventArgs is null + + + + Raises the event + + Thrown when BrowserExtendedNavigatingEventArgs is null + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 新窗口事件,只限Window XP SP2或以上系统支持 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overridden + + The send to this procedure + + + + A list of all the available window messages + + + + + Raises the event + + + + + 在网页窗口关闭时激发 + + + Do not confuse this with DWebBrowserEvents2.Quit... That's something else. + + + + + Flags used by INewWindowManager::EvaluateNewWindow. + These values are taken into account in the decision of whether to display a pop-up window. + + + + + No information Present + + + + + The page is unloading. This flag is set in response to the onbeforeunload and onunload events. + Some pages load pop-up windows when you leave them rather than when you enter. This flag is used to identify those situations. + + + + + The call to INewWindowManager::EvaluateNewWindow is the result of a user-initiated action + (a mouse click or key press). Use this flag in conjunction with the NWMF_FIRST_USERINITED flag + to determine whether the call is a direct or indirect result of the user-initiated action. + + + + + When NWMF_USERINITED is present, this flag indicates that the call to + INewWindowManager::EvaluateNewWindow is the first query that results from this user-initiated action. + Always use this flag in conjunction with NWMF_USERINITED. + + + + + The override key (ALT) was pressed. The override key is used to bypass the pop-up manager梐llowing + all pop-up windows to display梐nd must be held down at the time that INewWindowManager::EvaluateNewWindow is called. + + + + + The new window attempting to load is the result of a call to the showHelp method. Help is sometimes displayed in a separate window, + and this flag is valuable in those cases. + + + + + The new window is a dialog box that displays HTML content. + + + + + Indicates that the EvaluateNewWindow method is being called through a marshalled Component Object Model (COM) proxy + from another thread. In this situation, the method should make a decision and return immediately without performing + blocking operations such as showing modal user interface (UI). Lengthy operations will cause the calling thread to + appear unresponsive. + + + + + HRESULT constants + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 线条图 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + 画值 + + 画布 + X轴数据 + + + + 走势图 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + 初始化参数 + + + + + 返回或设置X轴间隔 + + + + + 标题 + + + + + 返回图片的宽度 + + + + + 返回或设置图片的高度 + + + + + X轴的间距 + + + + + Y轴的间距 + + + + + 标题的颜色 + + + + + 标题的字体 + + + + + 背景颜色 + + + + + X轴的颜色 + + + + + Y轴的颜色 + + + + + 返回X轴数据的最大值(供给Painter调用) + + + + + 返回图片数据 + + + + + 画布 + + + + + 作图器 + + + + + 释放内容资源 + + + + + 获取X轴中的最大值 + + + + + + + 获取所有X轴列中的最大值 + + + + + + + 初始化图片 + + X轴的数据 + + + + + 画一条走势图 + + + + + + 画多条走势图 + + + + + + 作图器的基础类 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + 返回此作图器的相关链走势图 + + + + + 获取某值在Y轴上的位置 + + 当前点的值 + 点坐标 + + + + 画XY轴线 + + 画布 + X轴的数据 + + + + 画标题 + + + + + + 画走势线 + + 画布 + X轴数据 + + + + 方块图 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + 画值 + + 画布 + X轴数据 + + + + 走势图的X轴数据 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + + + + + + + + 标题 + + + + + 值 + + + + + 标题的颜色 + + + + + 标题的字体 + + + + + 值的颜色 + + + + + 值的字体 + + + + + 绘制颜色 + + + + + 值是否可见 + + + + + 克隆自身 + + + + + + 定义X轴的数据集合 + + + 作者: Kingthy + 日期: 2007-09-11 + MSN: Kingthy@gmail.com + 转载请注明原作者,当你有更新修改时如果方便的希望能发一份给我.谢谢 + + + + + + + + + + + + + + + + 添加一批数据 + + 轴的标题 + + + + 添加一批数据 + + 轴的标题 + 轴的值 + + + + 重置轴的值 + + 轴的值 + + + + 克隆数据 + + + + + + 获取颜色 + + + + + + + + + + + + + 颜色变化时激发 + + + + + + + + + + + + + + + Required designer variable. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Required method for Designer support - do not modify + the contents of this method with the code editor. + + + + diff --git a/Bin/Debug/CommonControls/.NET4/ryUpdate.dll b/Bin/Debug/CommonControls/.NET4/ryUpdate.dll new file mode 100644 index 0000000..f1456bc Binary files /dev/null and b/Bin/Debug/CommonControls/.NET4/ryUpdate.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/Itrycn_Project.exe b/Bin/Release/CommonControls/.NET4 示例/Itrycn_Project.exe new file mode 100644 index 0000000..d36e33a Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/Itrycn_Project.exe differ diff --git a/Bin/Release/CommonControls/.NET4 示例/MyDb.dll b/Bin/Release/CommonControls/.NET4 示例/MyDb.dll new file mode 100644 index 0000000..87d72d0 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/MyDb.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/MyDb.xml b/Bin/Release/CommonControls/.NET4 示例/MyDb.xml new file mode 100644 index 0000000..f4779a0 --- /dev/null +++ b/Bin/Release/CommonControls/.NET4 示例/MyDb.xml @@ -0,0 +1,4829 @@ + + + + MyDb + + + + + 基于XML实现的权限类 + + + + + 用户名 + + + + + 用户id + + + + + 密码 + + + + + 权限控制Id + + + + + 用户备注 + + + + + 是否是管理员权限 + + + + + 是否是超级管理员权限 + + + + + 设置权限 + + 权限名称 + 权限值 + 返回是否设置成功 + + + + 获取权限 + + 权限名称 + 默认权限值 + 返回权限值 + + + + 获取权限 + + 权限名称 + 返回权限值 + + + + 批量导入权限 + + 权限相关的内容 + 返回是否执行成功 + + + + 导出权限 + + 返回导出文本 + + + + 清除所有权限 + + 返回是否执行成功 + + + + 汉字转拼音静态类,包括功能全拼和缩写,方法全部是静态的 + + + + + 汉字的机内码数组 + + + + + 机内码对应的拼音数组 + + + + + 把汉字转换成拼音(全拼) + + 汉字字符串 + 转换后的拼音(全拼)字符串 + + + + 把汉字转换成拼音(全拼) + + 汉字字符串 + 转换后的拼音(全拼)字符串 + + + + 把汉字转换成拼音(首拼) + + 汉字字符串 + 转换后的拼音(首拼)字符串 + + + + 把汉字转换成拼音(全拼) + + 汉字字符串 + 用指定字符分隔 + 转换后的拼音(全拼)字符串 + + + + 汉字转拼音缩写 + + 要转换的汉字字符串 + 拼音缩写 + + + + 汉字转拼音缩写 (字符串) (小写) (空格间隔) + + 要转换的汉字字符串 + 拼音缩写 + + + + 汉字转拼音缩写 (大写) + + 要转换的汉字字符串 + 拼音缩写 + + + + 汉字转拼音缩写 (字符串)(大写)(空格间隔) + + 要转换的汉字字符串 + 拼音缩写 + + + + 取单个字符的拼音声母 + + 要转换的单个汉字 + 拼音声母 + + + + 取单个字符的拼音声母 + + 要转换的单个汉字 + 拼音声母 + + + + Ini操作类 + + + + + 写入Ini + + + + + + + + + + 获取Ini + + + + + + + + + + + + 声明INI文件的读操作函数 GetPrivateProfileString() + + + + + + + + + + + + 声明INI文件的读操作函数 GetPrivateProfileString() + + + + + + + + + + 声明INI文件的读操作函数 GetPrivateProfileString() + + + + + + + + + + + + 获取所有节点名称(Section) + + 存放节点名称的内存地址,每个节点之间用\0分隔 + 内存大小(characters) + Ini文件 + 内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够 + + + + 编码 + + + + + Ini操作类 + + + + + + 根据section取所有key和值 + + + + + + + 读取INI文件中指定INI文件中的所有节点名称(Section) + + 所有节点,没有内容返回string[0] + + + + 读取INI文件 + + 段,格式[] + 键 + 返回byte类型的section组或键值组 + + + + 根据section取所有key + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入Ini + + + + + + + + 读取Ini + + + + + + + + 读取Ini + + + + + + + + + 读取Ini + + + + + + + + + 读取Ini + + + + + + + + + + + 写入ini + + + + + + + + + 删除Ini的Key + + + + + + + 删除Ini节点 + + + + + + 控件信息 + + + + + id + + + + + 控件对象 + + + + + 控件值类型 + + + + + 默认值 + + + + + 值类型 + + + + + 默认 + + + + + 取列表顺序值 + + + + + 取当前选择的列表值 + + + + + 取对象值 + + + + + 保存的设置类型 + + + + + Ini + + + + + XML + + + + + 对象值 + + + + + 显示的文本 + + + + + 图片序号 + + + + + id + + + + + Tag值 + + + + + 显示文本值 + + + + + + 星期数据 + + + + + 一周的开始时间 + + + + + 一周的结束时间 + + + + + XML操作类 + + + + + XML操作类 + + + + + 从XML文本中加载数据 + + + + + + 从指定的XML文本中加载 + + XML文本 + 如为1,表示加载成功,为0为失败 + + + + 载入空的XML文档 + + 如为1,表示加载成功,为0为失败 + + + + 从指定的文件中加载 + + XML文件路径 + 如为1,表示加载成功,为0为失败 + + + + 保存到指定文件中 + + 文件路径 + 如为1,表示保存成功,为0为失败 + + + + 判断节点是否存在 + + 属性名 + 属性值 + 返回1,表示存在,其它表示不存在 + + + + 定位节点 + + 属性名 + 属性值 + 返回第一个符合要求的结果 + + + + 定位节点,如果找不到节点,就新建一个节点 + + 属性名 + 属性值 + 返回第一个符合要求的结果 + + + + 根据用户的节点定位节点,输入节点时,一定要注意节点是属于类内部的,否则可能出错。 + + 返回第一个符合要求的结果 + + + + 定位设置节点 + + 返回第一个符合要求的结果 + + + + 在节点后插入数据 + + + + + + + 在节点前插入数据 + + + + + + + 获取节点数量 + + 属性名 + 属性值 + 返回符合要求的结果数量 + + + + 获取节点数量 + + 返回符合要求的结果数量 + + + + 获取节点数量 + + 属性名 + 属性值 + + + + 返回符合要求的结果数量 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 读取指定节点的值 + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 获取属性值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取所有的节点名称 + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 获取XML文件的根元素 + + + + + 获取所有列表 + + 如为1,表示获取成功,为0为失败 + + + + 获取所有列表 + + 如为1,表示获取成功,为0为失败 + + + + 新增节点 + + + + + + + + 新增节点并定位到新节点 + + + + + + + + 新增设置节点并定位 + + + + + + 在指定节点前新增节点并定位到新节点 + + + + + + + + + 获取当前节点 + + + + + + 删除节点 + + + + + + 获取XML文本 + + + + + + 获取XML文本 + + + + + + 获取文本 + + + + + + 获取文本 + + + + + + 字符串操作类 + + + + + 字符串转Base64 + + + + + + + Base64转字符串 + + + + + + + 转换指定字符串为布尔类型 + + + + + 转换指定字符串为Double类型 + + + + + 已重载.计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + + 第一个日期和时间 + 第二个日期和时间 + + + + + 已重载.计算一个时间与当前本地日期和时间的时间间隔,返回的是时间间隔的日期差的绝对值. + + 一个日期和时间 + + + + + 转换指定字符串为Int类型 + + + + + 转换指定字符串为Int类型 + + + + + 转换指定布尔类型为Int类型,true为1,false为0 + + + + + 判断指定字符串是否是布尔类型 + + + + + 判断指定字符串是否是Double类型 + + + + + 判断指定字符串是否是Int类型 + + + + + 根据年月日转换成日期 + + + + + + + + + 追加字符 + + + + + 获取2个字符串中间的内容,point1为空表示从首位开始算,point2为空表示算到结尾。 + + + + + 判断字符串是否只包含数字或英文 + + + + + + + 判断字符串是否匹配,支持?*通配符 + + 待匹配的字符串 + 匹配的通配符 + + + + + 通配符替换 + + + + + + + + + 获取匹配的内容 + + + + + + + + + 文件时间 + + + + + 创建时间 + + + + + 最后修改时间 + + + + + 访问时间 + + + + + 图片类型 + + + + + Bmp图片 + + + + + Jpeg图片 + + + + + Png图片 + + + + + Gif动态图片 + + + + + Tiff图片 + + + + + 对变量的拓展 + + + + + 替换文本(忽略大小写) + + + 需要替换的内容 + 替换后的内容 + + + + + 替换文本(忽略大小写),可支持通配符 + + + + + 是否是通配符表达式,不是,则普通替换,忽略大小写,是,则启用通配符替换 + + + + + 获取符合要求的第一个结果 + + + + 是否是正则 + + + + + 查找字符串,忽略大小写 + + + + + + + + + 查找字符串,忽略大小写 + + + + + + + + 判断字符串是否是数字或英文 + + + + + + + 是否在指定范围内 + + + + + + + + + 是否在指定范围内 + + + + + + + + + 转换指定字符串为Int类型 + + + 最小值 + 最大值 + 如果字符串不在范围内,则使用本默认值 + + + + + 转换指定布尔类型到Int类型,true为1,false为0 + + + + + + + 将指定类型转换成整型 + + + + + + + + 将指定类型转换成整型 + + + + + + + 将指定类型转换成长整型 + + + + + + + + 将指定类型转换成长整型 + + + + + + + 转换指定类型为Double类型 + + + + + + + + 转换指定类型为Double类型 + + + + + + + 转换DateTime类型到日期时间字符串 + + + + + + + 转换DateTime类型到日期字符串 + + + + + + + 转换DateTime类型到日期星期字符串 + + + + + + + 转换DateTime类型到Unix时间戳 + + + + + + + 转换Unix时间戳到DateTime类型 + + + + + + + 判断字符串是否与内容匹配 + + + + + + + + 将变量值转换成Double类型,如果不在指定区域范围内,则使用默认值 + + + + + + + + + + 转换到文件大小字符串 + + + + + + + 转换到文件大小字符串 + + + + + + + 转换指定类型为Decimal类型 + + + + + + + + 将变量值转换成Decimal类型 + + + + + + + 将变量值转换成Decimal类型,如果不在指定区域范围内,则使用默认值 + + + + + + + + + + 转换指定类型为DateTime类型 + + + + + + + + 将变量值转换成DateTime类型 + + + + + + + 转换指定类型为布尔类型 + + + + + + + 追加字符 + + + + + + + + 获取指定字符串之间的内容 + + + + + + + + + 获取指定字符串之间的内容 + + + + + + + + + + + + 判断指定字符串是否是Int类型 + + + + + + + 判断指定字符串是否是Double类型 + + + + + + + 判断是否是布尔类型 + + + + + + + 将字符串转换为Base64类型 + + + + + + + 判断字符串是否在指定长度 + + + + + + + + + 判断能否转换成日期格式 + + + + + + + 文件信息 + + + + + 获取版本号 + + + + + 获取版本号 + + + + + + + 判断是否是管理员方式运行 + + + + + + Hosts操作类 + + + + + 获取并转换hosts内容 + + hosts内容 + + + + + 获取hosts并转换hosts内容 + + hosts内容 + + + + + 追加内容到hosts里 + + 要追加的内容列表,每一行为ip 域名的格式 + 0表示无需新增,-1表示添加失败,1表示追加成功 + + + + 追加内容到hosts里 + + 要追加的内容 + 0表示无需新增,-1表示添加失败,1表示追加成功 + + + + 追加内容到hosts里 + + ip地址 + 域名 + 0表示无需新增,-1表示添加失败,1表示追加成功 + + + + 从hosts文件里删除内容 + + 要删除的内容 + 0表示无需删除,-1表示添加失败,1表示删除成功 + + + + 从hosts文件里删除内容 + + ip地址 + 域名 + 0表示无需删除,-1表示添加失败,1表示删除成功 + + + + Host信息 + + + + + IP + + + + + 域名 + + + + + 注释 + + + + + 是否要删除 + + + + + 音频播放类 + + + + + 临时音频文件 + + + + + 父窗口句柄 + + + + + 声音标签 + + + + play synchronously (default) + + + play asynchronously + + + silence (!default) if sound not found + + + pszSound points to a memory file + + + loop the sound until next sndPlaySound + + + don’t stop any currently playing sound + + + Stop Playing Wave + + + don’t wait if the driver is busy + + + name is a registry alias + + + alias is a predefined id + + + name is file name + + + name is resource name or atom + + + + 音频播放类 + + embedded music file + 临时保存的文件位置 + 父窗口句柄 + + + + 音频播放类 + + 要播放的音频位置 + 父窗口句柄 + + + + 音频播放类 + + + 父窗口句柄 + + + + 播放音频 + + + + + + 播放音频 + + + + + 关闭音频 + + + + + 文件操作类 + + + + + + + + + + 删除单个文件。 + + 删除的文件名 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + 反馈错误消息的字符串 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 删除单个文件。 + + 删除的文件名 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 永久删除单个文件。 + + 永久删除的文件名 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 删除一组文件。 + + 字符串数组,表示一组文件名 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + 反馈错误消息的字符串 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 移动文件到指定路径下 + + 要移动的文件名 + 移动到的目的路径 + + + + + 移动一个文件到指定路径下 + + 要移动的文件名 + 移动到的目的路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 反馈错误消息的字符串 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码 + + + + 移动一组文件到指定的路径下 + + 要移动的文件名数组 + 移动到的目的路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 反馈错误消息的字符串 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 复制文件到指定的文件名或路径 + + 要复制的文件名 + 复制到的目的文件名或路径 + + + + + 复制文件到指定的文件名或路径 + + 要复制的文件名 + 复制到的目的文件名或路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 返回错误信息 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 复制一组文件到指定的路径 + + 要复制的文件名数组 + 复制到的目的路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 返回错误信息 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 重命名一个文件为新名称,建议您使用更方便的Microsoft.VisualBasic.FileSystem.ReName();替换该方法 + + 要复制的文件名 + 复制到的目的文件名或路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 返回错误信息 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 删除单个或多个文件 + + 删除的文件名,如果是多个文件,文件名之间以字符串结尾符'\0'隔开 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + 反馈错误消息的字符串 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 移动或复制一个或多个文件到指定路径下 + + 操作类型,是移动操作还是复制操作 + 要移动或复制的文件名,如果是多个文件,文件名之间以字符串结尾符'\0'隔开 + 移动到的目的位置 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 反馈错误消息的字符串 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码 + + + + 如果指定文件夹不存在,则创建文件夹 + + + + + + 获取一个文件的全名 + + 文件名 + 返回生成文件的完整路径名 + + + + 获取一个文件的全名 + + 文件名 + 返回生成文件的完整路径名 + + + + 解释错误代码 + + 代码号 + 返回关于错误代码的文字描述 + + + + 运行文件 + + + + + + + + /运行文件 + + + + + + + + 运行程序 + + + + + + + 打开文件 + + + + + + + 打开文件夹并定位文件 + + + + + + + 打开网址 + + + + + + + 判断文件名是否有效 + + + + + + + 转换到有效文件名 + + + + + + + 追加日志 + + + + + + 追加文件 + + + + + + 读取文件内容,可以自动识别文件编码 + + + + + + + 读取文件所有行,可以自动识别文件编码 + + + + + + + 写入所有文本行到文件,如果文件夹不存在,会自动创建 + + + + + + + + 写入所有文本到文件,如果文件夹不存在,会自动创建 + + + + + + + + 从文件中加载图片,使用本方法,不会导致图片文件被占用。 + + + + + + 获取文件大小 + + + + + + + 添加文件到指定文件夹,会进行自动重命名,并返回重命名后的文件名(含路径) + + 要添加的文件路径 + 要添加到的文件夹 + 是否根据时间进行重命名 + 返回是否成功执行 + 成功执行则返回路径,否则返回空 + + + + 获取文件大小字符串 + + + + + + + 获取文件大小字符串 + + + + + + + 复制内容到剪切板 + + + + + + 添加某个控件为支持拖放属性 + + + + + + + 保存高质量不失真照片 + + + + + + + + 保存高质量不失真照片 + + + + + + + + 保存高质量不失真照片 + + + + + + + + 获取绝对路径 + + + + + + + 获取相对路径 + + + + + + + 获取图标 + + + + + + + + + + + + + + 销毁图标 + + + + + + + 获取文件图标 + + + + + + + + + + 用于取得一个文本文件的编码方式(Encoding)。 + + + + + 用于取得一个文本文件的编码方式(Encoding)。 + + + + + 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,Encoding.Default将被返回。 + + 文件名。 + + + + + 取得一个文本文件流的编码方式。 + + 文本文件流。 + + + + + 取得一个文本文件的编码方式。 + + 文件名。 + 默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。 + + + + + 取得一个文本文件流的编码方式。 + + 文本文件流。 + 默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。 + + + + + 通过给定的文件流,判断文件的编码类型 + + 文件流 + 文件的编码类型 + + + + 判断是否是不带 BOM 的 UTF8 格式 + + + + + + + 新模态窗体 + + + + + 设置窗体返回的结果值,并关闭窗体。 + + 当前窗体 + 模态变量 + 防止 + + + + 窗体返回的结果事件 + + + + + + + 当打开的窗体返回结果时激发 + + + + + 窗体返回的状态 + + + + + 实例化类 + + 父窗体,如果为null,则取桌面为父窗体 + + + + + 获取最顶级的父窗口 + + + + + + 显示新模态窗体,会暂时禁用父窗体,关闭当前窗体后,父窗体会恢复。 + + + + + 只运行一个实例,打开后,所有窗体都依然有效。 + + + + + + 显示窗体 + + 显示的位置 + + + + 显示在父窗体中间 + + + + + 窗体显示位置 + + + + + 右上角 + + + + + 顶部中间 + + + + + 顶部右边 + + + + + 中间 + + + + + 左下角 + + + + + 底部中间 + + + + + 右下角 + + + + + 父窗体居中 + + + + + 日期时间的操作类 + + + + + 获取当前是周几,周一到周日,分别是1-7. + + + + + + + 获取当前是周几,1-7,分别是返回一到日. + + + + + + + 获取当前是周几,输入日期,根据周几,分别是返回一到日. + + + + + + + 获取一周的开始和结束,开始时间为第一天的0点,结束时间以最后一天的0点为结束时间 + + + + + + + 获取2个日期相差几周 + + + + + + + + 获取2个日期相差几个月 + + + + + + + + 获取一个月的开始 + + + + + + + 判断是否在同一个星期。 + + + + + + + + 判断是否在同一个月。 + + + + + + + + 判断是否在同一天 + + + + + + + + 计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + + 第一个日期和时间 + 第二个日期和时间 + + + + + 计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + + 第一个日期和时间 + 第二个日期和时间 + 是否显示秒 + + + + + 计算一个时间与当前本地日期和时间的时间间隔,返回的是时间间隔的日期差的绝对值. + + 一个日期和时间 + + + + + 将c# DateTime时间格式转换为Unix时间戳格式 + + 时间 + long + + + + 时间戳转为C#格式时间 + + + + + + + 将c# DateTime时间格式转换为js时间戳格式 + + 时间 + long + + + + JS时间戳转为C#格式时间 + + + + + + + 根据年月日转换成日期 + + + + + + + + + 根据日期和时间转换成日期时间 + + + + + + + + 将时间转换成当前分钟开始的时间 + + + + + + + 将时间转换成当前秒钟开始的时间 + + + + + + + 当前时间在这一天里的秒数 + + + + + + + 窗体操作类 + + + + + 设置Comobox的行间距 + + + + + + + 移除关闭按钮。返回值,非零表示成功,零表示失败。 + + 窗口的句柄 + 是否成功 + + + + 把窗体放到最前 + + + + + + 显示窗体 + + + + + + + + 设置窗体是否置顶 + + + + + + + 显示没有焦点的窗口 + + + + + + 根据句柄获取窗口文本 + + + + + + + 根据句柄获取窗口类 + + + + + + + 获取当前活动的窗口句柄 + + + + + + 设置为当前活动窗口 + + + + + + + 根据窗口句柄来获得进程id + + + + + + + 显示窗体 + + + + + + 设置窗体父窗体为桌面,不会随着显示桌面而最小化,但无法设置窗体透明度 + + + + + + 结束进程 + + + + + + + 打开窗体,只打开一个实例(非模态) + + + + + + + 设置注册表操作,部分功能需要管理员权限 + + + + + 访问的注册表位置(64位还是32位) + + + + + 访问的注册表节点 + + + + + 设置是否开机启动 + + 是否开机启动 + 开机启动名称 + 启动命令 + + + + + 设置是否开机启动 + + 是否开机启动 + 开机启动名称 + + + + + 把指定文件设置为开机启动或取消开机启动 + + 是否开机启动 + 开机启动名称 + 要开机启动的文件路径 + + + + + 检查是否开机启动 + + 开机启动名称 + 开机启动命令 + + + + + 检查是否开机启动 + + 开机启动名称 + + + + + 判断指定文件是否是开机启动 + + 开机启动名称 + 文件路径 + + + + + 判断当前程序是否是开机启动 + + 开机启动名称 + + + + + 判断当前程序是否是开机启动 + + 开机启动名称 + 启动命令行 + + + + + 设置指定文件的浏览器控件内核版本 + + 文件名,要求不带路径 + 7000 表示IE7兼容视图模式;8000 表示IE8 标准模式 ;8888 表示IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + 采用的IE模式 + + + + + IE7兼容视图 + + + + + IE8 标准模式 + + + + + IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + IE9 标准模式 + + + + + IE9 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + IE10 标准模式 + + + + + IE10 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + 设置当前软件的浏览器控件内核版本 + + 7000 表示IE7兼容视图模式;8000 表示IE8 标准模式 ;8888 表示IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + 设置指定文件的浏览器控件内核版本 + + 文件名,要求不带路径 + IE内核版本 + + + + + 设置当前软件的浏览器控件内核版本 + + IE内核版本 + + + + + 系统函数 + + + + + + + + + + 红 + + + + + 绿 + + + + + 蓝 + + + + + 获取屏幕伽马值 + + + + + + + + 设置屏幕伽马值 + + + + + + + + 获取键盘和鼠标没有操作的时间 + + + + + + 设置屏幕 Gamma值 + + + + + + + + + 设置屏幕亮度 + + + + + + + 获取系统 + + + + + + 窗体操作类 + + + + + 构造函数 + + + + + + 析构 + + + + + 设置让窗体支持移动 + + + + + 是否允许可调节大小 + + + + + 可调节窗体大小的宽度 + + + + + + + + + + + 给控件增加拖放功能的类 + + + + + 拖放实例 + + + + + 高级拖放事件 + + + + + + + + + + 使支持拖放属性 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 网络操作类 + + + + + 通过NetworkInterface读取网卡Mac + + + + + + 通过NetworkInterface读取网卡Mac + + + + + + 根据mac字符串来获取最终的mac地址,可以是各种MAC地址格式,非法的内容将返回null + + + + + + + 远程唤醒 + + + + + + + + 远程唤醒 + + + + + + + + + 消息客户端类 + + + + + 判断当前消息主服务器是否创建成功 + + + + + 最后一次接收消息的时间,可用来判断服务端是否有响应 + + + + + 主句柄 + + + + + 当收到消息时激发 + + + + + 连接上主服务器时触发 + + + + + 收到服务端关闭通知 + + + + + 收到服务端关闭通知,即将关闭 + + + + + 服务端大小改变时激发 + + + + + 实例化客户端 + + 服务端ID + 当前客户端ID,会向服务器报告当前ID + 客户端 + + + + + + + + + 断开服务端连接 + + + + + 发送消息,采用多线程发送 + + + + + + + 向服务端发送心跳包 + + + + + 判断服务端句柄是否存在。 + + + + + + 共享内存 + + + + + 写共享内存 + + 需要映射的文件的字节数量 + 映射对象(简单类型、结构体等) + 文件映射对象的名称 + + + + + 写共享内存 + + 需要映射的文件的字节数量 + 映射对象(简单类型、结构体等) + 文件映射对象的名称 + 发送消息的窗口句柄 + 发送消息 + + + + + 读共享内存 + + 需要映射的文件的字节数量 + 类型 + 文件映射对象的名称 + 返回读到的映射对象 + + + + 读共享内存 + + 需要映射的文件的字节数量 + 类型 + 文件映射对象的名称 + 返回读到的映射字节数据 + + + + 消息服务器 + + + + + 消息事件 + + + + + + + 大小改变事件 + + + + + + + + 即将关闭事件 + + + + + + + 当收到消息时激发 + + + + + 消息处理类 + + + + + + + + + + + + + + + + + + + + + + + 发送消息,采用单线程发送 + + 要发送到的句柄 + 编号 + 消息内容 + + + + 发送消息,采用多线程发送 + + 要发送到的句柄 + 编号 + 消息内容 + + + + 消息类 + + + + + 是否取消 + + + + + 来源句柄 + + + + + + + + + + 消息文本 + + + + + 需要回复的内容 + + + + + 消息服务端类 + + + + + 判断当前消息主服务器是否创建成功 + + + + + 当收到消息时激发 + + + + + 当收到自定义消息时(非系统消息)激发 + + + + + 有消息客户端发起连接请求时激发 + + + + + 有消息客户端连接成功时激发 + + + + + 有消息客户端断开连接时激发 + + + + + + + 服务端ID,需要唯一性,共客户端识别 + 服务端 + + + + 释放资源 + + + + + 判断是否包含指定客户端 + + + + + + + + + + + + 设置客户端大小 + + + + + 根据客户端ID,获取客户端对象 + + + + + + + 根据客户端句柄,获取客户端对象 + + + + + + + 关闭所有客户端 + + + + + 关闭指定客户端 + + + + + + 关闭指定客户端 + + + + + + 向所有客户端发送消息,单线程 + + + + + + + 向指定客户端发送消息 + + + + + + + + 关闭在指定时间前失去响应的子客户端 + + + + + + 客户端信息 + + + + + 客户端句柄 + + + + + 客户端ID + + + + + 客户端连接时间 + + + + + 心跳时间 + + + + + 数据库引擎 + + + + + 数据库枚举类型 + + + + + Odbc引擎 + + + + + OleDb引擎 + + + + + Oracle引擎 + + + + + MSSQL引擎 + + + + + SQLite引擎 + + + + + MySql引擎 + + + + + 判断DataSet是否包含数据 + + + + + + + 获取首行数据 + + + + + + + 获取第一行第一列的值 + + + + + + + 将DataSet类型转换为RyQuickSQL列表类型 + + + + + + + 将DataSet类型转换为RyQuickSQL列表类型 + + + + + + + + 数据库操作接口 + + + + + 连接数据库 + + + + + + 断开数据库 + + + + + + 获取数量 + + + + + + + + 获取分页语句 + + + + + + + + + 获取分页语句 + + + + + + + + + 获取分页语句 + + + + + + + + + + 获取分页语句 + + + + + + + + + + 添加Parameter参数 + + + + + + + 清空Parameter参数 + + + + + + + 获取Parameter值 + + + + + + 根据RyQuickSQL类来获取Parameter值 + + + + + + + 开始执行事务 + + + + + 提交事务 + + + + + 判断是否包含数据 + + + + + + + + 返回-1000表示该数据库不支持本接口 + + + + + + + 读取数据 + + + + + + + 读取数据 + + + + + + + + 读取数据 + + + + + + + + 根据id号获取数据 + + + + + + + + 执行SQL语句 + + + + + + + + 执行SQL语句 + + + + + + + + 执行SQL语句 + + + + + + + 根据id号删除数据 + + + + + + + + 创建数据库 + + + + + + + 释放资源 + + + + + SQL字段类型 + + + + + SQL字段类型 + + + + + + + SQL字段类型 + + + + + + + + SQL字段名 + + + + + SQL字段值 + + + + + SQL字段长度 + + + + + 不是真的值,而是用于计算的值 + + + + + SQL快速操作类 + + + + + SQL快速操作类 + + + + + + 表名 + + + + + 操作字段列表 + + + + + 清理使用资源 + + + + + 清理使用资源 + + + + + 操作参数列表 + + + + + 操作参数列表 + + + + + 添加字符串字段 + + + + + + + 添加null值字段 + + + + + + 添加日期字段 + + + + + + + 添加int字段 + + + + + + + 添加double字段 + + + + + + + 添加decimal字段 + + + + + + + 添加bool字段 + + + + + + + 添加用于计算的值 + + + + + + + 添加Int64字段 + + + + + + + 清空内容 + + + + + 数量 + + + + + + + + + + 输出多条件搜索。 + + 字段名,多个字段请用逗号分隔。 + 多个条件之间请用空格隔开 + + + + + 获取插入SQL语句 + + + + + + 获取更新SQL语句 + + + + + + 添加参数 + + + + + + + 获取Ole参数 + + + + + + 获取SQL参数 + + + + + + AES加密解密类 + + + + + AES加密算法 + + 明文字符串 + 密钥 + 返回加密后的密文字节数组 + + + + AES解密 + + 密文字节数组 + 密钥 + 返回解密后的字符串 + + + + 加密 + + + + + + + + 解码 + + + + + + + + 转换密钥到合法密钥 + + + + + + + Base64编码类 + + + + + 编码 + + + + + + + 把字符串编码成Base64字符串 + + + + + + + + 解码 + + + + + + + MD5和SHA1操作类 + + + + + 获取MD5 + + + + + + + 获取MD5 + + + + + + + 获取SHA1 + + + + + + + 获取SHA1 + + + + + + + 获取HmacSHA1 + + + + + + + + 获取SHA256 + + + + + + + 获取HmacSHA256 + + + + + + + 获取SHA224 + + + + + + + 获取SHA512 + + + + + + + 获取HmacSHA512 + + + + + + + 使用using代替lock操作的对象,可指定写入和读取锁定模式 + + + + 利用IDisposable的using语法糖方便的释放锁定操作 + 内部类 + + + + 读写锁对象 + + + + 是否为写入模式 + + + + 利用IDisposable的using语法糖方便的释放锁定操作 + 构造函数 + + 读写锁 + 写入模式为true,读取模式为false + + + 释放对象时退出指定锁定模式 + + + + 空的可释放对象,免去了调用时需要判断是否为null的问题 + 内部类 + + + + 空的可释放对象 + + + + 空的释放方法 + + + + 读写锁 + + + + 保存数据 + + + + 使用using代替lock操作的对象,可指定写入和读取锁定模式 + 构造函数 + + + + 使用using代替lock操作的对象,可指定写入和读取锁定模式 + 构造函数 + 为Data属性设置初始值 + + + + 获取或设置当前对象中保存数据的值 + + 获取数据时未进入读取或写入锁定模式 + 设置数据时未进入写入锁定模式 + + + 是否启用,当该值为false时,Read()和Write()方法将返回 Disposable.Empty + + + + 进入读取锁定模式,该模式下允许多个读操作同时进行 + 退出读锁请将返回对象释放,建议使用using语块 + Enabled为false时,返回Disposable.Empty; + 在读取或写入锁定模式下重复执行,返回Disposable.Empty; + + + + 进入写入锁定模式,该模式下只允许同时执行一个读操作 + 退出读锁请将返回对象释放,建议使用using语块 + Enabled为false时,返回Disposable.Empty; + 在写入锁定模式下重复执行,返回Disposable.Empty; + + 读取模式下不能进入写入锁定状态 + + + + 中国农历类,最大支持公元0-9999年 + + 日期:2019-02-09 + 作者:http://www.cnblogs.com/zjfree/ + + + + 日历类型 + + + + + 无效 + + + + + Julian 日历 + + + + + Gregorian 日历 + + + + + 有效 + + + + + 公历节日 + + + + + 农历节日 + + + + + 某个月第n个星期几 + + + + + 获取农历 + + + + + + + 获取农历 + + + + + + + + + 获得某农历年的闰月,返回 1~12 对应一月到十二月,返回 0 表示无闰月 + + + + + + + 农历搜索方向 + + + + + 无效 + + + + + 向上 + + + + + 向下 + + + + + {* 日月食类型, 无, 日食, 月全食, 月偏食 } + + + + + 无 + + + + + 日食 + + + + + 月全食 + + + + + 月偏食 + + + + + {* 月相, 无, 朔, 望} + + + + + 无 + + + + + 朔 + + + + + 望 + + + + + 获得某公历年月日的农历日数和该日月相以及日月食类型和时刻 + + + + + + + + + + + + 获得某公历年月日的农历月数 + + + + + + + + + 获取阳历日期对应的农历日期 + + + + + + + + + + + + + 获得某公历年月日的农历月日和是否闰月的信息 + + + + + + + + + + + + 获得等效标准日数对应的某公历日,倒推而来 + + + + + + + + + + 比较两个农历日期(包括闰月信息),1 大于2返回1、1等于2返回0、1小于2返回-1 + + + + + + + + + + + + + + 获得某农历年月日(加是否闰月)的公历年月日 + 该函数采用反向二分法查找 + + + + + + + + + + + + + 获取农历某一个月的总天数 + + + + + + + + + 获取农历年份,范围约1901-2101年 + + + + + + + 获取农历年份,范围约0-9999年 + + + + + + + + + 获取农历月份,范围约1901-2101年 + + + + + + + 获取农历月份,范围约0-9999年 + + + + + + + + + 获取中文表示的农历月份 + + + + + + + 获取农历日,范围约1901-2101年 + + + + + + + 获取农历日,范围约0-9999年 + + + + + + + + + 获取农历日,范围约0-9999年 + + + + + + + 获取节气,范围约1901-2101年 + + + + + + + 获取节气,范围约0-9999年 + + + + + + + + + 返回y年第n个节气(如小寒为1)的日差天数值(pd取值真假,分别表示平气和定气) + + + + pd取值真假,分别表示平气和定气 + + + + + 获取等效标准日数 + + + + + + + + + 取本月天数,不考虑 1582 年 10 月的特殊情况 + + + + + + + + 获取节气,范围约1901-2101年 + + + + + + + 获取节气,范围约0-9999年 + + + + + + + + + 获取节气 + + + + + + + + + + + + 获取公历节日 + + + + + + + 获取公历节日 + + + + + + + + + 获取指定月份的第n个星期几的节日 + + + + + + + 返回星座,范围约1901-2101年 + + + + + 返回星座,范围约0-9999年 + + + + + 获取农历节日 + + + + + + + + + 获取农历节日 + + + + + + + 判断y年m月(1,2,..,12,下同)d日是Gregorian历还是Julian历(opt=1,2,3分别表示标准日历,Gregorge历和Julian历),是则返回1,是Julian历则返回0,若是Gregorge历所删去的那10天则返回-1 + + + + + 返回阳历y年m月d日的日差天数(在y年年内所走过的天数,如2000年3月1日为61) + + + + + 返回阳历y年日差天数为x时所对应的月日数(如y=2000,x=274时,返回1001(表示10月1日,即返回100*m+d)) + + + + + 获取指定日期的节气。 + + 要获取的年 + 要获取的月 + + + 立春:立是开始的意思,春是蠢动,表示万物开始有生气,这一天春天开始。 + 雨水:降雨开始,雨水将多。 + 惊蛰:春雷响动,惊动蛰伏地下冬眠的生物,它们将开始出土活动。 + 春分:这是春季九十天的中分点,这一天昼夜相等,所以古代曾称春分秋分为昼夜分。 + 清明:明洁晴朗,气候温暖,草木开始萌发繁茂。 + 谷雨:雨生百谷的意思。雨水增多,适时的降雨对谷物生长很为有利。 + 立夏:夏天开始,万物渐将随温暖的气候而生长。 + 小满:满指籽粒饱满,麦类等夏热作物这时开始结籽灌浆,即将饱满。 + 芒种:有芒作物开始成熟,此时也是秋季作物播种的最繁忙时节。 + 夏至:白天最长,黑夜最短,这一天中午太阳位置最高,日影短至终极,古代又称这一天为日北至或长日至。 + 小暑:暑是炎热,此时还未到达最热。 + 大暑:炎热的程度到达高峰。 + 立秋:秋天开始,植物快成熟了。 + 处暑:处是住的意思,表示暑气到此为止。 + 白露:地面水气凝结为露,色白,是天气开始转凉了。 + 秋分:秋季九十天的中间,这一天昼夜相等,同春分一样,太阳从正东升起正西落下。 + 寒露:水露先白而后寒,是气候将逐渐转冷的意思。 + 霜降:水气开始凝结成霜。 + 立冬:冬是终了,作物收割后要收藏起来的意思,这一天起冬天开始。 + 小雪:开始降雪,但还不多。 + 大雪:雪量由小增大。 + 冬至:这一天中午太阳在天空中位置最低,日影最长,白天最短, 黑夜最长,古代又称短日至或日南至。 + 小寒:冷气积久而为寒,此时尚未冷到顶点。 + 大寒:天候达到最寒冷的程度 + + + + + 获取年柱。 + + + + + 获得月柱 + + + + + + + 获取日柱。 + + + + + 返回甲子数x对应的天干数(如33为3) + + + + + 返回甲子数x对应的地支数(如33为9) + + + + + 获取日的天干地支 + + + + + + + 返回甲子数x对应的天干字符串 + + + + + 返回甲子数x对应的地支字符串 + + + + + 返回甲子数x对应的干支字符串 + + + + + + + 获取三伏开始时间 + + + 0表示1伏,1表示2伏,2表示3伏 + + + + + 节气 + + + + + 节气的时间。 + + + + + 节气名。 + + + + + 热键转换类 + + + + + 功能键。 + + + + + 修改键。 + + + + + 转换功能键到谷歌浏览器专用 + + + + + 将chrome功能键转换为普通功能键 + + + + + + + 按键值。 + + + + + 初始化类 的新实例。 + + The modifiers. + The key code. + + + + + + + + + + + + + + + + + 初始化类 的新实例。 + + + + + 加载热键 + + + + + + + 加载热键 + + + + + + 加载热键 + + + + + + 判断是否是热键 + + + + + 获取当前热键 + + + + + 已重载,返回“Ctrl+Alt+A”格式的字符串。 + + 类似“Ctrl+Alt+A”格式的字符串 + + + + 返回“Ctrl+Alt+A”格式的字符串。 + + 类似“Ctrl+Alt+A”格式的字符串 + + + + 功能键 + + + + + 无 + + + + + Alt键 + + + + + Ctrl键 + + + + + Shift键 + + + + + Win键 + + + + + 热键类 + + + + + 热键类 + + + + + + 热键注销 + + + + + 热键是否有效 + + + + + 释放热键 + + + + + 注册热键 + + + + + + + + + 注册热键 + + + + + + + + + 删除热键 + + + + + + + 删除所有热键 + + + + + 热键事件 + + + + + + 当使用热键时发生的事件 + + + + + 热键消息过滤 + + + + + + + 热键类型 + + + + + 热键id + + + + + 功能键 + + + + + 普通键 + + + + + 热键类型 + + + + + + + + Win32 API + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取当前前台窗口句柄 + + + + + + 获得当前活动窗体 + + + + + + 设置活动窗体 + + + + + + + 获取类名 + + + + + + + + + 获取当前线程对应的进程ID + + + + + + + + 判断指定句柄是否是一个窗口 + + + + + + + 获取窗口标题 + + + + + + + + + 查找窗口 + + + + + + + + 设置父窗口 + + + + + + + + 移动窗口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 结束进程 + + + + + + + + 发送消息 + + + + + + + + + + 发送消息 + + + + + + + + + 获取窗口位置和大小 + + + + + + + + 矩形 + + + + + 最左坐标 + + + + + 最上坐标 + + + + + 最右坐标 + + + + + 最下坐标 + + + + + WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。 + + + + + 系统通道ID + + + + + 用户通道ID + + + + + + + + + + + + + + + + + + + + + + + + + 获取消息 + + + + + + + + 发送消息 + + + + + + + + + + 设置父窗口 + + + + + + + + diff --git a/Bin/Release/CommonControls/.NET4 示例/MyDb_SQLite.dll b/Bin/Release/CommonControls/.NET4 示例/MyDb_SQLite.dll new file mode 100644 index 0000000..8987c2b Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/MyDb_SQLite.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/RyPrint.dll b/Bin/Release/CommonControls/.NET4 示例/RyPrint.dll new file mode 100644 index 0000000..04ff90d Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/RyPrint.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/RyWeb.dll b/Bin/Release/CommonControls/.NET4 示例/RyWeb.dll new file mode 100644 index 0000000..423e97c Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/RyWeb.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/System.Data.SQLite.dll b/Bin/Release/CommonControls/.NET4 示例/System.Data.SQLite.dll new file mode 100644 index 0000000..e15c908 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/System.Data.SQLite.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/UserDb/Win.dat b/Bin/Release/CommonControls/.NET4 示例/UserDb/Win.dat new file mode 100644 index 0000000..d18abd2 --- /dev/null +++ b/Bin/Release/CommonControls/.NET4 示例/UserDb/Win.dat @@ -0,0 +1,2 @@ +[Money_Op] +hwnd=74558 diff --git a/Bin/Release/CommonControls/.NET4 示例/XPTable.dll b/Bin/Release/CommonControls/.NET4 示例/XPTable.dll new file mode 100644 index 0000000..4ac2f2e Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/XPTable.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/cUpdate.dat b/Bin/Release/CommonControls/.NET4 示例/cUpdate.dat new file mode 100644 index 0000000..ebae366 --- /dev/null +++ b/Bin/Release/CommonControls/.NET4 示例/cUpdate.dat @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Bin/Release/CommonControls/.NET4 示例/ryControls.dll b/Bin/Release/CommonControls/.NET4 示例/ryControls.dll new file mode 100644 index 0000000..e8a9dc9 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/ryControls.dll differ diff --git a/Bin/Release/CommonControls/.NET4 示例/ryUpdate.dll b/Bin/Release/CommonControls/.NET4 示例/ryUpdate.dll new file mode 100644 index 0000000..c7a4776 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4 示例/ryUpdate.dll differ diff --git a/Bin/Release/CommonControls/.NET4/MyDb.dll b/Bin/Release/CommonControls/.NET4/MyDb.dll new file mode 100644 index 0000000..87d72d0 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/MyDb.dll differ diff --git a/Bin/Release/CommonControls/.NET4/MyDb.xml b/Bin/Release/CommonControls/.NET4/MyDb.xml new file mode 100644 index 0000000..f4779a0 --- /dev/null +++ b/Bin/Release/CommonControls/.NET4/MyDb.xml @@ -0,0 +1,4829 @@ + + + + MyDb + + + + + 基于XML实现的权限类 + + + + + 用户名 + + + + + 用户id + + + + + 密码 + + + + + 权限控制Id + + + + + 用户备注 + + + + + 是否是管理员权限 + + + + + 是否是超级管理员权限 + + + + + 设置权限 + + 权限名称 + 权限值 + 返回是否设置成功 + + + + 获取权限 + + 权限名称 + 默认权限值 + 返回权限值 + + + + 获取权限 + + 权限名称 + 返回权限值 + + + + 批量导入权限 + + 权限相关的内容 + 返回是否执行成功 + + + + 导出权限 + + 返回导出文本 + + + + 清除所有权限 + + 返回是否执行成功 + + + + 汉字转拼音静态类,包括功能全拼和缩写,方法全部是静态的 + + + + + 汉字的机内码数组 + + + + + 机内码对应的拼音数组 + + + + + 把汉字转换成拼音(全拼) + + 汉字字符串 + 转换后的拼音(全拼)字符串 + + + + 把汉字转换成拼音(全拼) + + 汉字字符串 + 转换后的拼音(全拼)字符串 + + + + 把汉字转换成拼音(首拼) + + 汉字字符串 + 转换后的拼音(首拼)字符串 + + + + 把汉字转换成拼音(全拼) + + 汉字字符串 + 用指定字符分隔 + 转换后的拼音(全拼)字符串 + + + + 汉字转拼音缩写 + + 要转换的汉字字符串 + 拼音缩写 + + + + 汉字转拼音缩写 (字符串) (小写) (空格间隔) + + 要转换的汉字字符串 + 拼音缩写 + + + + 汉字转拼音缩写 (大写) + + 要转换的汉字字符串 + 拼音缩写 + + + + 汉字转拼音缩写 (字符串)(大写)(空格间隔) + + 要转换的汉字字符串 + 拼音缩写 + + + + 取单个字符的拼音声母 + + 要转换的单个汉字 + 拼音声母 + + + + 取单个字符的拼音声母 + + 要转换的单个汉字 + 拼音声母 + + + + Ini操作类 + + + + + 写入Ini + + + + + + + + + + 获取Ini + + + + + + + + + + + + 声明INI文件的读操作函数 GetPrivateProfileString() + + + + + + + + + + + + 声明INI文件的读操作函数 GetPrivateProfileString() + + + + + + + + + + 声明INI文件的读操作函数 GetPrivateProfileString() + + + + + + + + + + + + 获取所有节点名称(Section) + + 存放节点名称的内存地址,每个节点之间用\0分隔 + 内存大小(characters) + Ini文件 + 内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够 + + + + 编码 + + + + + Ini操作类 + + + + + + 根据section取所有key和值 + + + + + + + 读取INI文件中指定INI文件中的所有节点名称(Section) + + 所有节点,没有内容返回string[0] + + + + 读取INI文件 + + 段,格式[] + 键 + 返回byte类型的section组或键值组 + + + + 根据section取所有key + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入ini + + + + + + + + 写入Ini + + + + + + + + 读取Ini + + + + + + + + 读取Ini + + + + + + + + + 读取Ini + + + + + + + + + 读取Ini + + + + + + + + + + + 写入ini + + + + + + + + + 删除Ini的Key + + + + + + + 删除Ini节点 + + + + + + 控件信息 + + + + + id + + + + + 控件对象 + + + + + 控件值类型 + + + + + 默认值 + + + + + 值类型 + + + + + 默认 + + + + + 取列表顺序值 + + + + + 取当前选择的列表值 + + + + + 取对象值 + + + + + 保存的设置类型 + + + + + Ini + + + + + XML + + + + + 对象值 + + + + + 显示的文本 + + + + + 图片序号 + + + + + id + + + + + Tag值 + + + + + 显示文本值 + + + + + + 星期数据 + + + + + 一周的开始时间 + + + + + 一周的结束时间 + + + + + XML操作类 + + + + + XML操作类 + + + + + 从XML文本中加载数据 + + + + + + 从指定的XML文本中加载 + + XML文本 + 如为1,表示加载成功,为0为失败 + + + + 载入空的XML文档 + + 如为1,表示加载成功,为0为失败 + + + + 从指定的文件中加载 + + XML文件路径 + 如为1,表示加载成功,为0为失败 + + + + 保存到指定文件中 + + 文件路径 + 如为1,表示保存成功,为0为失败 + + + + 判断节点是否存在 + + 属性名 + 属性值 + 返回1,表示存在,其它表示不存在 + + + + 定位节点 + + 属性名 + 属性值 + 返回第一个符合要求的结果 + + + + 定位节点,如果找不到节点,就新建一个节点 + + 属性名 + 属性值 + 返回第一个符合要求的结果 + + + + 根据用户的节点定位节点,输入节点时,一定要注意节点是属于类内部的,否则可能出错。 + + 返回第一个符合要求的结果 + + + + 定位设置节点 + + 返回第一个符合要求的结果 + + + + 在节点后插入数据 + + + + + + + 在节点前插入数据 + + + + + + + 获取节点数量 + + 属性名 + 属性值 + 返回符合要求的结果数量 + + + + 获取节点数量 + + 返回符合要求的结果数量 + + + + 获取节点数量 + + 属性名 + 属性值 + + + + 返回符合要求的结果数量 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 设置节点值 + + 属性名 + 属性值 + 如为1,表示加载成功,为0为失败 + + + + 读取指定节点的值 + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 获取属性值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取所有的节点名称 + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 读取指定节点的值 + + + + + + + + 获取XML文件的根元素 + + + + + 获取所有列表 + + 如为1,表示获取成功,为0为失败 + + + + 获取所有列表 + + 如为1,表示获取成功,为0为失败 + + + + 新增节点 + + + + + + + + 新增节点并定位到新节点 + + + + + + + + 新增设置节点并定位 + + + + + + 在指定节点前新增节点并定位到新节点 + + + + + + + + + 获取当前节点 + + + + + + 删除节点 + + + + + + 获取XML文本 + + + + + + 获取XML文本 + + + + + + 获取文本 + + + + + + 获取文本 + + + + + + 字符串操作类 + + + + + 字符串转Base64 + + + + + + + Base64转字符串 + + + + + + + 转换指定字符串为布尔类型 + + + + + 转换指定字符串为Double类型 + + + + + 已重载.计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + + 第一个日期和时间 + 第二个日期和时间 + + + + + 已重载.计算一个时间与当前本地日期和时间的时间间隔,返回的是时间间隔的日期差的绝对值. + + 一个日期和时间 + + + + + 转换指定字符串为Int类型 + + + + + 转换指定字符串为Int类型 + + + + + 转换指定布尔类型为Int类型,true为1,false为0 + + + + + 判断指定字符串是否是布尔类型 + + + + + 判断指定字符串是否是Double类型 + + + + + 判断指定字符串是否是Int类型 + + + + + 根据年月日转换成日期 + + + + + + + + + 追加字符 + + + + + 获取2个字符串中间的内容,point1为空表示从首位开始算,point2为空表示算到结尾。 + + + + + 判断字符串是否只包含数字或英文 + + + + + + + 判断字符串是否匹配,支持?*通配符 + + 待匹配的字符串 + 匹配的通配符 + + + + + 通配符替换 + + + + + + + + + 获取匹配的内容 + + + + + + + + + 文件时间 + + + + + 创建时间 + + + + + 最后修改时间 + + + + + 访问时间 + + + + + 图片类型 + + + + + Bmp图片 + + + + + Jpeg图片 + + + + + Png图片 + + + + + Gif动态图片 + + + + + Tiff图片 + + + + + 对变量的拓展 + + + + + 替换文本(忽略大小写) + + + 需要替换的内容 + 替换后的内容 + + + + + 替换文本(忽略大小写),可支持通配符 + + + + + 是否是通配符表达式,不是,则普通替换,忽略大小写,是,则启用通配符替换 + + + + + 获取符合要求的第一个结果 + + + + 是否是正则 + + + + + 查找字符串,忽略大小写 + + + + + + + + + 查找字符串,忽略大小写 + + + + + + + + 判断字符串是否是数字或英文 + + + + + + + 是否在指定范围内 + + + + + + + + + 是否在指定范围内 + + + + + + + + + 转换指定字符串为Int类型 + + + 最小值 + 最大值 + 如果字符串不在范围内,则使用本默认值 + + + + + 转换指定布尔类型到Int类型,true为1,false为0 + + + + + + + 将指定类型转换成整型 + + + + + + + + 将指定类型转换成整型 + + + + + + + 将指定类型转换成长整型 + + + + + + + + 将指定类型转换成长整型 + + + + + + + 转换指定类型为Double类型 + + + + + + + + 转换指定类型为Double类型 + + + + + + + 转换DateTime类型到日期时间字符串 + + + + + + + 转换DateTime类型到日期字符串 + + + + + + + 转换DateTime类型到日期星期字符串 + + + + + + + 转换DateTime类型到Unix时间戳 + + + + + + + 转换Unix时间戳到DateTime类型 + + + + + + + 判断字符串是否与内容匹配 + + + + + + + + 将变量值转换成Double类型,如果不在指定区域范围内,则使用默认值 + + + + + + + + + + 转换到文件大小字符串 + + + + + + + 转换到文件大小字符串 + + + + + + + 转换指定类型为Decimal类型 + + + + + + + + 将变量值转换成Decimal类型 + + + + + + + 将变量值转换成Decimal类型,如果不在指定区域范围内,则使用默认值 + + + + + + + + + + 转换指定类型为DateTime类型 + + + + + + + + 将变量值转换成DateTime类型 + + + + + + + 转换指定类型为布尔类型 + + + + + + + 追加字符 + + + + + + + + 获取指定字符串之间的内容 + + + + + + + + + 获取指定字符串之间的内容 + + + + + + + + + + + + 判断指定字符串是否是Int类型 + + + + + + + 判断指定字符串是否是Double类型 + + + + + + + 判断是否是布尔类型 + + + + + + + 将字符串转换为Base64类型 + + + + + + + 判断字符串是否在指定长度 + + + + + + + + + 判断能否转换成日期格式 + + + + + + + 文件信息 + + + + + 获取版本号 + + + + + 获取版本号 + + + + + + + 判断是否是管理员方式运行 + + + + + + Hosts操作类 + + + + + 获取并转换hosts内容 + + hosts内容 + + + + + 获取hosts并转换hosts内容 + + hosts内容 + + + + + 追加内容到hosts里 + + 要追加的内容列表,每一行为ip 域名的格式 + 0表示无需新增,-1表示添加失败,1表示追加成功 + + + + 追加内容到hosts里 + + 要追加的内容 + 0表示无需新增,-1表示添加失败,1表示追加成功 + + + + 追加内容到hosts里 + + ip地址 + 域名 + 0表示无需新增,-1表示添加失败,1表示追加成功 + + + + 从hosts文件里删除内容 + + 要删除的内容 + 0表示无需删除,-1表示添加失败,1表示删除成功 + + + + 从hosts文件里删除内容 + + ip地址 + 域名 + 0表示无需删除,-1表示添加失败,1表示删除成功 + + + + Host信息 + + + + + IP + + + + + 域名 + + + + + 注释 + + + + + 是否要删除 + + + + + 音频播放类 + + + + + 临时音频文件 + + + + + 父窗口句柄 + + + + + 声音标签 + + + + play synchronously (default) + + + play asynchronously + + + silence (!default) if sound not found + + + pszSound points to a memory file + + + loop the sound until next sndPlaySound + + + don’t stop any currently playing sound + + + Stop Playing Wave + + + don’t wait if the driver is busy + + + name is a registry alias + + + alias is a predefined id + + + name is file name + + + name is resource name or atom + + + + 音频播放类 + + embedded music file + 临时保存的文件位置 + 父窗口句柄 + + + + 音频播放类 + + 要播放的音频位置 + 父窗口句柄 + + + + 音频播放类 + + + 父窗口句柄 + + + + 播放音频 + + + + + + 播放音频 + + + + + 关闭音频 + + + + + 文件操作类 + + + + + + + + + + 删除单个文件。 + + 删除的文件名 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + 反馈错误消息的字符串 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 删除单个文件。 + + 删除的文件名 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 永久删除单个文件。 + + 永久删除的文件名 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 删除一组文件。 + + 字符串数组,表示一组文件名 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + 反馈错误消息的字符串 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 移动文件到指定路径下 + + 要移动的文件名 + 移动到的目的路径 + + + + + 移动一个文件到指定路径下 + + 要移动的文件名 + 移动到的目的路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 反馈错误消息的字符串 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码 + + + + 移动一组文件到指定的路径下 + + 要移动的文件名数组 + 移动到的目的路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 反馈错误消息的字符串 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 复制文件到指定的文件名或路径 + + 要复制的文件名 + 复制到的目的文件名或路径 + + + + + 复制文件到指定的文件名或路径 + + 要复制的文件名 + 复制到的目的文件名或路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 返回错误信息 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 复制一组文件到指定的路径 + + 要复制的文件名数组 + 复制到的目的路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 返回错误信息 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 重命名一个文件为新名称,建议您使用更方便的Microsoft.VisualBasic.FileSystem.ReName();替换该方法 + + 要复制的文件名 + 复制到的目的文件名或路径 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 返回错误信息 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + + + + 删除单个或多个文件 + + 删除的文件名,如果是多个文件,文件名之间以字符串结尾符'\0'隔开 + 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + 反馈错误消息的字符串 + 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + + + + 移动或复制一个或多个文件到指定路径下 + + 操作类型,是移动操作还是复制操作 + 要移动或复制的文件名,如果是多个文件,文件名之间以字符串结尾符'\0'隔开 + 移动到的目的位置 + 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + 指示是否显示进度对话框 + 指示当文件名重复时,是否自动为新文件加上后缀名 + 反馈错误消息的字符串 + 返回移动操作是否成功的标识,成功返回0,失败返回错误代码 + + + + 如果指定文件夹不存在,则创建文件夹 + + + + + + 获取一个文件的全名 + + 文件名 + 返回生成文件的完整路径名 + + + + 获取一个文件的全名 + + 文件名 + 返回生成文件的完整路径名 + + + + 解释错误代码 + + 代码号 + 返回关于错误代码的文字描述 + + + + 运行文件 + + + + + + + + /运行文件 + + + + + + + + 运行程序 + + + + + + + 打开文件 + + + + + + + 打开文件夹并定位文件 + + + + + + + 打开网址 + + + + + + + 判断文件名是否有效 + + + + + + + 转换到有效文件名 + + + + + + + 追加日志 + + + + + + 追加文件 + + + + + + 读取文件内容,可以自动识别文件编码 + + + + + + + 读取文件所有行,可以自动识别文件编码 + + + + + + + 写入所有文本行到文件,如果文件夹不存在,会自动创建 + + + + + + + + 写入所有文本到文件,如果文件夹不存在,会自动创建 + + + + + + + + 从文件中加载图片,使用本方法,不会导致图片文件被占用。 + + + + + + 获取文件大小 + + + + + + + 添加文件到指定文件夹,会进行自动重命名,并返回重命名后的文件名(含路径) + + 要添加的文件路径 + 要添加到的文件夹 + 是否根据时间进行重命名 + 返回是否成功执行 + 成功执行则返回路径,否则返回空 + + + + 获取文件大小字符串 + + + + + + + 获取文件大小字符串 + + + + + + + 复制内容到剪切板 + + + + + + 添加某个控件为支持拖放属性 + + + + + + + 保存高质量不失真照片 + + + + + + + + 保存高质量不失真照片 + + + + + + + + 保存高质量不失真照片 + + + + + + + + 获取绝对路径 + + + + + + + 获取相对路径 + + + + + + + 获取图标 + + + + + + + + + + + + + + 销毁图标 + + + + + + + 获取文件图标 + + + + + + + + + + 用于取得一个文本文件的编码方式(Encoding)。 + + + + + 用于取得一个文本文件的编码方式(Encoding)。 + + + + + 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,Encoding.Default将被返回。 + + 文件名。 + + + + + 取得一个文本文件流的编码方式。 + + 文本文件流。 + + + + + 取得一个文本文件的编码方式。 + + 文件名。 + 默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。 + + + + + 取得一个文本文件流的编码方式。 + + 文本文件流。 + 默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。 + + + + + 通过给定的文件流,判断文件的编码类型 + + 文件流 + 文件的编码类型 + + + + 判断是否是不带 BOM 的 UTF8 格式 + + + + + + + 新模态窗体 + + + + + 设置窗体返回的结果值,并关闭窗体。 + + 当前窗体 + 模态变量 + 防止 + + + + 窗体返回的结果事件 + + + + + + + 当打开的窗体返回结果时激发 + + + + + 窗体返回的状态 + + + + + 实例化类 + + 父窗体,如果为null,则取桌面为父窗体 + + + + + 获取最顶级的父窗口 + + + + + + 显示新模态窗体,会暂时禁用父窗体,关闭当前窗体后,父窗体会恢复。 + + + + + 只运行一个实例,打开后,所有窗体都依然有效。 + + + + + + 显示窗体 + + 显示的位置 + + + + 显示在父窗体中间 + + + + + 窗体显示位置 + + + + + 右上角 + + + + + 顶部中间 + + + + + 顶部右边 + + + + + 中间 + + + + + 左下角 + + + + + 底部中间 + + + + + 右下角 + + + + + 父窗体居中 + + + + + 日期时间的操作类 + + + + + 获取当前是周几,周一到周日,分别是1-7. + + + + + + + 获取当前是周几,1-7,分别是返回一到日. + + + + + + + 获取当前是周几,输入日期,根据周几,分别是返回一到日. + + + + + + + 获取一周的开始和结束,开始时间为第一天的0点,结束时间以最后一天的0点为结束时间 + + + + + + + 获取2个日期相差几周 + + + + + + + + 获取2个日期相差几个月 + + + + + + + + 获取一个月的开始 + + + + + + + 判断是否在同一个星期。 + + + + + + + + 判断是否在同一个月。 + + + + + + + + 判断是否在同一天 + + + + + + + + 计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + + 第一个日期和时间 + 第二个日期和时间 + + + + + 计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + + 第一个日期和时间 + 第二个日期和时间 + 是否显示秒 + + + + + 计算一个时间与当前本地日期和时间的时间间隔,返回的是时间间隔的日期差的绝对值. + + 一个日期和时间 + + + + + 将c# DateTime时间格式转换为Unix时间戳格式 + + 时间 + long + + + + 时间戳转为C#格式时间 + + + + + + + 将c# DateTime时间格式转换为js时间戳格式 + + 时间 + long + + + + JS时间戳转为C#格式时间 + + + + + + + 根据年月日转换成日期 + + + + + + + + + 根据日期和时间转换成日期时间 + + + + + + + + 将时间转换成当前分钟开始的时间 + + + + + + + 将时间转换成当前秒钟开始的时间 + + + + + + + 当前时间在这一天里的秒数 + + + + + + + 窗体操作类 + + + + + 设置Comobox的行间距 + + + + + + + 移除关闭按钮。返回值,非零表示成功,零表示失败。 + + 窗口的句柄 + 是否成功 + + + + 把窗体放到最前 + + + + + + 显示窗体 + + + + + + + + 设置窗体是否置顶 + + + + + + + 显示没有焦点的窗口 + + + + + + 根据句柄获取窗口文本 + + + + + + + 根据句柄获取窗口类 + + + + + + + 获取当前活动的窗口句柄 + + + + + + 设置为当前活动窗口 + + + + + + + 根据窗口句柄来获得进程id + + + + + + + 显示窗体 + + + + + + 设置窗体父窗体为桌面,不会随着显示桌面而最小化,但无法设置窗体透明度 + + + + + + 结束进程 + + + + + + + 打开窗体,只打开一个实例(非模态) + + + + + + + 设置注册表操作,部分功能需要管理员权限 + + + + + 访问的注册表位置(64位还是32位) + + + + + 访问的注册表节点 + + + + + 设置是否开机启动 + + 是否开机启动 + 开机启动名称 + 启动命令 + + + + + 设置是否开机启动 + + 是否开机启动 + 开机启动名称 + + + + + 把指定文件设置为开机启动或取消开机启动 + + 是否开机启动 + 开机启动名称 + 要开机启动的文件路径 + + + + + 检查是否开机启动 + + 开机启动名称 + 开机启动命令 + + + + + 检查是否开机启动 + + 开机启动名称 + + + + + 判断指定文件是否是开机启动 + + 开机启动名称 + 文件路径 + + + + + 判断当前程序是否是开机启动 + + 开机启动名称 + + + + + 判断当前程序是否是开机启动 + + 开机启动名称 + 启动命令行 + + + + + 设置指定文件的浏览器控件内核版本 + + 文件名,要求不带路径 + 7000 表示IE7兼容视图模式;8000 表示IE8 标准模式 ;8888 表示IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + 采用的IE模式 + + + + + IE7兼容视图 + + + + + IE8 标准模式 + + + + + IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + IE9 标准模式 + + + + + IE9 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + IE10 标准模式 + + + + + IE10 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + 设置当前软件的浏览器控件内核版本 + + 7000 表示IE7兼容视图模式;8000 表示IE8 标准模式 ;8888 表示IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + + + + + 设置指定文件的浏览器控件内核版本 + + 文件名,要求不带路径 + IE内核版本 + + + + + 设置当前软件的浏览器控件内核版本 + + IE内核版本 + + + + + 系统函数 + + + + + + + + + + 红 + + + + + 绿 + + + + + 蓝 + + + + + 获取屏幕伽马值 + + + + + + + + 设置屏幕伽马值 + + + + + + + + 获取键盘和鼠标没有操作的时间 + + + + + + 设置屏幕 Gamma值 + + + + + + + + + 设置屏幕亮度 + + + + + + + 获取系统 + + + + + + 窗体操作类 + + + + + 构造函数 + + + + + + 析构 + + + + + 设置让窗体支持移动 + + + + + 是否允许可调节大小 + + + + + 可调节窗体大小的宽度 + + + + + + + + + + + 给控件增加拖放功能的类 + + + + + 拖放实例 + + + + + 高级拖放事件 + + + + + + + + + + 使支持拖放属性 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 网络操作类 + + + + + 通过NetworkInterface读取网卡Mac + + + + + + 通过NetworkInterface读取网卡Mac + + + + + + 根据mac字符串来获取最终的mac地址,可以是各种MAC地址格式,非法的内容将返回null + + + + + + + 远程唤醒 + + + + + + + + 远程唤醒 + + + + + + + + + 消息客户端类 + + + + + 判断当前消息主服务器是否创建成功 + + + + + 最后一次接收消息的时间,可用来判断服务端是否有响应 + + + + + 主句柄 + + + + + 当收到消息时激发 + + + + + 连接上主服务器时触发 + + + + + 收到服务端关闭通知 + + + + + 收到服务端关闭通知,即将关闭 + + + + + 服务端大小改变时激发 + + + + + 实例化客户端 + + 服务端ID + 当前客户端ID,会向服务器报告当前ID + 客户端 + + + + + + + + + 断开服务端连接 + + + + + 发送消息,采用多线程发送 + + + + + + + 向服务端发送心跳包 + + + + + 判断服务端句柄是否存在。 + + + + + + 共享内存 + + + + + 写共享内存 + + 需要映射的文件的字节数量 + 映射对象(简单类型、结构体等) + 文件映射对象的名称 + + + + + 写共享内存 + + 需要映射的文件的字节数量 + 映射对象(简单类型、结构体等) + 文件映射对象的名称 + 发送消息的窗口句柄 + 发送消息 + + + + + 读共享内存 + + 需要映射的文件的字节数量 + 类型 + 文件映射对象的名称 + 返回读到的映射对象 + + + + 读共享内存 + + 需要映射的文件的字节数量 + 类型 + 文件映射对象的名称 + 返回读到的映射字节数据 + + + + 消息服务器 + + + + + 消息事件 + + + + + + + 大小改变事件 + + + + + + + + 即将关闭事件 + + + + + + + 当收到消息时激发 + + + + + 消息处理类 + + + + + + + + + + + + + + + + + + + + + + + 发送消息,采用单线程发送 + + 要发送到的句柄 + 编号 + 消息内容 + + + + 发送消息,采用多线程发送 + + 要发送到的句柄 + 编号 + 消息内容 + + + + 消息类 + + + + + 是否取消 + + + + + 来源句柄 + + + + + + + + + + 消息文本 + + + + + 需要回复的内容 + + + + + 消息服务端类 + + + + + 判断当前消息主服务器是否创建成功 + + + + + 当收到消息时激发 + + + + + 当收到自定义消息时(非系统消息)激发 + + + + + 有消息客户端发起连接请求时激发 + + + + + 有消息客户端连接成功时激发 + + + + + 有消息客户端断开连接时激发 + + + + + + + 服务端ID,需要唯一性,共客户端识别 + 服务端 + + + + 释放资源 + + + + + 判断是否包含指定客户端 + + + + + + + + + + + + 设置客户端大小 + + + + + 根据客户端ID,获取客户端对象 + + + + + + + 根据客户端句柄,获取客户端对象 + + + + + + + 关闭所有客户端 + + + + + 关闭指定客户端 + + + + + + 关闭指定客户端 + + + + + + 向所有客户端发送消息,单线程 + + + + + + + 向指定客户端发送消息 + + + + + + + + 关闭在指定时间前失去响应的子客户端 + + + + + + 客户端信息 + + + + + 客户端句柄 + + + + + 客户端ID + + + + + 客户端连接时间 + + + + + 心跳时间 + + + + + 数据库引擎 + + + + + 数据库枚举类型 + + + + + Odbc引擎 + + + + + OleDb引擎 + + + + + Oracle引擎 + + + + + MSSQL引擎 + + + + + SQLite引擎 + + + + + MySql引擎 + + + + + 判断DataSet是否包含数据 + + + + + + + 获取首行数据 + + + + + + + 获取第一行第一列的值 + + + + + + + 将DataSet类型转换为RyQuickSQL列表类型 + + + + + + + 将DataSet类型转换为RyQuickSQL列表类型 + + + + + + + + 数据库操作接口 + + + + + 连接数据库 + + + + + + 断开数据库 + + + + + + 获取数量 + + + + + + + + 获取分页语句 + + + + + + + + + 获取分页语句 + + + + + + + + + 获取分页语句 + + + + + + + + + + 获取分页语句 + + + + + + + + + + 添加Parameter参数 + + + + + + + 清空Parameter参数 + + + + + + + 获取Parameter值 + + + + + + 根据RyQuickSQL类来获取Parameter值 + + + + + + + 开始执行事务 + + + + + 提交事务 + + + + + 判断是否包含数据 + + + + + + + + 返回-1000表示该数据库不支持本接口 + + + + + + + 读取数据 + + + + + + + 读取数据 + + + + + + + + 读取数据 + + + + + + + + 根据id号获取数据 + + + + + + + + 执行SQL语句 + + + + + + + + 执行SQL语句 + + + + + + + + 执行SQL语句 + + + + + + + 根据id号删除数据 + + + + + + + + 创建数据库 + + + + + + + 释放资源 + + + + + SQL字段类型 + + + + + SQL字段类型 + + + + + + + SQL字段类型 + + + + + + + + SQL字段名 + + + + + SQL字段值 + + + + + SQL字段长度 + + + + + 不是真的值,而是用于计算的值 + + + + + SQL快速操作类 + + + + + SQL快速操作类 + + + + + + 表名 + + + + + 操作字段列表 + + + + + 清理使用资源 + + + + + 清理使用资源 + + + + + 操作参数列表 + + + + + 操作参数列表 + + + + + 添加字符串字段 + + + + + + + 添加null值字段 + + + + + + 添加日期字段 + + + + + + + 添加int字段 + + + + + + + 添加double字段 + + + + + + + 添加decimal字段 + + + + + + + 添加bool字段 + + + + + + + 添加用于计算的值 + + + + + + + 添加Int64字段 + + + + + + + 清空内容 + + + + + 数量 + + + + + + + + + + 输出多条件搜索。 + + 字段名,多个字段请用逗号分隔。 + 多个条件之间请用空格隔开 + + + + + 获取插入SQL语句 + + + + + + 获取更新SQL语句 + + + + + + 添加参数 + + + + + + + 获取Ole参数 + + + + + + 获取SQL参数 + + + + + + AES加密解密类 + + + + + AES加密算法 + + 明文字符串 + 密钥 + 返回加密后的密文字节数组 + + + + AES解密 + + 密文字节数组 + 密钥 + 返回解密后的字符串 + + + + 加密 + + + + + + + + 解码 + + + + + + + + 转换密钥到合法密钥 + + + + + + + Base64编码类 + + + + + 编码 + + + + + + + 把字符串编码成Base64字符串 + + + + + + + + 解码 + + + + + + + MD5和SHA1操作类 + + + + + 获取MD5 + + + + + + + 获取MD5 + + + + + + + 获取SHA1 + + + + + + + 获取SHA1 + + + + + + + 获取HmacSHA1 + + + + + + + + 获取SHA256 + + + + + + + 获取HmacSHA256 + + + + + + + 获取SHA224 + + + + + + + 获取SHA512 + + + + + + + 获取HmacSHA512 + + + + + + + 使用using代替lock操作的对象,可指定写入和读取锁定模式 + + + + 利用IDisposable的using语法糖方便的释放锁定操作 + 内部类 + + + + 读写锁对象 + + + + 是否为写入模式 + + + + 利用IDisposable的using语法糖方便的释放锁定操作 + 构造函数 + + 读写锁 + 写入模式为true,读取模式为false + + + 释放对象时退出指定锁定模式 + + + + 空的可释放对象,免去了调用时需要判断是否为null的问题 + 内部类 + + + + 空的可释放对象 + + + + 空的释放方法 + + + + 读写锁 + + + + 保存数据 + + + + 使用using代替lock操作的对象,可指定写入和读取锁定模式 + 构造函数 + + + + 使用using代替lock操作的对象,可指定写入和读取锁定模式 + 构造函数 + 为Data属性设置初始值 + + + + 获取或设置当前对象中保存数据的值 + + 获取数据时未进入读取或写入锁定模式 + 设置数据时未进入写入锁定模式 + + + 是否启用,当该值为false时,Read()和Write()方法将返回 Disposable.Empty + + + + 进入读取锁定模式,该模式下允许多个读操作同时进行 + 退出读锁请将返回对象释放,建议使用using语块 + Enabled为false时,返回Disposable.Empty; + 在读取或写入锁定模式下重复执行,返回Disposable.Empty; + + + + 进入写入锁定模式,该模式下只允许同时执行一个读操作 + 退出读锁请将返回对象释放,建议使用using语块 + Enabled为false时,返回Disposable.Empty; + 在写入锁定模式下重复执行,返回Disposable.Empty; + + 读取模式下不能进入写入锁定状态 + + + + 中国农历类,最大支持公元0-9999年 + + 日期:2019-02-09 + 作者:http://www.cnblogs.com/zjfree/ + + + + 日历类型 + + + + + 无效 + + + + + Julian 日历 + + + + + Gregorian 日历 + + + + + 有效 + + + + + 公历节日 + + + + + 农历节日 + + + + + 某个月第n个星期几 + + + + + 获取农历 + + + + + + + 获取农历 + + + + + + + + + 获得某农历年的闰月,返回 1~12 对应一月到十二月,返回 0 表示无闰月 + + + + + + + 农历搜索方向 + + + + + 无效 + + + + + 向上 + + + + + 向下 + + + + + {* 日月食类型, 无, 日食, 月全食, 月偏食 } + + + + + 无 + + + + + 日食 + + + + + 月全食 + + + + + 月偏食 + + + + + {* 月相, 无, 朔, 望} + + + + + 无 + + + + + 朔 + + + + + 望 + + + + + 获得某公历年月日的农历日数和该日月相以及日月食类型和时刻 + + + + + + + + + + + + 获得某公历年月日的农历月数 + + + + + + + + + 获取阳历日期对应的农历日期 + + + + + + + + + + + + + 获得某公历年月日的农历月日和是否闰月的信息 + + + + + + + + + + + + 获得等效标准日数对应的某公历日,倒推而来 + + + + + + + + + + 比较两个农历日期(包括闰月信息),1 大于2返回1、1等于2返回0、1小于2返回-1 + + + + + + + + + + + + + + 获得某农历年月日(加是否闰月)的公历年月日 + 该函数采用反向二分法查找 + + + + + + + + + + + + + 获取农历某一个月的总天数 + + + + + + + + + 获取农历年份,范围约1901-2101年 + + + + + + + 获取农历年份,范围约0-9999年 + + + + + + + + + 获取农历月份,范围约1901-2101年 + + + + + + + 获取农历月份,范围约0-9999年 + + + + + + + + + 获取中文表示的农历月份 + + + + + + + 获取农历日,范围约1901-2101年 + + + + + + + 获取农历日,范围约0-9999年 + + + + + + + + + 获取农历日,范围约0-9999年 + + + + + + + 获取节气,范围约1901-2101年 + + + + + + + 获取节气,范围约0-9999年 + + + + + + + + + 返回y年第n个节气(如小寒为1)的日差天数值(pd取值真假,分别表示平气和定气) + + + + pd取值真假,分别表示平气和定气 + + + + + 获取等效标准日数 + + + + + + + + + 取本月天数,不考虑 1582 年 10 月的特殊情况 + + + + + + + + 获取节气,范围约1901-2101年 + + + + + + + 获取节气,范围约0-9999年 + + + + + + + + + 获取节气 + + + + + + + + + + + + 获取公历节日 + + + + + + + 获取公历节日 + + + + + + + + + 获取指定月份的第n个星期几的节日 + + + + + + + 返回星座,范围约1901-2101年 + + + + + 返回星座,范围约0-9999年 + + + + + 获取农历节日 + + + + + + + + + 获取农历节日 + + + + + + + 判断y年m月(1,2,..,12,下同)d日是Gregorian历还是Julian历(opt=1,2,3分别表示标准日历,Gregorge历和Julian历),是则返回1,是Julian历则返回0,若是Gregorge历所删去的那10天则返回-1 + + + + + 返回阳历y年m月d日的日差天数(在y年年内所走过的天数,如2000年3月1日为61) + + + + + 返回阳历y年日差天数为x时所对应的月日数(如y=2000,x=274时,返回1001(表示10月1日,即返回100*m+d)) + + + + + 获取指定日期的节气。 + + 要获取的年 + 要获取的月 + + + 立春:立是开始的意思,春是蠢动,表示万物开始有生气,这一天春天开始。 + 雨水:降雨开始,雨水将多。 + 惊蛰:春雷响动,惊动蛰伏地下冬眠的生物,它们将开始出土活动。 + 春分:这是春季九十天的中分点,这一天昼夜相等,所以古代曾称春分秋分为昼夜分。 + 清明:明洁晴朗,气候温暖,草木开始萌发繁茂。 + 谷雨:雨生百谷的意思。雨水增多,适时的降雨对谷物生长很为有利。 + 立夏:夏天开始,万物渐将随温暖的气候而生长。 + 小满:满指籽粒饱满,麦类等夏热作物这时开始结籽灌浆,即将饱满。 + 芒种:有芒作物开始成熟,此时也是秋季作物播种的最繁忙时节。 + 夏至:白天最长,黑夜最短,这一天中午太阳位置最高,日影短至终极,古代又称这一天为日北至或长日至。 + 小暑:暑是炎热,此时还未到达最热。 + 大暑:炎热的程度到达高峰。 + 立秋:秋天开始,植物快成熟了。 + 处暑:处是住的意思,表示暑气到此为止。 + 白露:地面水气凝结为露,色白,是天气开始转凉了。 + 秋分:秋季九十天的中间,这一天昼夜相等,同春分一样,太阳从正东升起正西落下。 + 寒露:水露先白而后寒,是气候将逐渐转冷的意思。 + 霜降:水气开始凝结成霜。 + 立冬:冬是终了,作物收割后要收藏起来的意思,这一天起冬天开始。 + 小雪:开始降雪,但还不多。 + 大雪:雪量由小增大。 + 冬至:这一天中午太阳在天空中位置最低,日影最长,白天最短, 黑夜最长,古代又称短日至或日南至。 + 小寒:冷气积久而为寒,此时尚未冷到顶点。 + 大寒:天候达到最寒冷的程度 + + + + + 获取年柱。 + + + + + 获得月柱 + + + + + + + 获取日柱。 + + + + + 返回甲子数x对应的天干数(如33为3) + + + + + 返回甲子数x对应的地支数(如33为9) + + + + + 获取日的天干地支 + + + + + + + 返回甲子数x对应的天干字符串 + + + + + 返回甲子数x对应的地支字符串 + + + + + 返回甲子数x对应的干支字符串 + + + + + + + 获取三伏开始时间 + + + 0表示1伏,1表示2伏,2表示3伏 + + + + + 节气 + + + + + 节气的时间。 + + + + + 节气名。 + + + + + 热键转换类 + + + + + 功能键。 + + + + + 修改键。 + + + + + 转换功能键到谷歌浏览器专用 + + + + + 将chrome功能键转换为普通功能键 + + + + + + + 按键值。 + + + + + 初始化类 的新实例。 + + The modifiers. + The key code. + + + + + + + + + + + + + + + + + 初始化类 的新实例。 + + + + + 加载热键 + + + + + + + 加载热键 + + + + + + 加载热键 + + + + + + 判断是否是热键 + + + + + 获取当前热键 + + + + + 已重载,返回“Ctrl+Alt+A”格式的字符串。 + + 类似“Ctrl+Alt+A”格式的字符串 + + + + 返回“Ctrl+Alt+A”格式的字符串。 + + 类似“Ctrl+Alt+A”格式的字符串 + + + + 功能键 + + + + + 无 + + + + + Alt键 + + + + + Ctrl键 + + + + + Shift键 + + + + + Win键 + + + + + 热键类 + + + + + 热键类 + + + + + + 热键注销 + + + + + 热键是否有效 + + + + + 释放热键 + + + + + 注册热键 + + + + + + + + + 注册热键 + + + + + + + + + 删除热键 + + + + + + + 删除所有热键 + + + + + 热键事件 + + + + + + 当使用热键时发生的事件 + + + + + 热键消息过滤 + + + + + + + 热键类型 + + + + + 热键id + + + + + 功能键 + + + + + 普通键 + + + + + 热键类型 + + + + + + + + Win32 API + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 获取当前前台窗口句柄 + + + + + + 获得当前活动窗体 + + + + + + 设置活动窗体 + + + + + + + 获取类名 + + + + + + + + + 获取当前线程对应的进程ID + + + + + + + + 判断指定句柄是否是一个窗口 + + + + + + + 获取窗口标题 + + + + + + + + + 查找窗口 + + + + + + + + 设置父窗口 + + + + + + + + 移动窗口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 结束进程 + + + + + + + + 发送消息 + + + + + + + + + + 发送消息 + + + + + + + + + 获取窗口位置和大小 + + + + + + + + 矩形 + + + + + 最左坐标 + + + + + 最上坐标 + + + + + 最右坐标 + + + + + 最下坐标 + + + + + WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。 + + + + + 系统通道ID + + + + + 用户通道ID + + + + + + + + + + + + + + + + + + + + + + + + + 获取消息 + + + + + + + + 发送消息 + + + + + + + + + + 设置父窗口 + + + + + + + + diff --git a/Bin/Release/CommonControls/.NET4/MyDb_MSSQL.dll b/Bin/Release/CommonControls/.NET4/MyDb_MSSQL.dll new file mode 100644 index 0000000..f89404f Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/MyDb_MSSQL.dll differ diff --git a/Bin/Release/CommonControls/.NET4/MyDb_MySQL.dll b/Bin/Release/CommonControls/.NET4/MyDb_MySQL.dll new file mode 100644 index 0000000..ca817cf Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/MyDb_MySQL.dll differ diff --git a/Bin/Release/CommonControls/.NET4/MyDb_SQLite.dll b/Bin/Release/CommonControls/.NET4/MyDb_SQLite.dll new file mode 100644 index 0000000..8987c2b Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/MyDb_SQLite.dll differ diff --git a/Bin/Release/CommonControls/.NET4/MySql.Data.dll b/Bin/Release/CommonControls/.NET4/MySql.Data.dll new file mode 100644 index 0000000..b732da4 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/MySql.Data.dll differ diff --git a/Bin/Release/CommonControls/.NET4/RyPrint.dll b/Bin/Release/CommonControls/.NET4/RyPrint.dll new file mode 100644 index 0000000..04ff90d Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/RyPrint.dll differ diff --git a/Bin/Release/CommonControls/.NET4/RyWeb.dll b/Bin/Release/CommonControls/.NET4/RyWeb.dll new file mode 100644 index 0000000..6112f57 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/RyWeb.dll differ diff --git a/Bin/Release/CommonControls/.NET4/System.Data.SQLite.dll b/Bin/Release/CommonControls/.NET4/System.Data.SQLite.dll new file mode 100644 index 0000000..e15c908 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/System.Data.SQLite.dll differ diff --git a/Bin/Release/CommonControls/.NET4/ryControls.dll b/Bin/Release/CommonControls/.NET4/ryControls.dll new file mode 100644 index 0000000..e8a9dc9 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/ryControls.dll differ diff --git a/Bin/Release/CommonControls/.NET4/ryUpdate.dll b/Bin/Release/CommonControls/.NET4/ryUpdate.dll new file mode 100644 index 0000000..c7a4776 Binary files /dev/null and b/Bin/Release/CommonControls/.NET4/ryUpdate.dll differ diff --git a/Bin/混淆_Debug.nrproj b/Bin/混淆_Debug.nrproj new file mode 100644 index 0000000..5a57f4d --- /dev/null +++ b/Bin/混淆_Debug.nrproj @@ -0,0 +1,127 @@ + + Debug\CommonControls\CommonControls.exe + + Debug\CommonControls\ryControls.dll + + + Debug\CommonControls\ryUpdate.dll + + + Debug\CommonControls\MyDb_SQLite.dll + + + Debug\CommonControls\MyDb.dll + + + true + true + false + + + + http://timestamp.verisign.com/scripts/timstamp.dll + http://sha256timestamp.ws.symantec.com/sha256/timestamp + false + true + false + false + true + false + + + <AssemblyLocation>\Secure\<AssemblyFileName> + true + + + true + true + false + false + 9 + true + false + false + false + true + false + false + false + false + false + false + false + false + false + + false + false + false + false + + false + false + false + false + false + true + true + All + + false + + + true + false + Trial_Days + 14 + false + 20180503 + false + 10 + false + 5 + + true + true + + + + true + You are on day [current_minutes_days] of your [max_minutes_days] day evaluation period. Your trial period is expired! You need to purchase a license to run this software. + true + Your expiration date is reached! You need to purchase a license file to run this software. + true + You have used this software [current_uses] times out of a maximum of [max_uses]. You have [uses_left] uses left. Your trial period is expired! You need to purchase a license to run this software. + true + You can only run maximal [max_processes] instances of this software at the same time. + true + This software won't run without a valid license file. Either a valid license file could not be found or your license file is expired. + false + Nag Screen! This message will disappear when a valid license file is installed. You are on day [current_minutes_days] of your [max_minutes_days] day evaluation period. You have [minutes_days_left] days left. You have used this software [current_uses] times out of a maximum of [max_uses]. You have [uses_left] uses left. + -1 + + Lock System + 255255255 + 157211252 + + + false + false + Trial_Days + 1 + false + 20180503 + false + true + true + false + true + ####-####-####-####-#### + false + 10 + false + 5 + + Hr7YPNVEOuGLGJrWzxt2hKWI0xXn4h31i5nGAghNonQ=|<RSAKeyValue><Modulus>twxUWoRvbb2N6CMXQL36TBij9G7nxvU6rTULmVnbS1jYTvPQSKohB2o95vJvdlxjw7KBxYhIFqj9yEn5xvD4GVhj8+MEvG4lNqN1e1FErGin9YYYr4dTZHFe73aG5xxoscKZIg3YYdoBp0lgE2xwfaHyYe03M3mbhQx6axyf7Ak=</Modulus><Exponent>AQAB</Exponent><P>6OP29NbAV7sOKvOFRIeBbnJLh4fOiAjGtqiBlHLyOHt6w1s8N4o4Kr3N2KPVcpj82655KRzRlVDkwQika4eZ9w==</P><Q>yTY83K4a/WpcifMvuAFEuM9wVfXtbQUpV0MSSNgCmWcd6G3+GYShmPUW1gWMv+4H59iiPef1pnXvuzPYnQMp/w==</Q><DP>J/h4Oi1hda01EUoaZVicbkhPjkNQvyhCcrcZBlF0IR2QRFc0TpP6b9uDqNr1l2WKgGnBgbzge7AWksrY7VuooQ==</DP><DQ>PtmhQzFjHts1UqXStwA2bh/lsAQkiJQ/KJG7yWMn1LEAB5Ur9N6X94Y+/tU29NCuSX5Cl2G4OqnGG0yDke/mEw==</DQ><InverseQ>jiKqvwfWSUpKybcT3ucAedpT+kKuB/Qs1xJ0Z6bYOE8EsljxGbq8428Cma5rp33WMP6ybq2HwOddm/73ZFZZKQ==</InverseQ><D>bYP46/cUW8nvHxXvkZKYL/MGFPZNwaFyq7Jy8BrssxXCxOnmkbMH89HCm2ws99mq7qjcL3yr9LLCs5Re1oHRTQT2Vu2hXuGAGVjvHwYPLWGvcYvIuTWoTEw79m+lh/7CYDxfwzwWL095a8D40OvfHauk7xrXDB+qIsEJ7Gkjh0k=</D></RSAKeyValue> + + \ No newline at end of file diff --git a/Bin/混淆_Release.nrproj b/Bin/混淆_Release.nrproj new file mode 100644 index 0000000..f7ed767 --- /dev/null +++ b/Bin/混淆_Release.nrproj @@ -0,0 +1,127 @@ + + Release\CommonControls\CommonControls.exe + + Release\CommonControls\ryControls.dll + + + Release\CommonControls\ryUpdate.dll + + + Release\CommonControls\MyDb_SQLite.dll + + + Release\CommonControls\MyDb.dll + + + true + true + false + + + + http://timestamp.verisign.com/scripts/timstamp.dll + http://sha256timestamp.ws.symantec.com/sha256/timestamp + false + true + false + false + true + false + + + <AssemblyLocation>\Secure\<AssemblyFileName> + true + + + true + true + false + false + 9 + true + false + false + false + true + false + false + false + false + false + false + false + false + false + + false + false + false + false + + false + false + false + false + false + true + true + All + + false + + + true + false + Trial_Days + 14 + false + 20180503 + false + 10 + false + 5 + + true + true + + + + true + You are on day [current_minutes_days] of your [max_minutes_days] day evaluation period. Your trial period is expired! You need to purchase a license to run this software. + true + Your expiration date is reached! You need to purchase a license file to run this software. + true + You have used this software [current_uses] times out of a maximum of [max_uses]. You have [uses_left] uses left. Your trial period is expired! You need to purchase a license to run this software. + true + You can only run maximal [max_processes] instances of this software at the same time. + true + This software won't run without a valid license file. Either a valid license file could not be found or your license file is expired. + false + Nag Screen! This message will disappear when a valid license file is installed. You are on day [current_minutes_days] of your [max_minutes_days] day evaluation period. You have [minutes_days_left] days left. You have used this software [current_uses] times out of a maximum of [max_uses]. You have [uses_left] uses left. + -1 + + Lock System + 255255255 + 157211252 + + + false + false + Trial_Days + 1 + false + 20180503 + false + true + true + false + true + ####-####-####-####-#### + false + 10 + false + 5 + + Hr7YPNVEOuGLGJrWzxt2hKWI0xXn4h31i5nGAghNonQ=|<RSAKeyValue><Modulus>twxUWoRvbb2N6CMXQL36TBij9G7nxvU6rTULmVnbS1jYTvPQSKohB2o95vJvdlxjw7KBxYhIFqj9yEn5xvD4GVhj8+MEvG4lNqN1e1FErGin9YYYr4dTZHFe73aG5xxoscKZIg3YYdoBp0lgE2xwfaHyYe03M3mbhQx6axyf7Ak=</Modulus><Exponent>AQAB</Exponent><P>6OP29NbAV7sOKvOFRIeBbnJLh4fOiAjGtqiBlHLyOHt6w1s8N4o4Kr3N2KPVcpj82655KRzRlVDkwQika4eZ9w==</P><Q>yTY83K4a/WpcifMvuAFEuM9wVfXtbQUpV0MSSNgCmWcd6G3+GYShmPUW1gWMv+4H59iiPef1pnXvuzPYnQMp/w==</Q><DP>J/h4Oi1hda01EUoaZVicbkhPjkNQvyhCcrcZBlF0IR2QRFc0TpP6b9uDqNr1l2WKgGnBgbzge7AWksrY7VuooQ==</DP><DQ>PtmhQzFjHts1UqXStwA2bh/lsAQkiJQ/KJG7yWMn1LEAB5Ur9N6X94Y+/tU29NCuSX5Cl2G4OqnGG0yDke/mEw==</DQ><InverseQ>jiKqvwfWSUpKybcT3ucAedpT+kKuB/Qs1xJ0Z6bYOE8EsljxGbq8428Cma5rp33WMP6ybq2HwOddm/73ZFZZKQ==</InverseQ><D>bYP46/cUW8nvHxXvkZKYL/MGFPZNwaFyq7Jy8BrssxXCxOnmkbMH89HCm2ws99mq7qjcL3yr9LLCs5Re1oHRTQT2Vu2hXuGAGVjvHwYPLWGvcYvIuTWoTEw79m+lh/7CYDxfwzwWL095a8D40OvfHauk7xrXDB+qIsEJ7Gkjh0k=</D></RSAKeyValue> + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..387e701 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +## 睿元公用控件组 + +睿元公用控件组是一款公用的多功能控件组,集成了通用数据库操作类,并提供了各种常用功能的API接口,让代码编写更容易。 \ No newline at end of file diff --git a/Source/.vs/公用控件组V4/v16/.suo b/Source/.vs/公用控件组V4/v16/.suo new file mode 100644 index 0000000..077c1e6 Binary files /dev/null and b/Source/.vs/公用控件组V4/v16/.suo differ diff --git a/Source/.vs/公用控件组V4/v16/Server/sqlite3/db.lock b/Source/.vs/公用控件组V4/v16/Server/sqlite3/db.lock new file mode 100644 index 0000000..e69de29 diff --git a/Source/.vs/公用控件组V4/v16/Server/sqlite3/storage.ide b/Source/.vs/公用控件组V4/v16/Server/sqlite3/storage.ide new file mode 100644 index 0000000..e5de92b Binary files /dev/null and b/Source/.vs/公用控件组V4/v16/Server/sqlite3/storage.ide differ diff --git a/Source/Itrycn_Project/DbOp/FrmAdd.Designer.cs b/Source/Itrycn_Project/DbOp/FrmAdd.Designer.cs new file mode 100644 index 0000000..a156e7b --- /dev/null +++ b/Source/Itrycn_Project/DbOp/FrmAdd.Designer.cs @@ -0,0 +1,106 @@ +namespace Itrycn_Project.DbOp +{ + partial class FrmAdd + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnCancel = new ryControls.ButtonEx(); + this.btnOK = new ryControls.ButtonEx(); + this.label1 = new System.Windows.Forms.Label(); + this.txtName = new ryControls.TextBoxEx2(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.ForeColor = System.Drawing.Color.White; + this.btnCancel.Location = new System.Drawing.Point(363, 310); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(65, 27); + this.btnCancel.TabIndex = 5; + this.btnCancel.Text = "取消"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.ForeColor = System.Drawing.Color.White; + this.btnOK.Location = new System.Drawing.Point(292, 310); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(65, 27); + this.btnOK.TabIndex = 4; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.BtnOK_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 20); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(29, 12); + this.label1.TabIndex = 7; + this.label1.Text = "名称"; + // + // txtName + // + this.txtName.BackColor = System.Drawing.Color.White; + this.txtName.Location = new System.Drawing.Point(55, 12); + this.txtName.Name = "txtName"; + this.txtName.PasswordChar = '\0'; + this.txtName.ReadOnly = false; + this.txtName.SelectionLength = 0; + this.txtName.SelectionStart = 0; + this.txtName.Size = new System.Drawing.Size(372, 25); + this.txtName.TabIndex = 6; + // + // frmAdd + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(438, 347); + this.Controls.Add(this.label1); + this.Controls.Add(this.txtName); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Name = "frmAdd"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "新增"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ryControls.ButtonEx btnCancel; + private ryControls.ButtonEx btnOK; + private System.Windows.Forms.Label label1; + private ryControls.TextBoxEx2 txtName; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project/DbOp/FrmAdd.cs b/Source/Itrycn_Project/DbOp/FrmAdd.cs new file mode 100644 index 0000000..a4e826a --- /dev/null +++ b/Source/Itrycn_Project/DbOp/FrmAdd.cs @@ -0,0 +1,79 @@ +using ryCommon; +using ryCommonDb; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project.DbOp +{ + public partial class FrmAdd : Form + { + public ModalForm mr = null; + public string tableName = "MainTable1"; + public int isAdd = 1; + public string selectId = "-1"; + public FrmAdd() + { + InitializeComponent(); + } + #region 需要修改 + public void GetInfo(string id) + { + selectId = id; + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + DataSet ds = db.ReadData(tableName, id); + if (mydb.HaveData(ds)) + { + DataRow reader = ds.Tables[0].Rows[0]; + #region 读取信息 + txtName.Text = reader["Name"].ToString(); + #endregion + } + } + db.Free(); + } + + private void BtnOK_Click(object sender, EventArgs e) + { + if (txtName.Text == "") + { + MessageBox.Show("名称不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + RyQuickSQL mySQL = new RyQuickSQL(tableName); + mySQL.AddField("name", txtName.Text); + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + if (isAdd >= 1) + { + mySQL.AddField("addTime",DateTime.Now); + mySQL.AddField("editTime", DateTime.Now); + db.ExecuteNonQuery(mySQL.GetInsertSQL(), db.GetParameter(mySQL)); + } + else + { + mySQL.AddField("editTime", DateTime.Now); + db.ExecuteNonQuery(mySQL.GetUpdateSQL() + " where id=" + selectId, db.GetParameter(mySQL)); + } + } + db.Free(); + ModalForm.SetDialogResult(this, mr, DialogResult.OK); + } + #endregion + + private void BtnCancel_Click(object sender, EventArgs e) + { + ModalForm.SetDialogResult(this, mr, DialogResult.Cancel); + } + } +} diff --git a/Source/Itrycn_Project/DbOp/FrmAdd.resx b/Source/Itrycn_Project/DbOp/FrmAdd.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/Itrycn_Project/DbOp/FrmAdd.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/Source/Itrycn_Project/DbOp/FrmView.cs b/Source/Itrycn_Project/DbOp/FrmView.cs new file mode 100644 index 0000000..12574b0 --- /dev/null +++ b/Source/Itrycn_Project/DbOp/FrmView.cs @@ -0,0 +1,175 @@ +using ryCommon; +using ryCommonDb; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project.DbOp +{ + public partial class FrmView : Form + { + string orderSQL = "order by addTime desc"; + string tableName = "MainTable1"; + string titleName = "数据"; + public FrmView() + { + InitializeComponent(); + } + #region 需要修改的内容 + private void RySearch1_OnSearch(object sender, EventArgs e) + { + //需要修改此处 + //LoadDb("(" + TableProject.name + " like @SearchText or " + TableProject.des + " like @SearchText)"); + } + + private void CtlMyPage1_OnPageChange(object sender, EventArgs e) + { + #region 重新载入数据 + tableModel1.Rows.Clear(); + tableModel1.Selections.Clear(); + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + DataSet ds = db.ReadData(ctlMyPage1.GetSQLText, ctlMyPage1.T_Parameters); + for (int i = 0; i < ds.Tables[0].Rows.Count; i++) + { + DataRow row = ds.Tables[0].Rows[i]; + XPTable.Models.Row itemList = new XPTable.Models.Row() + { + Tag = row["id"].ToString() + }; + //需要修改此处 + //itemList.Cells.Add(new XPTable.Models.Cell(row[""].ToString()));//示例 + tableModel1.Rows.Add(itemList); + } + } + db.Free(); + #endregion + } + private void GetRow(string id, int index) + { + #region 重新载入数据 + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + DataSet ds = db.ReadData("select * from " + tableName + " where id=" + id); + if (mydb.HaveData(ds)) + { + DataRow row = ds.Tables[0].Rows[0]; + XPTable.Models.Row itemList = tableModel1.Rows[index]; + //需要修改此处 + //itemList.Cells[colName.Index].Text = row[TableProject.name].ToString(); + } + } + db.Free(); + #endregion + } + #endregion + public void LoadDb(string whereSQL) + { + string _whereSQL = whereSQL; + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + #region 重新载入数据 + db.AddParameter("SearchText", "%" + rySearch1.Text + "%"); + ctlMyPage1.RecordCount = db.GetCount(tableName, _whereSQL); + ctlMyPage1.T_Parameters = db.GetParameter(); + ctlMyPage1.SQLText= db.GetPageSQL(tableName, _whereSQL, orderSQL); + ctlMyPage1.SQLText2 = db.GetPageSQL2(tableName, _whereSQL, orderSQL); + ctlMyPage1.GotoPageIndex(1); + #endregion + } + db.Free(); + } + + private void BtnAdd_Click(object sender, EventArgs e) + { + FrmAdd frm = new FrmAdd() + { + Text = "添加"+ titleName, + Icon = Icon, + isAdd = 1 + }; + frm.mr = new ModalForm(this, frm); + frm.mr.OnDialogResult += new ModalForm.DialogResultHandler((object t, DialogResult dg) => { + if (dg == DialogResult.OK) + { + rySearch1.PerformClick(); + } + }); + frm.mr.ShowModal(); + } + + private void BtnEdit_Click(object sender, EventArgs e) + { + if (table1.SelectedItems.Length == 0) { return; } + string selectId = table1.SelectedItems[0].Tag.ToString(); + int index = table1.SelectedItems[0].Index; + FrmAdd frm = new FrmAdd() + { + Text = "修改"+ titleName, + Icon = Icon, + isAdd = 0 + }; + frm.GetInfo(selectId); + frm.mr = new ModalForm(this, frm); + frm.mr.OnDialogResult += new ModalForm.DialogResultHandler((object t, DialogResult dg) => { + if (dg == DialogResult.OK) + { + GetRow(selectId, index); + } + }); + frm.mr.ShowModal(); + } + + private void BtnDel_Click(object sender, EventArgs e) + { + if (table1.SelectedItems.Length == 0) { MessageBox.Show("请先选择要删除的项。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } + string selectId = table1.SelectedItems[0].Tag.ToString(); + if (MessageBox.Show("确定要删除该项吗?一旦删除将不可恢复。", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) + { + return; + } + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + db.DelById(tableName, selectId); + tableModel1.Rows.RemoveAt(table1.SelectedItems[0].Index); + } + } + + private void FrmView_Load(object sender, EventArgs e) + { + Text = "浏览"+ titleName; + 添加数据ToolStripMenuItem.Text = "添加"+ titleName; + 修改数据ToolStripMenuItem.Text = "修改" + titleName; + 删除数据ToolStripMenuItem.Text = "删除" + titleName; + rySearch1.PerformClick(); + } + + private void 添加数据ToolStripMenuItem_Click(object sender, EventArgs e) + { + btnAdd.PerformClick(); + } + + private void 修改数据ToolStripMenuItem_Click(object sender, EventArgs e) + { + btnEdit.PerformClick(); + } + + private void 删除数据ToolStripMenuItem_Click(object sender, EventArgs e) + { + btnDel.PerformClick(); + } + } +} diff --git a/Source/Itrycn_Project/DbOp/frmView.Designer.cs b/Source/Itrycn_Project/DbOp/frmView.Designer.cs new file mode 100644 index 0000000..8b7a667 --- /dev/null +++ b/Source/Itrycn_Project/DbOp/frmView.Designer.cs @@ -0,0 +1,210 @@ +namespace Itrycn_Project.DbOp +{ + partial class FrmView + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.rySearch1 = new ryControls.rySearch(); + this.table1 = new XPTable.Models.Table(); + this.columnModel1 = new XPTable.Models.ColumnModel(); + this.tableModel1 = new XPTable.Models.TableModel(); + this.ctlMyPage1 = new MyPage.ctlMyPage(); + this.btnDel = new ryControls.ButtonEx(); + this.btnEdit = new ryControls.ButtonEx(); + this.btnAdd = new ryControls.ButtonEx(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.添加数据ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.修改数据ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.删除数据ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + ((System.ComponentModel.ISupportInitialize)(this.table1)).BeginInit(); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // rySearch1 + // + this.rySearch1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(236)))), ((int)(((byte)(239)))), ((int)(((byte)(244))))); + this.rySearch1.EmptyText = "请输入搜索内容"; + this.rySearch1.Location = new System.Drawing.Point(12, 12); + this.rySearch1.Name = "rySearch1"; + this.rySearch1.Size = new System.Drawing.Size(329, 24); + this.rySearch1.TabIndex = 28; + this.rySearch1.OnSearch += new System.EventHandler(this.RySearch1_OnSearch); + // + // table1 + // + this.table1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.table1.ColumnModel = this.columnModel1; + this.table1.ContextMenuStrip = this.contextMenuStrip1; + this.table1.EditStartAction = XPTable.Editors.EditStartAction.SingleClick; + this.table1.EnableHeaderContextMenu = false; + this.table1.EnableToolTips = true; + this.table1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.table1.FullRowSelect = true; + this.table1.GridColor = System.Drawing.Color.Silver; + this.table1.GridLines = XPTable.Models.GridLines.Rows; + this.table1.GridLineStyle = XPTable.Models.GridLineStyle.Dash; + this.table1.HeaderFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.table1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.table1.Location = new System.Drawing.Point(12, 42); + this.table1.Name = "table1"; + this.table1.NoItemsText = "当前还没有任何数据"; + this.table1.Size = new System.Drawing.Size(1028, 551); + this.table1.TabIndex = 29; + this.table1.TableModel = this.tableModel1; + this.table1.Text = "table1"; + this.table1.ToolTipShowAlways = true; + // + // tableModel1 + // + this.tableModel1.RowHeight = 25; + // + // ctlMyPage1 + // + this.ctlMyPage1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.ctlMyPage1.Location = new System.Drawing.Point(12, 595); + this.ctlMyPage1.Name = "ctlMyPage1"; + this.ctlMyPage1.PageSize = 50; + this.ctlMyPage1.RecordCount = 0; + this.ctlMyPage1.Size = new System.Drawing.Size(506, 26); + this.ctlMyPage1.SQLText = ""; + this.ctlMyPage1.SQLText2 = ""; + this.ctlMyPage1.T_FirstCaption = "首页"; + this.ctlMyPage1.T_LastCaption = "末页"; + this.ctlMyPage1.T_NextCaption = "下一页"; + this.ctlMyPage1.T_Parameters = null; + this.ctlMyPage1.T_PreCaption = "上一页"; + this.ctlMyPage1.T_SkipCaption = "跳到"; + this.ctlMyPage1.T_TipCaption = "{pageindex}/{pagecount} 页,共 {recordcount} 条记录,每页 {pagesize} 条"; + this.ctlMyPage1.TabIndex = 30; + this.ctlMyPage1.OnPageChange += new System.EventHandler(this.CtlMyPage1_OnPageChange); + // + // btnDel + // + this.btnDel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnDel.ForeColor = System.Drawing.Color.White; + this.btnDel.Location = new System.Drawing.Point(978, 12); + this.btnDel.Name = "btnDel"; + this.btnDel.Size = new System.Drawing.Size(62, 24); + this.btnDel.TabIndex = 40; + this.btnDel.Text = "删除"; + this.btnDel.UseVisualStyleBackColor = true; + this.btnDel.Click += new System.EventHandler(this.BtnDel_Click); + // + // btnEdit + // + this.btnEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnEdit.ForeColor = System.Drawing.Color.White; + this.btnEdit.Location = new System.Drawing.Point(910, 12); + this.btnEdit.Name = "btnEdit"; + this.btnEdit.Size = new System.Drawing.Size(62, 24); + this.btnEdit.TabIndex = 39; + this.btnEdit.Text = "修改"; + this.btnEdit.UseVisualStyleBackColor = true; + this.btnEdit.Click += new System.EventHandler(this.BtnEdit_Click); + // + // btnAdd + // + this.btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdd.ForeColor = System.Drawing.Color.White; + this.btnAdd.Location = new System.Drawing.Point(842, 12); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(62, 24); + this.btnAdd.TabIndex = 38; + this.btnAdd.Text = "添加"; + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler(this.BtnAdd_Click); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.添加数据ToolStripMenuItem, + this.修改数据ToolStripMenuItem, + this.删除数据ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(125, 70); + // + // 添加数据ToolStripMenuItem + // + this.添加数据ToolStripMenuItem.Name = "添加数据ToolStripMenuItem"; + this.添加数据ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.添加数据ToolStripMenuItem.Text = "添加数据"; + this.添加数据ToolStripMenuItem.Click += new System.EventHandler(this.添加数据ToolStripMenuItem_Click); + // + // 修改数据ToolStripMenuItem + // + this.修改数据ToolStripMenuItem.Name = "修改数据ToolStripMenuItem"; + this.修改数据ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.修改数据ToolStripMenuItem.Text = "修改数据"; + this.修改数据ToolStripMenuItem.Click += new System.EventHandler(this.修改数据ToolStripMenuItem_Click); + // + // 删除数据ToolStripMenuItem + // + this.删除数据ToolStripMenuItem.Name = "删除数据ToolStripMenuItem"; + this.删除数据ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.删除数据ToolStripMenuItem.Text = "删除数据"; + this.删除数据ToolStripMenuItem.Click += new System.EventHandler(this.删除数据ToolStripMenuItem_Click); + // + // FrmView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1052, 625); + this.Controls.Add(this.btnDel); + this.Controls.Add(this.btnEdit); + this.Controls.Add(this.btnAdd); + this.Controls.Add(this.ctlMyPage1); + this.Controls.Add(this.table1); + this.Controls.Add(this.rySearch1); + this.Name = "FrmView"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "浏览"; + this.Load += new System.EventHandler(this.FrmView_Load); + ((System.ComponentModel.ISupportInitialize)(this.table1)).EndInit(); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private ryControls.rySearch rySearch1; + private XPTable.Models.Table table1; + private MyPage.ctlMyPage ctlMyPage1; + private XPTable.Models.TableModel tableModel1; + private XPTable.Models.ColumnModel columnModel1; + private ryControls.ButtonEx btnDel; + private ryControls.ButtonEx btnEdit; + private ryControls.ButtonEx btnAdd; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 添加数据ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 修改数据ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 删除数据ToolStripMenuItem; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project/DbOp/frmView.resx b/Source/Itrycn_Project/DbOp/frmView.resx new file mode 100644 index 0000000..6282a36 --- /dev/null +++ b/Source/Itrycn_Project/DbOp/frmView.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 141, 21 + + + 269, 21 + + + 22, 16 + + \ No newline at end of file diff --git a/Source/Itrycn_Project/Form1.Designer.cs b/Source/Itrycn_Project/Form1.Designer.cs new file mode 100644 index 0000000..95d2f37 --- /dev/null +++ b/Source/Itrycn_Project/Form1.Designer.cs @@ -0,0 +1,322 @@ +namespace WindowsFormsApp2 +{ + partial class Form1 + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.添加提醒ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.复制并添加提醒ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.修改提醒ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.删除提醒ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); + this.查看日志ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.notifyTray = new System.Windows.Forms.NotifyIcon(this.components); + this.menuTray = new System.Windows.Forms.ContextMenuStrip(this.components); + this.显示主窗体ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.关于ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.关闭软件ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.columnModel1 = new XPTable.Models.ColumnModel(); + this.tableModel1 = new XPTable.Models.TableModel(); + this.BtnRobot = new ryControls.ButtonEx(); + this.table1 = new XPTable.Models.Table(); + this.btnDel = new ryControls.ButtonEx(); + this.btnEdit = new ryControls.ButtonEx(); + this.btnAdd = new ryControls.ButtonEx(); + this.btnSetting = new ryControls.ButtonEx(); + this.ctlMyPage1 = new MyPage.ctlMyPage(); + this.rySearch1 = new ryControls.rySearch(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.contextMenuStrip1.SuspendLayout(); + this.menuTray.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.table1)).BeginInit(); + this.SuspendLayout(); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.添加提醒ToolStripMenuItem, + this.复制并添加提醒ToolStripMenuItem, + this.修改提醒ToolStripMenuItem, + this.删除提醒ToolStripMenuItem, + this.toolStripMenuItem2, + this.查看日志ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(161, 120); + // + // 添加提醒ToolStripMenuItem + // + this.添加提醒ToolStripMenuItem.Name = "添加提醒ToolStripMenuItem"; + this.添加提醒ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.添加提醒ToolStripMenuItem.Text = "添加提醒"; + // + // 复制并添加提醒ToolStripMenuItem + // + this.复制并添加提醒ToolStripMenuItem.Name = "复制并添加提醒ToolStripMenuItem"; + this.复制并添加提醒ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.复制并添加提醒ToolStripMenuItem.Text = "复制并添加提醒"; + // + // 修改提醒ToolStripMenuItem + // + this.修改提醒ToolStripMenuItem.Name = "修改提醒ToolStripMenuItem"; + this.修改提醒ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.修改提醒ToolStripMenuItem.Text = "修改提醒"; + // + // 删除提醒ToolStripMenuItem + // + this.删除提醒ToolStripMenuItem.Name = "删除提醒ToolStripMenuItem"; + this.删除提醒ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.删除提醒ToolStripMenuItem.Text = "删除提醒"; + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(157, 6); + // + // 查看日志ToolStripMenuItem + // + this.查看日志ToolStripMenuItem.Name = "查看日志ToolStripMenuItem"; + this.查看日志ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.查看日志ToolStripMenuItem.Text = "查看该提醒日志"; + // + // notifyTray + // + this.notifyTray.ContextMenuStrip = this.menuTray; + this.notifyTray.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyTray.Icon"))); + this.notifyTray.Text = "当游网络网页状态提醒器"; + this.notifyTray.Visible = true; + // + // menuTray + // + this.menuTray.Font = new System.Drawing.Font("微软雅黑", 10F); + this.menuTray.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.显示主窗体ToolStripMenuItem, + this.toolStripMenuItem3, + this.关于ToolStripMenuItem, + this.toolStripMenuItem1, + this.关闭软件ToolStripMenuItem}); + this.menuTray.Name = "menuTray"; + this.menuTray.Size = new System.Drawing.Size(149, 88); + // + // 显示主窗体ToolStripMenuItem + // + this.显示主窗体ToolStripMenuItem.ForeColor = System.Drawing.Color.Black; + this.显示主窗体ToolStripMenuItem.Name = "显示主窗体ToolStripMenuItem"; + this.显示主窗体ToolStripMenuItem.Size = new System.Drawing.Size(148, 24); + this.显示主窗体ToolStripMenuItem.Text = "显示主窗体"; + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(145, 6); + // + // 关于ToolStripMenuItem + // + this.关于ToolStripMenuItem.Name = "关于ToolStripMenuItem"; + this.关于ToolStripMenuItem.Size = new System.Drawing.Size(148, 24); + this.关于ToolStripMenuItem.Text = "关于"; + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(145, 6); + // + // 关闭软件ToolStripMenuItem + // + this.关闭软件ToolStripMenuItem.ForeColor = System.Drawing.Color.Black; + this.关闭软件ToolStripMenuItem.Name = "关闭软件ToolStripMenuItem"; + this.关闭软件ToolStripMenuItem.Size = new System.Drawing.Size(148, 24); + this.关闭软件ToolStripMenuItem.Text = "关闭软件"; + // + // BtnRobot + // + this.BtnRobot.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(76)))), ((int)(((byte)(95))))); + this.BtnRobot.Location = new System.Drawing.Point(493, 8); + this.BtnRobot.Name = "BtnRobot"; + this.BtnRobot.Size = new System.Drawing.Size(84, 26); + this.BtnRobot.TabIndex = 36; + this.BtnRobot.Text = "机器人设置"; + this.BtnRobot.UseVisualStyleBackColor = true; + // + // table1 + // + this.table1.ColumnModel = this.columnModel1; + this.table1.ContextMenuStrip = this.contextMenuStrip1; + this.table1.EnableToolTips = true; + this.table1.FullRowSelect = true; + this.table1.HeaderFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.table1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.table1.Location = new System.Drawing.Point(12, 75); + this.table1.Name = "table1"; + this.table1.NoItemsText = "当前列表没有任何项"; + this.table1.Size = new System.Drawing.Size(775, 599); + this.table1.TabIndex = 35; + this.table1.TableModel = this.tableModel1; + this.table1.Text = "table1"; + // + // btnDel + // + this.btnDel.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(76)))), ((int)(((byte)(95))))); + this.btnDel.Enabled = false; + this.btnDel.Location = new System.Drawing.Point(182, 39); + this.btnDel.Name = "btnDel"; + this.btnDel.Size = new System.Drawing.Size(79, 30); + this.btnDel.TabIndex = 34; + this.btnDel.Text = "删除提醒"; + this.btnDel.UseVisualStyleBackColor = true; + // + // btnEdit + // + this.btnEdit.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(76)))), ((int)(((byte)(95))))); + this.btnEdit.Enabled = false; + this.btnEdit.Location = new System.Drawing.Point(97, 39); + this.btnEdit.Name = "btnEdit"; + this.btnEdit.Size = new System.Drawing.Size(79, 30); + this.btnEdit.TabIndex = 33; + this.btnEdit.Text = "修改提醒"; + this.btnEdit.UseVisualStyleBackColor = true; + // + // btnAdd + // + this.btnAdd.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(76)))), ((int)(((byte)(95))))); + this.btnAdd.Location = new System.Drawing.Point(12, 39); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(79, 30); + this.btnAdd.TabIndex = 32; + this.btnAdd.Text = "添加提醒"; + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); + // + // btnSetting + // + this.btnSetting.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(76)))), ((int)(((byte)(95))))); + this.btnSetting.Location = new System.Drawing.Point(418, 8); + this.btnSetting.Name = "btnSetting"; + this.btnSetting.Size = new System.Drawing.Size(69, 26); + this.btnSetting.TabIndex = 31; + this.btnSetting.Text = "设置"; + this.btnSetting.UseVisualStyleBackColor = true; + // + // ctlMyPage1 + // + this.ctlMyPage1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.ctlMyPage1.Location = new System.Drawing.Point(12, 680); + this.ctlMyPage1.Name = "ctlMyPage1"; + this.ctlMyPage1.PageSize = 50; + this.ctlMyPage1.RecordCount = 0; + this.ctlMyPage1.Size = new System.Drawing.Size(506, 26); + this.ctlMyPage1.SQLText = ""; + this.ctlMyPage1.SQLText2 = ""; + this.ctlMyPage1.T_FirstCaption = "首页"; + this.ctlMyPage1.T_LastCaption = "末页"; + this.ctlMyPage1.T_NextCaption = "下一页"; + this.ctlMyPage1.T_Parameters = null; + this.ctlMyPage1.T_PreCaption = "上一页"; + this.ctlMyPage1.T_SkipCaption = "跳到"; + this.ctlMyPage1.T_TipCaption = "{pageindex}/{pagecount} 页,共 {recordcount} 条记录,每页 {pagesize} 条"; + this.ctlMyPage1.TabIndex = 30; + // + // rySearch1 + // + this.rySearch1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(236)))), ((int)(((byte)(239)))), ((int)(((byte)(244))))); + this.rySearch1.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(76)))), ((int)(((byte)(95))))); + this.rySearch1.EmptyText = "请输入提醒名称或备注进行查询"; + this.rySearch1.Location = new System.Drawing.Point(12, 8); + this.rySearch1.Name = "rySearch1"; + this.rySearch1.Size = new System.Drawing.Size(400, 25); + this.rySearch1.TabIndex = 29; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(352, 46); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(100, 21); + this.textBox1.TabIndex = 37; + this.textBox1.Text = "2222222"; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(799, 718); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.BtnRobot); + this.Controls.Add(this.table1); + this.Controls.Add(this.btnDel); + this.Controls.Add(this.btnEdit); + this.Controls.Add(this.btnAdd); + this.Controls.Add(this.btnSetting); + this.Controls.Add(this.ctlMyPage1); + this.Controls.Add(this.rySearch1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Name = "Form1"; + this.Text = "Form1"; + this.Load += new System.EventHandler(this.Form1_Load); + this.contextMenuStrip1.ResumeLayout(false); + this.menuTray.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.table1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 添加提醒ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 复制并添加提醒ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 修改提醒ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 删除提醒ToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem 查看日志ToolStripMenuItem; + public System.Windows.Forms.NotifyIcon notifyTray; + private System.Windows.Forms.ContextMenuStrip menuTray; + private System.Windows.Forms.ToolStripMenuItem 显示主窗体ToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem 关于ToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem 关闭软件ToolStripMenuItem; + private System.Windows.Forms.ToolTip toolTip1; + private XPTable.Models.ColumnModel columnModel1; + private XPTable.Models.TableModel tableModel1; + private ryControls.ButtonEx BtnRobot; + private XPTable.Models.Table table1; + private ryControls.ButtonEx btnDel; + private ryControls.ButtonEx btnEdit; + private ryControls.ButtonEx btnAdd; + private ryControls.ButtonEx btnSetting; + private MyPage.ctlMyPage ctlMyPage1; + private ryControls.rySearch rySearch1; + private System.Windows.Forms.TextBox textBox1; + } +} + diff --git a/Source/Itrycn_Project/Form1.cs b/Source/Itrycn_Project/Form1.cs new file mode 100644 index 0000000..b2572b7 --- /dev/null +++ b/Source/Itrycn_Project/Form1.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace WindowsFormsApp2 +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + } + + private void Form1_Load(object sender, EventArgs e) + { + //ryCommon.SuperForm form = new ryCommon.SuperForm(this); + //form.SetFormMove(this); + rySearch1.PerformClick(); + } + + private void BtnClick_Click(object sender, EventArgs e) + { + //SendKeys.SendWait("{enter}"); + } + void AddUrl() + { + Thread.Sleep(2000); + this.Invoke(new Action(() => + { + SendKeys.Send("^v"); + SendKeys.SendWait("{enter}"); + })); + } + + private void btnAdd_Click(object sender, EventArgs e) + { + textBox1.Select(0, 0); + } + } +} diff --git a/Source/Itrycn_Project/Form1.resx b/Source/Itrycn_Project/Form1.resx new file mode 100644 index 0000000..2fde559 --- /dev/null +++ b/Source/Itrycn_Project/Form1.resx @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 71, 13 + + + 236, 13 + + + 347, 13 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAANcNAADXDQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAIAAAADAAAABAAA + AAQAAAAFAAAABQAAAAQAAAAEAAAAAwAAAAIAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABgAAAAsAAAAPAAAAEgAA + ABQAAAAWAAAAFwAAABgAAAAYAAAAFwAAABYAAAAUAAAAEgAAAA8AAAAKAAAABgAAAAMAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAACgAAABMAAAAcAAAAIwAA + ACsRDgYzJx8LOzcrD0FDNBFGRzcSSEc3EkhDNBFGNysPQScfCzsRDQYzAAAAKwAAACMAAAAcAAAAEwAA + AAoAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABgAAABIAAAAgJB0LN25W + G12ZdiKIrYUkqreMJMK9kCTRwJIk28GTI+DCkyPiwpMj4sGTI+DAkiTbvZAk0beMJMKthSSqmXYiiG5V + G10kHAs3AAAAIAAAABIBAQAGAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIBAAYAAAAVJR4LMpJx + Inq7jyXIx5ck8cqYIf/KmCD/ypgf/8qYH//KmB//ypgf/8qYH//KmB//ypgf/8qYH//KmB//ypgf/8qY + IP/KmCH/x5ck8buPJceScSJ6JR0LMgAAABUCAQAGAAAAAQAAAAAAAAAAAAAAAAAAAAADAgEEAAAAEVRB + Fj+2jCe0ypkk+suZIP/KmB//ypgf/8qYH//KmB//ypgf/8qYH//KmB//ypgg/8mXH//FlB//yJYf/8qY + IP/KmB//ypgf/8qYH//KmB//y5kg/8qZJPq2jCezU0EWPgAAABEDAgEEAAAAAAAAAAAAAAAAAgEAAQAA + AAlHOBMwvJAou8yaIv/LmSD/y5kg/8uZIP/LmSD/y5kg/8uZIP/LmSD/y5kg/8uZIP/LmSD/xZUf/7eK + H//Bkh//y5kg/8uZIP/LmSD/y5kg/8uZIP/LmSD/y5kg/8yaIv+8kCi7RzgTMAAAAAkCAQABAAAAAAAA + AAAAAAADAAAAE6+HKIzMmyT/zJog/8yaIf/MmiH/zJoh/8yaIf/MmiH/zJoh/8yaIf/MmiH/zJoh/8uZ + If++jyD/xKde/7+VLv/KmCD/zJoh/8yaIf/MmiH/zJoh/8yaIf/MmiH/zJog/8ybJP+vhyiMAAAAEwAA + AAMAAAAAAAAAAAAAAAV2XB83yJkn4M2bIf/NmiH/zZoh/82aIf/NmiH/zZoh/82aIf/NmiH/zZoh/82a + If/NmiH/yJcf/7yVNf/l2bX/xqRR/8eVHv/NmiH/zZoh/82aIf/NmiH/zZoh/82aIf/NmiH/zZsh/8iZ + J991XB43AAAABQAAAAABAQABAAAACK+HKXTOnCX+zpsi/86bIv/OmyL/zpsi/86bIv/OmyL/zpsi/86b + Iv/OmyL/zpsi/82bIv/BkR7/y7Ft//Tv2f/VvoP/wpIf/86bIv/OmyL/zpsi/86bIv/OmyL/zpsi/86b + Iv/OmyL/zpwl/q6HKXMAAAAIAQEAAQAAAAEQDgkQwpUqq8+dI//OnCL/zpwi/86cIv/OnCL/zpwi/86c + Iv/OnCL/zpwi/86cIv/PnCL/zJoh/7ySK//j1a3/9vHc/+XZs//AlS3/zZoh/86cIv/OnCL/zpwi/86c + Iv/OnCL/zpwi/86cIv/PnSP/wpUqqw8NCRAAAAABAAAAAWZRHR/KmynQ0J0j/8+dI//PnSP/z50j/8+d + I//PnSP/z50j/8+dI//PnSP/z50j/8+dI//FlB//xqda//Lr0v/079j/8erQ/8elUf/Jlx//z50j/8+d + I//PnSP/z50j/8+dI//PnSP/z50j/9CdI//KmynQZlAdHwAAAAEAAAABj3AmMc6dKObQnSP/0J0j/9Cd + I//QnSP/0J0j/9CdI//QnSP/0J0j/9CdI//QniP/z5wj/76RJf/cy5v/9fDa//Tu1//179n/1r+D/8SU + IP/QnSP/0J0j/9CdI//QnSP/0J0j/9CdI//QnSP/0J0j/86dKOWPcCYxAAAAAQAAAAGkgClB0J8o8dGe + JP/RniT/0Z4k/9GeJP/RniT/0Z4k/9GeJP/RniT/0Z4k/9CdJP/GliD/wZ5I/+/my//079j/9O7X//Xv + 2f/m2bP/wpcv/8+dI//RniT/0Z4k/9GeJP/RniT/0Z4k/9GeJP/RniT/0J8o8aSAKUEAAAABAAAAAa+I + K07RoCj30p8k/9KfJf/SnyX/0p8l/9KfJf/SnyX/0Z8l/8+dJP/ImCP/vI4f/62DHP/SvYf/9e/Z//Tu + 1//07tf/9O7X//Hq0P/IplL/zJoh/9KfJf/SnyX/0p8l/9KfJf/SnyX/0p8l/9KfJP/RoCj3r4grTgAA + AAEAAAABtY0sVtKgKPrSoCX/06Al/9OgJf/ToCX/0p8l/86dJP/GliL/uIse/6yCHv+vjTr/yrWB/+7n + z//07tf/9O7X//Tu1//07tf/9e/Z/9bAhP/HliL/0qAl/9OgJf/ToCX/06Al/9OgJf/ToCX/0qAl/9Kg + KPq1jSxWAAAAAQAAAAG5kC1b06Eo/NOgJf/ToCb/0qAm/82cJf/DlCL/tIgd/6uDI/+2l0z/1MKZ//Hs + 4P///////f36//bx3//07tb/9O7X//Tu1//179n/5tmz/8SZMP/SnyX/06Am/9OgJv/ToCb/06Am/9Og + Jv/ToCX/06Eo/LiQLVsAAAABAAAAALuRLlzUoin81KEm/9ShJv/QniX/v5Ag/7KLLP+/pGL/3tGy//j1 + 7v///////////////////////fz5//bx4P/07tb/9O7X//Tu1//x6tD/yqhT/86cIv/UoSb/1KEm/9Sh + Jv/UoSb/1KEm/9ShJv/Uoin8u5EuXAAAAAD///8AvJIuWdWjKvvVoif/1aIm/9WkMP/dwHj/7eTN//z8 + +v///////////////////////////////////////fz5//bx4P/07tb/9O7X//Xv2f/XwIX/yZgk/9Wi + J//Voif/1aIn/9WiJ//Voif/1aIn/9WjKvu7ki5Z////AP///wC7ki9S1qQq+tajJ//Woif/16Yv/+K+ + Zv/v2qf/+O/a//78+f///////////////////////////////////////fz5//bx4P/07tb/9e/Z/+fa + s//GmzH/1KEm/9ajJ//Woyf/1qMn/9ajJ//Woyf/1qQq+buSL1L///8A///GALmRMEfWpCv116Mo/9ej + KP/Xoyf/1qIl/9ejKP/arDz/479o/+7YpP/479r//vz5/////////////////////////////fz5//bx + 4P/07tf/8erQ/8upVP/RniT/16Qo/9ejKP/Xoyj/16Mo/9ejKP/WpCv1uZEwRv//xgD//44AtY4wNtel + Le3YpCj/2KQo/9ikKP/YpCj/16Qo/9ekJ//XoyX/16Qo/9usPP/jv2j/7tmk//jv2v/+/Pn///////// + /////////fz5//bx4P/079n/2MGF/8uaJf/XpCj/2KQo/9ikKP/YpCj/2KQo/9elLe20jjA2//+PAP// + dgCqhjAj16Uu3tilKf/YpSn/2KUp/9ilKf/YpSn/2KUp/9ilKf/YpSn/2KQo/9ikJv/YpSn/3K09/+TA + af/v2aX/+PDa//79+f///////f37//fz4v/n2rP/yp4z/9ejKP/YpSn/2KUp/9ilKf/YpSn/16Uv3qmG + LyP//3cA//9qAIpuKxDWpjHC2aYq/9mmKf/Zpin/2aYp/9mmKf/Zpin/2aYp/9mmKf/Zpin/2aYp/9mm + Kf/ZpSj/2aQm/9mmKf/drj3/5MBp/+/Zpf/58Nr//Prz//Xv3P/Ys1j/16Mn/9mmKf/Zpin/2aYp/9mm + Kv/WpjHBiW4rD///agCnhC8AAAAAAtWmNJLapyv/2qYq/9qmKv/apir/2qYq/9qmKv/apir/2qYq/9qm + Kv/apir/2qYq/9qmKv/apir/2qYq/9qmKf/ZpSf/2qYq/92uPf/lwWr/7tih/+XEcv/Zpin/2qYq/9qm + Kv/apir/2qcr/9WmNJEAAAACpoQvAAAAAAD//1YA0KQ3T9upLvjbpyr/26cr/9unK//bpyv/26cr/9un + K//bpyv/26cr/9unK//bpyv/26cr/9unK//bpyv/26cr/9unK//bpyr/2qcp/9qmJ//bpyv/3Koy/9un + K//bpyr/26cr/9unKv/bqS730KQ3Tv//VQAAAAAAAAAAAP/QSgC8ljgT26ozwtyoK//cqCv/3Kgr/9yo + K//cqCv/3Kgr/9yoK//cqCv/3Kgr/9yoK//cqCv/3Kgr/9yoK//cqCv/3Kgr/9yoK//cqCv/3Kgr/9yo + K//cqCv/3Kgr/9yoK//cqCv/3Kgr/9uqNMK8ljgS/89KAAAAAAAAAAAAAAAAAP/qSwDYqjpR3asx8typ + K//cqSz/3Kks/9ypLP/cqSz/3Kks/9ypLP/cqSz/3Kks/9ypLP/cqSz/3Kks/9ypLP/cqSz/3Kks/9yp + LP/cqSz/3Kks/9ypLP/cqSz/3Kks/9ypK//dqzHy2Ko6Uf/pSwAAAAAAAAAAAAAAAAAAAAAA5LVEAKqL + PwTdrTl43qsx9t2pLP/dqSz/3aks/92pLP/dqSz/3aks/92pLP/dqSz/3aks/92pLP/dqSz/3aks/92p + LP/dqSz/3aks/92pLP/dqSz/3aks/92pLP/dqSz/3qsx9t2tOXipiT8E5LVEAAAAAAAAAAAAAAAAAAAA + AAD/6FQA5bZDAMehQgXerjti36002N6rL//eqi3/3qot/96qLf/eqi3/3qot/96qLf/eqi3/3qot/96q + Lf/eqi3/3qot/96qLf/eqi3/3qot/96qLf/eqi3/3qsv/9+tNNjerjtix6BDBeW1QwD/6FUAAAAAAAAA + AAAAAAAAAAAAAAAAAAD/y0kA3K9BAPi/MwDer0Ai4K86c+CuNrzfrTPk36ww9t+sL/7frC7/36su/9+r + Lv/fqy7/36su/9+rLv/fqy7/36wu/9+sL/7frDD2360z5OCuNrvgrzpz3rBAIvi/MwDcr0EA/8tKAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxvkYAsY03AOCxPwDnsjMA3rJHDOCxQC3gsDxS4LA6dOCv + OY3hrzif4a84quCvN6/grzev4a84quGvOJ/grzmN4LA6dOCwPFLgsUAs3rJHDOeyMwDgsT8AsIw3APC+ + RgAAAAAAAAAAAAAAAAAAAAAA4AAAB8AAAAOAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAAAABwAAAA+AAAAc= + + + + 458, 13 + + + -685, 51 + + + -544, 51 + + \ No newline at end of file diff --git a/Source/Itrycn_Project/FrmAbout.Designer.cs b/Source/Itrycn_Project/FrmAbout.Designer.cs new file mode 100644 index 0000000..dd7b683 --- /dev/null +++ b/Source/Itrycn_Project/FrmAbout.Designer.cs @@ -0,0 +1,180 @@ +namespace Itrycn_Project +{ + partial class FrmAbout + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmAbout)); + this.pnlTopLogo = new System.Windows.Forms.Panel(); + this.lblTitle = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.lblVisitUrl = new System.Windows.Forms.Label(); + this.LblQQ_Qun = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.btnCancel = new ryControls.ButtonEx(); + this.pnlTopLogo.SuspendLayout(); + this.SuspendLayout(); + // + // pnlTopLogo + // + this.pnlTopLogo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(125)))), ((int)(((byte)(182))))); + this.pnlTopLogo.Controls.Add(this.lblTitle); + this.pnlTopLogo.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTopLogo.Location = new System.Drawing.Point(0, 0); + this.pnlTopLogo.Name = "pnlTopLogo"; + this.pnlTopLogo.Size = new System.Drawing.Size(434, 59); + this.pnlTopLogo.TabIndex = 8; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblTitle.ForeColor = System.Drawing.Color.White; + this.lblTitle.Location = new System.Drawing.Point(12, 22); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(110, 16); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "睿元管理系统"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 71); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(35, 12); + this.label1.TabIndex = 9; + this.label1.Text = "官网:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(53, 71); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(0, 12); + this.label2.TabIndex = 10; + // + // lblVisitUrl + // + this.lblVisitUrl.AutoSize = true; + this.lblVisitUrl.Cursor = System.Windows.Forms.Cursors.Hand; + this.lblVisitUrl.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblVisitUrl.ForeColor = System.Drawing.Color.Blue; + this.lblVisitUrl.Location = new System.Drawing.Point(53, 71); + this.lblVisitUrl.Name = "lblVisitUrl"; + this.lblVisitUrl.Size = new System.Drawing.Size(77, 12); + this.lblVisitUrl.TabIndex = 11; + this.lblVisitUrl.Text = "立即访问官网"; + this.lblVisitUrl.Click += new System.EventHandler(this.LblVisitUrl_Click); + // + // LblQQ_Qun + // + this.LblQQ_Qun.AutoSize = true; + this.LblQQ_Qun.Cursor = System.Windows.Forms.Cursors.Hand; + this.LblQQ_Qun.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.LblQQ_Qun.ForeColor = System.Drawing.Color.Blue; + this.LblQQ_Qun.Location = new System.Drawing.Point(54, 94); + this.LblQQ_Qun.Name = "LblQQ_Qun"; + this.LblQQ_Qun.Size = new System.Drawing.Size(59, 12); + this.LblQQ_Qun.TabIndex = 14; + this.LblQQ_Qun.Text = "183161992"; + this.toolTip1.SetToolTip(this.LblQQ_Qun, "点击复制"); + this.LblQQ_Qun.Click += new System.EventHandler(this.LblQQ_Qun_Click); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(54, 94); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(0, 12); + this.label4.TabIndex = 13; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(13, 94); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(35, 12); + this.label5.TabIndex = 12; + this.label5.Text = "QQ群:"; + // + // btnCancel + // + this.btnCancel.ForeColor = System.Drawing.Color.White; + this.btnCancel.Location = new System.Drawing.Point(357, 237); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(65, 27); + this.btnCancel.TabIndex = 16; + this.btnCancel.Text = "确定"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // FrmAbout + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(434, 276); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.LblQQ_Qun); + this.Controls.Add(this.label4); + this.Controls.Add(this.label5); + this.Controls.Add(this.lblVisitUrl); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.pnlTopLogo); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "FrmAbout"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "关于"; + this.Load += new System.EventHandler(this.FrmAbout_Load); + this.pnlTopLogo.ResumeLayout(false); + this.pnlTopLogo.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel pnlTopLogo; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label lblVisitUrl; + private System.Windows.Forms.Label LblQQ_Qun; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private ryControls.ButtonEx btnCancel; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project/FrmAbout.cs b/Source/Itrycn_Project/FrmAbout.cs new file mode 100644 index 0000000..99f3d42 --- /dev/null +++ b/Source/Itrycn_Project/FrmAbout.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project +{ + public partial class FrmAbout : Form + { + public FrmAbout() + { + InitializeComponent(); + } + + private void FrmAbout_Load(object sender, EventArgs e) + { + lblTitle.Text = Itrycn_Info.Soft_Title + " V" + ryCommon.RySoft.VersionStr; + } + + private void LblVisitUrl_Click(object sender, EventArgs e) + { + ryCommon.RyFiles.OpenUrl(Itrycn_Info.Soft_Url); + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + } + + private void LblQQ_Qun_Click(object sender, EventArgs e) + { + try + { + Clipboard.SetText(LblQQ_Qun.Text); + MessageBox.Show("已成功复制到剪切板,请复制到QQ搜索。","提示",MessageBoxButtons.OK,MessageBoxIcon.Information); + } + catch { } + } + } +} diff --git a/Source/Itrycn_Project/FrmAbout.resx b/Source/Itrycn_Project/FrmAbout.resx new file mode 100644 index 0000000..6bbf01a --- /dev/null +++ b/Source/Itrycn_Project/FrmAbout.resx @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAEZcAABGXAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANyg + SADcoEgA3KBIANygSADcoEgA3KBIANygSADcoEgA3KBIANygSADcoEgAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANyg + SADcoEgA3KBIFtygSDjcoEhS3KBIVtygSFbcoEhT3KBIPNygSBncoEgC3KBIANygSADcoEgA3KBIAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcoEgA3KBIANyg + SADcoEgG3KBIQdygSJXcoEjT3KBI8dygSPzcoEj93KBI/dygSPzcoEjz3KBI2NygSJ7coEhJ3KBICtyg + SADcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KBIANyg + SADcoEgA3KBIL9ygSKTcoEjy3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SPXcoEiw3KBIOtygSADcoEgA3KBIANygSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANyg + SADcoEgA3KBIAdygSFrcoEjf3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEjn3KBIatygSAXcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADcoEgA3KBIANygSAHcoEhp3KBI8dygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj33KBIfNygSAXcoEgA3KBIAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3KBIANygSADcoEgA3KBIVtygSPDcoEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yf + R//cn0f/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj33KBIatygSADcoEgA3KBIAAAA + AAAAAAAAAAAAAAAAAADcoEgA3KBIANygSCrcoEjb3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/cn0f/5rx+/+jAhv/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjn3KBIOtyg + SADcoEgAAAAAAAAAAAAAAAAA3KBIANygSADcoEgE3KBIm9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9yfR//nvX//6MGI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEiw3KBICtygSADcoEgAAAAAAAAAAADcoEgA3KBIANygSDbcoEjs3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9yfR//cn0f/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSPXcoEhJ3KBIANygSAAAAAAAAAAAANygSADcoEgA3KBIh9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3aJM/92iTP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSJ7coEgC3KBIAAAAAAAAAAAA3KBIANygSA7coEjG3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yfRv/qxpH/7Muc/9ygR//coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI2NygSBncoEgAAAAAAAAAAADcoEgA3KBIKdyg + SOjcoEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3J9F/+7Sqf/y27r/3KBH/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjz3KBIPNygSAAAAAAAAAAAANyg + SADcoEhD3KBI99ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/bnkX/68qZ//Ti + x//doUv/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSPzcoEhT3KBIAAAA + AAAAAAAA3KBIANygSFLcoEj83KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yf + Rv/kt3T/+e/f/+KvZf/cn0b/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/dyg + SFbcoEgAAAAAAAAAAADcoEgA3KBIUdygSPvcoEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/92jTv/z3sD/89/A/9+nVf/cn0b/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj93KBIVtygSAAAAAAAAAAAANygSADcoEhA3KBI9tygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3J9G/+GtYv/25s//9OLG/+CrXf/cn0f/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSPzcoEhS3KBIAAAAAAAAAAAA3KBIANygSCbcoEjm3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3J9G/+CqW//04sf/8ty7/92iTf/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI8dygSDjcoEgAAAAAAAAAAADcoEgA3KBIDNygSMHcoEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBH/9yfRv/coEj/3KBI/9ygSP/coEj/259F/+Kxaf/57+D/47Ru/9yf + Rv/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjT3KBIFtygSAAAAAAAAAAAANygSADcoEgA3KBIftyg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygR//eplT/5bh3/92jTv/coEj/3KBI/9ygSP/coEf/3qRQ//fo + 0//owIb/255F/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSJXcoEgA3KBIAAAAAAAAAAAA3KBIANyg + SADcoEgv3KBI59ygSP/coEj/3KBI/9ygSP/coEj/3J9G/+KxaP/47d3/4a9k/9yfRv/coEj/3KBI/9yf + R//fqVn/+Ozb/+W5ef/bn0X/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjy3KBIQdygSADcoEgAAAAAAAAA + AADcoEgA3KBIANygSAHcoEiP3KBI/9ygSP/coEj/3KBI/9ygSP/coEf/3qVS//bmzv/u0af/3KBJ/9ue + Rf/bn0X/3J9H/+zLmv/36tf/36hY/9yfR//coEj/3KBI/9ygSP/coEj/3KBI/9ygSKTcoEgG3KBIANyg + SAAAAAAAAAAAAAAAAADcoEgA3KBIANygSCHcoEjQ3KBI/9ygSP/coEj/3KBI/9ygSP/cn0b/5bh3//nv + 4f/w17H/5bl3/+W3df/v06r/+vDj/+e+gv/cn0b/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjf3KBIL9yg + SADcoEgAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANygSEjcoEjo3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/5LVx//Pfwf/47Nv/+O3c//Thxf/luXf/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI8dyg + SFrcoEgA3KBIANygSAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANygSFjcoEjo3KBI/9yg + SP/coEj/3KBI/9ygSP/cn0b/3aJL/9+pWf/gqlr/3aJM/9yfRv/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SPDcoEhp3KBIAdygSADcoEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANyg + SEjcoEjQ3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3J9H/9yfR//coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEjb3KBIVtygSAHcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANyg + SADcoEgA3KBIANygSCHcoEiP3KBI59ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEjs3KBIm9ygSCrcoEgA3KBIANygSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANygSADcoEgA3KBIANygSAHcoEgv3KBIftygSMHcoEjm3KBI9tygSPvcoEj83KBI99yg + SOjcoEjG3KBIh9ygSDbcoEgE3KBIANygSADcoEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANygSADcoEgA3KBIDNygSCbcoEhB3KBIUdyg + SFHcoEhD3KBIKdygSA7coEgA3KBIANygSADcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcoEgA3KBIANygSADcoEgA3KBIANyg + SADcoEgA3KBIANygSADcoEgA3KBIANygSADcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//////+AAf/+AAB//AAAP/gAAA/wAAAP4AAAB8AAAAPAAAADgAAAAYAA + AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAHAAAADwAAAA+AA + AAfwAAAP+AAAH/wAAD/+AAB//4AB//////8= + + + \ No newline at end of file diff --git a/Source/Itrycn_Project/Itrycn_Info.cs b/Source/Itrycn_Project/Itrycn_Info.cs new file mode 100644 index 0000000..067ebb1 --- /dev/null +++ b/Source/Itrycn_Project/Itrycn_Info.cs @@ -0,0 +1,125 @@ +using ryCommon; +using ryCommonDb; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using static ryCommonDb.DataProvider; + +namespace Itrycn_Project +{ + /// + /// 配置类(本系统基于乘黄V1架构) + /// + public class Itrycn_Info + { + /// + /// 是否能关闭窗体。 + /// + public static bool isCanCloseForm = true; + /// + /// 在线升级配置文件的url + /// + public static string Update_Url = "http://www.itrycn.com/update/ryWebMon4.xml"; + /// + /// 软件标题 + /// + public static string Soft_Title = "睿元管理系统"; + /// + /// 软件ID + /// + public static string Soft_Id = "Money_Op"; + /// + /// 开机启动的参数 + /// + public static string Soft_Pram = "q"; + /// + /// 官网地址 + /// + public static string Soft_Url = "http://www.itrycn.com"; + /// + /// 用户文件夹,该相对路径设置,将在程序启动后转换 + /// + public static string UserDataFolder = "\\UserDb"; + /// + /// 左边分类内容新增 + /// + /// + public static void OnLeftTreeAdd(Itrycn.Frmmain frm) + { + frm.AddToTreeView(frm.treeView1.Nodes[0], typeof(DbOp.FrmView), "测试", "item.png"); + Itrycn_Info.LoadSetting(); + } + public static void LoadSetting() + { + //ryCommon.Storage Stor = new Storage(); + //Stor.SelectNodeBySet(); + //LowCountTip = Stor.GetAttrValue("LowCountTip", true); + //low_count = Stor.GetAttrValue("LowCount", 10); + } + /// + /// 单击分类时激发 + /// + /// + /// + public static void OnTreeClick(Itrycn.Frmmain frm, TreeViewEventArgs e) + { + Type id = (Type)e.Node.Tag; + frm.ShowForm(id); + } + } + public class Itrycn_Db + { + public static string SQLConnStr = "\\UserDb\\myDb.dat|"; + public static ryCommonDb.DataProvider.DataProviderType dataType = ryCommonDb.DataProvider.DataProviderType.SQLiteDataProvider; + public static IDbInterface CreateDataProvider() + { + return CreateDataProvider(dataType); + } + + public static IDbInterface CreateDataProvider(DataProviderType dataProviderType) + { + switch (dataProviderType) + { + //case DataProviderType.OdbcDataProvider: + // return new OdbcDataProvider(); + //case DataProviderType.OleDbDataProvider: + // return new OleDbDataProvider(); + //case DataProviderType.OracleDataProvider: + // return new OracleDataProvider(); + case DataProviderType.SQLiteDataProvider: + return new SQLiteDataProvider(); + default: + return null; + } + } + private static void CreateTable(ryCommonDb.DataProvider.DataProviderType dataType, string ConnStr) + { + DataProvider mydb = new DataProvider(); + IDbInterface db = CreateDataProvider(dataType); + if (db.ConnDb(ConnStr) == 1) + { + #region 表1 + RyQuickSQL mySQL = new RyQuickSQL("表1"); + mySQL.AddField("", ""); + mySQL.AddField("addTime", DateTime.Now); + mySQL.AddField("editTime", DateTime.Now); + db.CreateDb(mySQL); + #endregion + // + #region 表2 + mySQL.Clear(); + mySQL.TableName = "表2"; + mySQL.AddField("", ""); + db.CreateDb(mySQL); + #endregion + } + db.Free(); + } + public static void CreateTable() + { + CreateTable(dataType, SQLConnStr); + } + } +} diff --git a/Source/Itrycn_Project/Itrycn_Project.csproj b/Source/Itrycn_Project/Itrycn_Project.csproj new file mode 100644 index 0000000..ca0d5ec --- /dev/null +++ b/Source/Itrycn_Project/Itrycn_Project.csproj @@ -0,0 +1,193 @@ + + + + + Debug + AnyCPU + {62B5C3E8-4AF1-4A7F-A40B-A6186F83DBD2} + WinExe + Itrycn_Project + Itrycn_Project + v4.0 + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + x86 + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4 示例\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + ..\..\Bin\Release\CommonControls\.NET4 示例\ + TRACE + prompt + 4 + + + + ..\..\Bin\Debug\CommonControls\.NET4\RyWeb.dll + + + + + + + + + + + + + ..\..\Bin\Debug\CommonControls\.NET4\XPTable.dll + + + + + + Form + + + FrmAdd.cs + + + Form + + + FrmView.cs + + + Form + + + Form1.cs + + + Form + + + FrmAbout.cs + + + Form + + + frmLogin.cs + + + Form + + + frmmain.cs + + + Form + + + frmSetting.cs + + + + + + FrmAdd.cs + + + FrmView.cs + + + Form1.cs + + + FrmAbout.cs + + + frmLogin.cs + + + frmmain.cs + + + frmSetting.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV4 + + + {6b969ce8-d723-4b2c-a8fd-fad2fb28ff01} + MyDb_SQLiteV4 + + + {9eca3a84-8545-4c4d-84d6-d23e3bdf2d90} + ryControlsV4 + + + {B6784652-825A-482C-8A21-08E2539AF2BF} + RyPrint + + + {11a63e24-0257-4c54-a109-f1a609a52a62} + ryUpdateV4 + + + + + False + .NET Framework 3.5 SP1 + false + + + + + + + \ No newline at end of file diff --git a/Source/Itrycn_Project/Itrycn_Project.csproj.user b/Source/Itrycn_Project/Itrycn_Project.csproj.user new file mode 100644 index 0000000..a82707a --- /dev/null +++ b/Source/Itrycn_Project/Itrycn_Project.csproj.user @@ -0,0 +1,14 @@ + + + + ShowAllFiles + + + + + + + zh-CN + false + + \ No newline at end of file diff --git a/Source/Itrycn_Project/Program.cs b/Source/Itrycn_Project/Program.cs new file mode 100644 index 0000000..519882f --- /dev/null +++ b/Source/Itrycn_Project/Program.cs @@ -0,0 +1,39 @@ +using Itrycn; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace Itrycn_Project +{ + static class Program + { + static System.Threading.Mutex run; + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main(string[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Itrycn_Info.UserDataFolder = ryCommon.RyFiles.GetRealPath(Itrycn_Info.UserDataFolder); + run = new System.Threading.Mutex(true, Itrycn_Info.Soft_Id, out bool runone); + if (!runone) //已经运行了 + { + ryCommon.Ini ini = new ryCommon.Ini(Itrycn_Info.UserDataFolder + "\\Win.dat"); + ryControls.Win32.SendMessage((IntPtr)ini.ReadIni(Itrycn_Info.Soft_Id, "hwnd", 0), 17189, 100, 100); + } + else + { + Application.Run(new Frmmain(args)); + //Application.Run(new WindowsFormsApp2.Form1()); + } + //FrmLogin frm = new FrmLogin(); + //if (frm.ShowDialog() == DialogResult.OK) + //{ + // Application.Run(new Frmmain()); + //} + } + } +} diff --git a/Source/Itrycn_Project/Properties/AssemblyInfo.cs b/Source/Itrycn_Project/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f491a7d --- /dev/null +++ b/Source/Itrycn_Project/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Itrycn_Project")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Itrycn_Project")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("62b5c3e8-4af1-4a7f-a40b-a6186f83dbd2")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/Itrycn_Project/Properties/Resources.Designer.cs b/Source/Itrycn_Project/Properties/Resources.Designer.cs new file mode 100644 index 0000000..0487e9e --- /dev/null +++ b/Source/Itrycn_Project/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Itrycn_Project.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("Itrycn_Project.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 closetree { + get { + object obj = ResourceManager.GetObject("closetree", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap opentree { + get { + object obj = ResourceManager.GetObject("opentree", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Source/Itrycn_Project/Properties/Resources.resx b/Source/Itrycn_Project/Properties/Resources.resx new file mode 100644 index 0000000..d8999d4 --- /dev/null +++ b/Source/Itrycn_Project/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + ..\Resources\closetree.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\opentree.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Source/Itrycn_Project/Properties/Settings.Designer.cs b/Source/Itrycn_Project/Properties/Settings.Designer.cs new file mode 100644 index 0000000..87b3b8d --- /dev/null +++ b/Source/Itrycn_Project/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Itrycn_Project.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/Source/Itrycn_Project/Properties/Settings.settings b/Source/Itrycn_Project/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Source/Itrycn_Project/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Source/Itrycn_Project/RegSoft/frmLogin.Designer.cs b/Source/Itrycn_Project/RegSoft/frmLogin.Designer.cs new file mode 100644 index 0000000..823d7d2 --- /dev/null +++ b/Source/Itrycn_Project/RegSoft/frmLogin.Designer.cs @@ -0,0 +1,190 @@ +namespace Itrycn +{ + partial class FrmLogin + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtUserId = new ryControls.TextBoxEx2(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.txtPwd = new ryControls.TextBoxEx2(); + this.btnLogin = new ryControls.ButtonEx(); + this.btnCancel = new ryControls.ButtonEx(); + this.pnlTopLogo = new System.Windows.Forms.Panel(); + this.lblTitle = new System.Windows.Forms.Label(); + this.chkRememberUserId = new System.Windows.Forms.CheckBox(); + this.chkAutoLogin = new System.Windows.Forms.CheckBox(); + this.pnlTopLogo.SuspendLayout(); + this.SuspendLayout(); + // + // txtUserId + // + this.txtUserId.BackColor = System.Drawing.Color.White; + this.txtUserId.Location = new System.Drawing.Point(97, 103); + this.txtUserId.Name = "txtUserId"; + this.txtUserId.PasswordChar = '\0'; + this.txtUserId.ReadOnly = false; + this.txtUserId.SelectionLength = 0; + this.txtUserId.SelectionStart = 0; + this.txtUserId.Size = new System.Drawing.Size(209, 25); + this.txtUserId.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(50, 111); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(41, 12); + this.label1.TabIndex = 1; + this.label1.Text = "用户ID"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(50, 142); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(29, 12); + this.label2.TabIndex = 3; + this.label2.Text = "密码"; + // + // txtPwd + // + this.txtPwd.BackColor = System.Drawing.Color.White; + this.txtPwd.Location = new System.Drawing.Point(97, 134); + this.txtPwd.Name = "txtPwd"; + this.txtPwd.PasswordChar = '*'; + this.txtPwd.ReadOnly = false; + this.txtPwd.SelectionLength = 0; + this.txtPwd.SelectionStart = 0; + this.txtPwd.Size = new System.Drawing.Size(209, 25); + this.txtPwd.TabIndex = 1; + this.txtPwd.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TxtPwd_KeyDown); + // + // btnLogin + // + this.btnLogin.ForeColor = System.Drawing.Color.White; + this.btnLogin.Location = new System.Drawing.Point(171, 197); + this.btnLogin.Name = "btnLogin"; + this.btnLogin.Size = new System.Drawing.Size(65, 27); + this.btnLogin.TabIndex = 2; + this.btnLogin.Text = "登陆"; + this.btnLogin.UseVisualStyleBackColor = true; + this.btnLogin.Click += new System.EventHandler(this.BtnLogin_Click); + // + // btnCancel + // + this.btnCancel.ForeColor = System.Drawing.Color.White; + this.btnCancel.Location = new System.Drawing.Point(242, 197); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(65, 27); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "取消"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // pnlTopLogo + // + this.pnlTopLogo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(125)))), ((int)(((byte)(182))))); + this.pnlTopLogo.Controls.Add(this.lblTitle); + this.pnlTopLogo.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTopLogo.Location = new System.Drawing.Point(0, 0); + this.pnlTopLogo.Name = "pnlTopLogo"; + this.pnlTopLogo.Size = new System.Drawing.Size(377, 59); + this.pnlTopLogo.TabIndex = 7; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblTitle.ForeColor = System.Drawing.Color.White; + this.lblTitle.Location = new System.Drawing.Point(12, 22); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(110, 16); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "睿元管理系统"; + // + // chkRememberUserId + // + this.chkRememberUserId.AutoSize = true; + this.chkRememberUserId.Location = new System.Drawing.Point(97, 165); + this.chkRememberUserId.Name = "chkRememberUserId"; + this.chkRememberUserId.Size = new System.Drawing.Size(84, 16); + this.chkRememberUserId.TabIndex = 8; + this.chkRememberUserId.Text = "记住用户ID"; + this.chkRememberUserId.UseVisualStyleBackColor = true; + // + // chkAutoLogin + // + this.chkAutoLogin.AutoSize = true; + this.chkAutoLogin.Location = new System.Drawing.Point(202, 165); + this.chkAutoLogin.Name = "chkAutoLogin"; + this.chkAutoLogin.Size = new System.Drawing.Size(72, 16); + this.chkAutoLogin.TabIndex = 9; + this.chkAutoLogin.Text = "自动登陆"; + this.chkAutoLogin.UseVisualStyleBackColor = true; + this.chkAutoLogin.CheckedChanged += new System.EventHandler(this.ChkAutoLogin_CheckedChanged); + // + // FrmLogin + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(377, 247); + this.Controls.Add(this.chkAutoLogin); + this.Controls.Add(this.chkRememberUserId); + this.Controls.Add(this.pnlTopLogo); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnLogin); + this.Controls.Add(this.label2); + this.Controls.Add(this.txtPwd); + this.Controls.Add(this.label1); + this.Controls.Add(this.txtUserId); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Name = "FrmLogin"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "登陆"; + this.Load += new System.EventHandler(this.FrmLogin_Load); + this.pnlTopLogo.ResumeLayout(false); + this.pnlTopLogo.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ryControls.TextBoxEx2 txtUserId; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private ryControls.TextBoxEx2 txtPwd; + private ryControls.ButtonEx btnLogin; + private ryControls.ButtonEx btnCancel; + private System.Windows.Forms.Panel pnlTopLogo; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.CheckBox chkRememberUserId; + private System.Windows.Forms.CheckBox chkAutoLogin; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project/RegSoft/frmLogin.cs b/Source/Itrycn_Project/RegSoft/frmLogin.cs new file mode 100644 index 0000000..990ca69 --- /dev/null +++ b/Source/Itrycn_Project/RegSoft/frmLogin.cs @@ -0,0 +1,119 @@ +using Itrycn_Project; +using ryCommon; +using RyHardWare; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace Itrycn +{ + public partial class FrmLogin : Form + { + public delegate void LoginHandler(object sender,out bool LoginSuccess); + [Description("点击登录按钮时激发")] + public event LoginHandler OnLoginClick; + public FrmLogin() + { + InitializeComponent(); + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + } + private void BtnLogin_Click(object sender, EventArgs e) + { + txtUserId.Enabled = false; + txtPwd.Enabled = false; + btnLogin.Enabled = false; + LoginPram.UserId = txtUserId.Text; + LoginPram.Pwd = txtPwd.Text; + bool LoginSuccess = false; + OnLoginClick?.Invoke(this,out LoginSuccess); + txtUserId.Enabled = true; + txtPwd.Enabled = true; + btnLogin.Enabled = true; + if (LoginSuccess) + { + #region 登录成功 + ryCommon.Ini ryIni = new Ini(Itrycn_Info.UserDataFolder + "\\Setting.dat"); + if (chkAutoLogin.Checked || chkRememberUserId.Checked) + { + ryIni.WriteIni("User", "id", LoginPram.UserId); + if (chkAutoLogin.Checked) + { + LoginPram.isAutoLogin = 2; + ryIni.WriteIni("User", "pwd", rySafe.AES.Encode("121" + LoginPram.Pwd, RyHardWare.Network.GetMacs() + "|" + LoginPram.UserId)); + } + else + { + LoginPram.isAutoLogin = 1; + ryIni.DelKey("User", "pwd"); + } + } + else + { + ryIni.DelKey("User", "id"); + LoginPram.isAutoLogin = 0; + } + #endregion + DialogResult = DialogResult.OK; + } + } + + private void TxtPwd_KeyDown(object sender, KeyEventArgs e) + { + if(e.KeyCode==Keys.Enter) + { + btnLogin.PerformClick(); + } + } + + private void FrmLogin_Load(object sender, EventArgs e) + { + lblTitle.Text = Itrycn_Info.Soft_Title; + if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(Itrycn_Info.UserDataFolder))) + { + System.IO.Directory.CreateDirectory(Itrycn_Info.UserDataFolder); + } + ryCommon.Ini ryIni = new Ini(Itrycn_Info.UserDataFolder + "\\Setting.dat"); + txtUserId.Text=ryIni.ReadIni("User", "id", LoginPram.UserId); + if(txtUserId.Text!="") + { chkRememberUserId.Checked = true; } + string pwd = rySafe.AES.Decode(ryIni.ReadIni("User", "pwd", ""), Network.GetMacs() + "|" + txtUserId.Text); + if (pwd.IndexOf("121") == 0) { pwd = pwd.Substring(3); } else { pwd = ""; } + txtPwd.Text = pwd; + if (pwd != "") + { + chkAutoLogin.Checked = true; + txtUserId.Enabled = false; + txtPwd.Enabled = false; + btnLogin.PerformClick(); + btnLogin.Enabled = false; + } + else + { + txtUserId.SelectionLength = 0; + txtUserId.SelectionStart = 0; + txtPwd.Select(); + } + } + + private void ChkAutoLogin_CheckedChanged(object sender, EventArgs e) + { + if (chkAutoLogin.Checked) { chkRememberUserId.Checked = true; } + } + } + public class LoginPram + { + public static string UserId = ""; + public static string Pwd = ""; + public static int isAutoLogin = 0; + } +} diff --git a/Source/Itrycn_Project/RegSoft/frmLogin.resx b/Source/Itrycn_Project/RegSoft/frmLogin.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/Itrycn_Project/RegSoft/frmLogin.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/Source/Itrycn_Project/Resources/closetree.png b/Source/Itrycn_Project/Resources/closetree.png new file mode 100644 index 0000000..1906bbc Binary files /dev/null and b/Source/Itrycn_Project/Resources/closetree.png differ diff --git a/Source/Itrycn_Project/Resources/opentree.png b/Source/Itrycn_Project/Resources/opentree.png new file mode 100644 index 0000000..fb05270 Binary files /dev/null and b/Source/Itrycn_Project/Resources/opentree.png differ diff --git a/Source/Itrycn_Project/clsForm.cs b/Source/Itrycn_Project/clsForm.cs new file mode 100644 index 0000000..83cf0be --- /dev/null +++ b/Source/Itrycn_Project/clsForm.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn +{ + public static class MDIClientSupport + { + [DllImport("user32.dll")] + private static extern int GetWindowLong(IntPtr hWnd, int nIndex); + [DllImport("user32.dll")] + private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + [DllImport("user32.dll", ExactSpelling = true)] + private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + private const int GWL_EXSTYLE = -20; + private const int WS_EX_CLIENTEDGE = 0x200; + private const uint SWP_NOSIZE = 0x0001; + private const uint SWP_NOMOVE = 0x0002; + private const uint SWP_NOZORDER = 0x0004; + private const uint SWP_NOREDRAW = 0x0008; + private const uint SWP_NOACTIVATE = 0x0010; + private const uint SWP_FRAMECHANGED = 0x0020; + private const uint SWP_SHOWWINDOW = 0x0040; + private const uint SWP_HIDEWINDOW = 0x0080; + private const uint SWP_NOCOPYBITS = 0x0100; + private const uint SWP_NOOWNERZORDER = 0x0200; + private const uint SWP_NOSENDCHANGING = 0x0400; + public static bool SetBevel(this Form form, bool show) + { + foreach (Control c in form.Controls) + { + switch (c) + { + case MdiClient client: + if (client != null) + { + int windowLong = GetWindowLong(c.Handle, GWL_EXSTYLE); + if (show) + { + windowLong |= WS_EX_CLIENTEDGE; + } + else + { + windowLong &= ~WS_EX_CLIENTEDGE; + } + SetWindowLong(c.Handle, GWL_EXSTYLE, windowLong); + // Update the non-client area. + SetWindowPos(client.Handle, IntPtr.Zero, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + return true; + } + break; + } + } + return false; + } + } +} diff --git a/Source/Itrycn_Project/frmSetting.Designer.cs b/Source/Itrycn_Project/frmSetting.Designer.cs new file mode 100644 index 0000000..f50684c --- /dev/null +++ b/Source/Itrycn_Project/frmSetting.Designer.cs @@ -0,0 +1,140 @@ +namespace Itrycn_Project +{ + partial class FrmSetting + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmSetting)); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.chkAutoLogin = new System.Windows.Forms.CheckBox(); + this.btnCancel = new ryControls.ButtonEx(); + this.btnOK = new ryControls.ButtonEx(); + this.ChkAutoRun = new System.Windows.Forms.CheckBox(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Location = new System.Drawing.Point(2, 3); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(628, 430); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.ChkAutoRun); + this.tabPage1.Controls.Add(this.chkAutoLogin); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(620, 404); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "普通"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // chkAutoLogin + // + this.chkAutoLogin.AutoSize = true; + this.chkAutoLogin.Location = new System.Drawing.Point(13, 12); + this.chkAutoLogin.Name = "chkAutoLogin"; + this.chkAutoLogin.Size = new System.Drawing.Size(264, 16); + this.chkAutoLogin.TabIndex = 0; + this.chkAutoLogin.Text = "下次启动软件进行自动登陆(重启软件后生效)"; + this.chkAutoLogin.UseVisualStyleBackColor = true; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.ForeColor = System.Drawing.Color.White; + this.btnCancel.Location = new System.Drawing.Point(541, 443); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(79, 30); + this.btnCancel.TabIndex = 22; + this.btnCancel.Text = "取消"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.ForeColor = System.Drawing.Color.White; + this.btnOK.Location = new System.Drawing.Point(456, 443); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(79, 30); + this.btnOK.TabIndex = 21; + this.btnOK.Text = "保存"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.BtnOK_Click); + // + // ChkAutoRun + // + this.ChkAutoRun.AutoSize = true; + this.ChkAutoRun.Location = new System.Drawing.Point(13, 34); + this.ChkAutoRun.Name = "ChkAutoRun"; + this.ChkAutoRun.Size = new System.Drawing.Size(108, 16); + this.ChkAutoRun.TabIndex = 1; + this.ChkAutoRun.Text = "开机时启动软件"; + this.ChkAutoRun.UseVisualStyleBackColor = true; + // + // FrmSetting + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(630, 485); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.tabControl1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "FrmSetting"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "设置"; + this.Load += new System.EventHandler(this.FrmSetting_Load); + this.Resize += new System.EventHandler(this.FrmSetting_Resize); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.CheckBox chkAutoLogin; + private ryControls.ButtonEx btnCancel; + private ryControls.ButtonEx btnOK; + private System.Windows.Forms.CheckBox ChkAutoRun; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project/frmSetting.cs b/Source/Itrycn_Project/frmSetting.cs new file mode 100644 index 0000000..db4cdf0 --- /dev/null +++ b/Source/Itrycn_Project/frmSetting.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project +{ + public partial class FrmSetting : Form + { + public FrmSetting() + { + InitializeComponent(); + } + + private void FrmSetting_Resize(object sender, EventArgs e) + { + tabControl1.Refresh(); + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + } + + private void BtnOK_Click(object sender, EventArgs e) + { + mySetting.Save(); + ryCommon.RyRegedit.RegRoot = Microsoft.Win32.RegistryHive.CurrentUser; + ryCommon.RyRegedit.SetAutoRun(ChkAutoRun.Checked, Itrycn_Info.Soft_Id, "\"" + Application.ExecutablePath + "\" "+ Itrycn_Info.Soft_Pram); + DialogResult = DialogResult.OK; + } + ryControls.RySetting mySetting = new ryControls.RySetting(); + private void FrmSetting_Load(object sender, EventArgs e) + { + mySetting.FilePath = Itrycn_Info.UserDataFolder + "\\Setting.xml"; + mySetting.Add("AutoLogin", chkAutoLogin,false); + mySetting.Read(); + ryCommon.RyRegedit.RegRoot = Microsoft.Win32.RegistryHive.CurrentUser; + ChkAutoRun.Checked = ryCommon.RyRegedit.IsAutoRun(Itrycn_Info.Soft_Id, "\"" + Application.ExecutablePath + "\" "+ Itrycn_Info.Soft_Pram); + } + } +} diff --git a/Source/Itrycn_Project/frmSetting.resx b/Source/Itrycn_Project/frmSetting.resx new file mode 100644 index 0000000..67eda94 --- /dev/null +++ b/Source/Itrycn_Project/frmSetting.resx @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu+nQCUlIQAfXx1WoaF + eteGhXrXhoV614WEetN7enNGh4d7AHNxbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdFjcAHRY3AB0WNwAdFjcAHRY3AAAAAAA4MkgAZGFlAFpX + XguNjH+2lZWE/5WVhP+VlYT/lZWE/4uKfZ8pIj8EVFFbACkjPwAAAAAAHRY3AB0WNwAdFjcAHRY3AB0W + NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRY3AJiYhgB2dXAAkZCBAGZkZgAzLkUAFQ0yABQM + MQCoqZAAf352WpOTg/eVlYT/lZWE/5WVhP+VlYT/kpGC7nt5c0WQkIEAAAAAAA8ILgAyLEUAaWZoAIWE + egBhXmIAY2BkAB0WNwAAAAAAAAAAAAAAAAAAAAAAAAAAAB0WNwCkpY4AeHZxAGNgZBlzcW5XYV5iKCAZ + OQj///8A////AG5sazaOjX/XlZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/jIt+yGdlZyno7bkA///2ABkS + NAdiX2MqcG1sSExIVQlgXWIAYl9jAB0WNwAAAAAAAAAAAAAAAAAdFjcAo6SNAHh2cQBdWmAXh4Z7qZKR + gvuMjH7ihYR5tX59dpN/fXaUjIx+2pWVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/i4p9z3x6 + dIZ9fHWKhIN5so2Mf+KQkIHzgH93fCkiPwZfXGEAYV5jAB0WNwAAAAAAAAAAAAAAEwB/fnYAYF1iGIaG + e6mUlIP/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lJSD/5SUhP+VlYT/lZWE/5WVhP+SkoL3gH52ejgzSQddWmAAAAAAAAAAAAAAAAAAYl9jAAIA + JgGIiHyOlJSD/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+SkoL3g4J4YJmahwAxK0QAAAAAAAAA + AAB6eHIAoqOMAJOTg3mVlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhPuSkYJXl5eFAD45 + TAAAAAAAAAAAAIB+dgCRkYEAj4+ANJSUhO6VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lJSD/5SUg/+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lJSD2o2N + fxyNjX8ARUBQAAAAAAAAAAAAHRY3AIeGewCIh3sTk5OD0ZWVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+UlIP/lpaF/5ubi/+fn4//n5+P/5qaiv+VlYT/lJSD/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+TkoKzeXdyBXx6dAAAAAAAAAAAAAAAAAAjHTsAcG5sAHd2cQqSkYLDlZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/6Kikv+0tKf/vr6y/8HBtf/BwbX/vb2x/7KypP+fn4//lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/5CQgaH///8AJyE+AB0WNwAAAAAAQj1PACkiPgCMjH4Ac3FuMZGRgeKVlYT/lZWE/5WV + hP+VlYT/lZWE/5aWhf+rq53/wcG1/8XFufzExLjZxMS4t8TEuLvExLjgxcW5/7+/s/+np5f/lZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/j46Ay2ViZRt5d3IAAAAaADAqQwByb20AAAAAAG1qajuKin3FlZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/qama/8PDt//ExLjmw8O4bcPDtxvDw7cGw8O3B8PDtyPDw7iCxMS48cHB + tf+jo5T/lJSD/5WVhP+VlYT/lZWE/5WVhP+UlIP+h4Z7rmRhZCj5/8QAZ2VnAGdlZzN+fXWIjo6A5pWV + hP+VlYT/lZWE/5WVhP+VlYT/lZWE/5ycjP++vrH/xMS47sLCt1LGx7oAw8O3AMPDtwDDw7cAw8O3AAAA + AADCwrdvxcW5+bm5rP+YmIj/lZWE/5WVhP+VlYT/lZWE/5WVhP+UlIT/jIt+2Hp4c3RhXmMkjYx/3pSU + g/+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+UlIP/qama/8TEuP/CwraakpCRAby7sgDAwLUAAAAAACAZ + OQDBwbUAvr2zALm4rwvCwre6w8O3/6OjlP+UlIP/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/k5OD/4uK + fbuTk4PwlZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+zs6X/xMS4+728slPCwrcAv7+0AAAA + AAAAAAAAAAAAAAAAAADb3MoAzc2/AL6+tHbExLj/rKyd/5SUg/+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/kpKC0Zybi+2fno3/n52N/p+djf6fnY3+n52N/p+djf6fnY3+n56N/rm4q//Dw7j2tbWtQLu7 + sQAhGjoAAAAAAAAAAAAAAAAAAAAAAFVQYgDGxroAubmwYcTEuP+zs6X/np2M/p+djf6fnY3+n52N/p+d + jf6fnY3+n52N/p+ejf+bmovPpKKR8aakk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/ubiq/8PD + uPyysapaxMS4AJybmQAdFjcAAAAAAAAAAAAdFjcA////AO7w2QC2tq19xMS4/7W0pf+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6OgkdOkopKgpqST6aakk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + kv+zsqP/xMS4/7a2rqhFQFYHcW14AGhkcQAdFjcAHRY3AIyKjQCIhooAgH2EFLu6scXDw7f/r62e/6ak + kv+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJPlpKKRiqalkwSlo5M1pqSTp6akk/qmpJP/pqST/6ak + k/+mpJP/pqST/6qomP/AwLP/wcC29aOin2kAAAACjYuOAFlVZgBfW2oAmpmYAC8pRQirqaSGw8O3/L29 + r/+oppX/pqST/6akk/+mpJP/pqST/6akk/+mpJP2pqSTmaWjky2oppQDpKKSAKakkwCjoZEJpaOSgaak + k/qmpJP/pqST/6akk/+mpJP/pqST/7Kxov/Dw7f/vr608KakoYyBfoQyXFhoFWFdaxeIhYk8q6qkn8HA + tfjCwrX/r62e/6akk/+mpJP/pqST/6akk/+mpJP/pqST86WjkmyioJAEpqOTAKSikgCal4sApaOSAJ6c + jgCZlooSpKKSzqakk/+mpJP/pqST/6akk/+mpJP/p6WU/7SzpP/Cwrb/w8O3/7q6seq0s6vRtLSs1Ly8 + su/ExLj/wcG0/7GvoP+mpJP/pqST/6akk/+mpJP/pqST/6akk/+joZGrj4yEBKGfkAClo5IAjYuCAAAA + AAAdFjcAgHx5AIJ/ewuioJDEpqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/66snP+6uav/wcCz/8PD + tv/Dw7b/wMCz/7i3qf+sqpr/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6Cdj5f//+8AAAAOAAAA + AAAAAAAAAAAAAB0WNwCLiIEAioeAHaKgkdumpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + lP+pqJf/rKqa/6yqmv+pp5f/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/oJ6Ptmhk + agdtaW0AHRY3AAAAAAAAAAAA/P3NAKOhkQCTkIZLpKKS96akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+ioJDhiYZ/Jo6LgwAdFjcAAAAAAAAAAABhXGUA////AJyajJOmpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6Wjkv6YlopdqKaUAB0WNwAAAAAAAAAAAIB9egDS0rEApKKSUqakk+empJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqSTwqOhkSWoppUAHRY3AAAAAAAAAAAAhIF8AJqYiwCoppQApaOSTqak + k+SmpJP/pqST/6akk/empJPnpqST5qakk/umpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/mmpJPkpqST6aakk/mmpJP/pqST/6akk8KkopImpaOSAK+tmQAdFjcAAAAAAAAAAAAAAAAAoqCQAKKg + kACqqJUApaOSTaakk7+mpJOHpqSTR6akkyampJMkpaOTdaakk/OmpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJPnpaOTYKakkyKmpJMppqSTTqakk5OmpJOspKKSJ6akkwCwr5oAm5mMAAAAAAAAAAAAAAAAAAAA + AAAAAAAAop+QAKKgkAD///8ApaOSDKimlQCmpJMApqSTAKWjkgCNioIBpaOShqakk/+mpJP/pqST/6ak + k/+mpJP/pqST+aSikmeqqJYApaOTAKakkwCmpJMAm5mMAKSikgimpJMAsK+aAJuZjAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAoqCRAKOhkQClo5IApaOSAKSikgB1cnIAo6GRAKKgkQChn5AZpaOSzqak + k/+mpJP/pqST/6akk/+lo5KynpyOCqGfkAChn5AAlZKHAKWjkgClo5IApKKSAJ+djgCcmo0AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdFjcA////AK6s + mACkopJ2pqST+Kakk/ampJP2pqST8qOhkVWnpZMAqKaUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/+AH//BAAg/gAAAHwAAAA4AAAAGAAAABgAAAAYAAAAGAAAABgAAAA4AA + AAEAAAAAAAAAAAAAAAAAAQAAAAPAAAADwAAAAYAAAAAAAAAAAAAAAAAAAAAAAIAAAAOAAAABgAAAAYAA + AAGAAAABgAAAAcAAAAPgAAAH8AAAD//AB/8= + + + \ No newline at end of file diff --git a/Source/Itrycn_Project/frmmain.Designer.cs b/Source/Itrycn_Project/frmmain.Designer.cs new file mode 100644 index 0000000..935d482 --- /dev/null +++ b/Source/Itrycn_Project/frmmain.Designer.cs @@ -0,0 +1,542 @@ +namespace Itrycn +{ + partial class Frmmain + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("系统"); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Frmmain)); + this.pnlTopLogo = new System.Windows.Forms.Panel(); + this.lblTitle = new System.Windows.Forms.Label(); + this.pnlLeft = new System.Windows.Forms.Panel(); + this.picExpand = new System.Windows.Forms.PictureBox(); + this.panel3 = new System.Windows.Forms.Panel(); + this.treeView1 = new System.Windows.Forms.TreeView(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.pnlMenu = new System.Windows.Forms.Panel(); + this.superColor1 = new ryControls.SuperColor(); + this.BtnAbout = new System.Windows.Forms.Button(); + this.btnSetting = new System.Windows.Forms.Button(); + this.menuHomeUrl = new System.Windows.Forms.Button(); + this.panel1 = new System.Windows.Forms.Panel(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.搜索ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.方法ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.是ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); + this.MenuTray = new System.Windows.Forms.ContextMenuStrip(this.components); + this.显示主界面ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.退出ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.chromeTabControl1 = new ryControls.ChromeTabControl(); + this.tabPage7 = new System.Windows.Forms.TabPage(); + this.label1 = new System.Windows.Forms.Label(); + this.tabPage8 = new System.Windows.Forms.TabPage(); + this.chinaCalendar1 = new ryControls.ChinaCalendar(); + this.tabControlEx1 = new ryControls.TabControlEx(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.tabPage3 = new System.Windows.Forms.TabPage(); + this.tabPage4 = new System.Windows.Forms.TabPage(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.tabPage5 = new System.Windows.Forms.TabPage(); + this.tabPage6 = new System.Windows.Forms.TabPage(); + this.lableX1 = new ryControls.Controls.LableX(); + this.pnlTopLogo.SuspendLayout(); + this.pnlLeft.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picExpand)).BeginInit(); + this.pnlMenu.SuspendLayout(); + this.contextMenuStrip1.SuspendLayout(); + this.MenuTray.SuspendLayout(); + this.chromeTabControl1.SuspendLayout(); + this.tabPage7.SuspendLayout(); + this.tabControlEx1.SuspendLayout(); + this.SuspendLayout(); + // + // pnlTopLogo + // + this.pnlTopLogo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(125)))), ((int)(((byte)(182))))); + this.pnlTopLogo.Controls.Add(this.lblTitle); + this.pnlTopLogo.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTopLogo.Location = new System.Drawing.Point(0, 0); + this.pnlTopLogo.Name = "pnlTopLogo"; + this.pnlTopLogo.Size = new System.Drawing.Size(1393, 59); + this.pnlTopLogo.TabIndex = 6; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblTitle.ForeColor = System.Drawing.Color.White; + this.lblTitle.Location = new System.Drawing.Point(25, 21); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(110, 16); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "睿元管理系统"; + // + // pnlLeft + // + this.pnlLeft.Controls.Add(this.picExpand); + this.pnlLeft.Controls.Add(this.panel3); + this.pnlLeft.Controls.Add(this.treeView1); + this.pnlLeft.Dock = System.Windows.Forms.DockStyle.Left; + this.pnlLeft.Location = new System.Drawing.Point(0, 89); + this.pnlLeft.Name = "pnlLeft"; + this.pnlLeft.Size = new System.Drawing.Size(200, 714); + this.pnlLeft.TabIndex = 8; + // + // picExpand + // + this.picExpand.Cursor = System.Windows.Forms.Cursors.Hand; + this.picExpand.Image = global::Itrycn_Project.Properties.Resources.closetree; + this.picExpand.Location = new System.Drawing.Point(187, 247); + this.picExpand.Name = "picExpand"; + this.picExpand.Size = new System.Drawing.Size(10, 49); + this.picExpand.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.picExpand.TabIndex = 8; + this.picExpand.TabStop = false; + this.picExpand.Click += new System.EventHandler(this.PicExpand_Click); + // + // panel3 + // + this.panel3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(125)))), ((int)(((byte)(182))))); + this.panel3.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel3.Location = new System.Drawing.Point(0, 697); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(200, 17); + this.panel3.TabIndex = 7; + // + // treeView1 + // + this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.treeView1.BackColor = System.Drawing.Color.White; + this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.treeView1.Font = new System.Drawing.Font("宋体", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.treeView1.ForeColor = System.Drawing.Color.Black; + this.treeView1.FullRowSelect = true; + this.treeView1.HideSelection = false; + this.treeView1.ImageIndex = 5; + this.treeView1.ImageList = this.imageList1; + this.treeView1.ItemHeight = 20; + this.treeView1.LineColor = System.Drawing.Color.Silver; + this.treeView1.Location = new System.Drawing.Point(3, 6); + this.treeView1.Name = "treeView1"; + treeNode2.ImageKey = "system.png"; + treeNode2.Name = "节点0"; + treeNode2.Text = "系统"; + this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] { + treeNode2}); + this.treeView1.SelectedImageIndex = 5; + this.treeView1.ShowNodeToolTips = true; + this.treeView1.Size = new System.Drawing.Size(181, 684); + this.treeView1.TabIndex = 3; + this.treeView1.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.TreeView1_BeforeSelect); + this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.TreeView1_AfterSelect); + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "news.png"); + this.imageList1.Images.SetKeyName(1, "help.png"); + this.imageList1.Images.SetKeyName(2, "system.png"); + this.imageList1.Images.SetKeyName(3, "type.png"); + this.imageList1.Images.SetKeyName(4, "item.png"); + this.imageList1.Images.SetKeyName(5, "selected.png"); + // + // pnlMenu + // + this.pnlMenu.Controls.Add(this.superColor1); + this.pnlMenu.Controls.Add(this.BtnAbout); + this.pnlMenu.Controls.Add(this.btnSetting); + this.pnlMenu.Controls.Add(this.menuHomeUrl); + this.pnlMenu.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlMenu.Location = new System.Drawing.Point(0, 59); + this.pnlMenu.Name = "pnlMenu"; + this.pnlMenu.Size = new System.Drawing.Size(1393, 30); + this.pnlMenu.TabIndex = 9; + // + // superColor1 + // + this.superColor1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.superColor1.Cursor = System.Windows.Forms.Cursors.Hand; + this.superColor1.Location = new System.Drawing.Point(307, 6); + this.superColor1.Name = "superColor1"; + this.superColor1.Size = new System.Drawing.Size(73, 22); + this.superColor1.TabIndex = 16; + // + // BtnAbout + // + this.BtnAbout.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.BtnAbout.FlatAppearance.BorderSize = 0; + this.BtnAbout.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(102)))), ((int)(((byte)(153))))); + this.BtnAbout.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.BtnAbout.ForeColor = System.Drawing.SystemColors.ControlText; + this.BtnAbout.Location = new System.Drawing.Point(154, 6); + this.BtnAbout.Name = "BtnAbout"; + this.BtnAbout.Size = new System.Drawing.Size(68, 20); + this.BtnAbout.TabIndex = 15; + this.BtnAbout.Text = "关于"; + this.BtnAbout.UseVisualStyleBackColor = true; + this.BtnAbout.Click += new System.EventHandler(this.BtnAbout_Click); + // + // btnSetting + // + this.btnSetting.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.btnSetting.FlatAppearance.BorderSize = 0; + this.btnSetting.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(102)))), ((int)(((byte)(153))))); + this.btnSetting.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnSetting.ForeColor = System.Drawing.SystemColors.ControlText; + this.btnSetting.Location = new System.Drawing.Point(79, 6); + this.btnSetting.Name = "btnSetting"; + this.btnSetting.Size = new System.Drawing.Size(68, 20); + this.btnSetting.TabIndex = 14; + this.btnSetting.Text = "软件设置"; + this.btnSetting.UseVisualStyleBackColor = true; + this.btnSetting.Click += new System.EventHandler(this.BtnSetting_Click); + // + // menuHomeUrl + // + this.menuHomeUrl.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.menuHomeUrl.FlatAppearance.BorderSize = 0; + this.menuHomeUrl.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(102)))), ((int)(((byte)(153))))); + this.menuHomeUrl.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.menuHomeUrl.ForeColor = System.Drawing.SystemColors.ControlText; + this.menuHomeUrl.Location = new System.Drawing.Point(4, 6); + this.menuHomeUrl.Name = "menuHomeUrl"; + this.menuHomeUrl.Size = new System.Drawing.Size(68, 20); + this.menuHomeUrl.TabIndex = 13; + this.menuHomeUrl.Text = "访问官网"; + this.menuHomeUrl.UseVisualStyleBackColor = true; + this.menuHomeUrl.Click += new System.EventHandler(this.MenuHomeUrl_Click); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(125)))), ((int)(((byte)(182))))); + this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel1.Location = new System.Drawing.Point(200, 786); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(1193, 17); + this.panel1.TabIndex = 10; + // + // timer1 + // + this.timer1.Interval = 1000; + this.timer1.Tick += new System.EventHandler(this.Timer1_Tick); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.搜索ToolStripMenuItem, + this.方法ToolStripMenuItem, + this.是ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(101, 70); + // + // 搜索ToolStripMenuItem + // + this.搜索ToolStripMenuItem.Name = "搜索ToolStripMenuItem"; + this.搜索ToolStripMenuItem.Size = new System.Drawing.Size(100, 22); + this.搜索ToolStripMenuItem.Text = "搜索"; + // + // 方法ToolStripMenuItem + // + this.方法ToolStripMenuItem.Name = "方法ToolStripMenuItem"; + this.方法ToolStripMenuItem.Size = new System.Drawing.Size(100, 22); + this.方法ToolStripMenuItem.Text = "方法"; + // + // 是ToolStripMenuItem + // + this.是ToolStripMenuItem.Name = "是ToolStripMenuItem"; + this.是ToolStripMenuItem.Size = new System.Drawing.Size(100, 22); + this.是ToolStripMenuItem.Text = "是"; + // + // notifyIcon1 + // + this.notifyIcon1.ContextMenuStrip = this.MenuTray; + this.notifyIcon1.Visible = true; + // + // MenuTray + // + this.MenuTray.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.显示主界面ToolStripMenuItem, + this.退出ToolStripMenuItem}); + this.MenuTray.Name = "MenuTray"; + this.MenuTray.Size = new System.Drawing.Size(137, 48); + // + // 显示主界面ToolStripMenuItem + // + this.显示主界面ToolStripMenuItem.Name = "显示主界面ToolStripMenuItem"; + this.显示主界面ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.显示主界面ToolStripMenuItem.Text = "显示主界面"; + this.显示主界面ToolStripMenuItem.Click += new System.EventHandler(this.显示主界面ToolStripMenuItem_Click); + // + // 退出ToolStripMenuItem + // + this.退出ToolStripMenuItem.Name = "退出ToolStripMenuItem"; + this.退出ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.退出ToolStripMenuItem.Text = "退出"; + this.退出ToolStripMenuItem.Click += new System.EventHandler(this.退出ToolStripMenuItem_Click); + // + // chromeTabControl1 + // + this.chromeTabControl1.AllowDragTab = false; + this.chromeTabControl1.BackTabPageImage = null; + this.chromeTabControl1.Controls.Add(this.tabPage7); + this.chromeTabControl1.Controls.Add(this.tabPage8); + this.chromeTabControl1.Cursor = System.Windows.Forms.Cursors.Default; + this.chromeTabControl1.ImageList = this.imageList1; + this.chromeTabControl1.ItemSize = new System.Drawing.Size(150, 25); + this.chromeTabControl1.Location = new System.Drawing.Point(310, 110); + this.chromeTabControl1.Name = "chromeTabControl1"; + this.chromeTabControl1.SelectedIndex = 0; + this.chromeTabControl1.ShowAddButton = true; + this.chromeTabControl1.ShowCloseButton = true; + this.chromeTabControl1.Size = new System.Drawing.Size(521, 368); + this.chromeTabControl1.SizeMode = System.Windows.Forms.TabSizeMode.Fixed; + this.chromeTabControl1.TabContextMenuStrip = null; + this.chromeTabControl1.TabIndex = 14; + this.chromeTabControl1.TabMaxWidth = 150; + this.chromeTabControl1.TabOffColorEnd = System.Drawing.Color.Gainsboro; + this.chromeTabControl1.TabOffColorStart = System.Drawing.Color.White; + // + // tabPage7 + // + this.tabPage7.Controls.Add(this.lableX1); + this.tabPage7.Controls.Add(this.label1); + this.tabPage7.ImageIndex = 0; + this.tabPage7.Location = new System.Drawing.Point(1, 29); + this.tabPage7.Name = "tabPage7"; + this.tabPage7.Padding = new System.Windows.Forms.Padding(3); + this.tabPage7.Size = new System.Drawing.Size(519, 338); + this.tabPage7.TabIndex = 0; + this.tabPage7.Text = "这是一个好人的abv充电"; + this.tabPage7.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(160, 62); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(41, 12); + this.label1.TabIndex = 0; + this.label1.Text = "label1"; + // + // tabPage8 + // + this.tabPage8.Location = new System.Drawing.Point(1, 29); + this.tabPage8.Name = "tabPage8"; + this.tabPage8.Padding = new System.Windows.Forms.Padding(3); + this.tabPage8.Size = new System.Drawing.Size(519, 338); + this.tabPage8.TabIndex = 1; + this.tabPage8.Text = "tabPage8"; + this.tabPage8.UseVisualStyleBackColor = true; + // + // chinaCalendar1 + // + this.chinaCalendar1.BackColor = System.Drawing.Color.White; + this.chinaCalendar1.DateTime = new System.DateTime(2019, 2, 9, 10, 54, 20, 495); + this.chinaCalendar1.HolidayFolder = "E:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\IDE\\SysDb\\" + + "Holidays"; + this.chinaCalendar1.Location = new System.Drawing.Point(261, 133); + this.chinaCalendar1.Name = "chinaCalendar1"; + this.chinaCalendar1.Size = new System.Drawing.Size(851, 509); + this.chinaCalendar1.TabIndex = 12; + // + // tabControlEx1 + // + this.tabControlEx1.Controls.Add(this.tabPage1); + this.tabControlEx1.Controls.Add(this.tabPage3); + this.tabControlEx1.Controls.Add(this.tabPage4); + this.tabControlEx1.Controls.Add(this.tabPage2); + this.tabControlEx1.Controls.Add(this.tabPage5); + this.tabControlEx1.Controls.Add(this.tabPage6); + this.tabControlEx1.ItemSize = new System.Drawing.Size(0, 1); + this.tabControlEx1.Location = new System.Drawing.Point(200, 200); + this.tabControlEx1.Name = "tabControlEx1"; + this.tabControlEx1.SelectedIndex = 0; + this.tabControlEx1.Size = new System.Drawing.Size(400, 191); + this.tabControlEx1.TabBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(233)))), ((int)(((byte)(233)))), ((int)(((byte)(233))))); + this.tabControlEx1.TabBackground = null; + this.tabControlEx1.TabIndex = 77; + // + // tabPage1 + // + this.tabPage1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(233)))), ((int)(((byte)(233)))), ((int)(((byte)(233))))); + this.tabPage1.Location = new System.Drawing.Point(4, 5); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(392, 182); + this.tabPage1.TabIndex = 0; + this.tabPage1.Tag = 0; + this.tabPage1.Text = "tabPage1"; + // + // tabPage3 + // + this.tabPage3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(233)))), ((int)(((byte)(233)))), ((int)(((byte)(233))))); + this.tabPage3.Location = new System.Drawing.Point(4, 5); + this.tabPage3.Name = "tabPage3"; + this.tabPage3.Padding = new System.Windows.Forms.Padding(3); + this.tabPage3.Size = new System.Drawing.Size(392, 182); + this.tabPage3.TabIndex = 2; + this.tabPage3.Tag = 0; + this.tabPage3.Text = "tabPage3"; + // + // tabPage4 + // + this.tabPage4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(233)))), ((int)(((byte)(233)))), ((int)(((byte)(233))))); + this.tabPage4.Location = new System.Drawing.Point(4, 5); + this.tabPage4.Name = "tabPage4"; + this.tabPage4.Padding = new System.Windows.Forms.Padding(3); + this.tabPage4.Size = new System.Drawing.Size(392, 182); + this.tabPage4.TabIndex = 3; + this.tabPage4.Tag = 0; + this.tabPage4.Text = "tabPage4"; + // + // tabPage2 + // + this.tabPage2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(233)))), ((int)(((byte)(233)))), ((int)(((byte)(233))))); + this.tabPage2.Location = new System.Drawing.Point(4, 5); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(392, 182); + this.tabPage2.TabIndex = 1; + this.tabPage2.Tag = 0; + this.tabPage2.Text = "tabPage2"; + // + // tabPage5 + // + this.tabPage5.Location = new System.Drawing.Point(4, 5); + this.tabPage5.Name = "tabPage5"; + this.tabPage5.Padding = new System.Windows.Forms.Padding(3); + this.tabPage5.Size = new System.Drawing.Size(392, 182); + this.tabPage5.TabIndex = 4; + this.tabPage5.Tag = 0; + this.tabPage5.Text = "tabPage5"; + this.tabPage5.UseVisualStyleBackColor = true; + // + // tabPage6 + // + this.tabPage6.Location = new System.Drawing.Point(4, 5); + this.tabPage6.Name = "tabPage6"; + this.tabPage6.Padding = new System.Windows.Forms.Padding(3); + this.tabPage6.Size = new System.Drawing.Size(392, 182); + this.tabPage6.TabIndex = 5; + this.tabPage6.Tag = 0; + this.tabPage6.Text = "tabPage6"; + this.tabPage6.UseVisualStyleBackColor = true; + // + // lableX1 + // + this.lableX1.AutoSize = true; + this.lableX1.Location = new System.Drawing.Point(137, 141); + this.lableX1.Name = "lableX1"; + this.lableX1.Size = new System.Drawing.Size(47, 12); + this.lableX1.TabIndex = 1; + this.lableX1.Text = "lableX1"; + this.lableX1.DoubleClick += new System.EventHandler(this.lableX1_DoubleClick); + // + // Frmmain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(1393, 803); + this.Controls.Add(this.chromeTabControl1); + this.Controls.Add(this.chinaCalendar1); + this.Controls.Add(this.panel1); + this.Controls.Add(this.pnlLeft); + this.Controls.Add(this.pnlMenu); + this.Controls.Add(this.pnlTopLogo); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.IsMdiContainer = true; + this.Name = "Frmmain"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "睿元管理系统"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Frmmain_FormClosing); + this.Load += new System.EventHandler(this.Frmmain_Load); + this.Shown += new System.EventHandler(this.Frmmain_Shown); + this.Resize += new System.EventHandler(this.Frmmain_Resize); + this.pnlTopLogo.ResumeLayout(false); + this.pnlTopLogo.PerformLayout(); + this.pnlLeft.ResumeLayout(false); + this.pnlLeft.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picExpand)).EndInit(); + this.pnlMenu.ResumeLayout(false); + this.contextMenuStrip1.ResumeLayout(false); + this.MenuTray.ResumeLayout(false); + this.chromeTabControl1.ResumeLayout(false); + this.tabPage7.ResumeLayout(false); + this.tabPage7.PerformLayout(); + this.tabControlEx1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel pnlTopLogo; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.Panel pnlLeft; + private System.Windows.Forms.PictureBox picExpand; + private System.Windows.Forms.Panel panel3; + public System.Windows.Forms.TreeView treeView1; + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.Panel pnlMenu; + private System.Windows.Forms.Button menuHomeUrl; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button btnSetting; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.Button BtnAbout; + private ryControls.TabControlEx tabControlEx1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.TabPage tabPage4; + private System.Windows.Forms.TabPage tabPage5; + private System.Windows.Forms.TabPage tabPage6; + private ryControls.SuperColor superColor1; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 搜索ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 方法ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 是ToolStripMenuItem; + private ryControls.ChinaCalendar chinaCalendar1; + private System.Windows.Forms.NotifyIcon notifyIcon1; + private System.Windows.Forms.ContextMenuStrip MenuTray; + private System.Windows.Forms.ToolStripMenuItem 显示主界面ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 退出ToolStripMenuItem; + private ryControls.ChromeTabControl chromeTabControl1; + private System.Windows.Forms.TabPage tabPage7; + private System.Windows.Forms.TabPage tabPage8; + private System.Windows.Forms.Label label1; + private ryControls.Controls.LableX lableX1; + } +} + diff --git a/Source/Itrycn_Project/frmmain.cs b/Source/Itrycn_Project/frmmain.cs new file mode 100644 index 0000000..fefbab0 --- /dev/null +++ b/Source/Itrycn_Project/frmmain.cs @@ -0,0 +1,275 @@ +using Itrycn_Project; +using ryCommon; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn +{ + public partial class Frmmain : Form + { + string[] prog_args; + public Frmmain(string[] args) + { + InitializeComponent(); + prog_args = args; + } + public TreeNode AddToTreeView(TreeNode parent, Type id, string text, string imageKey) + { + return AddToTreeView(parent, id, text, imageKey, ""); + } + public TreeNode AddToTreeView(TreeNode parent, Type id, string text, string imageKey, string ToolTipText) + { + TreeNode btn = new TreeNode() + { + SelectedImageKey = "selected.ico", + ImageKey = imageKey, + Text = text, + Tag = id, + ToolTipText = ToolTipText + }; + parent.Nodes.Add(btn); + return btn; + } + Dictionary dict_form = new Dictionary(); + /// + /// 显示子窗体 + /// + /// + /// + public Form ShowForm(Type type) + { + if (this.ActiveMdiChild != null) + { + if (this.ActiveMdiChild.GetType() == type) { return this.ActiveMdiChild; } + } + if (dict_form.ContainsKey(type)) + { + dict_form[type].Show(); + dict_form[type].BringToFront(); + return dict_form[type]; + } + else + { + Form frm = (Form)Activator.CreateInstance(type); + frm.Icon = Icon; + frm.MdiParent = this; + frm.BackColor = Color.White; + frm.FormBorderStyle = FormBorderStyle.None; + frm.Dock = DockStyle.Fill;//完全填充到应用程序 + //frm.WindowState = FormWindowState.Maximized; + frm.Show(); + dict_form.Add(type, frm); + return frm; + } + } + DateTime dt_lastupdate = DateTime.Now; + protected override void WndProc(ref System.Windows.Forms.Message msg) + { + switch (msg.Msg) + { + case 17189: //处理消息 + { + #region 激活窗体 + switch (msg.WParam.ToInt32()) + { + case 100:// + #region 显示界面 + if ((int)msg.LParam.ToInt32() == 100) + { + this.WindowState = FormWindowState.Normal; + this.Top = (Screen.PrimaryScreen.WorkingArea.Height - this.Height) / 2; + this.Left = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2; + //RyForm.SetActiveWindow(Handle); + RyForm.BringToTop(Handle); + } + #endregion + break; + } + #endregion + } + break; + default: + base.WndProc(ref msg);//调用基类函数处理非自定义消息。 + break; + } + } + SysFuns.WinHotReg winHotKey; + private void WinHotKey_OnHotkey(int HotKeyID) + { + switch (HotKeyID) + { + case 101: + MessageBox.Show("这是一个测试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + break; + } + } + private void Frmmain_Load(object sender, EventArgs e) + { + ChinaDate.GetYear(2020,2,1); + winHotKey = new SysFuns.WinHotReg(Handle); + winHotKey.RegHotKey(101, SysFuns.KeyModifiers.Alt, Keys.F11); + winHotKey.OnHotkey += WinHotKey_OnHotkey; + string txt = RyFiles.ReadAllText(@"E:\我的代码\毕方项目\C#\当游自动同步系统\Bin\Debug\AutoCutCopy\del.txt"); + //System.Drawing.Imaging.ImageCodecInfo[] encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); + //for (int j = 0; j < encoders.Length; ++j) + //{ + // MessageBox.Show(encoders[j].MimeType); + //} + //ctMsgList1.AddItem("(" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ")", list); + //ctMsgList1.AddItem("(" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ")", list); + Itrycn_Info.OnLeftTreeAdd(this); + //MessageBox.Show(ChinaDate.Get3Fu(2019, 2).ToString()); + //object mainHandle = ryCommon.Model.ryMemoryShare.ReadFromMemory(1024, typeof(string), "3H3BrowserHandle"); + //MessageBox.Show(mainHandle.ToString()); + isExpand = false; + PicExpand_Click(picExpand,new EventArgs()); + Text = Itrycn_Info.Soft_Title+ " V" + ryCommon.RySoft.VersionStr; + notifyIcon1.Icon = this.Icon; + notifyIcon1.Text = Itrycn_Info.Soft_Title; + lblTitle.Text = Itrycn_Info.Soft_Title; + picExpand.Left = treeView1.Left + treeView1.Width + 1; + pnlLeft.Width = picExpand.Left + picExpand.Width + 1; + picExpand.Top = (pnlLeft.Height - picExpand.Height) / 2; + treeView1.ExpandAll(); + this.SetBevel(false); + dt_lastupdate = DateTime.Now; + LiveUpdate.RyUpdate update = new LiveUpdate.RyUpdate(Itrycn_Info.Update_Url); + update.CheckUpdate(); + treeView1.SelectedNode = treeView1.Nodes[0].Nodes[0]; + foreach (Control ctl in this.Controls) + { + try + { + switch(ctl) + { + case MdiClient ctlMDI: + ctlMDI.BackColor = this.BackColor; + break; + } + } + catch (InvalidCastException) + { + } + } + timer1.Enabled = true; + } + + bool isExpand = true; + private void TreeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e) + { + if (e.Node.Tag == null) { e.Cancel = true; return; } + if (!Itrycn_Info.isCanCloseForm) { e.Cancel = true; return; } + } + + private void TreeView1_AfterSelect(object sender, TreeViewEventArgs e) + { + if (e.Node.Tag == null) { return; } + Itrycn_Info.OnTreeClick(this, e); + } + + private void PicExpand_Click(object sender, EventArgs e) + { + if (isExpand) + { + picExpand.Image = Itrycn_Project.Properties.Resources.opentree; + toolTip1.SetToolTip(picExpand,"展开列表"); + treeView1.Visible = false; + picExpand.Left = 0; + pnlLeft.Width = picExpand.Width; + } + else + { + picExpand.Image = Itrycn_Project.Properties.Resources.closetree; + toolTip1.SetToolTip(picExpand, "关闭列表"); + treeView1.Visible = true; + picExpand.Left = treeView1.Left + treeView1.Width + 1; + pnlLeft.Width = picExpand.Left + picExpand.Width + 1; + } + isExpand = !isExpand; + } + + private void Frmmain_Resize(object sender, EventArgs e) + { + picExpand.Top = (pnlLeft.Height - picExpand.Height) / 2; + } + private void MenuHomeUrl_Click(object sender, EventArgs e) + { + ryCommon.RyFiles.OpenUrl(Itrycn_Info.Soft_Url); + } + + private void BtnSetting_Click(object sender, EventArgs e) + { + FrmSetting frm = new FrmSetting(); + if(frm.ShowDialog()==DialogResult.OK) + { + Itrycn_Info.LoadSetting(); + } + } + + private void Timer1_Tick(object sender, EventArgs e) + { + if (dt_lastupdate.AddMinutes(30) < DateTime.Now) + { + dt_lastupdate = DateTime.Now; + LiveUpdate.RyUpdate update = new LiveUpdate.RyUpdate(Itrycn_Info.Update_Url); + update.CheckUpdate(); + } + } + + private void BtnAbout_Click(object sender, EventArgs e) + { + FrmAbout frm = new FrmAbout(); + frm.ShowDialog(); + } + + private void Frmmain_FormClosing(object sender, FormClosingEventArgs e) + { + if (!Itrycn_Info.isCanCloseForm) + { + e.Cancel = true; + MessageBox.Show("当前还有操作正在运行,请稍后关闭软件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + private void Frmmain_Shown(object sender, EventArgs e) + { + ryCommon.Ini ini = new Ini(Itrycn_Info.UserDataFolder + "\\Win.dat"); + ini.WriteIni(Itrycn_Info.Soft_Id, "hwnd", Handle.ToInt32()); + if (prog_args.Length >= 1) + { + if (prog_args[0] ==Itrycn_Info.Soft_Pram) + this.Hide(); + } + } + + private void 退出ToolStripMenuItem_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void 显示主界面ToolStripMenuItem_Click(object sender, EventArgs e) + { + this.WindowState = FormWindowState.Normal; + this.Top = (Screen.PrimaryScreen.WorkingArea.Height - this.Height) / 2; + this.Left = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2; + RyForm.Show(this); + } + + private void buttonEx2_Click(object sender, EventArgs e) + { + ryControls.Skin.SkinCommon.ButtonSkin.BackColor = Color.Red; + } + + private void lableX1_DoubleClick(object sender, EventArgs e) + { + MessageBox.Show("这是一个测试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } +} diff --git a/Source/Itrycn_Project/frmmain.resx b/Source/Itrycn_Project/frmmain.resx new file mode 100644 index 0000000..5370dff --- /dev/null +++ b/Source/Itrycn_Project/frmmain.resx @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADO + EgAAAk1TRnQBSQFMAgEBBgEAAagBBwGoAQcBEAEAARABAAT/AREBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABIAMAAQEBAAEQBgABEJ4AAf8BfwGcAXMBewFvAf8BfxoAAf8BfwG1AVYBMQFGAd4Be1IAAb0BdwG1 + AVYBjAExAXMBTgG1AVYBrQE1AVIBSgGcAXMB/wF/FAAB/wF/AYQBEAIAAecBHAG9AXdKAAH/AX8BewFv + ATEBRgHOATkBGAFjAd4BewHeAXsBvQF3Af8BfwFaAWsBEAFCAe8BPQE5AWcB/wF/EgABnAFzAYQBEAIA + AYQBEAGcAXNGAAEYAWMBEAFCAXMBTgGcAXMB/wF/AZwBcwExAUYBKQElASkBJQHOATkBWgFrAf8BfwG9 + AXcBtQFWAe8BPQHWAVoSAAG9AXcBxgEYAgABQgEIAVoBa0QAASkBJQFSAUoBvQF3ARgBYwFrAS0BawEt + AfcBXgH/AX8B/wF/AVoBawGtATUBSgEpAbUBVgG9AXcB1gFaAQgBIRQAAf8BfwGMATEEAAE5AWdCAAG9 + AXcBSgEpAecBHAEQAUIBnAFzAgAB/wF/ATkBZwH3AV4B/wF/AgABvQF3AXMBTgEIASEB5wEcAXsBbwHe + AXsBGAFjAfcBXgH3AV4B9wFeAfcBXgH3AV4B9wFeAfcBXgH3AV4BGAFjAZQBUgEhAQQEAAEYAWNAAAEp + ASUBUgFKAd4BewIAAd4BewGUAVIBSgEpAc4BOQEQAUIBKQElAVIBSgG9AXcCAAH/AX8B1gFaAQgBIQHG + ARgcAAEhAQRAAAE5AWcBEAFCAVIBSgHvAT0BKQElAXMBTgG9AXcEAAHeAXsBtQFWAUoBKQGtATUBcwFO + ARABQgH3AV4BGAFjAYwBMQFKASkBawEtAWsBLQFrAS0BawEtAWsBLQFrAS0BawEtAWsBLQGMATEBIQEE + BAABrQE1QAABnAFzARABQgGtATUBGAFjAf8BfwwAAf8BfwFaAWsB7wE9Ac4BOQF7AW8UAAH/AX8BlAFS + BAABzgE5Af8Bf0AAAcYBGAEQAUIB/wF/FAAB/wF/AdYBWgHGARgSAAH/AX8BMQFGBAABMQFGAf8Bf0IA + Ab0BdwGUAVIBzgE5AbUBVgG9AXcMAAHeAXsB9wFeAc4BOQFSAUoBnAFzEAAB/wF/Aa0BNQQAAZQBUgH/ + AX9IAAHeAXsB9wFeAc4BOQEQAUIBWgFrAf8BfwH/AX8BnAFzAVIBSgGtATUBtQFWAb0BdxIAAf8BfwGM + ATEEAAH3AV5QAAH/AX8BewFvATEBRgGtATUBzgE5Ae8BPQFaAWsB/wF/FgAB/wF/AQgBIQFCAQgBOQFn + WAAB3gF7Ad4Bex4AAf8BfwHeAXvSAAH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/ + AX8MAAH/AX8B3QF7AZcBawGSAWMBbwFfAW8BXwGSAWMBlwFvAd0BewH/AX8OAAGdAXMBlwFCAbMBHQGT + ARkBkwEZAZMBGQEVATIBOwFfAf8BfwYAAf8BfwExAUYBawEtAWsBLQGMATEBjAExAWsBLQGMATEBjAEx + AWsBLQFrAS0BjAExAWsBLQFrAS0BjAExAVoBawQAAf8BfwHeAXsBmwF3AVgBcwE2AXMBFQFzARUBcwE2 + AXMBWAFzAZsBdwHeAXsB/wF/CAAB/wF/AbkBbwFxAV8BbwFfAW8BXwFvAV8BbwFfAW8BXwFvAV8BcQFj + AbkBbwH/AX8IAAH/AX8BGgFbAZMBGQH0ASkBGgFfAZcBQgGzAR0BOwFjAXcBPgGTARkCNgHeAXsEAAHe + AXsBKQElAfcBXgF7AW8B1gFaAXMBTgF7AW8BGAFjAVIBSgF7AW8BWgFrATEBRgF7AW8BewFvAYwBMQG1 + AVYCAAH/AX8BmwF3AY8BdgEoAX4BBQF+AQUBfgEFAX4BBQF+AQUBfgEFAX4BKAF6AY8BdgGbAXcB/wF/ + BAAB/wF/AZYBawFvAV8BbwFfAW8BXwFwAV8BlgFrAZUBawFwAV8BbwFfAW8BXwFvAV8BlgFrAf8BfwYA + AfoBVgGTARkB+QFSAf8BfwIAARoBVwGTARkEAAGdAW8BswEdARUBLgH/AX8CAAHeAXsBawEtAb0BdwIA + Ab0BdwF7AW8CAAHeAXsBGAFjBAAB9wFeBAABMQFGAbUBVgIAAb0BewFrAXoB5QF5AeYBcQHlAXkBBQF+ + AeYBdQHmAXEBBgF+AeYBeQHnAXEB5gF1AWsBegG9AXsCAAH/AX8BuAJvAV8BbwFfAW8BXwFvAV8BlQFr + Af8BfwH/AX8BlQFnAW8BXwFvAV8BbwFfAW8BXwG5AW8B/wF/AgABvQFzAZMBGQH5AVYGAAF8AWsB2QFO + Af8BfwQAAb4BdwGTARkBuAFKAgAB3gF7AWsBLQFaAWsB3gF7ATkBZwH3AV4B3gJ7AW8BtQFWAd4BewG9 + AXcBlAFSAd4BewHeAXsB7wE9AdYBWgH/AX8BFQF3AQYBfgFsAXoBNgF7AWwBegEGAX4B8gF6ATUBewEn + AX4BawF6AVcBewHQAXoBBgF+ARUBdwH/AX8B3QF3AXEBXwFvAV8BbwFfAW8BXwFvAV8BcAFfAZcBbwGX + AW8BcAFfAW8BXwFvAV8BbwFfAW8BXwFxAWMB3QF7Af8BfwF3AT4BFQEuAf8BfxIAATsBXwGTARkBvgF3 + Ad4BewFrAS0BcwFOARgBYwFzAU4BMQFGARgBYwG1AVYB7wE9ARgBYwHWAVoB7wE9AfcBXgH3AV4BawEt + AdYBWgH/AX8BjgF6AQYBfgGvAX4BmgF/Aa4BfgEoAXYBmgF/AVcBfwEHAX4BsAF6Ad0BfwHxAX4BBgF+ + AY4BegH/AX8BlwFrAW8BXwFvAV8BbwFfAW8BXwFvAV8BcAFfAbkBbwGYAm8BXwFvAV8BbwFfAW8BXwFv + AV8BbwFfAZcBbwG9AXMBkwEZAVwBZxQAAf8BfwGzAR0BGgFbAd4BewFrAS0BvQF3AgABnAFzAVoBawIA + Ad4BewEYAWMCAAH/AX8B9wFeBAABMQFGAbUBVgHeAXsBawF+AQcBfgEnAX4BSQF6AQcBcgHzAXYB3QF/ + AfEBfgEHAXoBNgF7Ad0BfwGuAX4BBgF+AWsBfgHeAXsBcQFjAW8BXwFvAV8BbwFfAW8BXwFvAV8BcQFj + Af4BfwHeAXsBkQFjAW8BXwFvAV8BbwFfAW8BXwFvAV8BkgFjATsBYwGTARkBnQFvAd4BewH/AX8MAAH/ + AX8B3wF7Ad4BewI2AXcBPgHeAXsBawEtAZwBcwH/AX8BewFvATkBZwH/AX8BvQF3AdYBWgH/AX8B3gF7 + AbUBVgH/AX8B/wF/ARABQgHWAVoBvQF7AUoBfgEnAX4BKQF2AUwBbgE2AXcB/gF/AXgBfwEoAX4BbAF2 + Ad0BfwGbAX8BSQF+AScBfgFKAX4BvQF7AW8BXwFvAV8BbwFfAW8BXwFvAV8BbwFfAXABXwHdAXcB/wF/ + AdwBdwGTAWcBbwFfAW8BXwFvAV8BbwFfAW8BXwH6AVYBkwEZAZMBGQGTARkBfAFvDAAB/wF/AfQBKQGT + ARkBkwEZAVYBOgHeAXsBawEtAZQBUgEYAWMBcwFOATEBRgEYAWMBtQFWARABQgEYAWMB9wFeAe8BPQEY + AWMBGAFjAWsBLQHWAVoBvQF7AUoBfgEnAX4BFAF/Af8BfwH/AX8BeAF/AWoBfgEIAXYBWAF7Af8BfwET + AX8BJwF+AScBfgFKAX4BvQF7AW8BXwFvAV8BbwFfAW8BXwFvAV8BcAFfAW8BXwGTAWcB3QF3Af8BfwHe + AXsBkwFnAW8BXwFvAV8BbwFfAW8BXwEaAVsBkwEZAdkBUgEaAVsB3gF3DAAB/wF/ATsBYwEaAVsBFQEq + AXcBPgHeAXsBawEtAb0BdwIAAZwBcwFaAWsCAAHeAXsBGAFjAgAB/wF/AfcBXgQAATEBRgHWAVoBvQF7 + AUoBfgEoAX4B8QF+ATUBfwGvAX4BKAF6AQkBcgE2AXcB/wF/AZkBfwFKAX4BJwF+ASgBfgFKAX4BvQF7 + AXEBYwFvAV8BbwFfAW8BXwGXAWsB3QF7AZQBZwFvAV8BcAFjAd0BdwIAAboBcwFvAV8BbwFfAW8BXwGS + AWMBfAFrAZMBGQG9AXMWAAEVAS4BuAFOAd4BewFrAS0BvQF3AgABnAFzAVoBawIAAd4BewH3AV4CAAH/ + AX8B1gFaBAABMQFGAdYBWgHeAXsBbAF+ASgBfgEIAXoBBwFyAQkBcgGPAXIBegF7Af8BfwG7AX8BjAF+ + ASgBfgEoAX4BKAF+AWwBfgHeAXsBlwFrAW8BXwFvAV8BbwFfAbkBbwIAAd0BewGTAWMBkgFjAd0BewIA + AbkCbwFfAW8BXwFvAV8BlwFrAf8BfwH0ASkBmAFGFAABnQFzAZMBGQF8AW8B3gF7ASkBJQFrAS0BzgE5 + AWsBLQFKASkBzgE5AYwBMQEpASUBzgE5Aa0BNQEpASUBzgE5Ac4BOQHnARwB1gFaAf8BfwGuAXoBKAF+ + AbABdgFYAXcBmwF7Af8BfwH/AX8BeAF/AYwBfgEoAX4BKAF+ASgBfgEoAX4BrgF6Af8BfwHdAXcBcAFf + AW8BXwFvAV8BkQFjAdwBdwH/AX8B/wF/Af8BfwH/AX8B3AF3AXEBYwFvAV8BbwFfAXEBYwHdAXsCAAE6 + AV8BkwEZAZ0BcwYAAd4BewG+AXcB/wF/BAAB/wF/AjYB9QEpAf8BfwH/AX8BOQFnAfcBXgH3AV4B9wFe + ARgBYwH3AV4B9wFeARgBYwH3AV4B9wFeARgBYwH3AV4B9wFeARgBYwG9AXcB/wF/ARQBewFJAX4BVgF/ + Af8BfwHdAX8BeQF/AdEBfgFKAX4BSAF+AUkBfgFJAX4BSQF+AUkBfgEUAXsB/wF/Af8BfwG4Am8BXwFv + AV8BbwFfAXABXwGVAWcBuAFvAbkBbwGVAWsBcAFfAW8BXwFvAV8BbwFfAbkBbwH/AX8CAAH/AX8BFQEu + AdMBIQG9AXcEAAEaAVcBswEdAf8BfwIAAf8BfwG4AUoBkwEZAZ0BbwIAAd4BewEQAUIBrQE1Aa0BNQHO + ATkBzgE5Aa0BNQGtATUBrQE1Aa0BNQGtATUBzgE5Ac4BOQGtATUBrQE1ATkBZwIAAbwBewFrAX4BjQF+ + Aa8BfgGMAX4BSgF+AUkBfgFJAX4BSQF+AUkBfgFJAX4BSQF+AWsBfgG8AXsEAAH/AX8BlgFrAW8BXwFv + AV8BbwFfAW8BXwFvAV8BbwFfAW8BXwFvAV8BbwFfAW8BXwGWAWsB/wF/BgAB3gF7ARUBLgGTARkBGgFb + Ad4BewH6AVYBswEdAd4BewGcAW8BNQEyAZMBGQFbAWMEAAH/AX8BzgE5AecBHAHnARwBxgEYAcYBGAEI + ASEB5wEcAecBHAHnARwB5wEcAcYBGAHGARgBCAEhAecBHAE5AWcCAAH/AX8BegF7AY0BfgFJAX4BSQF+ + AUkBfgFJAX4BSQF+AUkBfgFJAX4BSQF+AY0BfgF6AXsB/wF/BgAB/wF/AbgBbwFwAWMBbwFfAW8BXwFv + AV8BbwFfAW8BXwFvAV8BcAFfAbgBbwH/AX8KAAH/AXsB2QFOAZMBGQGzAR0B0wEhAbMBGQHTASEBkwEZ + AjYBnQFvCAAB/wF/Af8BfwHeAXsBawEtARgBYwH/AX8B/wF/Af8BfwH/AX8B3gF7AWsBLQEYAWMB/wF/ + Af8BfwH/AX8EAAH/AX8B3QF7AVgBewETAXsB0AF+Aa8BfgGvAX4B0AF+ARMBewF4AXsB3QF7Af8BfwoA + Af8BfwHdAXcBlwFrAXEBYwFvAV8BbwFfAXEBYwGXAWsB3QF7Af8BfxAAAb0BcwHYAU4B9AElAdQBIQFW + AToBWwFnAf8Bfw4AAf8BfwGMATEBWgFrCgABawEtAVoBawYAAUIBTQE+BwABPgMAASgDAAFAAwABIAMA + AQEBAAEBBgABARYAA/8BAAT/BAAB/AE/Af4BHwQAAfABBwH+AQ8EAAGAAQEB/wEHBgAB/wGDBgAB/wHB + BAABBAEgBgABEAEIBgABAQGABgABBwHgAf8BwAQAAR8B+AH/AYEEAAEHAeAB/wEDBAABwAEDAf4BDwQA + AfABDwH+AR8EAAH+AX8B/wE/BAAE/wQAAeABBwHgAQcB8AEHAgABwAEDAcABAwHAAQMCAAGAAQEBgAEB + AcIBYQESAWwBgAEBAgABjgExBgABDwH4BgABHwH4ARIBTAQAAQcB4AYAAQcB4AYAAQcB4AESAUwDAAEg + AR8B/AESAUwCAAEEASABHwH4BgABjgEwBgABhgEhAgABgAEBAYABAQHAAQMCAAGAAQEBwAEDAeABBwGA + AQABwAEDAeABBwH4AQ8B4wHnCw== + + + + 132, 17 + + + 222, 17 + + + 323, 17 + + + 488, 17 + + + 606, 17 + + + + + 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 + B//wAAf/8AAH//AAB//wAAf/+AAH//4AD/8= + + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/Config/Itrycn_Db.cs b/Source/Itrycn_Project2/Config/Itrycn_Db.cs new file mode 100644 index 0000000..d398516 --- /dev/null +++ b/Source/Itrycn_Project2/Config/Itrycn_Db.cs @@ -0,0 +1,63 @@ +using ryCommonDb; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using static ryCommonDb.DataProvider; + +namespace Itrycn_Project +{ + public static class Itrycn_Db + { + public static string SQLConnStr = "\\UserDb\\myDb.dat|"; + public static ryCommonDb.DataProvider.DataProviderType dataType = ryCommonDb.DataProvider.DataProviderType.SQLiteDataProvider; + public static IDbInterface CreateDataProvider() + { + return CreateDataProvider(dataType); + } + + public static IDbInterface CreateDataProvider(DataProviderType dataProviderType) + { + switch (dataProviderType) + { + //case DataProviderType.OdbcDataProvider: + // return new OdbcDataProvider(); + //case DataProviderType.OleDbDataProvider: + // return new OleDbDataProvider(); + //case DataProviderType.OracleDataProvider: + // return new OracleDataProvider(); + case DataProviderType.SQLiteDataProvider: + return new SQLiteDataProvider(); + default: + return null; + } + } + private static void CreateTable(ryCommonDb.DataProvider.DataProviderType dataType, string ConnStr) + { + DataProvider mydb = new DataProvider(); + IDbInterface db = CreateDataProvider(dataType); + if (db.ConnDb(ConnStr) == 1) + { + #region 表1 + RyQuickSQL mySQL = new RyQuickSQL("表1"); + mySQL.AddField("", ""); + mySQL.AddField("addTime", DateTime.Now); + mySQL.AddField("editTime", DateTime.Now); + db.CreateDb(mySQL); + #endregion + // + #region 表2 + mySQL.Clear(); + mySQL.TableName = "表2"; + mySQL.AddField("", ""); + db.CreateDb(mySQL); + #endregion + } + db.Free(); + } + public static void CreateTable() + { + CreateTable(dataType, SQLConnStr); + } + } +} diff --git a/Source/Itrycn_Project2/Config/Soft_Config.cs b/Source/Itrycn_Project2/Config/Soft_Config.cs new file mode 100644 index 0000000..471134b --- /dev/null +++ b/Source/Itrycn_Project2/Config/Soft_Config.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Itrycn_Project +{ + /// + /// 配置类,保存在运行期间会被改变的配置信息(本系统基于乘黄V2架构) + /// + public static class Soft_Config + { + /// + /// 是否能关闭窗体。 + /// + public static bool IsCanCloseForm = true; + /// + /// 在点击主窗口关闭按钮时,隐藏窗体(只有开启了托盘图标,本功能才能生效,此时需要通过托盘图标进行关闭)。 + /// + public static bool HideByCloseBtn = true; + public static void LoadSetting() + { + //ryCommon.Storage Stor = new Storage(); + //Stor.SelectNodeBySet(); + //LowCountTip = Stor.GetAttrValue("LowCountTip", true); + //low_count = Stor.GetAttrValue("LowCount", 10); + } + } +} diff --git a/Source/Itrycn_Project2/Config/Soft_Info.cs b/Source/Itrycn_Project2/Config/Soft_Info.cs new file mode 100644 index 0000000..444af1c --- /dev/null +++ b/Source/Itrycn_Project2/Config/Soft_Info.cs @@ -0,0 +1,58 @@ +using ryCommon; +using ryCommonDb; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using static ryCommonDb.DataProvider; + +namespace Itrycn_Project +{ + /// + /// 配置类,保存在运行期间不会被改变的配置信息(本系统基于乘黄V2架构) + /// + public static class Soft_Info + { + /// + /// 在线升级配置文件的url + /// + public const string Update_Url = "http://www.itrycn.com/update/ryWebMon4.xml"; + /// + /// 软件标题 + /// + public const string Soft_Title = "睿元管理系统"; + /// + /// 软件ID + /// + public const string Soft_Id = "Money_Op"; + /// + /// 开机启动的参数 + /// + public const string Soft_Pram = "q"; + /// + /// 官网地址 + /// + public const string Soft_Url = "http://www.itrycn.com"; + /// + /// 售后QQ群 + /// + public const string QQ_Qun = "183161992"; + /// + /// 关于界面内容. + /// + public const string AboutText = "#softname# #ver#"; + /// + /// 用户文件夹,该相对路径设置,将在程序启动后转换 + /// + public static string UserDataFolder = @"\UserDb"; + /// + /// 是否允许显示托盘图标 + /// + public static bool ShowTray { get; } = true; + /// + /// 是否显示捐赠方式 + /// + public static bool DonateVisabled { get; } = true; + } +} diff --git a/Source/Itrycn_Project2/DbOp/FrmAdd.Designer.cs b/Source/Itrycn_Project2/DbOp/FrmAdd.Designer.cs new file mode 100644 index 0000000..a156e7b --- /dev/null +++ b/Source/Itrycn_Project2/DbOp/FrmAdd.Designer.cs @@ -0,0 +1,106 @@ +namespace Itrycn_Project.DbOp +{ + partial class FrmAdd + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnCancel = new ryControls.ButtonEx(); + this.btnOK = new ryControls.ButtonEx(); + this.label1 = new System.Windows.Forms.Label(); + this.txtName = new ryControls.TextBoxEx2(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.ForeColor = System.Drawing.Color.White; + this.btnCancel.Location = new System.Drawing.Point(363, 310); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(65, 27); + this.btnCancel.TabIndex = 5; + this.btnCancel.Text = "取消"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.ForeColor = System.Drawing.Color.White; + this.btnOK.Location = new System.Drawing.Point(292, 310); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(65, 27); + this.btnOK.TabIndex = 4; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.BtnOK_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 20); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(29, 12); + this.label1.TabIndex = 7; + this.label1.Text = "名称"; + // + // txtName + // + this.txtName.BackColor = System.Drawing.Color.White; + this.txtName.Location = new System.Drawing.Point(55, 12); + this.txtName.Name = "txtName"; + this.txtName.PasswordChar = '\0'; + this.txtName.ReadOnly = false; + this.txtName.SelectionLength = 0; + this.txtName.SelectionStart = 0; + this.txtName.Size = new System.Drawing.Size(372, 25); + this.txtName.TabIndex = 6; + // + // frmAdd + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(438, 347); + this.Controls.Add(this.label1); + this.Controls.Add(this.txtName); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Name = "frmAdd"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "新增"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ryControls.ButtonEx btnCancel; + private ryControls.ButtonEx btnOK; + private System.Windows.Forms.Label label1; + private ryControls.TextBoxEx2 txtName; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project2/DbOp/FrmAdd.cs b/Source/Itrycn_Project2/DbOp/FrmAdd.cs new file mode 100644 index 0000000..a4e826a --- /dev/null +++ b/Source/Itrycn_Project2/DbOp/FrmAdd.cs @@ -0,0 +1,79 @@ +using ryCommon; +using ryCommonDb; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project.DbOp +{ + public partial class FrmAdd : Form + { + public ModalForm mr = null; + public string tableName = "MainTable1"; + public int isAdd = 1; + public string selectId = "-1"; + public FrmAdd() + { + InitializeComponent(); + } + #region 需要修改 + public void GetInfo(string id) + { + selectId = id; + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + DataSet ds = db.ReadData(tableName, id); + if (mydb.HaveData(ds)) + { + DataRow reader = ds.Tables[0].Rows[0]; + #region 读取信息 + txtName.Text = reader["Name"].ToString(); + #endregion + } + } + db.Free(); + } + + private void BtnOK_Click(object sender, EventArgs e) + { + if (txtName.Text == "") + { + MessageBox.Show("名称不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + RyQuickSQL mySQL = new RyQuickSQL(tableName); + mySQL.AddField("name", txtName.Text); + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + if (isAdd >= 1) + { + mySQL.AddField("addTime",DateTime.Now); + mySQL.AddField("editTime", DateTime.Now); + db.ExecuteNonQuery(mySQL.GetInsertSQL(), db.GetParameter(mySQL)); + } + else + { + mySQL.AddField("editTime", DateTime.Now); + db.ExecuteNonQuery(mySQL.GetUpdateSQL() + " where id=" + selectId, db.GetParameter(mySQL)); + } + } + db.Free(); + ModalForm.SetDialogResult(this, mr, DialogResult.OK); + } + #endregion + + private void BtnCancel_Click(object sender, EventArgs e) + { + ModalForm.SetDialogResult(this, mr, DialogResult.Cancel); + } + } +} diff --git a/Source/Itrycn_Project2/DbOp/FrmAdd.resx b/Source/Itrycn_Project2/DbOp/FrmAdd.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/Itrycn_Project2/DbOp/FrmAdd.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/Source/Itrycn_Project2/DbOp/FrmView.cs b/Source/Itrycn_Project2/DbOp/FrmView.cs new file mode 100644 index 0000000..12574b0 --- /dev/null +++ b/Source/Itrycn_Project2/DbOp/FrmView.cs @@ -0,0 +1,175 @@ +using ryCommon; +using ryCommonDb; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project.DbOp +{ + public partial class FrmView : Form + { + string orderSQL = "order by addTime desc"; + string tableName = "MainTable1"; + string titleName = "数据"; + public FrmView() + { + InitializeComponent(); + } + #region 需要修改的内容 + private void RySearch1_OnSearch(object sender, EventArgs e) + { + //需要修改此处 + //LoadDb("(" + TableProject.name + " like @SearchText or " + TableProject.des + " like @SearchText)"); + } + + private void CtlMyPage1_OnPageChange(object sender, EventArgs e) + { + #region 重新载入数据 + tableModel1.Rows.Clear(); + tableModel1.Selections.Clear(); + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + DataSet ds = db.ReadData(ctlMyPage1.GetSQLText, ctlMyPage1.T_Parameters); + for (int i = 0; i < ds.Tables[0].Rows.Count; i++) + { + DataRow row = ds.Tables[0].Rows[i]; + XPTable.Models.Row itemList = new XPTable.Models.Row() + { + Tag = row["id"].ToString() + }; + //需要修改此处 + //itemList.Cells.Add(new XPTable.Models.Cell(row[""].ToString()));//示例 + tableModel1.Rows.Add(itemList); + } + } + db.Free(); + #endregion + } + private void GetRow(string id, int index) + { + #region 重新载入数据 + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + DataSet ds = db.ReadData("select * from " + tableName + " where id=" + id); + if (mydb.HaveData(ds)) + { + DataRow row = ds.Tables[0].Rows[0]; + XPTable.Models.Row itemList = tableModel1.Rows[index]; + //需要修改此处 + //itemList.Cells[colName.Index].Text = row[TableProject.name].ToString(); + } + } + db.Free(); + #endregion + } + #endregion + public void LoadDb(string whereSQL) + { + string _whereSQL = whereSQL; + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + #region 重新载入数据 + db.AddParameter("SearchText", "%" + rySearch1.Text + "%"); + ctlMyPage1.RecordCount = db.GetCount(tableName, _whereSQL); + ctlMyPage1.T_Parameters = db.GetParameter(); + ctlMyPage1.SQLText= db.GetPageSQL(tableName, _whereSQL, orderSQL); + ctlMyPage1.SQLText2 = db.GetPageSQL2(tableName, _whereSQL, orderSQL); + ctlMyPage1.GotoPageIndex(1); + #endregion + } + db.Free(); + } + + private void BtnAdd_Click(object sender, EventArgs e) + { + FrmAdd frm = new FrmAdd() + { + Text = "添加"+ titleName, + Icon = Icon, + isAdd = 1 + }; + frm.mr = new ModalForm(this, frm); + frm.mr.OnDialogResult += new ModalForm.DialogResultHandler((object t, DialogResult dg) => { + if (dg == DialogResult.OK) + { + rySearch1.PerformClick(); + } + }); + frm.mr.ShowModal(); + } + + private void BtnEdit_Click(object sender, EventArgs e) + { + if (table1.SelectedItems.Length == 0) { return; } + string selectId = table1.SelectedItems[0].Tag.ToString(); + int index = table1.SelectedItems[0].Index; + FrmAdd frm = new FrmAdd() + { + Text = "修改"+ titleName, + Icon = Icon, + isAdd = 0 + }; + frm.GetInfo(selectId); + frm.mr = new ModalForm(this, frm); + frm.mr.OnDialogResult += new ModalForm.DialogResultHandler((object t, DialogResult dg) => { + if (dg == DialogResult.OK) + { + GetRow(selectId, index); + } + }); + frm.mr.ShowModal(); + } + + private void BtnDel_Click(object sender, EventArgs e) + { + if (table1.SelectedItems.Length == 0) { MessageBox.Show("请先选择要删除的项。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } + string selectId = table1.SelectedItems[0].Tag.ToString(); + if (MessageBox.Show("确定要删除该项吗?一旦删除将不可恢复。", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) + { + return; + } + DataProvider mydb = new DataProvider(); + IDbInterface db = Itrycn_Db.CreateDataProvider(Itrycn_Db.dataType); + if (db.ConnDb(Itrycn_Db.SQLConnStr) == 1) + { + db.DelById(tableName, selectId); + tableModel1.Rows.RemoveAt(table1.SelectedItems[0].Index); + } + } + + private void FrmView_Load(object sender, EventArgs e) + { + Text = "浏览"+ titleName; + 添加数据ToolStripMenuItem.Text = "添加"+ titleName; + 修改数据ToolStripMenuItem.Text = "修改" + titleName; + 删除数据ToolStripMenuItem.Text = "删除" + titleName; + rySearch1.PerformClick(); + } + + private void 添加数据ToolStripMenuItem_Click(object sender, EventArgs e) + { + btnAdd.PerformClick(); + } + + private void 修改数据ToolStripMenuItem_Click(object sender, EventArgs e) + { + btnEdit.PerformClick(); + } + + private void 删除数据ToolStripMenuItem_Click(object sender, EventArgs e) + { + btnDel.PerformClick(); + } + } +} diff --git a/Source/Itrycn_Project2/DbOp/frmView.Designer.cs b/Source/Itrycn_Project2/DbOp/frmView.Designer.cs new file mode 100644 index 0000000..8b7a667 --- /dev/null +++ b/Source/Itrycn_Project2/DbOp/frmView.Designer.cs @@ -0,0 +1,210 @@ +namespace Itrycn_Project.DbOp +{ + partial class FrmView + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.rySearch1 = new ryControls.rySearch(); + this.table1 = new XPTable.Models.Table(); + this.columnModel1 = new XPTable.Models.ColumnModel(); + this.tableModel1 = new XPTable.Models.TableModel(); + this.ctlMyPage1 = new MyPage.ctlMyPage(); + this.btnDel = new ryControls.ButtonEx(); + this.btnEdit = new ryControls.ButtonEx(); + this.btnAdd = new ryControls.ButtonEx(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.添加数据ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.修改数据ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.删除数据ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + ((System.ComponentModel.ISupportInitialize)(this.table1)).BeginInit(); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // rySearch1 + // + this.rySearch1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(236)))), ((int)(((byte)(239)))), ((int)(((byte)(244))))); + this.rySearch1.EmptyText = "请输入搜索内容"; + this.rySearch1.Location = new System.Drawing.Point(12, 12); + this.rySearch1.Name = "rySearch1"; + this.rySearch1.Size = new System.Drawing.Size(329, 24); + this.rySearch1.TabIndex = 28; + this.rySearch1.OnSearch += new System.EventHandler(this.RySearch1_OnSearch); + // + // table1 + // + this.table1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.table1.ColumnModel = this.columnModel1; + this.table1.ContextMenuStrip = this.contextMenuStrip1; + this.table1.EditStartAction = XPTable.Editors.EditStartAction.SingleClick; + this.table1.EnableHeaderContextMenu = false; + this.table1.EnableToolTips = true; + this.table1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.table1.FullRowSelect = true; + this.table1.GridColor = System.Drawing.Color.Silver; + this.table1.GridLines = XPTable.Models.GridLines.Rows; + this.table1.GridLineStyle = XPTable.Models.GridLineStyle.Dash; + this.table1.HeaderFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.table1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.table1.Location = new System.Drawing.Point(12, 42); + this.table1.Name = "table1"; + this.table1.NoItemsText = "当前还没有任何数据"; + this.table1.Size = new System.Drawing.Size(1028, 551); + this.table1.TabIndex = 29; + this.table1.TableModel = this.tableModel1; + this.table1.Text = "table1"; + this.table1.ToolTipShowAlways = true; + // + // tableModel1 + // + this.tableModel1.RowHeight = 25; + // + // ctlMyPage1 + // + this.ctlMyPage1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.ctlMyPage1.Location = new System.Drawing.Point(12, 595); + this.ctlMyPage1.Name = "ctlMyPage1"; + this.ctlMyPage1.PageSize = 50; + this.ctlMyPage1.RecordCount = 0; + this.ctlMyPage1.Size = new System.Drawing.Size(506, 26); + this.ctlMyPage1.SQLText = ""; + this.ctlMyPage1.SQLText2 = ""; + this.ctlMyPage1.T_FirstCaption = "首页"; + this.ctlMyPage1.T_LastCaption = "末页"; + this.ctlMyPage1.T_NextCaption = "下一页"; + this.ctlMyPage1.T_Parameters = null; + this.ctlMyPage1.T_PreCaption = "上一页"; + this.ctlMyPage1.T_SkipCaption = "跳到"; + this.ctlMyPage1.T_TipCaption = "{pageindex}/{pagecount} 页,共 {recordcount} 条记录,每页 {pagesize} 条"; + this.ctlMyPage1.TabIndex = 30; + this.ctlMyPage1.OnPageChange += new System.EventHandler(this.CtlMyPage1_OnPageChange); + // + // btnDel + // + this.btnDel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnDel.ForeColor = System.Drawing.Color.White; + this.btnDel.Location = new System.Drawing.Point(978, 12); + this.btnDel.Name = "btnDel"; + this.btnDel.Size = new System.Drawing.Size(62, 24); + this.btnDel.TabIndex = 40; + this.btnDel.Text = "删除"; + this.btnDel.UseVisualStyleBackColor = true; + this.btnDel.Click += new System.EventHandler(this.BtnDel_Click); + // + // btnEdit + // + this.btnEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnEdit.ForeColor = System.Drawing.Color.White; + this.btnEdit.Location = new System.Drawing.Point(910, 12); + this.btnEdit.Name = "btnEdit"; + this.btnEdit.Size = new System.Drawing.Size(62, 24); + this.btnEdit.TabIndex = 39; + this.btnEdit.Text = "修改"; + this.btnEdit.UseVisualStyleBackColor = true; + this.btnEdit.Click += new System.EventHandler(this.BtnEdit_Click); + // + // btnAdd + // + this.btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdd.ForeColor = System.Drawing.Color.White; + this.btnAdd.Location = new System.Drawing.Point(842, 12); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(62, 24); + this.btnAdd.TabIndex = 38; + this.btnAdd.Text = "添加"; + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler(this.BtnAdd_Click); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.添加数据ToolStripMenuItem, + this.修改数据ToolStripMenuItem, + this.删除数据ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(125, 70); + // + // 添加数据ToolStripMenuItem + // + this.添加数据ToolStripMenuItem.Name = "添加数据ToolStripMenuItem"; + this.添加数据ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.添加数据ToolStripMenuItem.Text = "添加数据"; + this.添加数据ToolStripMenuItem.Click += new System.EventHandler(this.添加数据ToolStripMenuItem_Click); + // + // 修改数据ToolStripMenuItem + // + this.修改数据ToolStripMenuItem.Name = "修改数据ToolStripMenuItem"; + this.修改数据ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.修改数据ToolStripMenuItem.Text = "修改数据"; + this.修改数据ToolStripMenuItem.Click += new System.EventHandler(this.修改数据ToolStripMenuItem_Click); + // + // 删除数据ToolStripMenuItem + // + this.删除数据ToolStripMenuItem.Name = "删除数据ToolStripMenuItem"; + this.删除数据ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.删除数据ToolStripMenuItem.Text = "删除数据"; + this.删除数据ToolStripMenuItem.Click += new System.EventHandler(this.删除数据ToolStripMenuItem_Click); + // + // FrmView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1052, 625); + this.Controls.Add(this.btnDel); + this.Controls.Add(this.btnEdit); + this.Controls.Add(this.btnAdd); + this.Controls.Add(this.ctlMyPage1); + this.Controls.Add(this.table1); + this.Controls.Add(this.rySearch1); + this.Name = "FrmView"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "浏览"; + this.Load += new System.EventHandler(this.FrmView_Load); + ((System.ComponentModel.ISupportInitialize)(this.table1)).EndInit(); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private ryControls.rySearch rySearch1; + private XPTable.Models.Table table1; + private MyPage.ctlMyPage ctlMyPage1; + private XPTable.Models.TableModel tableModel1; + private XPTable.Models.ColumnModel columnModel1; + private ryControls.ButtonEx btnDel; + private ryControls.ButtonEx btnEdit; + private ryControls.ButtonEx btnAdd; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 添加数据ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 修改数据ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 删除数据ToolStripMenuItem; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project2/DbOp/frmView.resx b/Source/Itrycn_Project2/DbOp/frmView.resx new file mode 100644 index 0000000..6282a36 --- /dev/null +++ b/Source/Itrycn_Project2/DbOp/frmView.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 141, 21 + + + 269, 21 + + + 22, 16 + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/FrmAbout.Designer.cs b/Source/Itrycn_Project2/FrmAbout.Designer.cs new file mode 100644 index 0000000..f361a85 --- /dev/null +++ b/Source/Itrycn_Project2/FrmAbout.Designer.cs @@ -0,0 +1,207 @@ +namespace Itrycn_Project +{ + partial class FrmAbout + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmAbout)); + this.pnlTopLogo = new System.Windows.Forms.Panel(); + this.lblTitle = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.lblVisitUrl = new System.Windows.Forms.Label(); + this.LblQQ_Qun = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.pnlTopLogo.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // pnlTopLogo + // + this.pnlTopLogo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(125)))), ((int)(((byte)(182))))); + this.pnlTopLogo.Controls.Add(this.lblTitle); + this.pnlTopLogo.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTopLogo.Location = new System.Drawing.Point(0, 0); + this.pnlTopLogo.Name = "pnlTopLogo"; + this.pnlTopLogo.Size = new System.Drawing.Size(493, 59); + this.pnlTopLogo.TabIndex = 8; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblTitle.ForeColor = System.Drawing.Color.White; + this.lblTitle.Location = new System.Drawing.Point(12, 22); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(110, 16); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "睿元管理系统"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 67); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(35, 12); + this.label1.TabIndex = 9; + this.label1.Text = "官网:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(53, 67); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(0, 12); + this.label2.TabIndex = 10; + // + // lblVisitUrl + // + this.lblVisitUrl.AutoSize = true; + this.lblVisitUrl.Cursor = System.Windows.Forms.Cursors.Hand; + this.lblVisitUrl.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblVisitUrl.ForeColor = System.Drawing.Color.Blue; + this.lblVisitUrl.Location = new System.Drawing.Point(53, 67); + this.lblVisitUrl.Name = "lblVisitUrl"; + this.lblVisitUrl.Size = new System.Drawing.Size(77, 12); + this.lblVisitUrl.TabIndex = 11; + this.lblVisitUrl.Text = "立即访问官网"; + this.lblVisitUrl.Click += new System.EventHandler(this.LblVisitUrl_Click); + // + // LblQQ_Qun + // + this.LblQQ_Qun.AutoSize = true; + this.LblQQ_Qun.Cursor = System.Windows.Forms.Cursors.Hand; + this.LblQQ_Qun.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.LblQQ_Qun.ForeColor = System.Drawing.Color.Blue; + this.LblQQ_Qun.Location = new System.Drawing.Point(234, 67); + this.LblQQ_Qun.Name = "LblQQ_Qun"; + this.LblQQ_Qun.Size = new System.Drawing.Size(59, 12); + this.LblQQ_Qun.TabIndex = 14; + this.LblQQ_Qun.Text = "183161992"; + this.toolTip1.SetToolTip(this.LblQQ_Qun, "点击复制"); + this.LblQQ_Qun.Click += new System.EventHandler(this.LblQQ_Qun_Click); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(234, 67); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(0, 12); + this.label4.TabIndex = 13; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(193, 67); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(35, 12); + this.label5.TabIndex = 12; + this.label5.Text = "QQ群:"; + // + // pictureBox1 + // + this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); + this.pictureBox1.Location = new System.Drawing.Point(85, 105); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(319, 174); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pictureBox1.TabIndex = 17; + this.pictureBox1.TabStop = false; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.label3.Location = new System.Drawing.Point(13, 297); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(365, 12); + this.label3.TabIndex = 18; + this.label3.Text = "注:本软件永久免费,您可以任意分发分享本软件,但不得破解本软件"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label6.Location = new System.Drawing.Point(100, 90); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(285, 12); + this.label6.TabIndex = 19; + this.label6.Text = "支持微信或支付宝进行捐助,您可以捐助任意金额"; + // + // FrmAbout + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(493, 318); + this.Controls.Add(this.label6); + this.Controls.Add(this.label3); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.LblQQ_Qun); + this.Controls.Add(this.label4); + this.Controls.Add(this.label5); + this.Controls.Add(this.lblVisitUrl); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.pnlTopLogo); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "FrmAbout"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "关于"; + this.Load += new System.EventHandler(this.FrmAbout_Load); + this.pnlTopLogo.ResumeLayout(false); + this.pnlTopLogo.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel pnlTopLogo; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label lblVisitUrl; + private System.Windows.Forms.Label LblQQ_Qun; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label6; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project2/FrmAbout.cs b/Source/Itrycn_Project2/FrmAbout.cs new file mode 100644 index 0000000..31eb40e --- /dev/null +++ b/Source/Itrycn_Project2/FrmAbout.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project +{ + public partial class FrmAbout : Form + { + public FrmAbout() + { + InitializeComponent(); + } + + private void FrmAbout_Load(object sender, EventArgs e) + { + lblTitle.Text = Soft_Info.Soft_Title + " V" + ryCommon.RySoft.VersionStr; + LblQQ_Qun.Text = Soft_Info.QQ_Qun; + if (Soft_Info.Soft_Url.Length == 0) { lblVisitUrl.Enabled = false; } + } + + private void LblVisitUrl_Click(object sender, EventArgs e) + { + ryCommon.RyFiles.OpenUrl(Soft_Info.Soft_Url); + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + } + + private void LblQQ_Qun_Click(object sender, EventArgs e) + { + try + { + Clipboard.SetText(LblQQ_Qun.Text); + MessageBox.Show("已成功复制到剪切板,请复制到QQ搜索。","提示",MessageBoxButtons.OK,MessageBoxIcon.Information); + } + catch { } + } + } +} diff --git a/Source/Itrycn_Project2/FrmAbout.resx b/Source/Itrycn_Project2/FrmAbout.resx new file mode 100644 index 0000000..a94005d --- /dev/null +++ b/Source/Itrycn_Project2/FrmAbout.resx @@ -0,0 +1,1255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAAT8AAACuCAYAAABA6wr5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wwAADsMBx2+oZAAA9eVJREFUeF7s/QegZkWRP37fSeQchjSBMDAMYUhDzjBkJCM5g0RzAsyoYBZxDZiz + iK5p1XV31XWDYYM5rRFRsuTMBOo9n3P5XpvHCwMM+xve/VvQ0+c5p0N1dXV1VXWdc4fqr/BX+P8MzO/T + gw/OG867f13d/1DK87+mp2Z6sE81Mm/y4Wdzux9z+l+PB/4q/P4K/5+BkQVjocx/oLuwYOb39/3Kwvpr + emqmmntnN133dj/m9r87kTd8H3T3Hi/8Vfj9Ff6/A3M7YXfr9TXnV/9V9/7n5+qeb36g7v/G5fXAP19e + c//lfXX/N9//1/QUTrf97N/r/mt+WXVvJwQ7qUfwzZfn4nHCw4Tf/PlUyD/n4MG+5WFo7wc8T2phtHqP + VP+R+htsc+7ch0v31Eu5wfJg3jz7+p9hEAd12vptG4O/weBvMFqbgfSftkar397XVq4H7+V32mzHNlgn + ORjEbxDattv+0/6cOY/fpPjfgB6rOcOmz9wHOpzm0QK6sUHPzS7Ne7DT4QyXZtf9nl/31INX/6Ru/8QF + 9cBLpteNJy5Z1x8yVNfvN1RX79GlvcfXtfuOqWv2Garr9hn317QI07V7j33U9IfDJ9R1Rw3VvWdNqXsu + Pqju+sYHuom+t+6qO7up7mTD/Hk9G8yfi2/vHtbm59MSR9cKHyb8sggsgLvuuqvuvvvuuv/+++vee+/t + k+v77rtv5Ldr93I/z+T33HPPyHPttGXzWz9JFpi6+lVXSp/y/H7ggQdG2vY7ArEVBNrzW1I2dZSX9C/X + hn7lygQGhYr2gNzvjOPOO+/s+08ZqR2jHDxe4aEd+LXjDJ6S/oIjvDMeye/U0X/qSIO/2/uSunJ1tWls + rsHgxrMooMfAHJBupqQzde7tLlB3TsfqD3bLAFWkOd0qmHvtD+v6i4+pGzphd92eY+s3B3f5kWPr9uMX + q1uOH1M3nThUfzp5TP3ppKG6rUt/OvmvaVGmm0959HTDCV3+9KW6Oew2rW6zunn2hLrxpIn1wGffVXUf + fujmHZN0+X2d8MMIHcc/5M/9S/gL4Qcw/uc///l6//vfXx/96Efrwx/+cH3kIx+pj33sY33+oQ99qE+5 + L8/v5JK6H//4x/syacfz973vffXZz362brvttr4/8L3vfa8v88EPfnCk/mCf7uU33N797nfX17/+9RHB + FSGUcfzmN7+pD3zgA3X55Zf3basbHPzWjufvfe976+c//3m/8EEES9pJDtDmE5/4RF/nHe94R33729/u + +1fmpptuqr/7u7/r8TKOf/zHf3yo1rAAVObRUgTMNddc09fXDjyl97znPT3dvvSlL/UCC6jzb//2b/19 + 44CX5Fr90MwchJ6jpfShjhydtOGZfm+44Ya+v0UNqMNDN5e464SfcwuUcOdB+7wCPSvMqbs//+q65aCh + unHPobr26CXqlk64XXdap/V1i+jG7vqWbrHdeupQ3dRdX3N8t/i66z+dPO6vaRGmm04a+6jpzm6urj1z + qK46vdPcT+vmsBOGtx44pn63x+J183Nn1pyr/61jhoc2Rpt2r/p1vDG8XP4CRhV+V111Ve277761+OKL + 92nJJZesZZZZps+XWGKJPs+158mlxRZbrE+5P1odadasWfXTn/50RGN60YteVEsvvfRftLfUUkuN1Mlz + 7YwfP75/dvbZZ9eNN97Y4x38AWFj8a+//vp9ueClrrGkHfe0+653vasXbAA+IMKobfcXv/hFTZo0aQTP + c889t6699tr+2Xe/+93aZZdd+jaXXXbZOvHEE0faAtpJCgzeI0i//OUv1zrrrPMwnEM78/Lb3/62Lwvf + Zz/72bX88sv39JgwYUJfxnjdUyd4asf1Y0nKt7SxET4VND8kGtb7bCSdyBveo7qJ6h506A1TcE5d+5rd + 6vfbLV7XP31c3XVGp9l1gu66U5etm7vFctPRY+u6gxer3+3TaYKdYLx678Xqur2Wq+t3X77TDmmIf02L + Kl0/+9HTrXtPqFsO6DT3k8bXTd2c3nb64nXNMzqB2AnF23fvNMJDO5P4Wx8rng/MgD3u6dIjce6ows9i + 3m233WpoaKjGjh3b54NpzJgxD7tuf4+W8lxuoW655Zb9Io7WdOaZZz6sTHvd5pL648aN669PO+20uvnm + m/s2Wu0K0PgIgdSTjCdttWMj/ILLoNBrBRiBs+66647Ue+UrX9lrjLRF2uP+++/f3ydEzjrrrL5OcEoa + hMFn//Ef/1FrrbXWw8aca/Pyxz/+sS9HAyT8CSn0aMczOMbBtpJyb7AMQSrX7j/90z/1/S1yQB5T0eVz + OtbuDd7uet5DzF5zb6vrX7Bj/WqXpevG05lEi9d1nWl7E5PpaZ2msFe3gI5euu68cGbd/84j676PnFt3 + fei8uvsDp9V97z227vjgaX9NizDd+aHTHzX96eJZ9cfnrlB/OJiPdmxd32nsNxB8ndb+x04bvPbwbiPb + bWzN/beLe6Xv/gcpM3d1vDG62+lhwg9Y6Nddd12vYWQB0ALWXnvtWnPNNWuVVVaplVdeuVZdddX+Wj5x + 4sSHXbe5tMYaa/SJxmWBEQxbbbVV/c///M9DvVadf/75teKKK/ZJ3dVWW+0v2ll99dV7rYvwy6I+44wz + HmY+gwgR5tu0adN63LRDI1KHsKDdRID6zXS84447+npowPT8wx/+ULfccktvzv7pT3/q+/nZz35W06dP + 7+saC431d7/7Xd/nN7/5zV7zQzd9we3WW2+t66+/vm9HGxJh3abcV0b6+7//+55e2jfOVoDtvffevRmq + P8LvvPPO6+npOZxCa/QyT64z/tBzMIW+aD558uR+DrQn0WC/9a1vjdB0UUKPAZdE9//w9nRvf6+3aubf + XHe8aYf65a5DdfdxS/dm0XWdiXTH4Z2GsNuSdePzZ9SNX/9It7P/rKs/p69/d9fQfb3XUAvE6bC28Nf0 + 1Ew9C959R933Hx+ve956cF2z35L1J64NZnC3wd160pi6vtP+bthrbN3xs8/3dYYdfqN7/f5C87PwaX77 + 7bffyIJz/bnPfa6+9rWv9SYZv5ac/0ly/cUvfrG/L7nOM+mrX/1qv6BPPvnkvk3Ca8cdd+x9cvGvESpf + +MIXehMr9bSVXJv/8A//0PsKCc4IhGc84xkjwg/+GYP86quv7vuWtEMrMx71WqFCWL3zne/sDxjAf/3X + f9UJJ5zQCzJ1DjjggDrooIPqkEMO6a8jxNXdbLPN6tBDD+1NXBsGIeI+QUSQHHjggX29pz3taf31oyXt + HHzwwT1tos2hVdqT77PPPv3mBAi/Zz3rWb0g92yHHXbotV2+RmPOHKFr6PhoSR11L7jggpGNwsbHr/hU + gGFO6QRVp/31wu/BTuPu791f93zx5XXTdp3AO26oHug0gTscZhzQpQOXqJs//dquTKcFzKcJzKkH5j9k + MltMvVI/vx7o2up//zU9ZVNn2/WXc806BvivL9dNz964rttjXN1x7JKd8BtX153RaYEHdnxw1NLdVN/a + +/4eKQpmVLOXxhPzjYA4/fRO7bzzzv4ZYZVyETaD0JqJee4e01KbFnbM3sE2RrtOmfwmiLQjMS2jsbUw + Wl0mojoRJLkmyBygECbwJAjWW2+9h5VVJgJPIpTa30nuRahGcEm5t6A0KOzST/Ck+fHJAiexfI7oqSzh + aUMB2QBCh0EY7X7ufepTn+q1SZsCn9+//uu/9vcXNYhqYcaQW/25xvxuMbBorvl1XX1QJ+SO6Hb9M1au + q05frO7YvzODjl+l7v7pP3Vlu0IWy0OBsMMCswP28pxhoTc8dB38NT1VU/9iTqepm0fnGj0P3HNT/fKl + 29etewzVzZ22f8OpY+pPnSZ49U7d77cfPGwVDE/7X8BfCD+JyRctyaI95ZRTetMtC2oQWmEHRisnhOXV + r371yILebrvt6ve///2I5tdC6gaf9ppZSNuKcDj11FMfVq7tu70Pjj/++BGB1ebwcaoZzY8GtMkmm4w8 + bwWXa/dSP2VynTLtb+mxls+zNk/y26YRAUdYn3POOb3m5znNkwYNMieDeQBd2kOMPCdQbQSEnzZpucz5 + pwR00q/HeN7cjqnxzbAmcMule9RNHfNff3In9LoFcD0huO8y9eDV/9bv+g90tUbj/9F4b0EQfkrd5KFf + y3PtdWC034P3Hgu0ddq5faTrFnK/zUdrr63f4pn7Lf0Gn4HB+guClBksO3LfLHb/E2jz+g3tgf5Ao+be + Wn94wfZ1y+7j6oYzh+qW45aoX3YC8Lr9xtbcq37Sic1hxW0QHlH4xeyVTjrppJETTYcCHPKf+cxneg2J + OSsxS6X89pzGkBNUPq0Xv/jFfXuEDdP117/+dU9ARNJviHn77bfXP//zP/dtaOuHP/zhCCE5+5/znOfU + Xnvt1Qvo5z//+b1JHvNO+Zh7rmPuydWjHRnbzjvv3Gs2ESzMRQtfP8x7p9FwJZg22mijvh7zdfbs2b02 + lGfR1NKWa4k2NnXq1BFzlsbGv5bn0mhCT+Kjg6P+1GfqEmzG/IIXvKD3QQJz4aCIaaq+5z/4wQ9GaOVk + WpiLefnKV74yQhd56PS3f/u3/bX5MQfmSxiP8cDFWM3FUwM6Pukz6p7jjjk1/7qf143HrlI3HT62bjpt + 8br92KH6w76d6ft3r+gWRWcRzB8+xMpyCm2SB5RZELSLHaRO2mqft+2P1mf4PtBePxr0YxnANfcG20i5 + wWft9YJiUJVt+2uvgeej0SX10tdgvQVB6j6MTvd3ul6n8tnI5nNjdOmertl+Y7v5R3XD0WPq6iPG1wPH + dQLwpGXrxk4Y3nXZQfXAYznw0KE0KPz4s9wDtDW+OxqBhbHccsvVSiutVCussMJIzmFuQVq8P/7xj/t6 + /HJ8SRaphUX4OSgAg2EU3//+93thQbvTJqc+yETR0AgAbdLYpkyZ0uPiZFd5uQSX5HxxyjKRCQ0LnjAi + vPTDJE9Ar9hB2qWxOzR4zWte0/ep7q9+9as+fCZmqDLRQv3ONW3MSTRhol3+x2233fZh9Qg/v+WtIDR2 + /dDsjJG2K3c4YmMIY6AHzS/CmGD+0Y9+1I/BCfQll1zS42GuHFygjblBD7/NnXki6AlF7dLQbQQR6k8l + 4Seer+P6jlE7PuiYHlPP/eLr67odh+pPpyxR150+tm49cKhufPbm3fM7HtIKlLcQ/8zfIAvqiYTwpM7I + ouwg14N5+hsUdk8EWiGj3Rb39APaa7weaO8P4pK1pYw0KBQHxzNa3237o917LKD8aHX6ex0KtPieCp32 + P2wCz+nGWMXxddsXn9u/CXK7gOlTOwvg8C7vNsO6Z/Q41cel+XlmER9xxBEjz5KyoKUIgD333LPXRIBF + +7KXvWxkoRN+zDdtthPh93//93/3hw3asAgdPmTilW0nQjCuBaxsK0CCTytonOiqA8TkOb1OeQHL0VJp + SRtuuGF/n9C8+OKL+/uAEHKQkXrabzVI9/wmNLgLANwxEw0u9drU1pPTaAk6kLFqI7gnd6/V/GiHhJ86 + mFMYjvYiYNNfriPgaKg0QIAGT2nhZ+gPvdnBpr3vwh3q+oM74Xfq2PpDx/A3zR6q+/750prXlaMV9MKy + +2f4HdBhuo0Gj/YsMFjG70eql/uDwrXl9ScC6rd9Boe0O5gHsn5Gq5t77bNA2hntWXhytGfg0eo+EqSs + vOV5YA6d2/au2y7N4QS2Ec6ZX/d3w5vzwN2dybtCXX3sEvUH/r8zhuqajh/mfffDff1BeJjwAzp7NLOX + 2cl3lsUTQTcoeCRtRBOhNV144YX9fWVpG7/85S9HmMNzYSEOVpy2EgDad+roUCNEQNCUI1Bpc605Sash + 1OQ0HiZkcm8saEcbYteE73imPs1Pe4Dm5+RU39p67Wtf29dRl8AW6kKDIhijdfGRoYV+tUfLojHDk8Ck + Ae+66669oFIGPhLtCw40TNqYe0cddVRPG/hE62OW0naj+Ul2dZpfTmaZvVwEgde97nU9vTNHSZkrORob + D9cAeCoLP6d9/RLuuP/OXvh1m9GJS9cNZ02o67rd/vpjxtWNXap7ru9WZmcSWxvE5MOVmIcJgizQxwrq + AG2kbhZp2g2M1nbutZrVY8UhfYP02d4D7e+srUcrE0h7oH3eXsPT74yzfdbWD7SC/7GOcbRy2u3b7ua0 + 3/wos13T/eV8uBCJnRbYVb3z0n3qhn3G1I0nTKhbTh5f1+02vm79wEnd87+EvxB+YFD40bxi9soJwzxr + F5bFZLHlmr/qJz/5SV/PWxgxey2sbbbZZsRxD5hdwlae+cxn9mY1waQdwoLZiyiSdt785jf3MXR8eEzE + hHoQOM997nP717SErtDmCDWa21vf+taHCQbm+9ve9rbeNJRoqJk8vkivlr385S/vn/3Lv/xLfx8QRNqW + +MbQJnFxgp9f+tKX9gL5sssu6zUvwsmJLMH/+te/vt70pjf1eHmuD+1ceuml/fXf/M3f1Nvf/va66KKL + et+eMBaanbFqB13UhwNg2mo7mi/hl80GreDuvpSNCv2jqebZxhtv3IcRgUGzl2D9xje+8ReMvUhAiEqX + cXz3y6pD6YbTFqsbzxhTf+x2+j8dMKbueuVmDy0MLgwLqVsY5MxDayrjkLcLbbRFNwijlcm9lj6P1PZg + 2cH8sUCE5iAuacP90dobra9Hwgu0r3pG2AWUjzmtzqB2295zPYjro0GLQ+DP/d/fn/LOnQ+3Lrnuru7p + bYLuqlMN7/2HV9Ztu3S8cNJKdb0A9wMn1O2XbNPXHoTHJPxan5/c7zwbTO2iIpji84vm5z7BuPXWW48I + PxP6whe+sF+UEi3K4tMWbSg+P0Bo0aDaclmoAqAtYsQyOSbANX8doro2EfrLBMrb5yDXnmOCTKQ8bXqm + HUJMIDHBstNOO/WHQepo88orr+wPPoxX6AyNlh9PG4RM+penL207oGBaa5NgTxtyb3igARyVz2lv6E2I + B79ofpmPweSZ5GSbqQ8i/GKCP6WEX8ftZoIG2G/73e/rzl2ubj6+0/pOG1PX7zlUd7/jUKuj1wXy7Tfl + hEkYQ5J5y+GXJL4y8ZaPlJSTcy+wTIRciTaIoPj0pz/dP09cqHI2MGCeBd3rx/O8ogjCdwuCN77xjX19 + 7YobdQ0Pv/X3ne98py8nDvSwww7rn9lQgTE7cFSPkpH5/OQnPznSnhAq963LjNP9jOWGh97xtsG6x42T + sUrWuHEGXLOa+P6VDR0fKaGv9tpxuWcswtQIuG6ldv/aAO6u+V5rHP6/twiIwHv/44q6fp/O5D1lQl0t + +PmQMXX7BetD5y9gVLOXiavzLA4aRwJrmb3HHXdcvzAtyCyi0XJtOHHUJlOVVuS+ujQ/GlYmweFA+mvb + sLBNVkD5LbbYon+WFDy8AdLGpCmbyUg/yYHrMJ5yeTbIjO0z4Drt0tAIaP1vuummIwxIMDqtdt945V5/ + a6Ftx3X6IGyY1KGBlOuZM2eOvFFCiGIKNPLcgUc0bWOI8EtdeWICowm6dpo9KPyUU/6pZPYSY/h9WKDJ + 59UN565Wd5w4pm45cWz/Wao/vf2IfjH0X/ewRh68pxeEg+KF4DP2x5tCy/CcBNCbpdDet4FwaWReWT7u + ayOvKObZYxGA8YOnjeTp08k+fhKnm2eEUiAB+MoDfT7vec8b4YMoIxSWtJ/kdyICuIzcS708j1YagAuF + wPOWLo+UBsu0v7mHLJWeXJYMRUTG7KUJutephQ/88j/r2iPG1W3Hdlrf6RPq2v2G6o6Ltuge/iU8TPhl + AiL80jFNLz4/hGX2hjgQbAnV/ibFxZ0hmF3BgYdnyjj5dKIZ7YfpR6gxwSxwp61i2mh5JshXXwgWX1E5 + 9thj+zKbb755X8fhidxO4QDEYYbdycEJTcgHFOROkbXjdS27HO1sUPhI/Gr/+Z//Wf/+7//elydQ5DQ3 + 1yaZ4JE7RBGzCG++Ol9VYV7DlXbBt+m50BqhONoUN5eT7tBcv8GF9srXGDrSGjERDa3VwmmRtOIItPj8 + 0g5z3/3B+ZFj3GjMhLbTbzg4mW5DXZjUfKBPBejFxLCs6GD41O/Gs1foBN9Q3Xhyl/YS2NppfiNlhqGj + 7ENXw4A+3AnhVa/1iRiYNGnNWmuNSTVp8mo1acpaNWntFWvNtSbXWmtOrHXWWqumTF2zVl+ze7b21Fp2 + aJkaGrNErbPeup2B3S2+B+f37pjQOTR3cGa+rBsuGffQXjiVexJBqEyS3+6LraXlu3afgsAi8N63HI9w + 9aRPFgOgofkwhjL4Q13rl0bFSnEQGb6jmaU+HtC3EKjc49LRH6uKVeO5w7Fhek3qcdCP/qwNB6L81ACd + aW0Rkmi75pR1ao0pq9fUNdarNVdfo9aa0uVT16hJa06tKR1t9bXG5Em11uQ1a+2pa3V1uWjG1Rabz+zb + fHTohN/Pv1k3Htptgp01cNNJ44ff6X7Flg89fziMavYaIDU1gsqpZYQfwlqAWUSSawNsdwKJ8MuXWxDk + JS95SX/fYs1pbxYqYUS4EDJ2HsKHsCK0+LkIEQKR0ER8izzllZHTUE4//fReEBGG6uiHkMy1NgiRo48+ + euRrMHAIM7jm46MZEAraIYQlApcQM6aUx1gRqvB6+tOf3mu1+uS/xDDwk9uF3adp0YJtCIAgDR1sBl4n + w1Bo5XDE+PVBmHsfOuWVHTzwgBvwnOZnTlqBJ0WwJcEpPj/Cj+aXxUurJawJxkUNT1z4DWuK7RjQzfgI + 95hzYKRIP70PaRTucTb1z+b0wu7QAw7uhN/4mrzWpK717ln3P79y6BbB6lqetdGukVy3ZQdTW57Z3PIp + 8AkydbXh1U+QccqZvdnk8oGKPMdHhF+LR/oKTnhPOZAPepANuZe2bMQO67R1+OGHj9w/5phj+jo2mLnz + HuwPKOaJ0XuIlr7O86CwZb/n4+uHHnUEpVxsv/NuNTRusW7tbdLffTSwyT1h4dcuaLZ2CEHYkeie24VI + c/dHIxqChditA542FeHHTCOIWvOtBf2EeHJMpV76o4kEV5D6hBm/V1u2TWEw+BJqCRYOaEd/3i/OgUvG + krpygrrtH2BGZi0tL+VoqBmH8nllTkJDO3sLykqEbw5R0Mq3+NwPwwO/4UuDIfz0Z+zoHcGYN2qSMoaM + KfMGL/5J9Zz2OrAhIJVnttlUMo5FCT0GI2g8fuEHjCObhrHjE797k23+vXVPV7QvrXHmddeW332YhXbn + 3d+Jvvs7Ws+uobFDNW3K2n1RYWc+zhG6htbmT/5ISf+ZjyT13U8bmae4H9q5oCSkTNYaCK+IUfVce9wp + oOXdQR5JWbn++emBPuOKYY0FWlxSn5KQ+wQh3AhGvtjh+Lz7a06HAmHVl/MNqi6b12nPjlEegHr/2uHc + TmnZpttkrNfNNPeosFDCLwjT/JiQGUxebwP8dPGXIJLUHlBYNNEs+KBoPYDmh5DKK0v4aQuk30yK35Iw + EZqI3SmmHR+U188CqQuYCHvssUdfjkBInTBPm+xeEX45hIgQ1T7tsWVK/RonNV89CybvOwcw4u67796X + F1ztlBYYF5rSWkMbrgN+0OCvvcQZMj+o/+n7LW95S18OQyeB9sAD7dGbhggsZm6GtKGM8aAFupiH4EL4 + cdaDCD9j1SbN6KkT6pJ/wOMXfqEbED5l7MZnbsCvHniw3vKze+qtv7273vnrOfWO39xZb/2f++sNv+ru + /fzu+qdrH5qrrr199927xnXCb73JUzv9pWu/e0S4+MqPE3iajvZtYg49RCawCNwLP5oDfmrlfZeRWSxn + qqpjblkLykp87YkU4CYSrSDawDx5biOkKHDF9Hh2PMXNom9WSBtdAfC7tRU+p6Upq294uDamrEuaH9zx + GcCTPoQBFzh520q99K8eV5C2Cb+77hv+EMWP7p5Tl/70gXrLr++ry347vy797X31ll/eX2//5dx6+4/n + 1jev6+apl5P31a4779IJv6Ha7H9b8wMGRLvLgQfE2wMPwbc+EmqQmTCD5viXTL57Fr6JoEVqk4lnZ9Qm + AjrtFcuWxd8ypr70YfGabBOU0A9ttKfELRAmymMCJ1tMW0LIGJIy0XYnu6LQEu0zodMe4ec5XAkIGuyr + XvWqfmzaFULCpIQfLZTvEBD0yqYffjpMwRekL23wX/LdGB/hafzw9jEBz5kZchtFFkF7iIOhQjMbA6aO + 8KP5JZxHOb4bC8t8OE3PHEnmTLLA9Jd3gtvTXm1G82vnZ1FBP+rhoXfwxDU/kAM2tIvZe/kvqpa59Noa + +55ra/zlt9S4915fE957ew2949Za7E1/qlP+6fcM4b61A/c5oMZ18zy5E36EocWq7QgKm6D2uUuAZ3it + 5UXJnAWnlsa5ZzMjJMNTbV3tD17Lra+WT9JucAO5xvsRxvipxaFdX8rH7OXOIliBU9r0nf6SAye9eInw + 63SMurfr9rIf319Lv/WaGnrXDTX0njtq6P231ND7uvT+P9XQ639Zz/zWPXVn18S93Qxvu3VnSXXCb8vN + Rz+0aGGhhJ+BQ5zwseNkUITfoIkWLamFlrjaCRHcZ/aKX9OmSUycnz7ben471Mgu6ZSHwMikpN92YoI3 + kGdiLH6voukzSZtJJt09zIUxE/LC/5XX2+zgCRcAaNM6mQko/lD1CL9ofmk75bTjIGY0cPATbRptuBws + SG2GNq4lEFqgAeEW0yo+v5QDoVfutc+AtlLGtQXgwwbRCtH/qfJJqx7zEfSfmM8vtLNBZu6dYrr/+U4G + Lvae39fQ315fQ1fe2qVucf7tnTX0qXtq3Pturqd/z1+E0FDVAfseXIuNHVNT1542LPweYuG072RW+yyI + AD4OT4Q/+KLh1a4B4J6UiIHUk7dCMIIxSbvuDc5zfgc/4Lo1iyk9YLBu6mywwQZ9uWh+QKiPezTo1Gvr + 84FrXxD/vPvu6B7Orct/c2+Nf19H28/eXeM+fXcNffrGGvpM9/sz93QC8LZ6zg/8WYKuaCf+tpu1dQ11 + dJ656VbDDT4KLLTmBwg60j0ENcAIv9EmCXHa+61gDOGYaE4fEcrCMulinTwPsdIGLYzvzEQrSzsBg5MC + IgQ9S/30Sfg5lQpThIEwT64l1zRGJp92aDoOATxz4CC+CmifZmQitSfRzHJwYpd2kpZ2jTXtayc+mUHB + zffJPNCe8r7nlzYBnJIC6kX4YTz1zJnQImAO2vKB3JO3cxac5N6EYfZqk2D9v+TzA2gXs5cLILz92avv + rbEfvK6GvtBpIZ/pNJIrO03kypu76ztrzHuvrWO/19GoZ635tee+B9SYrv6ktdbr8Bi+L2aOP4zGn0Mo + FkRfo+uTW8ZGwqfLHJU7xDDfhKUDs8HNnaVFGaD9SyIVhCXRyMPD4W0WiTLKg3auW9B27iUQXn0HfA70 + 4O8NJ9fWod/wy7rB41ljLLzgwK1jLEJ+gD68CquOzf8ObrzuPpfC0Hs62v7tXTX+47fU+E/eUBOuvKnG + XXl1LfPBa+uF/3FLt9iM/+7acette9/qzE1HF2AtPCnCjw+E2ZvFaABOKzEJbY2vzoKlsUiEmOQk0n1l + 5Mxaz5m+jsFz1I/hEEqdTDLTT7sOVvgROEoRzMksU1db2nfYEHORlsKc1p/DBjsX4QQ8Z0o6NQ2TUL1N + 8PTp03tfS3ZQQoqpx/ennsWunPuEFrMwzKIfp7XqScxJb1x47sQX80fo0RBpnsIAMJODFGM0DhpkhA96 + xzcCJ4HMaAYwGX+pegSbBeRexm9jiPCzI6OdttExc2UO0MY1OsqlzFvmUB3XfIyEn43Hae//FZ9f5jDC + D1+gt43Gsy9cfX+N+fBtnSbSmbyfuKsW/9QdNeETN9fYbpFOuPyPdfp/3NN1e3/X3n21+9P2682xdadu + WPM57DtkXvGKV4zwRdaOg7X0C3Kd3DyHD7kjQARg+KOtH6GTfowhfcV1AdqNra0/2KY+03/ayXpJ2/md + xCoCcLFOB58TlsEzws9auGOOU9376wNX3VHj3//HTvh1tP1Yt7lceXuXOg3wM92m8+5b6nnei+iqe397 + 61k71ND4zuzt5MCC4EkRfvH5xfQhKBwkkPgWMZM0OxwhJifxB1N2DGXtIl6g1x5i57Q3ws/rXfyA4qII + Akf4NCWmItVcP/wn2nSwEAbhqNcXIQc/ix+YXM/0ifh2YkIsgtJrZXFKE1actIQJEINF+Hlm0pyIac+E + Eg756IF2CWYmKhCK4iDFMzuzibcL0wgdYnBYGwffiYWSAw504LhWT2K+JrSIoKcxM59mzJjRbyA2IbgM + HnhwrpsbQrCdg+23375PfptHuXlMbm48N1eeE+5ZCNpuX+9blNAv15F1/HiE3/BCbEHgvPHh8czfp6+5 + vyZ8rDO/PvWnGvuJW2qxT91dS13ZaYJX3llj33Ndnfpf93cmbrfxdGX36YTfEl39ddbesOtA+EaNxPm1 + woCpyBVBMEmUAJufezYz4Sn4ySZP4w7gUeWEfanjN9cRsOGbO/XwhRxvqJ9+lNeHsUXg4TPPbHS5h+/T + RjbRrHs84IQ3vCfHGznIs3atKfc8y6Z/5JFH9s9BzN7+wOMBn5V9oN71u3m12Ac74ddp12OuoFnTsq8f + 3mg6Oj/7R9067MXC3Npti21qzDgHHrP69h4d/iz8bjyhS53wu+6xCr8QxMJD3HYSCawkWkEWh2v3/JYQ + gGbnnvruIab7qeOZ3YMgAQSZRZw2mApikggcGqHDBW1qT90Ec4I3vOEN/T3tCroU5R6B6hrR1TOxBGqE + mIOBvJamLrM3cXf6hp96BArhG8A4NLmMRbweHIE2CRP1CA0nukCftCoCRj3PuRLUQ3PPMIn7knIEnGe0 + Pqdw8ERHwg0TA+MU15g3TCTzEVqlzmAOB2Uk1+6116Fn2nGoYwyLGp648Hu45gfQzXhtitGyr+hk4NAH + ru80v9tqzN/eU0NXdKkzyYauvK/Gvf+uOuY/7xxuqVP09txn35rQ0WjypHW7hodfu6Mxo1fmGA3DX5L7 + 7W9lmJX4MbjlOm9jSOZEzjoJhMdB6rbhaZL2HewAawzvwIFC0PYnAa4e+AV3yUluWxZoK7Ii9wCctW/T + B8rQDLXZH3jca7OfX+/9bdW4d13V0fbOGn9Fp/VdcUeN64g/9Om7auh9N9QzfzZ8Kjy3I/QOs2b1mt+M + mQs+8ND2ExZ+ASZRHP6DEyYNTmByZXO/fd4SM4k26YAgxBNO47627STtCSctLW1ghARzIq7TqrTJOc+H + ElAvvhf1CcNMJL9ivsiiT0I0wo/mZyf2zGmxPtTTH61YaAgBoZ6PFUQLZfbS7IKPQyOHL+pyqtOs0p/Y + yYTKMEVpX6nHVCIQgd0+hyHGQCM1P4CJny/sSC39Q/fQbbS5kdoyg3nq+OhEmH1RQj9zw9PXwRPz+WUc + 8fmZx3w+7MPdXrzE27pF+a6ra+x7b6yh995c4993bQ29pzPHXn9NHf6NzlJRsBN+e+13YI3rFuXkKeuR + AHXP3Af+4g2Plub6CV2lHFKxgFoIf7ZWSep4ewlkzaRs+I/FlPLpOxswSCSCzRsMtgOX9JV2+CE9T9lW + 2IHUBRlfOyZaoHv85HfcM3xg9PafzqvF3/abjq6d1vfeW7v8zv60d8zlHZ3f8Ls689/urAe6adLyjlt2 + 62lM12aXLxgWUvgZjAVnUXOmc+gnnCWxP+7J+Qucdgq3cJLluWdyv9XzO224T8Njcjj5bVVy/jDt6FNd + wshO6lUrZfVD3YZH3mIA/FGeESbqEUAB5jGzVLvqUtExqN3M+NyHi/reYsgpMc0voS4mLWYv4HNjtmY3 + dsjgNBhjirtCk9AH7gHadCvgnDYSXtqlAfr6jF0aswp3iYnDD6lti9Xz9hmmJ9CdxqfPzEXmKTRt5yZz + adzyzE1Sypkr14TzUwH6GRhZa49f+LULF03Mg80xcX6/uO2BuujH99TLfn5vvfzH99YrfvpAvepnd/T5 + Rd+7rz6ZM6iu430PPKB3xK+51lQN9122b3iYE45/loHNU1gUF0QrAF2zsAA+EGKlPD61kbdlCaN8ks2a + cVCBL5W3PtThy1aHYNWf5Bk8PHf4RwjT0NTlemkDn2l+6qdfZblQlDMGm7VyrdC0bllGykj64WsHyhJ+ + 2tPnfNPQpe91e81FP3igo+vcjt731at+8kC98id3dOmuesUP7q4v39iJSH9h6sG5tcvWndnbCb/NN/1f + NnsNKoucE5/jnPklzzWBJflNm8nz3OM8znVbV2CwRAg4tFAugg8IM1EOI9L6qPDMUlqWl/f1RRtShpDK + bsdPpx9t6jcCTNvKpE1lCBBt0jq17z58CLT4+9QR6hKfH+FnQgHa0LocYkT4Mae1yecoZouWpE3aRD49 + xURhWgmDYUqqBxeCLTRQllZpjJgMHvozJ3yDcJRawecZAeq+caJp5shv17mH9q7hljJS5kVq2yCQ4ew3 + 32IrOBYVLKzwC5gPm2G0m5F3vOfcWrignxFtSPOG/1oIGD5Kc+Axt/Y/cJ9eI1l72vr9QrWwbazRuMx/ + 1pK2JZaIZ60WyB+OB5T11k/up5w8bfpUG8ADKeNZqx2qb80AffLptc/bpC4hHYjw86ytE17nRwwEZ199 + 8Uy9lkdilvNze06T5e+reag4t3CxmEkCC3jNzVs06N+v4L7+/Jq1zdY1NG6oNtn8/4HZawCtAAlkInMv + wuexQBZxC23bgfRBKNlxMrEYdbQ2BiH1QXuderSgTCgTdHB8+e3gIq+pEX52zzxzYMKJ7RncpDApcyJh + IW3/gElNm0z/tLgwSMq3+OR6sB0QwdhCfstbOuX3aLRr22ifp+/ca/FalNBjO4LyExN+GXPMXj7SHDzh + euHqTK6RNh58oOtnft03t5ur/r2re+vuB++pQw49sBd+k9dZuxN8XeHuf5aKNvGtg65BmtOMMv8RaNH8 + AP4kREYTVsrT/MwFXsrrj6MlbweFt/iy3SPAWsGWa5pj5pe7Jc/lUsrJ+bsBGoaOec/f89Ax48anMXv5 + /Dwdngtzp0x3rWuoao5N7PFDj3wpbKfd9uwPPDbfZEZ3c0GwkJofGGR+4FqiBdAYnERJtBWQOjQXOwSn + fBtG0f524qScCdImQtJ8PKfBMUH5JxCVCs8EU1YfyqpLA0vIiDbSvzzCgQZFKyJM9e/gwCSZXK/vOUnT + X0JzJGMTRyUO0aRhMiZyAP40v+zeToMJQ5qfXVwcl77hq394atepNc1QOQ5ni0//nmkzjKMuGmesgAaG + NtqSh57wjobRptAi9YE2jRXNnDLSpJVLP1LmGy5MXbSDm7pPBehHMzKkJyb8Msac9uKFnGLO3GKbmrnJ + FrXZjE1rs0037/2+m26yUW2x6czaYpMta+uNNqwZMzeqzbbeupZYbPHe7J00ZXLfn7Bcbg9t4lvxeMAc + ad/GR/hx2UhcJ/p2uAXQnxsiwobrxSlv/tyrFM3PWnHIpR+al3J4Cf8RcrSsjJPwizBTX1kHhuq6R/gF + 4uqhAYq00CbNUDn38Rwg2JVlHRmzgz6JWwcduVXSvzc8WDvWyyYbb1VbbTKrNp+xeV93441ndO1sUhtu + OqM22KK73mx6bbzVhrXB5tNr+oxpDx3QdBpw1/92m2zet/fo8CQIP5BreXufGWSH83kcr7YIw8jrXXL+ + L45Xr5Z5sV/OKe9achLkHt8YwQVMvABR952CajvvtgoZISgCTDJfSHaYgLBMiZiC8GyFhlNKTG53on4T + WplIQgienntGMCrnFJAfz0GHcpiMvyN0IHij+UlOs5wie11NaA1BC5i0wm60K4yFjw9tMKBDGT5N/j07 + I99avqoSwQX0h6betdVPaArf/BbIra92jnLd5gSfD0s4PDFv/Ig5pW6BGe3Ax+kzMwz+Fkxouiihx2AE + jSdu9hqLsUUASLlevEtOcZlaQ4t1aULHL93v8UOd6dctxKFxgr+XrCXGLNlpfsMaD7NXCAzfmt/aiZ/U + Zuq3+/xsmd9obgRsaItHUjZzR1FwD374K2Xdk8xn7okPdY+giWIRU1ublBJlzbF7BKVvDAai+YlYAMpS + PNyTsgnmYwpSDhiVzdgJwNzLu/bS2E5T9krgmKHxNW78Eh39xtfYjq7D95TpaNvRdNyE4blwb+z47n53 + b8WVVuvbfHRYSLM3kxPIJARMao7UTYgdIKekFqpF6ZndJsRoU+7xS9Bkop7HJM0ulcQsaYUfgRmT1CRb + pAQiQksgude02jAQSfvxYaSvtk/4xYw1PkKQczlt6otgzmLh7OUmyHOAhmjRnv5px2FM8MQ0xuaZQGqC + MbROWzRYtE2sVPps6WrBZfMB2kj9tCengeTdTMlC4/8LpCyBKLRImdDFdwifCtCPaoTMj0f4/ZmHM05j + ZHKKLaWxJF5VnpjI3FOGQHDtJFPut+c26oA5TRu+60j7cyAVmtP8AjYx7VIMWAW+/yhgPjGXNjX1HZrp + yz1alrIOKRJzmzaNS319E+xZV+37xInXtIbDSzS/8Eveakr4jaQ+WriHDwg+yg/ewIc51LMGbKq0tWiT + 1oFDF3WT0MdYQj/jdT99uBf6p46yFJMFw0JqfmEOAHm/5Q4EDNDip3FkYdgtLL6U459LsKREkFjkiJ24 + MSdsTAHaSMDEue+5pI662iL8tG2SLE4Tn8njO2s1GOWy6zl1EvunX/gGZ3Xb3xKByMSWex4Bw1fhFC/j + Y8omdlAifJghaINGoZ9yTJb0YafPyRpow3ccmLQ7aAuEXxvO0uKNNkxyZqp68CMwJbt0FgCwadBY0dT4 + 7OjZNOCc3FhiKimLHvkO3KKGJy78hjU/9AEZb36Dlg75DVJGnrmVo3ELKZf78e9mjuUsiPjTA60WhSfS + h01bHa6S3AsfmD/9tfi3EByMwVwGh/Aft0fu+YBG2s+BB5dPC3nO/x1cU7+NPUy/g3i1v8OToW/qtPTM + dfp9pHH+JSyk5gd0puN0auEwhfgKvKkglMIOSGozpXJSyvxiNkb4ERKkuAnkw6MC80t4C4L562TUwrKb + MQkcclDd5U5Gte9NE6o5E9L7kGL8CNwQX8gCvxd8LXjMxISEL+HDhM3bKTGlIzilnL4yifkB7V7aF2rg + vlhAZimtzSl0PlhqHA5N4GZH1CdfSL5iSyChl53O7sU3E80PMGX1Qcj4TBbh51kmPOVsLLQUbegPHdHG + DmlM8AlDMbHEL/JZMvkxu/lyLSQB3mirLoHebhrpV39epkcz5dBEm08F6CkyTJYOnpjZi0cHIXwemoN2 + HgbnJNAKmTZ3H++Hx/CqeXZwFsicOWUPL/sCEICPvwDoXgKGAS0zVkkga7WFdtPDm8rrP5ofi8s9SdhX + wHy7R3sLTZKD4BkcJNZNC235QOgy+Cy/W/q2QrCl9+AYR4eFEH4t0XSczh2XmwxCI29RBMnsZJCTWuHH + J8dnAQw0g5VT8+M7o11Qjy289BlcCFYLVd8SYZRJ8FtwdBaxg4D26J2vLb4XeNISI/hMYDQo13xgWRiE + RnZu5T2nFSrPdGRCAuPlu0s0vjrttwaNgRBEq4SvAOO3Y/Jnqif+ipkE2skPEOrw1582lUEnWmGYQptt + iE4WnNwYxIARztoxzvSjfq5brcRcSPxDTxXoOWNkPTxxn58xhxcDoQH6emYzssm3mztQTn3mnuc27dRN + m+aGf05MJlOVgPBxDFaCmEr1khNumS9lUz+uFWsksZs0R5o+s5Pm7t6gxQA3fMGnLtaTAhE+x9eeO8RK + nwRd4jytcbwezQ8t/ElT/Yj3NB5jkeBgXeYTanjH+JTlbtIPCG3gJOYWTsoYk35DB3QExuHA0+GPz8cp + l74XDAup+ek8iOealpKdzOlmCA6UQaTU4cQnoBDRgYITw0FQ3kkSU9AEtBMPMFHas/D1r2+TiCEymZID + C2Ulhw20oQg2O2VeXQJMcnUiAJVJWwQHvIzHhNK0lIOb59qUE1h8ZcpJds4IP4KHlgWMoV1gGU/AhhLh + J0QmX2tuAePAKZA+01YYK79pfNlQWhpJNi0hPEAbWcTAdfpOf2kbtPO7KKHHcIREj1/4tWPIeNs5CniW + t3HwQO6lDmitiBZaAQhaOhJemY/wlZS5YqKmfBvKkjXCUgqkDm2tBfVFYHjW8rk8829NDvbf8nrbZmtq + h37GNkg36zT1WXuDtM4hS8pQeHId/NImP2ZwVy71FgwLIfzaicpkG4SPDmShWkROZgFkM0jXypPYMSVp + ftG8gOcBJmD7bq1T4/Z5QLtOUgmfECTEUJdJmjARu0t2UslJGL8WMLbEHKmbtnLNLARwYDrH+dv2K2eq + 5g0TZZmkzFbPObDjHwstB4VXoNX8hL5E8wNhgpSXt3UHGSu/aZ1O2lo6hXl8lp/5GgH/SDBaP+61vLGo + oMdsBL3HL/zasYXGwDhbOsodSJh78x3+Ainn0M9zQnA0aNtDO79pRu3cSO3vvEcrRbhmfSiXDx/gcwqG + ZxQMoE7Ahh/BkoQPmL3G3Zq9aV9KHQcMwYMGmfsJTwu0NCT8KAHac+AC2o2UO4hcaMfrOm2zqAK0vNxX + RpvOCBYMT4LPz6BbZrfYqbhUbiefTnMIOYSJCusrx1Rab0Mow3/Bx+Eev5wDDWX9di2n7RF6TjqZF+5R + v6MOK0f1bf+SHA1UObsk1Vsf6gQH7cBT23ZaZT3TjpNZQocmqX2nrBgYofkhlaViU8+F02jfRDBtjYeg + kwutycQyZ6IV84MOCr/kLXO6js9PPcKTK6EVepLFw5z46Ec/2h/6eNNFDBXc21fT3PMbveBqszL+fALd + +KZNm9YL9YC+MgaarDmwy2vPPGnLiTB6xHWxqKGn4AgZn7jwa+cCDfh4bQ6SjUjKu7f4w8K06eP3gJAv + cW9o2tZTTiRDtCybP7eGZ/hNm6MJHDkfdfiF9saS4Y5JWXwmRMsXWFhO5q0NF2uTw0RtMCezAYr/gwfh + lvjXxMwSmL7cAjebeHgRLwRHfaMFfjVm43KoqCzhl3VA+IXG+JZl41sBaKE/uCXnO9e+fuGmD1pvaMRv + js782QuGhRB+IVyuQRagBc8HBGmmLYls8fLvOZl1Uisx5yBqEmkzTEFl7FSeu1YPMTAQX5i+LDrhIHYH + 5ZR34qWsycsugUD5w+ASYaYcZnVo4UAEnvw0/iiPSdIeLYsvArPDzSFLPnSqXf1qR18mxOGKNqjr2nMK + mt+hjUkn/JyCwY/Pj9mbHT/CBbS0BYQfWqhnwRBwQJspJ3eYw3cJP2M0DrkxZdzuacthDdqYLzgTgKEb + c9hChVsYG/jtk1sOpTAceqO99rSvfkz5RQ09VUZI+MR9fu38gSzu5Fl4+Z3UmnPJwWhlrRP90Hja5+jZ + 5lL6c9oL1AuOguYH21YXDPLXILjn4C912nZSPm2gRQ5Z5EAZa9291JUHd9c57VU2ZQjXAF+zexIIzUO/ + vPubui1dXLdW1oJhIYXfIORecqdTTIIgGKQzAKePwCCdNMYkbJNydoNWK6JVJe4tzNASOXXtxByiAAEt + 8Dy3cNuFSs23k6SuAOOMgyAgdNxPf0k0uJjryrfCogX90w4JTDgwOVvtSl2pXSgBroPslHDMaW+grcO0 + V04fGWto09KIn8obHOpqiwacZzaWfJS0bVs5C5V/NG2nTtp30j7aGP5fQ0+dERI9HuE3jHtLX35d43Ia + agES/r4XmTELPmbasgjkkrkG2smpOlN0kGZyZR0WtCFNNmcblDZZM4M5i0mbYvxsYPrRRtpPsinZjNvx + ADjxXVt32lGXRZD++fL0k/d5M6dpR1nRALQ99/A9zTM0sClqh3B0z1hYbvpERzG+yrG40qbnaJvoDjil + PDdNAqul4ElhCU2E5QyO85FhIc1eA0Z4EpcJB1Eqth0CsajazKMsOqkVHgZrt6E5mXiml0VJm7IjCF4U + qiHsAgGEjxAYFjjhpQ1aDaKYCAcPCRex82qHUAtBCBHPJQuYyWeRO9lkqvuIAfwI1rweBBCezzHjsEPB + 04GJgEpmKCGrHWMRcCqHr/79dnpGaJtwISg0NBpcxp8XwdEN/Sw4z5x0cw8QSPq3QUTzA3w6dnz960dc + ZUwXphMaoA181Y2JhsnyVRvzSAtnwji9w6g+IZYNh5mTMSW0RRtSaCKnVcLlqQD9jI+sgyem+WXB85UZ + I94IL+Gb0CAxcaDd/HKd1x9Dp8ENm6aexSy5br+NB+CS366zydngRS6AhKpI6QMPJMIh86m+NdCW005b + 95H874OQZy1ugMmLD4WPAfdziGh8KTc4xkBwCV2SB9+kfEgktH40XB8OCyn8AD+CkBWajMTXEZublpCX + mVuE/TYY/g7H6w4MlLMDWZB2JYveAuQPsQMQgoScxcwEDRHsuoQBqa+e+uoSkn4TDgHCOO0TTNR0PhE4 + wCWCgfBr//6tXZ9g9AzedivmHwF1xRVX9MKCaU4boAkKCUiKQPGMn5GA9AqY8AZC3diNq/URoRsNg2kM + NziimUQD1WeAcEUTTl4MnW+7KasuoUWwwtWrbhkjIZy/E4JxLCDCDX7ozhQ2fs/s6Jkn46CFokNS6EL4 + oWsrABYV9EtgZB08MeEXYWGjNEYJDwGHXtlk0O2RFp375jc8L1cn85l2c502bcwttO275ptOXWvQPT6v + zIeU64AymRv81QqSlM09fr6MHwwKl0F8QDvvhKkx8Q1GqOVP3OqLid8KwPaasLYhBLfQJji2uFqLqdsK + 9wXDQgi/dGTRxASQEDUhIybF+54twpLBtDuNZ7Sh7DaQD0FdE2w0r7Z8rgkXPjkw2mSBtJUceFlfn9qA + T9umxKkfIPxomsoomxNsQPgkXq6dpFy39/kqEwdGeCZK3jOqO4AjOlDn01bakQh+J9oAbQhRpk1bNrS1 + 67aBuiL0acrw8Uw/+muZxfWg8HJoFWbO4kxfcskzvr+4GRY19DM9Mt1P/MADGBOT1SbLd+wZl43xW4A2 + BuahwzrP0I9AFFcqcbfw2+YVxtBQQjcHb3zMDtnSpk2UdeD99awnbYfHWxM1z5mwaVc9ONPoxaymLfjY + 9PnD1XdgoIwNjgISnGyOyqpjbBScfHsPhD7iALWvTbnyrllyxpRYVnyFJpQKVlXWAVq1tAbWZmhE6YEb + ng+eXDQZO+UHnu0YnZQvGBZS8zMghCfRswgQ0IkLJiEYCT+CIw73TI5kIYoFpGmx2ZnMwAQjjh2AWU1Q + 8IHEz5dkkmhVBFAWsPJ2FX4OYQdhmBA4zANvE2yH4Z9gVsLTAsYQeQ/R5GAqmp8xKOf0mGakT35DO7vJ + Uk8bxpUxMzvkntH8nJrBi8BmitKWHIKgW4SOXdeGEryUyY7M/+lwKOOhLWNkZST9qmMczNP24wkWZ9pB + 72h4DpIczqC3a/ccWknm0alwXALqysN8mXdzYdzm4qkAPXVG1tQTP/BoN4J2odoAQ4s2z3PO/dCHph/I + vZSXEh6j/dE0ntYlAvTBUki5CD8HeH5rmy8wuGSOWlxzjWcCLArl3Nd3q6BI+VwckMOXReFZW9ZaaCE+ + yVyDjCXgedYmt4/+4Sg2dzQIbYKvFNrhwwXDQgi/DMJCpUUEEcKI/yw7mVe6hI4Ih2B2QRpx5I65va3h + vrCQHMVbqHyI6tPACI2cLkntwAkeZREPQZm0fImCH/nY4AdCWKCshW53InTgxnFrB7bDCWNhNmfC7G60 + JruLkBE7WDQqjMnv4JkwEqEv2qPlGbfk2j0aFJyye+lPSApGxnhhCLihB2GlDDoRZsbswKM1e4MbHxC8 + XRsLs4gAj3lBuOmLcNSOzUQ5/dBI4JO3CzjTJfPI/BIDiaFGo3+YT24hMXsHGXtRQD9zw9PXwcKZvTZi + AiqbKWD2Gq95kaMPl4RDPuUTbC/ZoNRlwUQJsJG7Vp/PED/hOc+0JdeuDdAmlf7No7LmUtsWPGUDXgSe + 8toWvUCIqMPXqx9tZr6sQWXxQU5xberpU1ImfKce3gqoY2OEe/gB3jZeOFkX6KBMwKaKplxRxpDxZIPJ + M8I8SpH1FvzIHOXxvLHALfjBVQ4XFtWC4UnQ/GgWbYxYuzAMwGFAFgN/G+IqY2Cc5yFOmAoh+AwJEu2k + rQwsO1bu0ZByMkloWLwpYzISkAxCRPi0whAEx3bhukbwtmyew9e1PLiD9nd7X9/8E5gDbvyBwRtEqxis + A5gKaGlczOEEsI6GMwheLWhfLB6maWkpDy2T/M5OHlqOlpTLfMvN7f+lAw+AbniRds6fSrgBfCG0SMJ3 + Nhmn57RwQo3wCG3Qxfzx4SqnDtNOPdcOn1gGDvncZ7XQul3rD6+wIPhateO63YwSnE+gaFMiaAA+CJ45 + TZZsoNqHTwC/qSusTHl4CIdKP+0XWFgtsXTCP5SAjIsPHM28vKA8IMjUcd84XEebVIbJKviZdUMRggMB + GdCWOXC2EOtOjG3wk/ArN9SCYSGEXwZEs6J9tYskk44R7EaAAKGVteXiQwFpD5hwWknbVqtWt4vTQPnk + gF3B7pVyCOwEOsIrub4iWBC+FR4RHMq0OIHUT/kImOQB5VIWpC8+i8QLollOCduyg33qi78Dw6unfruh + BAZxAu09OAgiHRR+uc6iCL3b59Ig/fOsreOaj6cdz6KCngojpHhiPr/MBcsk48uBRyD0Dq1TTi6FNrke + nB+/85EAGxto+wY0ynau2vbkFJDwGEjdQR4RIqU8/GiTIPgM5iDXGQ/rJnMbn3QSXCgz6Tt1aJZAW62S + lOcEf4Df271BsxkYS/z+6gY3gdlpKzSy2SwYFkL4pXOEJ5G9YuPEkWQOEk5QRaKT4FRZWhipTyiaUMf5 + TIF8rZkg1C6/E9PVzoDIjs3ldgR9uB8iRPNTz25nd/NM4qdqY/mCswl0Na/jDXmfhh81YJLn9n9kuhMd + XVlCevj3rbfdVD/71U/rxz/9Qf3uql/Vb3/zq/rlz35aP//xj+q2W2/uG8QEmvz9H67uzZKb/3RjveHi + 19YqK69Y48YO1WZbbFL//C9fe6if+b22+4v/+VX99Ge/qJ//4pcjO7dJJzTt9OiKzonz6/t4CPEwXd9O + R1OmAZ+rzSnXTHAOYgxpDgi0zFXoifFyP4uLtuqtDzuueWBqKCu5dhrtvjn9//8g54cLDMDvZKw2DvQ1 + J96IoD05BDC/gJbC6S7cyEk+oema31u4TA5EgMMmdc0l/kZvcwNSBrgWWqV/m3nazHvZEoEMJ2sRTvyR + SQ7EIhitE6FncBFbyHccy0h9fJJ62vHc4YTyDjLdB3Ci2YUHggfclFGPFuc394vNmhnOfYUW2somrG19 + A7F/eM/6jlsJhM+5Zoxdm8A9J9xiidE7bXM9LRieBOFH/acac3QLk+Ac52OwcAzEUbcDEeEYmEjohQUi + IYb7Jt3plVdn0iaGokUoR0PSvsQvoizTAvFMQhYc5qP5ZUHbKdrDEHl2LoKvz0cRIP3v7v/5frrsyuZa + euMb3trHzu284061+6671S477VzbzNq6Pz3utbK+Urfkukr7H3JQ7bzrLjV7t91r7TUn1VI+ad7htsNu + O9X3f/i9vhzm/MKXv1QzZ82qrWZtUwc/7ZA+xCf48BGGWWh+YcKMK2DT4KsT4yjshWni0MNpJNyYCMKG + OOD5+mwk2pQGNbtcE4ZO72jXDqQwsXY9I5AFpCZExnzZ6J4KYKqG/wGPX/NreYbGHHow60C0KImA6DfU + jm/aOWl5Kzlw7URSXbQOvzKLB+dUWevDcwd0aZMv3RqTInzNTdqUJ7WmbXjKKWqep08KR1tPYr63kPos + rmyOUvqUS9awdoWdhXfb4Hw+fOWEEQHt5sMI1i3hp35Lt/Q9CKPRbMHwJAi/tiNIMHNpAC1BLCyLyPF9 + C9ToCDGL1OLKQOTtoPSTvhxmxOch1MXC9MziJyjSN82P8GvNsDAPSPvMbALlfe/7QGeKf7wzMz9SH/nw + J+vjH7uyPvmJz9SHP/SJ+thHP1Uf/cgV9ekrP98JqO37T2r7xPZQnzomGNOlsePq0KOOrL/7h7+vv//y + V+oDn/xYjVlxuRqagLk7GgwtVksutVyNWXKZmtJpUZe87k31D1/6x7rqqqvrii9+oYaW4rwdWysvsVxv + rmfMnOdUeeOiYXEXZAwgTMFPlL+jkIQOWVw07YQYcEHE3EoKM6d87lkU8b14xzIxYhaGwxzwSIy5qKCn + zgiJnpjPL/zBXItDPXQX/hL+zmYUGKSFOmkrvNh+jSQ54ddC+oqgEbyfezHFJdq9+wm/CV6Zxwi/9K2s + Q0rPKSo2X/g5XEz98A3NHngupX/+x2yYoU17Us36ADSz3LM2gXZyzzc5A/jKPW1H8xtRVpp1C1znd0vv + tsyjw0IKPymTGuJghHxlYjARVPxyQF0aBSFmYu0ATN/RoB2cPpyOZmKp/3aXgFPm9Me0o5EEHtbOvM4U + 6OiEyE5iN9xwow7vybXeutNr6pT1avLkqZ3Zvn6naXXmXHc9ucunTF2n1ll/g1pimWVrzBIr1LilurTM + irXkKhNr6c7cH7P0MrXCmmvU5A3Wrw0236w2nb1LrTN751ptm81r2Q6XiVOn1fKT166lpq5bK03boFZe + fUpttslW9bwXXljPfsXLa+pmm9QKK65cqy2x/Eh8FDoRftkkaH520DyTMi6CTcxTFlMWQa4TOKsOnw9H + uvspH5oO/qahx9HvbR7aetqkFWkPDOKzKKHHaGQdPHHND6AVM5BPC8/6DqTDCTSw8DMf6E8TtojxMzPO + dXIHTkDbrBwmqfAUbgi0boWfdZQ2Mve0tYB5IOzyfjq6x7WUdl1LMXszTyD+N2skz/MHkODi8EI7xsat + BQ9WDYA/aww94CChj/xzn/tc33c2WW4Cb54oK3LBmNDCBg63HJARcminb8IvYwLBz4Yh8iB0BPrTHhy1 + rQ3nBQuGhRB+LYTpAeFjN0FEmgHzUBgGpvHVE8JGWQtEWEl2C8fT/BBOMrUhTEOsFPMM4VqhicgJvtS2 + vx3A9LCztJoPH4kTKoR2Yqo95QiT973nvf3EMhMnTvT2xvgaM5ZJahfrtLqxHV5ju+sx3e42rruWT+jU + 97Hja7HlVqglOwG5+KR1aom1162l1l23+z21Vp0+vTbYcstauROiQxNXqlV32LJ2fe4Ztcdzz6x9zj2z + Zu5/QK3IV7LeujW0ymo1tOTyNaMTfnsceFBN3GhGlzbshd96K63ZM1doihYWAGEzaPZimtAfwzk9i9Az + D0wJ94RGMLUwuHGjCy1SOQxnY6LFcU0ob75o5hgLzZzg6cMG5dRauwQtwYju6AtPJ4+t4FhU0FNuZK0/ + Mc0PZCwR6OgVTSebhIXvOZPY79B/tOvRaMPp71l7Smku0k8S90Ug7YRHWhjEGQze0xb8zX20q2h+Ev+h + sngq93y1RzvpcxAHedvnYP/8ctoxVjDYDv+fZ4QfaOsD5nDoCdQTfuO3cWQ+rJUFw0IIv5YIGbTcQsmp + DPPXbuE+AkfwAb9J8Gh+yrtm3sn5CQzIYJnLDkX0oV+5ncGOQOvLazOO3TFMzOy0SXUniIXXpG0EksaP + X2xY0HUCb/zinYk6dumasMSKNXaJVfo0YenVasKyq9fYZSbW4iuuVWOXX72WWaMTeBvMqCWnz6hx60+r + obWn1tDkybXqRhvXAcccXy999etrn3NOrzX33LFmnHBo7Xn+s+qVX/xU7Xj6iTVm/fVq9R22r2k77VLr + b7t97XbQoTUbU6y2Si225rAQXmelNXrfaGhFY8shgzi/hLq0gC7om3c+lXV6ljAIZqtQAzQwfnRGX2Vt + QIShNtAUbTE9vw1TWg7QXdKPpIzNKSfRaOt9ZO0saugpN0y+DhZO8wPmAh3yMdrQTrI5K0/4RUsLT0sJ + k8HHmVPz4aBCHfeV49ujYdOWbCrumcckZq/nwkDMq1xZcwL8FpBvDsS+cgf5QIDf8dmmf0oCnPjM3ZNo + e8E5H0NVx2/jZaJqh7YWgYkm+jUOPBG6wdM9+AVXBz5cUeSCAx/jx18B2qW++AOZ8kJuPE+bDjvgLJYY + wFlsKtoEb8mYFgxPgvBrmQRBaG00Lgg5tYmqHKJnogANY3B3GxyIRNvJ2x8WZ9oCgintYsqF4aJNtm25 + fnjbYzuh12lzY7r+O41v3GLLdxrecjW+E3iLLTWxxi27Ri22wqQa36Uxy69Z41fqtLlO+EmLrb5uLdOZ + rWtsvU2t0Jm3Y6etV4t1pu5yG2xYW8/er1762jfVMy5+da21yw616k7b1vpHHFgnve11temxh9eE9det + E5//gnrn5z9Xexx7bI2bvGattNnGtcwG69XSU/hKx9daK67RC/WMk6ZKsMDbQnKijY6hfRgR0BgyRqaN + RaYdTOpZu0Nmc7FZCDYH7XwGMtcguXtwoE1HEGgr3yhc1NBjOcImT1zza/lVNILFFz6SGzvLAtCOs0ll + DvA38047hANAO5uGung19EubNqjci1/Nb8+U16YNzDNl4y7iZ6Pdc+M48bShmVe53w5EgP7xDJ6AV8bo + rSMRAdxKogOUI8QSqE/LklhdDjkBPg2+DjuB9kQHuB9lBP/axLXJiiMEjYXvEk9JNMPwZsbGrQLUg6/1 + D3fl3WMtht6h2f+TIOdAkJGYZE54CUD+OJog8Myg7QQkPqLSUoSvkPS0Rb5COXPN7iB55uTSZIR5MJkJ + 15aTRra+HVloTYKIETGETE4z1D7tadiPt26tuMoaneBbtsZ2wo/QG1psleG0/Co1ZoVul19x1Ro/cc2a + sPqkWnptpu7UGj9pSq2w7rSascuutf4eu9VyMzet5TebWatutnktN3WDWnPapv396bvvVpO237bW7ITg + 6nvvVDOOOKDW2XG7etErL6oP/+Pf18HnnVVDUzotedLEWn6TDWtiR69JU6fVZhtu1vv87HzGyJw0NgyD + tvExoTuaMFHsrspzJWS8NL/EpSmH3tkYUkbCaAkPME8WuV3b3x8R0pE541Oyg+fwwwET3NImbdIB01MB + ngzhhxYtoEtoZsFl0eF5ZdEs95JLaJe2knO3tGWSogy07bfCcbTkECobYIsz4QAGxwFyL4Ivvx+tHaA8 + RcSBnGtaZXAVipKy8ftnDHLukTwP7gnvAfFB55lxC19pocUF4NuUlaufQ5pHh4UQfiHOIGEtGGYAiWyn + yR/wUc5u4VUtTkn2vQBFwlG8Ez8eB6u6+U1rpEl6PSjqsXbstASeEysxP3ZRfanrd7uw2+TrK5yxnKRf + +Myn6guf+3y95a1vrzXXmlwTxo3vhEC3iBdfvtP0Og1suTW6vNudVp1UY1dZvZbqBN6ULbeq/U88qTbc + aedaec21a/IO29W0ww+oVXbfoZbddKNacYPptcYWW9Tym25cK2+1ea2zy069AFxz+1m17fFH1oUfubwO + evZZNfOAvWuHY4+srQ4/qCZutUWtPH3DWnmtKbXB+hvVJRddXFd89JMjflI+NyYQnxpzF+5/+MM1I0wg + JAYt0VUuJizj5UsisNCM8OP3Y/57FiaLZtEKP4JUOBHnMue++UJv7wPzCeZDEsxeuznGy07dvrWyKKHn + yhHWfDzC78+LK4Ig4DetijYSP52UzcimwC/GndP+UXC0pK23BwZO3tt5SC7hX6Ydy0hf5g3dOfVTZscd + hkPHzjz79D7udP7cboQd6g92meiBn1/1m/rtr39Tv/5ll37zu/rD766q637RbWa//F398nfDsadX/e6a + +mV37/e/+WX96qpf1k9//5v6+W9+Vdf89hf166t+V7/49e/qt7/vrn/7w05xuacP+QK/+dW1/bom/Gy8 + xmvTtZ5thvzKLJSMJXQSr4q/0JF2qV57CMfCcY8vOXzJ7xxeV2YQmPnWClqpi1580guGhTR7pSAUBMFo + 9wD1v51sg6XKAmURM3VHG2juGWwkvSDnnIxqC4O5n5T+lMe4wenBOcNa5NXX3lDTN9yoK9NpiostWYst + 35m8K06pxVdduxZbZXKN74TfMlPW7gTgxNpkt93rZW+7rHY78um1+MwZtczWm9W0Q/fvzdoVt9uqll5/ + Wq22yaY1pdvB1tl9l5q60w41Zbuta+LWm9d2Jzy9Trz45bX76SfUBnvtWhvM3qMvs1anCa7eqelLrrZm + LbXsSvXFL3ylZ+AdOsGaMWD+LMRhmveXPb0Iw9YUC10kvlBaG6C15MMG2RxSlrYhbkwf2uRfTbhSymgf + Q+ZjqvCgyducoq3wd/1f+aRVy7vhTcDsAjaA0MVGnft4VOIby8JXLos582jDTn05OudailAA6miT1p0y + V3zi0/2zOfPu6wW2Yczv/tlp511raAyh0/XZlVt8XDfX3fWQnKtH++O65N6Y8d3vxWqx7p6y48Z3JvvQ + hP63suPHLd3/FtIltOtr/8ilcX/Xz5/f1wWhFcGfMSVlPBLhF5jX8EhoEtBe3AEE2uBz0N5rZUU7b48O + T5LZCx4NQQhBkGYW4sizY4IMoB1ICCR3X64tPgw+D+1wbsbPxAzL+4vtos1itzt5cbpvZ97wBF574001 + feOZ/UnuhGVXqAkrrdmZvGvUEhOn1lJrrF1LrDmlll9nvVp2nXVr+fWm1fo77FjrbrtdrbLztrXhAfvU + rKOPqEn77VFjNppWy66/fq3Vmb5Tdty+1urM3Y33nd2buWvvukNt+LS9a9Wdt66h9daqmZ22+OoPf7CO + e9lLa6mZm9SyG29cS02ZWkNLLVOXvfPyurPbZffdd+8eZ4KFvwX8mUZ91o+DJmuXDU2z4OTM3viDaGk0 + EO2lTGgk5SQP0LKZ2e6n3SSCNp82QkumjHa0S/j9/7/m92c+xr8tX7f8aNMJbeLzy/ygo3uhWejM7wXU + pyFlDsKfySUB6YG06wsqKfPG17+pxw2+hB/M7rn3/tphpx1r1912rN322L22mja1dttgjdpp/VVr9aWG + atKqy9bSy3TWzWJDtfISw3/kf8yExYpAHNf362/UjKvllpwwLAy7tETX34rLLFErrzi2Lnnti7pehoV8 + eCX0MSabK9xCl3Y8rm2UIOMJPQMtrXNwRPMLpM8/r4M/54P3FgwLIfxaRCGVTvmIxPWYXCoptThIOyUS + +sJcpcLzewgTEAipLA3OjsnM9Zum6DltIq976cfXXnLCKESDnwkhaTeJVZIGFy7VOObznDn313/813/W + xW94Y62weifwJizembor1rhV1qpxEyePCL+hFVapsRNXq4kbbVzLdAJwfKcRbbrXXnXq2c+uZ7/opXXo + uefUTmefWrudeWrtfOhhNXXW1rXSztt0Wl8n9HbevnY46vA6+RUX1vr77lHjNl6vdjz9+Lrk81fUmzoz + fc8zTq8Jm8yoxWdsWItNmdKZ2SvUW9757rr1zrs6Gu03gjeTE029nYE+11zz5z9Ew+HMPGWSKiduK/UI + P/QHhJ9dNAcnfKS+RO2ETT2ObG1zH0g2Cia3dr1ZwMxjyvkKjvnQNzOP8Et/NqS8r7yooefGkXWwcJof + CL8bt0TbM2ZCP+YsXzR64XEbVt5OkuNnfJ63bdrX02iBNnBlBU/LHVwoJ6bSCwCSgwY+Nu1xfcDjd7/7 + Tc/zhnHfPffWA3fc1kmVezsbfG798etfqh+/64X188vPqY89f9960RHb15G7zqrZW25eFxxzbB281961 + xrpTa6Upq9RqUybWYp2Qm7zuWrXHnlvXCcfsVCcet1NtP2vtOv2kA+o5zzmwvvzl9/b06pbOX9AHOHCB + PxzbWN8IQXgOQjRm4A+M4TOn2qmHD40zgtI1awY98K8U+uBPtFdnwbCQmh9EMEUQc02bY4o6WPAuaOvn + sAD5CvgbJKEXDjwkgZ5OdfMOr9MiiZllQMqHUHwLdgbEofnlFTZ+LYuR0PPMrhoB6JqPRLS7soQCn9qK + q06sJVZYqTNzV6+hFbu00uo1dtW1avFOAK6y3oY1dYtOmG0wvZabtm6tOGNGLdHht/6uu9QLzntxnX7K + ObXjIYfWue//m/rYz79X577u4pq4+Wa9Vjhtlx07DXDb2rHTDI85//m18f571aRdt6+Xffz99b7vfKP2 + 7iZoqU02rlU7DXH17bat8Wt0Ani55etdH/pg3doJlb33nj1iTjrECZ0I+w9/+KMjNGfqOwyi4RmTnVId + ifDDKOiG9sznvCmCWTCpzQpthTl4x9QcYD6LUbtCEjwXeuBangMPudcJaRDajNn7VICFFX6B1pwFWfTt + Gx543Hx4tS8LPYs29YC6nkUTTMqhlOcRstZGW1ZuPQWMR9vf/ta/1RGHHV7z53aY3353fe+rf1+/+fpX + 62/f86H67qf/tr7+rnfW+1/04vrK+z5Yb3/la+q8px9T5x99XD3/6FNqr132rpnbbV/rbDKtJnUWydIr + LV2LLzOhZm6xdp17zk715jeeWgfvP6t22W6jWnedCXXFJ98+TK+HhpT1P2jyAwdz8G4VELwS+oV/81tO + bqSs8UpOg1MmQIFJuTa162XBsBDCL8iDXMtJd9qFQfNzCEAG7QBCIGYYbSHIp05LMARw+tuemNFSQhwM + 4eQJ+MSNb9ClXtpMW7QWJ6JAhL2/ETI0dkwttdKqteTqUzsNb3IttuY6NX61YeG30U671UEnn1ob7bJz + LTl1ck2aNavW3mH7mrr9DrXl7rNrs5136663q+Pe8tp690+/W8e//qJapdtV+frW22X72mifPWv9PXap + Tfbbq45/0fPrOW99Q51w0UtqpzNPrnV2361W2HKLmrjN1rXGVlvWsp2QH9uZvR/95Cfqljtu73a04Xcv + W/wlp+jvfvd7+jGAlvZojDZZgA4rIqg882mmuAto3gQfUDcxXuiGibxDHQjdBwHjC3UJjvqlvT9S+f+X + 0GMwgsYTN3uBDQS/ePFfbhPI14OMPSEk+A/t3KNR2zzUoRGpR0u3ydvgBfKGR0UstDQzH77+TDuUlENb + p6GUB/3feMvwO9T/8/Nf1OsveUM/jrl33FlXvu3N9U9/8+a67M1vqP/67+90RuoDdf2t19ddD95b93Zj + +89vf6ueddQJtfO2e9VmW+xWM2duV7tsvV1tvfFGNZWLp1MEllt+qdp0k9Vr9p5b1OQ1lq11p6xUm2+2 + Vl3+ruF+7r5r7ghftSCCw0ZpzJQfOJMFNlXjZsW140RfFl3GZONW1pjzMRMHmOgYWsppvqGdNCgzCNEF + w5Pg8zNRYRLg80v8QpCgqfjtOc0DwewStBVaGk2MtgBxTOPaaSRNAtE4PS1WQsrxunYQj3M+p5ZOxZhr + QB9O0RAdQZw+tqebToKEI4Drrrm+9ttn32FBscTStczk9WvxKRvUhM7UnbD6pJqwyho1bZsdatv9Dqj1 + OwG3ZGcerLPjDjX7xBNq2m6718pbbNaf9k7pBN30Q/avvV78rNr3+efVFoce1J/wrrPTtrXebjvWenvs + 3GmKO9UR55xVz33DJTXriENr+W22qDU6s3jyzjv0J8JTt9iq1tt4084UXa1jkE/UNddd3Wlte/U0gT8a + 9Hh242BOfOpTnx5hIvR38ICufJ7tdxAJvxx4oL1n0fyYVImd1AYXROoxnQm/dkfPNdAfptWmzS6anznL + RrSooafOyDp74pof2tDiRttMc503bvBWaJFn6rk2f9ZFgFLgOT5tX8HMWrJZobvcmx/Kpl1tvfVvLh15 + RdMpbL8Fzp9Tf/j+t+rbH3t3/eCbX687b/UnVLsCns+hfMytu266pV551gvriAOPqqMOPLb22WqnesNz + nl0XnnlabTht/Zq41tRaZsVVapmlV+z6GV/rrbdGvfHN59ehh+1W733vW7vu5tR3vv39kdfSwofZXINn + 6MX6aEH51JHzH4dWzgRyP2BzRaOMXZ61kLx9Jv2vx/llcgKYBPhiCAHEfhd9LYSChscHQor72rBTV4nW + FlWVmuwgw4kQ7U1d7QiclHtfTx0Bl7QUr8p54Z4TVZwTwDhCP9z3XNKWD5zyE/IlWsRwv/P2u+rvPvf5 + /lh91clr19DyE2uxSdNrycnT+rCWldbZoBZfY63+sGPiJhvVWrO26IXfLscdU0c+93m1w2GH1YzONN2w + S6t22t6MPfeow5/77Dr4ec+q9TqNb4sD9+lDWjY5YK/afP996qhzz6l9Tzixpu+1Z6279x41rSszaaft + a+3OxNxk2+1rq1nd7rvFlnX4wQfVi178vG78b+xp4ETcZ5Liq7MjfuITw19yNg4f0BQKg7ZMpSwUjMFl + kNfazIN3R8NIzF5/wMgcohthx8mOtuagNcXanHlN4Nm4zIn5MD9wlVof76KEnjNH2POJCz+QVybRtF1w + kkXXCq/2eQRAq6UANHdQlQWbDbldTy1kw2rbsUlawPA3Nm/SdgZofeHjl9en3vry+vrnr6w/XntN/faG + m+uqbi7vn3t73Ve3dzXm1Y2/u7kuOeuZ9Zk3v70+/LKX1flP379mz5pWM7bYoJZea81aseObxR2MjB2q + XfecVa9/04trg+nr1Cev+EjX3V31tc6szibXznVOe9vkc2fA2DI+uXpy/K2csbWnwSkj/C3P23ZbYZfr + 5P/rwq8dSBIIMeQ0hPbrExkABmmRl7y6kgU3CEwGBxypQ7AGslOm/wjhFtzLc9ATvsvnzXuwEx6/qmnr + T68xiy1ZS0xcrX9FbYNOs9t81z1q8oab1DKdCTx5s81q12OeXtsddVhn9m5b577qFfWySy6u/bp7Wx+4 + d20we6fa/OB96tjzn1NHPeec2vPow+uoc06vvU4+pmYd+rQ67Jxz6uXvvrz2OuvUWn2PTlucvX1N22Xr + mrrVFjVp481r0qZb1zqzdqx1N9u2xo5ZvJYcmjCyoODq+2jeljH+9pVB4BCEhosugwwiDdI5ZaL5tXRp + aTc4n/nta9wEZ9q2eQzCaHPw/xp6bEeG9niE358Xc8ZM8zNWfGuDsdk4ZAoNfE/OnyewwXp53ybt4MNz + dcRg2iRsQAKBbc5iTiMonZKKTaN920A8d23jl1MKxMXlk0/SvoccVpdc/MZ66+vf3Gt4xnjffbfVm195 + fr3v1S+vL37uK/Xbq6+pP954ff3hj7+re+72mli3Vrr/b/j1NfXVy95WV337X+ua//p2HTtr4zpvt63r + pD07a2SN1WvMchNr9ZVWqSWWXbJWnLhCTVlrYi3e9fnGS17TUcf73X8ciSIIoJUxBj9WFjrxwQfwUvgJ + qGMDRhfWXP6aIKuCwoKmPmbAlaMtZaIAqSNveTG8/f/k9TYpDNJCmJ9Z5IQKYtHwWiRdRxPxagsf1ODC + 8RtREjSpPAbLd+PSv7xdqJK6LX7BV84MEBjqix2CnIe6dsctt0KtOWOTOuLMc+vYTmDttP8Btf3svWub + ffetw847u058yYtrxuxda7uDDqgLXvfqOvvCF9Texx1RWx+8d2132H510gXPqfPfekmd2Jm/Z1z4/Nr7 + 9ONr1pEH1TM7QfnGbqcm/Kbtv2ttdMButVEnANfacpNaUWzgZlvViptuXqtvvmUNjZtQyyw1/EfDI9i5 + DqL5OZDIWzPG50Sc/wgtPU9Cpywu9JbyW1knvPwsoDVp2znVf54l53NRV3vcFIQBeCReWFTQYzKCzhPT + /DIewi90DY/hyfCxFHqnjgOjPItv1TO/0T/zlTlJnue5lggDdSkHf34uZm9sjR8a12vb9wndmndffePT + n6xPdMrBDzvTFCZ3PXBP3Xn3bZ0W+Pu6tytz7/331fVXX1t3/uRH9aPPfrF+/NnP1xde/4p625kH18uP + 371eeNbRtV23wa/WaX/LTly1xk9YvMZ1/ejvze98e6dbdpTs7OyMEz2SCGj4oUsAj+Y5SD33QX6H193n + Ow0N+OkDaSOgLsUgdEr6X/f5QUTnFoX3a72I76SP2elNDvcwQF5WlpzC+IacT/M4UWyjwPkGOMt9qocJ + 5ntzHMHa5VAWHuMjncw+piz/FsAYGJEaLkRg0Oxqifwwwisyb36vyUzfuDO/l1u2llpl1Zo0fUZnhu5Y + M7q+znj+C+qN731vHXjyiTWzM1N3Pf6o2miv3WrTPXer2cccUgeecnSn5R1ch5xxfJ350ufXS9/W7f6X + X1oXvOW1dearzq8Dzjuttnr6wTX7tBP7E999n3lGbX/sobX/6cfVmRc8s4447fja8aD9a4Ndd6qJs7as + VTebWStPndrRYr/eOR7c+T3y2h5TluMYeM75a/fzYVIvyO+www49bdGK4ziLsl1cmNMrg2LVBDTrK8kp + Jpqgq/bR0hsf5tRGkb+hrB2vCzLJlfdM4K95CZ0XJfQYjKDx+IVfeEhujMZrA7ehGx8/s3vZvC1Wm4Hn + gAkXuif2UVxkysqTMjfut/OU6/z1N+3k2WLjJ/RxeMpc/6ebOqzn1/333VW3/M8v6rf/8PX6+Xe+34+t + m8GaM//eunfu3f2hx33zH6ibb7ixfvuNf68rX/ry+vFH3l3Xf/vv6plPn10vOHr/+od3XFJvO+/4WmXN + 1Wu51SbWKquvVePHOJScUBe8+qKHhN+w730QbIQ5wIwpP7ixtvkg5L46sWa4bVpo6+JPLpfQJPRrT8Uf + GZ4Es9euRmsTFCs0hc/JQQe7mx+PuZpJJOCESnjlygkPk4lGA2mOYqc76vMTWLhOiPxmohGCBKNAT/FU + AUKSY997r/qnDsOtJZJrhELUkUnrn8+v3/7xqtp29s618Q5b165dO2tvvGmNXXbFWnKttWrGjjvWTocc + 1Gt6Oxx5SK/1rb/bjrXLUYfXc97ymjr5Jc+rvU56er3ug++qf/7p9+q9X7yyXvney+qNn/pgnfemV9XT + nv+M2v3M42uXk46uzQ47oLY46sDa4tC968izT643XHZJ/fO/f70++/dfqj0OO7SWWGdKTVhrjXrO+RfW + r3/+q5E3X+yI/CI5uHEYQfPLOBwc2WgsEPRxskijQ2MmRz5bJVmo0VbQO/TFLGieEzaCEV0jfJ08mk/0 + NS8WedoyvwSvZ3jABpR6ixJ66oysz8cv/DIGdMazBLzN2EbjkA2tQtfQFA/aNPAbbT3P0Yw2ki9nR/hl + XZhPSgOa+zOtNhoxqSkb4ceNBA9ljzzisBo/brid573ohb1QmzdvTn3sPZfXZ959eX3tU5+re2+/vR/P + A3Purvs7AXh/J7poiH/stPdPXPrqescFz6ovXnpJ/cfH3lcfeO559dHnPas+95qX1KXPOaV223KzDu8p + td60SbXFJhvUKkstUW+/7C29MP3hj3/Ur0NA8fD3aCg1QtC4a7hTxIYaMz9gaMmcZ5LaoGl31iN+wVs2 + bnTVljKhjVNj7Uj6kDv1lgv7Yg5TluCBj9XxbMGwEMIPGBTG0FmQlbIbSploOT8HxohgcgjCmdvWDSNJ + 7qvn5WfaByAMJH1jTAPPF4ntOq2arIyyERQjgq+H+Z0JcE99/5c/qcOecUKd96oL64TnPrumdxrTahvM + qDVnblrLrrdODU1cuVacOaM2P2DvXuvbt9PiTn3Z+fXR736zvnbV/9TbPn9lnf/2t9QH/uFL9YXv/0dd + 9nefqRe869La+5yTa4dTj6r9n3NGXfzJD9SpF7+0ph+yR2243y61S2cin/+aC+tL3/hKveVdl9Ws2bvX + ChusV0Mrr9jH+d13z/DfMgmdaBF2QvQQ9hOfn+ftmIy1vUcTwzxxOYSm0QZzT0L3lKNl0mwigM2TTarV + cuTaaOtJtPfgvSihp8AIaZ6Y2RutpR1Py88tr7oWhkRAob+NJzQOzVMudUI3dQaBny/lImjwc3A565wz + +2fezth+2+36P5lw95x7a7d9dqud99ipLnnx+fXdf/tmzZl7bzeoTl/rBON984fpcNetd9a7L7u4Lnrp + eXXpK55ZH3/Vc+trb3lVffIlz6pPvvr59YoTn1ZHbb9FnXPUvnX+2YfVhc94Wp1y4Pb17//42a72/Prq + P3xj5JVSwit4OiwLRAO0ueJLQOj1OHe0QyNJO49E0/Z+e53nksM8gC4Cnt3T54JhIYSfiQAcnyS1Tluh + 1y6uXBNSWZxSexjSlh9kFKYe7cZiVA+ECcT+cCgrS5vx3m/KJAcRgqknN4J/+s6/1YEnHVMvffub62nP + OLUmbb1lTdx4k1pt801rlS26NGuzWmnLTWulLTaprQ45sJ79ptfVC7qyh134vHrph99TF7zvnXXQs86u + pz3zrDr51S+rfZ59Zv8Wx46nHVvbdlrhM99ySV3ZCcpXfuw9tcUJh9QqO2xae598VL3nq5+p13/o3bXZ + HrvU5C02q1VnblRjVlul3vb+99b9nTkePC1ATvLQh/DL62UthMFA6tJU2jlx3TKPNvNFFin0tiEJZcji + 52TOQk19vwfnmBb4f+n1NoBnaNE2WVqNgydjl9M8aCyEHhrIs2HkzRd0ofk5aaexWCvcEurSeGg7Qjxo + e9Hw9MnVQQvSvti5zClw/bo3v7623X672nLzLeqCF3rtrHqf3j5HHFDb7rdzPffMM+qDH7i87rr7tq6C + L87cUv/xk591m/1v64c/+3Vd9rFP1KXvu6wufdPz6+2vPKnedclp9bLnH1wvPWufes1xu9YLjzmornjj + BfXZNz23nnPAzDr3sFn1rW98uuZ2AvaXP7lqJExKbixwbV9XZf0Zf0JdyAvCkQyQ8JcxO9QIH4W38CFa + oVnakVgq6JW/aaIel4R2aMQ0P3X/1097I/z4eJhlTl5IYd8PEzLh2u5lwAmhcFBBNXadP2hu8AJGOZVp + KQZFy2FesOctPCdgAigDdhttOgkTRhMThGnY+gh6AdfhGVztoPpmUlzy2tfV1X/8Q/3kN7+sDbedVUec + fXodeMaptfqWW9RyG87oBN9mtcwmM2rDg/evg5//7Nru6CP719W2OOSAzoQ9sPY+8+Q683VdW1064ZUX + 9P68LY86uGY+/Wm12TEH1zadQD3jDa+uD339q/WHuffVF3/yn7Xfi8+pDQ7bq2Yd2dV/7pm1/7mn1+Z7 + z66tOwaZ0vVL89ts+x3qrZde1m8qET7MIXSl4jv5QkPJSRg6o6Vx+S2hDdoyM8yL0/F8102eOclvddzj + MuC0Vs+Cj0BFb/05kRSqxMTFeGHWMC+NUdmnAiys8AvPEEQW2KDG4VNLynjO2rDoCETmHCD8bDZo037m + q92AAxY5gWqTB56H9soHF/fbuqIVepB16Z577qrZ++1R628yrfbdfce6+JJXdevz9v7ZH66/pa7853+v + l73nA/XCy95dx1z47DrxFefXKRe+oF70smfWW15zSn3grafXOSfsUIfuP7NOOWifuui8E+t9LzmrPv2q + c+u1ZxxSv/q+ue2UiIfvDyM4JYczHkEn/mG/AxmXTbelaTZh98RDhvf5t91HS5s54PZqBWXayPX/uuYH + DNZO551aZqlXxyAmufYailNZCVNQcWkHdkiM4ssVTrAEJ/tybHwiBm/BEqz5misCRnsjBLRBQ3FoEueo + 3+LPWmK3EyOwVHkq+cwZm9Y3v/Evdff9D9SUDafXMpPWqjU3n1mrbbF5rbDJprVct7ssv9UWNXXf2bXX + eWfWtsc+vSbvuH1N32d2bbD/3nXKK15cL37Hm+v5f/PGet4731THvOIFtfVxh9RmRx1YuzzjuNrulOPq + 6JeeXy95x2X1vs9/tl7ynsvq5EsvqlMve03NPuekWqozK1bdblbN2nvf2v3AQ+qks8+tk848u8aNX6Km + rD6pf/UsTM+vh4acyOL6hFYYv7Ggo+vQ1T255KsuhJi5UN+8mAe/k2eu5DYY9HadhZ051jeHPd+K0170 + xoBJGA9d25i3RQk9B4ywwRPX/Iyf9mK8EfJyUQwB1ob7aM/nB2zY7kkOg0DLly0QespxLYRfgevU+Yu6 + w6wx8udXzdd9d91eR3bWyT677VC7bL9VvfwVF9Q8J7NdGd8weu8//nOd8Ia31tGve1Pte+5RNeuYQ7uN + +uja6NCD6rDOSvmb151fFz3/xDry0O3qiL33rJWWGKpdNp5cX7/8zfXKYw+tf/88i8M7I8MwiCsInnzH + +IJVBgafR3iFf0IrKZ+xB2J1Q3fWX4RnW16K4CMkWYALhoUQfhlEO6iWGIEsYEhTdSGYwfBlRcI7GeY7 + dN/gOdkDgxOf8Bllk2tT4mAFqSNPyskQQi29zHL1uc99oR7suGeDaeuXv9fhs1IrzJhZy87cqlaZuWmt + OGvzWnmbLfsPkq6984617l67dybuuXXWRa+ql3724/XiD76rnvGqC+vZF7+8jn3hebXzKUfV01/+wjr5 + da+srU86shOAx9Ssjqm2O+34Pu1x7hl11Csv7Ezi42rirtvWGjttU2t1Zs1GW29fJ55yVn3ggx+rHXeb + 3f91NyEsIPQL2GR8cMA4WpM245KHJg4uAoPtDNIUROAF2jqZJ0Iw/Sehe/qML2hRQz+KkaE8HuH3Zx4O + Lfg/WRmSwx7jdEBES6ZZuzZ+G1FOe20SrBp1aNksGL+BdWItqE/7pnlzbdCsbew0cKf46T/rKvPh/he6 + DfWCC15c51/44rr9zjt6IXjfA3fX4UfuW6d1Wto555xaz3/pq+t/fn9LP8Y5D9xXH/vKV+tFH7iijn7j + +2rD446vLboNffOn7VuTdu74cO+da9On713HPPPQeuGLDqozzj20Znca4GITxtRO221b+x8woz5+xRv7 + /n9/9R/7g87wRAtwk2KuMlUFw7NE0MpbIKwXdDFeNBHPyNqgsaGj9W/DB1wBoT3LUTvoox6a2eAjT1iB + 7uXrMY8OT4LmR6jxuzEp7XBs74RPyGkTmURvWNAODJCay68RB7FFE1ue+cS8IumdbMXfZ/L1KdSFqeA0 + GcFcq8vWRxh+CHXgAi94OAn19Qw+FLvSLrvt2h8I3H7zLbXJRhv33/JbavW1aplpG9biG2xcK3QM7YOk + PkxKQG11wAG19eGH1skvf2l9pFsMz//Q5b1/b/eTj65zXvOSOuH8Z9feZ5xQz3n7m+rSL3+2ntb9XveQ + vfs04+kH1/qHHVAbHn5gbXzEQbX+gfvU9P1n11o7bF2Tt92mVt90Zm266+513DPOqs1mbdtpEKv2m0Ho + FoYCQnmYWegkWYz8LfwuoQEN2jVzzRgtRMn8yNHUiXDix8whoYpeEvqhG8ZTxwkk+vlNEDil51/hv0p/ + fpsHoTLBdVFCj8EIGo9f88sY8FsrdHJAF2GfDUeiuUXzC6iDR1Mngqw90MgbSrTxtJf4yZaW0Xrgkz8G + NG7cmPrN737bD+P2O2+p3fbernaavWk9/dgD69jTz6hnvuA19Ykrvlw/+5/f1j93c/+Mt7yl9n/lRXXk + 2z9SWz/rgtr1WS+o2eed20cjrL/XdjVjvx3qgHOOrdmHb1OzD5tZM7fdoJZZabGavP5Q/e1XLu+p89Vv + fONhrzFmTMlBXFhSTNq4AVy3kHHhK8+4rwIt7XO2oI3QJZ8OQzevcqb8guFJ0PwsGhPFR5fP+Uj+sLW/ + IeFTPhkcf1B2TkLQZ68SGiB+LGYvYk2fPr0PYfFJHz465nEG5o0P7RKmhKaJICz8zWC7CVyYKj6PI+d3 + kNtV1aFVfe1r/1i33tKZkT/9Wa2/3gY1fomla+k1JtWy665fS0/fqJbdaMNaeuZGtfyWM2vjvWbXvqee + UjueeGzt98yz642f+mQd9Lxn1TbHHVHbn3B4HffS59ZJL3t+HdoJwxe+49L69A/+q1795SvryEteWrs+ + 9xm16fGH1UZHH1Qbd0Jw0p671KTddqo19/CWx461zqztarWtZg1/DHWTTgOdMLamrbJqL0TCTOgXettx + mb1hIg5gn7uiSRgbOsglmrWQA2PPvOQzSV6Hs0EAGwsfFU3RZ4HEVDo5S3l0NLfo6qvOfLShOWGI7ubB + nCS+a1FDT61hknXwxMxeNG8XNjoxbdFdyhxEEIp7TBxgC2joucOqPPMGQwQdn672bTppEx+D9J96WUtn + n+uDvsP9XvvHa/p7d953V83cfuPadMdpdeQp3Wa925a15c7b15mdtnX+ay6qSz/6wbrwvR+pbc+6oLa7 + +O21zSveUlu/5JLa6+I31SbnnFlrH31wzTju4NrqlCNq92N3rn1P2b4OPX3v2m7vTWu5NYfqXR98Xf/B + 1G9/9zs9v8GtFTbB0X1hP+3G0KYIKuUyHsBERkvKT0CbSfhRfXQENE9msXvoZqMHwePRYSGFn2TX6r+O + MjA4OSeuj4sCRBIE7ZkByv2pPH4kYDHZIdt2wlRe5qd5GCyCtYNrrzEnX0vqtcRHHK8H/VlVn9t/0PRn + P/lpTZ3aqejjl+jN3uXX7Xa6DabXhBnr15JbblLLztqsVt1qi9r0gP1qq+OfXtOP6ATyWafW6a96WV34 + /nfVGW++qHY/5/ja91mn1REvfk4d++qX1Pkf/0C95HMfrff/6Fv1oiveXzM7ATnlwD1q+iH71rR9Z9fU + PXap1Xaa1X/odK2ttq6VtugE3zabdSZ2t7ONH6r1Vl2pN3sCGaOxYxqfqzcmOymGSMD3IKC3cWdBJZcI + OlqeNiXmQp5JgzRMXYznW3atQB6cj8e++/7vQY/RCFqPX/ihSQsZozdcxKji69CKRcH6cT/lvJMqJtMm + 7sMHfLXCwjyXuHXURed8BoxmnTaZ0ExGBwf6zDwFzn7meTV2fLeWurKEn2e333NHbbTdjG5DnVK7HDSr + djlgi9pqt5m19T7iVWfXjk/btfY947Q66ILX194vf3MdcMlltd1LXlMbdRrgjDNfUBsdd3LNOv7wOvHl + Z9d2x+5Xu5++Zx1/Qbfhn7BHbbjt6vWhj3VruRve3Pvu/QsNN5C5N1bWRb7G4sQ6X8aRQgcbqANLZrLT + YnRimaCb5Jn4UVaetzm0F00Z8Ff7re2Yyo+N/54E4efT2jQDmlwWmmsmANXXgCwUiDmtodXF9HUAkTcC + fOgxmp82CE5tKCtUQPBu+kz/g7mDE387xAFI+pG0ZRETGkyLYQE4p+bNva9nuBkbdUJn3JK1+Cpr1tJT + 1+7/Bu9SG02vFWZ1Zu9mnQBcd72auu22tdVRh9dGRx7U/wnKd3zuM/WZ73273vDFT9Ye53VMc/Lhtfuz + T6+NOuaZdOh+tcN5p9UFn/5QnXzZJbXlqU+vGUfsX1P32bX/i25Tdtm51tltx96XOGm77Wtip70tt8lG + terGG/bCb7XVV+p3VmNCO/gam9wCI8SNy5iETTjUyIRjStqHjYAAdRCCFmiJLupItOpofhYOV4L7BKq5 + 0X7oH1rKLUZzFQj9szDh0S7SRQU9VsOodfDENb8sKOB36CykJxtCwj5CC5CPnaKlhQlaLcdmg97KcBEB + i97vNqmPZ1tA39POPKvGjOtM6a7M73/3kNl89+211e6dFTFtxdp0p/Vrk63XrnU2XrtWn7FebbzrVrXx + zuvX5G0n1REXnlHnvOPjtfdr31Lbvf7NtckFr6otzzu/tjrxzNr25GNri5M7K6Xb6KcdsUvHt9vX7NOf + Vlvuu1W97xMP+dLmDn8FvR1PK3Bco0Xo0W6UAP7hEcIvY6UBp1xLg/i2H8mlknvyx857T4LZSxNhVmUi + +X58l0vIiZNXk+wP74h459gU28dnxWfBVHJSDJi98fkRVnxYvjwspEA4ByEbAus7hHedQWNUC1MfTEO5 + EBpCT3K6nJPjOffdWf/0j1+t5z7vBbX65PVq3LIT+2/4+ZzV0muvUxNnzqzF11m71tt2uzripNPqmDPP + 6b/avPfZZ9Txr3hJveS976xz3/TaevqLn1U7nHxkbXbCITXz1CNrg2MOqQ2OOrTWPXjfWuegfWrS/rvW + hofv14fATNtvj1pzh21rSqd1rb3nrrXKjI1qjQ02qT2PPKp2Pf7oWnzdyTW01JK11qqr9eER0VIJPC4C + ZqwNQ3gKf57EEex0FqAl1wKHr7JMKy/NOyAyHzaRbFAOl8yHRcpvgs5hNuab7/15OT1/vFxf+Wv4Fmvm + gJAFYTq5Z4saegxG0Hhiwi88xmeMVwm8zEkr3MyHZ2ifcg44Qk9z5JmT8NApf8NDEqcGzHO+mN3+GQFz + SUjYzLQjP/+Cl/XuC58+u+H64Q+C3HHP3bXt7tvVauutWjvtNas22XJaTV5/zVp92pq19Z6zas/DdqwN + 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 + LwBaya8VrWjFFxKt5NeKVrTiCwjp/wC1GUU+XPdJNAAAAABJRU5ErkJggg== + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAEZcAABGXAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANyg + SADcoEgA3KBIANygSADcoEgA3KBIANygSADcoEgA3KBIANygSADcoEgAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANyg + SADcoEgA3KBIFtygSDjcoEhS3KBIVtygSFbcoEhT3KBIPNygSBncoEgC3KBIANygSADcoEgA3KBIAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcoEgA3KBIANyg + SADcoEgG3KBIQdygSJXcoEjT3KBI8dygSPzcoEj93KBI/dygSPzcoEjz3KBI2NygSJ7coEhJ3KBICtyg + SADcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3KBIANyg + SADcoEgA3KBIL9ygSKTcoEjy3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SPXcoEiw3KBIOtygSADcoEgA3KBIANygSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANyg + SADcoEgA3KBIAdygSFrcoEjf3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEjn3KBIatygSAXcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADcoEgA3KBIANygSAHcoEhp3KBI8dygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj33KBIfNygSAXcoEgA3KBIAAAAAAAAAAAAAAAAAAAA + AAAAAAAA3KBIANygSADcoEgA3KBIVtygSPDcoEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yf + R//cn0f/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj33KBIatygSADcoEgA3KBIAAAA + AAAAAAAAAAAAAAAAAADcoEgA3KBIANygSCrcoEjb3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/cn0f/5rx+/+jAhv/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjn3KBIOtyg + SADcoEgAAAAAAAAAAAAAAAAA3KBIANygSADcoEgE3KBIm9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9yfR//nvX//6MGI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEiw3KBICtygSADcoEgAAAAAAAAAAADcoEgA3KBIANygSDbcoEjs3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9yfR//cn0f/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSPXcoEhJ3KBIANygSAAAAAAAAAAAANygSADcoEgA3KBIh9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3aJM/92iTP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSJ7coEgC3KBIAAAAAAAAAAAA3KBIANygSA7coEjG3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yfRv/qxpH/7Muc/9ygR//coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI2NygSBncoEgAAAAAAAAAAADcoEgA3KBIKdyg + SOjcoEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3J9F/+7Sqf/y27r/3KBH/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjz3KBIPNygSAAAAAAAAAAAANyg + SADcoEhD3KBI99ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/bnkX/68qZ//Ti + x//doUv/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSPzcoEhT3KBIAAAA + AAAAAAAA3KBIANygSFLcoEj83KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yf + Rv/kt3T/+e/f/+KvZf/cn0b/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/dyg + SFbcoEgAAAAAAAAAAADcoEgA3KBIUdygSPvcoEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/92jTv/z3sD/89/A/9+nVf/cn0b/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj93KBIVtygSAAAAAAAAAAAANygSADcoEhA3KBI9tygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3J9G/+GtYv/25s//9OLG/+CrXf/cn0f/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSPzcoEhS3KBIAAAAAAAAAAAA3KBIANygSCbcoEjm3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3J9G/+CqW//04sf/8ty7/92iTf/coEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBI8dygSDjcoEgAAAAAAAAAAADcoEgA3KBIDNygSMHcoEj/3KBI/9yg + SP/coEj/3KBI/9ygSP/coEj/3KBH/9yfRv/coEj/3KBI/9ygSP/coEj/259F/+Kxaf/57+D/47Ru/9yf + Rv/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjT3KBIFtygSAAAAAAAAAAAANygSADcoEgA3KBIftyg + SP/coEj/3KBI/9ygSP/coEj/3KBI/9ygR//eplT/5bh3/92jTv/coEj/3KBI/9ygSP/coEf/3qRQ//fo + 0//owIb/255F/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSJXcoEgA3KBIAAAAAAAAAAAA3KBIANyg + SADcoEgv3KBI59ygSP/coEj/3KBI/9ygSP/coEj/3J9G/+KxaP/47d3/4a9k/9yfRv/coEj/3KBI/9yf + R//fqVn/+Ozb/+W5ef/bn0X/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjy3KBIQdygSADcoEgAAAAAAAAA + AADcoEgA3KBIANygSAHcoEiP3KBI/9ygSP/coEj/3KBI/9ygSP/coEf/3qVS//bmzv/u0af/3KBJ/9ue + Rf/bn0X/3J9H/+zLmv/36tf/36hY/9yfR//coEj/3KBI/9ygSP/coEj/3KBI/9ygSKTcoEgG3KBIANyg + SAAAAAAAAAAAAAAAAADcoEgA3KBIANygSCHcoEjQ3KBI/9ygSP/coEj/3KBI/9ygSP/cn0b/5bh3//nv + 4f/w17H/5bl3/+W3df/v06r/+vDj/+e+gv/cn0b/3KBI/9ygSP/coEj/3KBI/9ygSP/coEjf3KBIL9yg + SADcoEgAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANygSEjcoEjo3KBI/9ygSP/coEj/3KBI/9yg + SP/coEj/5LVx//Pfwf/47Nv/+O3c//Thxf/luXf/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI8dyg + SFrcoEgA3KBIANygSAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANygSFjcoEjo3KBI/9yg + SP/coEj/3KBI/9ygSP/cn0b/3aJL/9+pWf/gqlr/3aJM/9yfRv/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SPDcoEhp3KBIAdygSADcoEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANyg + SEjcoEjQ3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3J9H/9yfR//coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEjb3KBIVtygSAHcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANyg + SADcoEgA3KBIANygSCHcoEiP3KBI59ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9ygSP/coEj/3KBI/9yg + SP/coEjs3KBIm9ygSCrcoEgA3KBIANygSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANygSADcoEgA3KBIANygSAHcoEgv3KBIftygSMHcoEjm3KBI9tygSPvcoEj83KBI99yg + SOjcoEjG3KBIh9ygSDbcoEgE3KBIANygSADcoEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAANygSADcoEgA3KBIANygSADcoEgA3KBIDNygSCbcoEhB3KBIUdyg + SFHcoEhD3KBIKdygSA7coEgA3KBIANygSADcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcoEgA3KBIANygSADcoEgA3KBIANyg + SADcoEgA3KBIANygSADcoEgA3KBIANygSADcoEgA3KBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA//////+AAf/+AAB//AAAP/gAAA/wAAAP4AAAB8AAAAPAAAADgAAAAYAA + AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAHAAAADwAAAA+AA + AAfwAAAP+AAAH/wAAD/+AAB//4AB//////8= + + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/FrmStart.Designer.cs b/Source/Itrycn_Project2/FrmStart.Designer.cs new file mode 100644 index 0000000..4273e53 --- /dev/null +++ b/Source/Itrycn_Project2/FrmStart.Designer.cs @@ -0,0 +1,207 @@ +namespace Itrycn_Project2 + + +{ + partial class FrmStart + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); + this.MenuTray = new System.Windows.Forms.ContextMenuStrip(this.components); + this.显示主窗体ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.退出软件ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.关于ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.打开官网ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.捐助ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.chromeTabControl1 = new ryControls.ChromeTabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.richTextBox21 = new ryControls.Controls.RichTextBox2(); + this.extendedWebBrowser1 = new ExtendedWebBrowser2.ExtendedWebBrowser(); + this.MenuTray.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.chromeTabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.SuspendLayout(); + // + // notifyIcon1 + // + this.notifyIcon1.ContextMenuStrip = this.MenuTray; + this.notifyIcon1.Visible = true; + this.notifyIcon1.DoubleClick += new System.EventHandler(this.显示主窗体ToolStripMenuItem_Click); + // + // MenuTray + // + this.MenuTray.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.显示主窗体ToolStripMenuItem, + this.退出软件ToolStripMenuItem}); + this.MenuTray.Name = "MenuTray"; + this.MenuTray.Size = new System.Drawing.Size(137, 48); + // + // 显示主窗体ToolStripMenuItem + // + this.显示主窗体ToolStripMenuItem.Name = "显示主窗体ToolStripMenuItem"; + this.显示主窗体ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.显示主窗体ToolStripMenuItem.Text = "显示主窗体"; + this.显示主窗体ToolStripMenuItem.Click += new System.EventHandler(this.显示主窗体ToolStripMenuItem_Click); + // + // 退出软件ToolStripMenuItem + // + this.退出软件ToolStripMenuItem.Name = "退出软件ToolStripMenuItem"; + this.退出软件ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.退出软件ToolStripMenuItem.Text = "退出软件"; + this.退出软件ToolStripMenuItem.Click += new System.EventHandler(this.退出软件ToolStripMenuItem_Click); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.关于ToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(789, 25); + this.menuStrip1.TabIndex = 2; + this.menuStrip1.Text = "menuStrip1"; + // + // 关于ToolStripMenuItem + // + this.关于ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.打开官网ToolStripMenuItem, + this.捐助ToolStripMenuItem}); + this.关于ToolStripMenuItem.Name = "关于ToolStripMenuItem"; + this.关于ToolStripMenuItem.Size = new System.Drawing.Size(44, 21); + this.关于ToolStripMenuItem.Text = "关于"; + // + // 打开官网ToolStripMenuItem + // + this.打开官网ToolStripMenuItem.Name = "打开官网ToolStripMenuItem"; + this.打开官网ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.打开官网ToolStripMenuItem.Text = "打开官网"; + this.打开官网ToolStripMenuItem.Click += new System.EventHandler(this.打开官网ToolStripMenuItem_Click); + // + // 捐助ToolStripMenuItem + // + this.捐助ToolStripMenuItem.Name = "捐助ToolStripMenuItem"; + this.捐助ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.捐助ToolStripMenuItem.Text = "关于和捐助"; + this.捐助ToolStripMenuItem.Click += new System.EventHandler(this.捐助ToolStripMenuItem_Click); + // + // chromeTabControl1 + // + this.chromeTabControl1.AllowDragTab = false; + this.chromeTabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.chromeTabControl1.BackTabPageImage = null; + this.chromeTabControl1.Controls.Add(this.tabPage1); + this.chromeTabControl1.Cursor = System.Windows.Forms.Cursors.Default; + this.chromeTabControl1.ItemSize = new System.Drawing.Size(100, 25); + this.chromeTabControl1.Location = new System.Drawing.Point(1, 28); + this.chromeTabControl1.Name = "chromeTabControl1"; + this.chromeTabControl1.SelectedIndex = 0; + this.chromeTabControl1.ShowAddButton = false; + this.chromeTabControl1.ShowCloseButton = false; + this.chromeTabControl1.Size = new System.Drawing.Size(787, 506); + this.chromeTabControl1.SizeMode = System.Windows.Forms.TabSizeMode.Fixed; + this.chromeTabControl1.TabContextMenuStrip = null; + this.chromeTabControl1.TabIndex = 0; + this.chromeTabControl1.TabMaxWidth = 100; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.extendedWebBrowser1); + this.tabPage1.Controls.Add(this.richTextBox21); + this.tabPage1.Location = new System.Drawing.Point(1, 29); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(785, 476); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "首页"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // richTextBox21 + // + this.richTextBox21.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richTextBox21.DetectUrls = false; + this.richTextBox21.EmptyText = "cc对对对反反复复"; + this.richTextBox21.ForeColor = System.Drawing.Color.Black; + this.richTextBox21.Location = new System.Drawing.Point(164, 79); + this.richTextBox21.Name = "richTextBox21"; + this.richTextBox21.OnlyInputText = true; + this.richTextBox21.Size = new System.Drawing.Size(385, 195); + this.richTextBox21.TabIndex = 0; + this.richTextBox21.Text = ""; + // + // extendedWebBrowser1 + // + this.extendedWebBrowser1.ForceOpenThisWindow = false; + this.extendedWebBrowser1.Location = new System.Drawing.Point(124, 77); + this.extendedWebBrowser1.MinimumSize = new System.Drawing.Size(20, 20); + this.extendedWebBrowser1.Name = "extendedWebBrowser1"; + this.extendedWebBrowser1.ScriptErrorsSuppressed = true; + this.extendedWebBrowser1.Size = new System.Drawing.Size(250, 250); + this.extendedWebBrowser1.TabIndex = 1; + // + // FrmStart + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(789, 538); + this.Controls.Add(this.menuStrip1); + this.Controls.Add(this.chromeTabControl1); + this.Name = "FrmStart"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "FrmStart"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmStart_FormClosing); + this.Load += new System.EventHandler(this.FrmStart_Load); + this.Shown += new System.EventHandler(this.FrmStart_Shown); + this.MenuTray.ResumeLayout(false); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.chromeTabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ryControls.ChromeTabControl chromeTabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.NotifyIcon notifyIcon1; + private System.Windows.Forms.ContextMenuStrip MenuTray; + private System.Windows.Forms.ToolStripMenuItem 显示主窗体ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 退出软件ToolStripMenuItem; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem 关于ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 捐助ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 打开官网ToolStripMenuItem; + private ryControls.Controls.RichTextBox2 richTextBox21; + private ExtendedWebBrowser2.ExtendedWebBrowser extendedWebBrowser1; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project2/FrmStart.cs b/Source/Itrycn_Project2/FrmStart.cs new file mode 100644 index 0000000..3f1a34f --- /dev/null +++ b/Source/Itrycn_Project2/FrmStart.cs @@ -0,0 +1,136 @@ +using Itrycn_Project; +using ryCommon; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project2 +{ + public partial class FrmStart : Form + { + string[] prog_args; + public FrmStart(string[] args) + { + InitializeComponent(); + prog_args = args; + //配置软件信息 + notifyIcon1.Text = Soft_Info.Soft_Title; + Text = Soft_Info.Soft_Title + " V" + RySoft.VersionStr; + if (!Soft_Info.ShowTray) { notifyIcon1.Visible = false; } + if (!Soft_Info.DonateVisabled) { 捐助ToolStripMenuItem.Text = "关于"; } + if (Soft_Info.Soft_Url.Length == 0) { 打开官网ToolStripMenuItem.PerformClick(); } + notifyIcon1.Icon = Icon; + } + + private void 显示主窗体ToolStripMenuItem_Click(object sender, EventArgs e) + { + this.WindowState = FormWindowState.Normal; + var topmost = this.TopMost; + this.TopMost = true; + this.Show(); + this.TopMost = topmost; + } + + private void 退出软件ToolStripMenuItem_Click(object sender, EventArgs e) + { + Application.Exit(); + } + + private void FrmStart_Shown(object sender, EventArgs e) + { + ryCommon.Ini ini = new Ini(Soft_Info.UserDataFolder + "\\Win.dat"); + ini.WriteIni(Soft_Info.Soft_Id, "hwnd", Handle.ToInt32()); + if (prog_args.Length >= 1) + { + //如果是自启动,并且开启了右下角托盘图标,则隐藏自身。 + if (prog_args[0] == Soft_Info.Soft_Pram && Soft_Info.ShowTray) + this.Hide(); + } + } + + private void FrmStart_FormClosing(object sender, FormClosingEventArgs e) + { + if (Soft_Info.ShowTray && Soft_Config.HideByCloseBtn && e.CloseReason== CloseReason.UserClosing) + { + e.Cancel = true; + this.Hide(); + notifyIcon1.ShowBalloonTip(3000, Soft_Info.Soft_Title, "软件已经最小化到此处,请右击托盘图标进行关闭。", ToolTipIcon.Info); + return; + } + if (!Soft_Config.IsCanCloseForm) + { + e.Cancel = true; + MessageBox.Show("当前还有操作正在运行,请稍后关闭软件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + protected override void WndProc(ref System.Windows.Forms.Message msg) + { + switch (msg.Msg) + { + case 17189: //处理消息 + { + #region 激活窗体 + switch (msg.WParam.ToInt32()) + { + case 100:// + #region 显示界面 + if ((int)msg.LParam.ToInt32() == 100) + { + this.Show(); + this.WindowState = FormWindowState.Normal; + this.Top = (Screen.PrimaryScreen.WorkingArea.Height - this.Height) / 2; + this.Left = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2; + //RyForm.SetActiveWindow(Handle); + RyForm.BringToTop(Handle); + 显示主窗体ToolStripMenuItem.PerformClick(); + this.BringToFront(); + this.Select(); + this.Focus(); + RyForm.BringToTop(Handle); + } + #endregion + break; + } + #endregion + } + break; + default: + base.WndProc(ref msg);//调用基类函数处理非自定义消息。 + break; + } + } + + private void 捐助ToolStripMenuItem_Click(object sender, EventArgs e) + { + if (Soft_Info.DonateVisabled) + { + FrmAbout frm = new FrmAbout(); + frm.ShowDialog(); + frm.Dispose(); + } + else + { + MessageBox.Show(Soft_Info.AboutText.Replace("#softname#", Soft_Info.Soft_Title).Replace("#ver#", "V" + RySoft.VersionStr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + + private void 打开官网ToolStripMenuItem_Click(object sender, EventArgs e) + { + ryCommon.RyFiles.OpenUrl(Soft_Info.Soft_Url); + } + + private void FrmStart_Load(object sender, EventArgs e) + { + //Itrycn_Project.Itrycn_Db.CreateTable(); + LiveUpdate.RyUpdate update = new LiveUpdate.RyUpdate(Soft_Info.Update_Url); + update.CheckUpdate(); + RyFiles.GetRelativePath("%cc"); + } + } +} diff --git a/Source/Itrycn_Project2/FrmStart.resx b/Source/Itrycn_Project2/FrmStart.resx new file mode 100644 index 0000000..63fdca7 --- /dev/null +++ b/Source/Itrycn_Project2/FrmStart.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 135, 17 + + + 246, 17 + + + 54 + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/Itrycn_Project.csproj.user b/Source/Itrycn_Project2/Itrycn_Project.csproj.user new file mode 100644 index 0000000..a82707a --- /dev/null +++ b/Source/Itrycn_Project2/Itrycn_Project.csproj.user @@ -0,0 +1,14 @@ + + + + ShowAllFiles + + + + + + + zh-CN + false + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/Itrycn_Project2.csproj b/Source/Itrycn_Project2/Itrycn_Project2.csproj new file mode 100644 index 0000000..fd188e9 --- /dev/null +++ b/Source/Itrycn_Project2/Itrycn_Project2.csproj @@ -0,0 +1,189 @@ + + + + + Debug + AnyCPU + {DC9FDB61-FEDD-4795-AFDC-8376AB781C56} + WinExe + Itrycn_Project2 + Itrycn_Project2 + v4.0 + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + x86 + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4 示例\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + ..\..\Bin\Release\CommonControls\.NET4 示例\ + TRACE + prompt + 4 + + + + ..\..\Bin\Debug\CommonControls\.NET4\RyWeb.dll + + + + + + + + + + + + + ..\..\Bin\Debug\CommonControls\.NET4\XPTable.dll + + + + + + + + Form + + + FrmAdd.cs + + + Form + + + FrmView.cs + + + Form + + + FrmAbout.cs + + + Form + + + FrmStart.cs + + + Form + + + FrmScan.cs + + + Form + + + frmLogin.cs + + + Form + + + frmSetting.cs + + + + + + FrmAdd.cs + + + FrmView.cs + + + FrmAbout.cs + + + FrmStart.cs + + + FrmScan.cs + + + frmLogin.cs + + + frmSetting.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV4 + + + {6b969ce8-d723-4b2c-a8fd-fad2fb28ff01} + MyDb_SQLiteV4 + + + {9eca3a84-8545-4c4d-84d6-d23e3bdf2d90} + ryControlsV4 + + + {B6784652-825A-482C-8A21-08E2539AF2BF} + RyPrint + + + {11a63e24-0257-4c54-a109-f1a609a52a62} + ryUpdateV4 + + + + + False + .NET Framework 3.5 SP1 + false + + + + + + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/Itrycn_Project2.csproj.user b/Source/Itrycn_Project2/Itrycn_Project2.csproj.user new file mode 100644 index 0000000..9b86104 --- /dev/null +++ b/Source/Itrycn_Project2/Itrycn_Project2.csproj.user @@ -0,0 +1,6 @@ + + + + ShowAllFiles + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/OTools/FrmScan.Designer.cs b/Source/Itrycn_Project2/OTools/FrmScan.Designer.cs new file mode 100644 index 0000000..4fa7c6f --- /dev/null +++ b/Source/Itrycn_Project2/OTools/FrmScan.Designer.cs @@ -0,0 +1,176 @@ +namespace Itrycn_Project2 + + +{ + partial class FrmScan + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); + this.MenuTray = new System.Windows.Forms.ContextMenuStrip(this.components); + this.显示主窗体ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.退出软件ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.关于ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.打开官网ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.捐助ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.chromeTabControl1 = new ryControls.ChromeTabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.MenuTray.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.chromeTabControl1.SuspendLayout(); + this.SuspendLayout(); + // + // notifyIcon1 + // + this.notifyIcon1.ContextMenuStrip = this.MenuTray; + this.notifyIcon1.Visible = true; + this.notifyIcon1.DoubleClick += new System.EventHandler(this.显示主窗体ToolStripMenuItem_Click); + // + // MenuTray + // + this.MenuTray.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.显示主窗体ToolStripMenuItem, + this.退出软件ToolStripMenuItem}); + this.MenuTray.Name = "MenuTray"; + this.MenuTray.Size = new System.Drawing.Size(137, 48); + // + // 显示主窗体ToolStripMenuItem + // + this.显示主窗体ToolStripMenuItem.Name = "显示主窗体ToolStripMenuItem"; + this.显示主窗体ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.显示主窗体ToolStripMenuItem.Text = "显示主窗体"; + this.显示主窗体ToolStripMenuItem.Click += new System.EventHandler(this.显示主窗体ToolStripMenuItem_Click); + // + // 退出软件ToolStripMenuItem + // + this.退出软件ToolStripMenuItem.Name = "退出软件ToolStripMenuItem"; + this.退出软件ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.退出软件ToolStripMenuItem.Text = "退出软件"; + this.退出软件ToolStripMenuItem.Click += new System.EventHandler(this.退出软件ToolStripMenuItem_Click); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.关于ToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(789, 25); + this.menuStrip1.TabIndex = 2; + this.menuStrip1.Text = "menuStrip1"; + // + // 关于ToolStripMenuItem + // + this.关于ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.打开官网ToolStripMenuItem, + this.捐助ToolStripMenuItem}); + this.关于ToolStripMenuItem.Name = "关于ToolStripMenuItem"; + this.关于ToolStripMenuItem.Size = new System.Drawing.Size(44, 21); + this.关于ToolStripMenuItem.Text = "关于"; + // + // 打开官网ToolStripMenuItem + // + this.打开官网ToolStripMenuItem.Name = "打开官网ToolStripMenuItem"; + this.打开官网ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.打开官网ToolStripMenuItem.Text = "打开官网"; + this.打开官网ToolStripMenuItem.Click += new System.EventHandler(this.打开官网ToolStripMenuItem_Click); + // + // 捐助ToolStripMenuItem + // + this.捐助ToolStripMenuItem.Name = "捐助ToolStripMenuItem"; + this.捐助ToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.捐助ToolStripMenuItem.Text = "关于和捐助"; + this.捐助ToolStripMenuItem.Click += new System.EventHandler(this.捐助ToolStripMenuItem_Click); + // + // chromeTabControl1 + // + this.chromeTabControl1.AllowDragTab = false; + this.chromeTabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.chromeTabControl1.BackTabPageImage = null; + this.chromeTabControl1.Controls.Add(this.tabPage1); + this.chromeTabControl1.Cursor = System.Windows.Forms.Cursors.Default; + this.chromeTabControl1.ItemSize = new System.Drawing.Size(100, 25); + this.chromeTabControl1.Location = new System.Drawing.Point(1, 28); + this.chromeTabControl1.Name = "chromeTabControl1"; + this.chromeTabControl1.SelectedIndex = 0; + this.chromeTabControl1.ShowAddButton = false; + this.chromeTabControl1.ShowCloseButton = false; + this.chromeTabControl1.Size = new System.Drawing.Size(787, 506); + this.chromeTabControl1.SizeMode = System.Windows.Forms.TabSizeMode.Fixed; + this.chromeTabControl1.TabContextMenuStrip = null; + this.chromeTabControl1.TabIndex = 0; + this.chromeTabControl1.TabMaxWidth = 100; + // + // tabPage1 + // + this.tabPage1.Location = new System.Drawing.Point(1, 29); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(785, 476); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "首页"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // FrmStart + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(789, 538); + this.Controls.Add(this.menuStrip1); + this.Controls.Add(this.chromeTabControl1); + this.Name = "FrmStart"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "FrmStart"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmStart_FormClosing); + this.Load += new System.EventHandler(this.FrmStart_Load); + this.Shown += new System.EventHandler(this.FrmStart_Shown); + this.MenuTray.ResumeLayout(false); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.chromeTabControl1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ryControls.ChromeTabControl chromeTabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.NotifyIcon notifyIcon1; + private System.Windows.Forms.ContextMenuStrip MenuTray; + private System.Windows.Forms.ToolStripMenuItem 显示主窗体ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 退出软件ToolStripMenuItem; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem 关于ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 捐助ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 打开官网ToolStripMenuItem; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project2/OTools/FrmScan.cs b/Source/Itrycn_Project2/OTools/FrmScan.cs new file mode 100644 index 0000000..a977619 --- /dev/null +++ b/Source/Itrycn_Project2/OTools/FrmScan.cs @@ -0,0 +1,135 @@ +using Itrycn_Project; +using ryCommon; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project2 +{ + public partial class FrmScan : Form + { + string[] prog_args; + public FrmScan(string[] args) + { + InitializeComponent(); + prog_args = args; + //配置软件信息 + notifyIcon1.Text = Soft_Info.Soft_Title; + Text = Soft_Info.Soft_Title + " V" + RySoft.VersionStr; + if (!Soft_Info.ShowTray) { notifyIcon1.Visible = false; } + if (!Soft_Info.DonateVisabled) { 捐助ToolStripMenuItem.Text = "关于"; } + if (Soft_Info.Soft_Url.Length == 0) { 打开官网ToolStripMenuItem.PerformClick(); } + notifyIcon1.Icon = Icon; + } + + private void 显示主窗体ToolStripMenuItem_Click(object sender, EventArgs e) + { + this.WindowState = FormWindowState.Normal; + var topmost = this.TopMost; + this.TopMost = true; + this.Show(); + this.TopMost = topmost; + } + + private void 退出软件ToolStripMenuItem_Click(object sender, EventArgs e) + { + Application.Exit(); + } + + private void FrmStart_Shown(object sender, EventArgs e) + { + ryCommon.Ini ini = new Ini(Soft_Info.UserDataFolder + "\\Win.dat"); + ini.WriteIni(Soft_Info.Soft_Id, "hwnd", Handle.ToInt32()); + if (prog_args.Length >= 1) + { + //如果是自启动,并且开启了右下角托盘图标,则隐藏自身。 + if (prog_args[0] == Soft_Info.Soft_Pram && Soft_Info.ShowTray) + this.Hide(); + } + } + + private void FrmStart_FormClosing(object sender, FormClosingEventArgs e) + { + if (Soft_Info.ShowTray && Soft_Config.HideByCloseBtn && e.CloseReason== CloseReason.UserClosing) + { + e.Cancel = true; + this.Hide(); + notifyIcon1.ShowBalloonTip(3000, Soft_Info.Soft_Title, "软件已经最小化到此处,请右击托盘图标进行关闭。", ToolTipIcon.Info); + return; + } + if (!Soft_Config.IsCanCloseForm) + { + e.Cancel = true; + MessageBox.Show("当前还有操作正在运行,请稍后关闭软件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + protected override void WndProc(ref System.Windows.Forms.Message msg) + { + switch (msg.Msg) + { + case 17189: //处理消息 + { + #region 激活窗体 + switch (msg.WParam.ToInt32()) + { + case 100:// + #region 显示界面 + if ((int)msg.LParam.ToInt32() == 100) + { + this.Show(); + this.WindowState = FormWindowState.Normal; + this.Top = (Screen.PrimaryScreen.WorkingArea.Height - this.Height) / 2; + this.Left = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2; + //RyForm.SetActiveWindow(Handle); + RyForm.BringToTop(Handle); + 显示主窗体ToolStripMenuItem.PerformClick(); + this.BringToFront(); + this.Select(); + this.Focus(); + RyForm.BringToTop(Handle); + } + #endregion + break; + } + #endregion + } + break; + default: + base.WndProc(ref msg);//调用基类函数处理非自定义消息。 + break; + } + } + + private void 捐助ToolStripMenuItem_Click(object sender, EventArgs e) + { + if (Soft_Info.DonateVisabled) + { + FrmAbout frm = new FrmAbout(); + frm.ShowDialog(); + frm.Dispose(); + } + else + { + MessageBox.Show(Soft_Info.AboutText.Replace("#softname#", Soft_Info.Soft_Title).Replace("#ver#", "V" + RySoft.VersionStr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + + private void 打开官网ToolStripMenuItem_Click(object sender, EventArgs e) + { + ryCommon.RyFiles.OpenUrl(Soft_Info.Soft_Url); + } + + private void FrmStart_Load(object sender, EventArgs e) + { + //Itrycn_Project.Itrycn_Db.CreateTable(); + LiveUpdate.RyUpdate update = new LiveUpdate.RyUpdate(Soft_Info.Update_Url); + update.CheckUpdate(); + } + } +} diff --git a/Source/Itrycn_Project2/OTools/FrmScan.resx b/Source/Itrycn_Project2/OTools/FrmScan.resx new file mode 100644 index 0000000..63fdca7 --- /dev/null +++ b/Source/Itrycn_Project2/OTools/FrmScan.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 135, 17 + + + 246, 17 + + + 54 + + \ No newline at end of file diff --git a/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.Designer.cs b/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.Designer.cs new file mode 100644 index 0000000..823d7d2 --- /dev/null +++ b/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.Designer.cs @@ -0,0 +1,190 @@ +namespace Itrycn +{ + partial class FrmLogin + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtUserId = new ryControls.TextBoxEx2(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.txtPwd = new ryControls.TextBoxEx2(); + this.btnLogin = new ryControls.ButtonEx(); + this.btnCancel = new ryControls.ButtonEx(); + this.pnlTopLogo = new System.Windows.Forms.Panel(); + this.lblTitle = new System.Windows.Forms.Label(); + this.chkRememberUserId = new System.Windows.Forms.CheckBox(); + this.chkAutoLogin = new System.Windows.Forms.CheckBox(); + this.pnlTopLogo.SuspendLayout(); + this.SuspendLayout(); + // + // txtUserId + // + this.txtUserId.BackColor = System.Drawing.Color.White; + this.txtUserId.Location = new System.Drawing.Point(97, 103); + this.txtUserId.Name = "txtUserId"; + this.txtUserId.PasswordChar = '\0'; + this.txtUserId.ReadOnly = false; + this.txtUserId.SelectionLength = 0; + this.txtUserId.SelectionStart = 0; + this.txtUserId.Size = new System.Drawing.Size(209, 25); + this.txtUserId.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(50, 111); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(41, 12); + this.label1.TabIndex = 1; + this.label1.Text = "用户ID"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(50, 142); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(29, 12); + this.label2.TabIndex = 3; + this.label2.Text = "密码"; + // + // txtPwd + // + this.txtPwd.BackColor = System.Drawing.Color.White; + this.txtPwd.Location = new System.Drawing.Point(97, 134); + this.txtPwd.Name = "txtPwd"; + this.txtPwd.PasswordChar = '*'; + this.txtPwd.ReadOnly = false; + this.txtPwd.SelectionLength = 0; + this.txtPwd.SelectionStart = 0; + this.txtPwd.Size = new System.Drawing.Size(209, 25); + this.txtPwd.TabIndex = 1; + this.txtPwd.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TxtPwd_KeyDown); + // + // btnLogin + // + this.btnLogin.ForeColor = System.Drawing.Color.White; + this.btnLogin.Location = new System.Drawing.Point(171, 197); + this.btnLogin.Name = "btnLogin"; + this.btnLogin.Size = new System.Drawing.Size(65, 27); + this.btnLogin.TabIndex = 2; + this.btnLogin.Text = "登陆"; + this.btnLogin.UseVisualStyleBackColor = true; + this.btnLogin.Click += new System.EventHandler(this.BtnLogin_Click); + // + // btnCancel + // + this.btnCancel.ForeColor = System.Drawing.Color.White; + this.btnCancel.Location = new System.Drawing.Point(242, 197); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(65, 27); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "取消"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // pnlTopLogo + // + this.pnlTopLogo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(125)))), ((int)(((byte)(182))))); + this.pnlTopLogo.Controls.Add(this.lblTitle); + this.pnlTopLogo.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTopLogo.Location = new System.Drawing.Point(0, 0); + this.pnlTopLogo.Name = "pnlTopLogo"; + this.pnlTopLogo.Size = new System.Drawing.Size(377, 59); + this.pnlTopLogo.TabIndex = 7; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblTitle.ForeColor = System.Drawing.Color.White; + this.lblTitle.Location = new System.Drawing.Point(12, 22); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(110, 16); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "睿元管理系统"; + // + // chkRememberUserId + // + this.chkRememberUserId.AutoSize = true; + this.chkRememberUserId.Location = new System.Drawing.Point(97, 165); + this.chkRememberUserId.Name = "chkRememberUserId"; + this.chkRememberUserId.Size = new System.Drawing.Size(84, 16); + this.chkRememberUserId.TabIndex = 8; + this.chkRememberUserId.Text = "记住用户ID"; + this.chkRememberUserId.UseVisualStyleBackColor = true; + // + // chkAutoLogin + // + this.chkAutoLogin.AutoSize = true; + this.chkAutoLogin.Location = new System.Drawing.Point(202, 165); + this.chkAutoLogin.Name = "chkAutoLogin"; + this.chkAutoLogin.Size = new System.Drawing.Size(72, 16); + this.chkAutoLogin.TabIndex = 9; + this.chkAutoLogin.Text = "自动登陆"; + this.chkAutoLogin.UseVisualStyleBackColor = true; + this.chkAutoLogin.CheckedChanged += new System.EventHandler(this.ChkAutoLogin_CheckedChanged); + // + // FrmLogin + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(377, 247); + this.Controls.Add(this.chkAutoLogin); + this.Controls.Add(this.chkRememberUserId); + this.Controls.Add(this.pnlTopLogo); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnLogin); + this.Controls.Add(this.label2); + this.Controls.Add(this.txtPwd); + this.Controls.Add(this.label1); + this.Controls.Add(this.txtUserId); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Name = "FrmLogin"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "登陆"; + this.Load += new System.EventHandler(this.FrmLogin_Load); + this.pnlTopLogo.ResumeLayout(false); + this.pnlTopLogo.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ryControls.TextBoxEx2 txtUserId; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private ryControls.TextBoxEx2 txtPwd; + private ryControls.ButtonEx btnLogin; + private ryControls.ButtonEx btnCancel; + private System.Windows.Forms.Panel pnlTopLogo; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.CheckBox chkRememberUserId; + private System.Windows.Forms.CheckBox chkAutoLogin; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.cs b/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.cs new file mode 100644 index 0000000..38976d4 --- /dev/null +++ b/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.cs @@ -0,0 +1,119 @@ +using Itrycn_Project; +using ryCommon; +using RyHardWare; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace Itrycn +{ + public partial class FrmLogin : Form + { + public delegate void LoginHandler(object sender,out bool LoginSuccess); + [Description("点击登录按钮时激发")] + public event LoginHandler OnLoginClick; + public FrmLogin() + { + InitializeComponent(); + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + } + private void BtnLogin_Click(object sender, EventArgs e) + { + txtUserId.Enabled = false; + txtPwd.Enabled = false; + btnLogin.Enabled = false; + LoginPram.UserId = txtUserId.Text; + LoginPram.Pwd = txtPwd.Text; + bool LoginSuccess = false; + OnLoginClick?.Invoke(this,out LoginSuccess); + txtUserId.Enabled = true; + txtPwd.Enabled = true; + btnLogin.Enabled = true; + if (LoginSuccess) + { + #region 登录成功 + ryCommon.Ini ryIni = new Ini(Soft_Info.UserDataFolder + "\\Setting.dat"); + if (chkAutoLogin.Checked || chkRememberUserId.Checked) + { + ryIni.WriteIni("User", "id", LoginPram.UserId); + if (chkAutoLogin.Checked) + { + LoginPram.isAutoLogin = 2; + ryIni.WriteIni("User", "pwd", rySafe.AES.Encode("121" + LoginPram.Pwd, RyHardWare.Network.GetMacs() + "|" + LoginPram.UserId)); + } + else + { + LoginPram.isAutoLogin = 1; + ryIni.DelKey("User", "pwd"); + } + } + else + { + ryIni.DelKey("User", "id"); + LoginPram.isAutoLogin = 0; + } + #endregion + DialogResult = DialogResult.OK; + } + } + + private void TxtPwd_KeyDown(object sender, KeyEventArgs e) + { + if(e.KeyCode==Keys.Enter) + { + btnLogin.PerformClick(); + } + } + + private void FrmLogin_Load(object sender, EventArgs e) + { + lblTitle.Text = Soft_Info.Soft_Title; + if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(Soft_Info.UserDataFolder))) + { + System.IO.Directory.CreateDirectory(Soft_Info.UserDataFolder); + } + ryCommon.Ini ryIni = new Ini(Soft_Info.UserDataFolder + "\\Setting.dat"); + txtUserId.Text=ryIni.ReadIni("User", "id", LoginPram.UserId); + if(txtUserId.Text!="") + { chkRememberUserId.Checked = true; } + string pwd = rySafe.AES.Decode(ryIni.ReadIni("User", "pwd", ""), Network.GetMacs() + "|" + txtUserId.Text); + if (pwd.IndexOf("121") == 0) { pwd = pwd.Substring(3); } else { pwd = ""; } + txtPwd.Text = pwd; + if (pwd != "") + { + chkAutoLogin.Checked = true; + txtUserId.Enabled = false; + txtPwd.Enabled = false; + btnLogin.PerformClick(); + btnLogin.Enabled = false; + } + else + { + txtUserId.SelectionLength = 0; + txtUserId.SelectionStart = 0; + txtPwd.Select(); + } + } + + private void ChkAutoLogin_CheckedChanged(object sender, EventArgs e) + { + if (chkAutoLogin.Checked) { chkRememberUserId.Checked = true; } + } + } + public static class LoginPram + { + public static string UserId = ""; + public static string Pwd = ""; + public static int isAutoLogin = 0; + } +} diff --git a/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.resx b/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/Itrycn_Project2/OTools/RegSoft/frmLogin.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/Source/Itrycn_Project2/Program.cs b/Source/Itrycn_Project2/Program.cs new file mode 100644 index 0000000..b9f4770 --- /dev/null +++ b/Source/Itrycn_Project2/Program.cs @@ -0,0 +1,56 @@ +using Itrycn; +using Itrycn_Project2; +using ryCommon; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project +{ + static class Program + { + static System.Threading.Mutex run; + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main(string[] args) + { + Application.ThreadException += Application_ThreadException; + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Soft_Info.UserDataFolder = ryCommon.RyFiles.GetRealPath(Soft_Info.UserDataFolder); + run = new System.Threading.Mutex(true, Soft_Info.Soft_Id, out bool runone); + if (!runone) //已经运行了 + { + ryCommon.Ini ini = new ryCommon.Ini(Soft_Info.UserDataFolder + "\\Win.dat"); + ryControls.Win32.SendMessage((IntPtr)ini.ReadIni(Soft_Info.Soft_Id, "hwnd", 0), 17189, 100, 100); + } + else + { + Application.Run(new FrmStart(args)); + //Application.Run(new WindowsFormsApp2.Form1()); + } + //FrmLogin frm = new FrmLogin(); + //if (frm.ShowDialog() == DialogResult.OK) + //{ + // Application.Run(new Frmmain()); + //} + } + static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Exception ex = e.ExceptionObject as Exception; + MessageBox.Show(string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}\r\nCLR即将退出:{3}", ex.GetType(), ex.Message, ex.StackTrace, e.IsTerminating)); + RyFiles.WriteAllText(Application.StartupPath + "\\错误.txt", DateTime.Now.ToString() + "\r\n\r\n错误描述:" + ex.Message + "\r\n\r\n异常堆栈:" + ex.StackTrace + "\r\n\r\n异常方法:" + ex.TargetSite, Encoding.UTF8); + } + static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) + { + Exception ex = e.Exception; + MessageBox.Show(string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace)); + RyFiles.WriteAllText(Application.StartupPath + "\\线程错误.txt", DateTime.Now.ToString() + "\r\n\r\n错误描述:" + ex.Message + "\r\n\r\n异常堆栈:" + ex.StackTrace + "\r\n\r\n异常方法:" + ex.TargetSite, Encoding.UTF8); + } + } +} diff --git a/Source/Itrycn_Project2/Properties/AssemblyInfo.cs b/Source/Itrycn_Project2/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f491a7d --- /dev/null +++ b/Source/Itrycn_Project2/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Itrycn_Project")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Itrycn_Project")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("62b5c3e8-4af1-4a7f-a40b-a6186f83dbd2")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/Itrycn_Project2/Properties/Resources.Designer.cs b/Source/Itrycn_Project2/Properties/Resources.Designer.cs new file mode 100644 index 0000000..f47dab2 --- /dev/null +++ b/Source/Itrycn_Project2/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Itrycn_Project2.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.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("Itrycn_Project2.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性 + /// 重写当前线程的 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/Source/Itrycn_Project2/Properties/Resources.resx b/Source/Itrycn_Project2/Properties/Resources.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/Itrycn_Project2/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/Source/Itrycn_Project2/Properties/Settings.Designer.cs b/Source/Itrycn_Project2/Properties/Settings.Designer.cs new file mode 100644 index 0000000..87b3b8d --- /dev/null +++ b/Source/Itrycn_Project2/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Itrycn_Project.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/Source/Itrycn_Project2/Properties/Settings.settings b/Source/Itrycn_Project2/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Source/Itrycn_Project2/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Source/Itrycn_Project2/clsForm.cs b/Source/Itrycn_Project2/clsForm.cs new file mode 100644 index 0000000..83cf0be --- /dev/null +++ b/Source/Itrycn_Project2/clsForm.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn +{ + public static class MDIClientSupport + { + [DllImport("user32.dll")] + private static extern int GetWindowLong(IntPtr hWnd, int nIndex); + [DllImport("user32.dll")] + private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + [DllImport("user32.dll", ExactSpelling = true)] + private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + private const int GWL_EXSTYLE = -20; + private const int WS_EX_CLIENTEDGE = 0x200; + private const uint SWP_NOSIZE = 0x0001; + private const uint SWP_NOMOVE = 0x0002; + private const uint SWP_NOZORDER = 0x0004; + private const uint SWP_NOREDRAW = 0x0008; + private const uint SWP_NOACTIVATE = 0x0010; + private const uint SWP_FRAMECHANGED = 0x0020; + private const uint SWP_SHOWWINDOW = 0x0040; + private const uint SWP_HIDEWINDOW = 0x0080; + private const uint SWP_NOCOPYBITS = 0x0100; + private const uint SWP_NOOWNERZORDER = 0x0200; + private const uint SWP_NOSENDCHANGING = 0x0400; + public static bool SetBevel(this Form form, bool show) + { + foreach (Control c in form.Controls) + { + switch (c) + { + case MdiClient client: + if (client != null) + { + int windowLong = GetWindowLong(c.Handle, GWL_EXSTYLE); + if (show) + { + windowLong |= WS_EX_CLIENTEDGE; + } + else + { + windowLong &= ~WS_EX_CLIENTEDGE; + } + SetWindowLong(c.Handle, GWL_EXSTYLE, windowLong); + // Update the non-client area. + SetWindowPos(client.Handle, IntPtr.Zero, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + return true; + } + break; + } + } + return false; + } + } +} diff --git a/Source/Itrycn_Project2/frmSetting.Designer.cs b/Source/Itrycn_Project2/frmSetting.Designer.cs new file mode 100644 index 0000000..f50684c --- /dev/null +++ b/Source/Itrycn_Project2/frmSetting.Designer.cs @@ -0,0 +1,140 @@ +namespace Itrycn_Project +{ + partial class FrmSetting + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmSetting)); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.chkAutoLogin = new System.Windows.Forms.CheckBox(); + this.btnCancel = new ryControls.ButtonEx(); + this.btnOK = new ryControls.ButtonEx(); + this.ChkAutoRun = new System.Windows.Forms.CheckBox(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Location = new System.Drawing.Point(2, 3); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(628, 430); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.ChkAutoRun); + this.tabPage1.Controls.Add(this.chkAutoLogin); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(620, 404); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "普通"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // chkAutoLogin + // + this.chkAutoLogin.AutoSize = true; + this.chkAutoLogin.Location = new System.Drawing.Point(13, 12); + this.chkAutoLogin.Name = "chkAutoLogin"; + this.chkAutoLogin.Size = new System.Drawing.Size(264, 16); + this.chkAutoLogin.TabIndex = 0; + this.chkAutoLogin.Text = "下次启动软件进行自动登陆(重启软件后生效)"; + this.chkAutoLogin.UseVisualStyleBackColor = true; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.ForeColor = System.Drawing.Color.White; + this.btnCancel.Location = new System.Drawing.Point(541, 443); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(79, 30); + this.btnCancel.TabIndex = 22; + this.btnCancel.Text = "取消"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.ForeColor = System.Drawing.Color.White; + this.btnOK.Location = new System.Drawing.Point(456, 443); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(79, 30); + this.btnOK.TabIndex = 21; + this.btnOK.Text = "保存"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.BtnOK_Click); + // + // ChkAutoRun + // + this.ChkAutoRun.AutoSize = true; + this.ChkAutoRun.Location = new System.Drawing.Point(13, 34); + this.ChkAutoRun.Name = "ChkAutoRun"; + this.ChkAutoRun.Size = new System.Drawing.Size(108, 16); + this.ChkAutoRun.TabIndex = 1; + this.ChkAutoRun.Text = "开机时启动软件"; + this.ChkAutoRun.UseVisualStyleBackColor = true; + // + // FrmSetting + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(630, 485); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.tabControl1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "FrmSetting"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "设置"; + this.Load += new System.EventHandler(this.FrmSetting_Load); + this.Resize += new System.EventHandler(this.FrmSetting_Resize); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.CheckBox chkAutoLogin; + private ryControls.ButtonEx btnCancel; + private ryControls.ButtonEx btnOK; + private System.Windows.Forms.CheckBox ChkAutoRun; + } +} \ No newline at end of file diff --git a/Source/Itrycn_Project2/frmSetting.cs b/Source/Itrycn_Project2/frmSetting.cs new file mode 100644 index 0000000..05813ea --- /dev/null +++ b/Source/Itrycn_Project2/frmSetting.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Itrycn_Project +{ + public partial class FrmSetting : Form + { + public FrmSetting() + { + InitializeComponent(); + } + + private void FrmSetting_Resize(object sender, EventArgs e) + { + tabControl1.Refresh(); + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + } + + private void BtnOK_Click(object sender, EventArgs e) + { + mySetting.Save(); + ryCommon.RyRegedit.RegRoot = Microsoft.Win32.RegistryHive.CurrentUser; + ryCommon.RyRegedit.SetAutoRun(ChkAutoRun.Checked, Soft_Info.Soft_Id, "\"" + Application.ExecutablePath.Replace("/", "\\") + "\" "+ Soft_Info.Soft_Pram); + DialogResult = DialogResult.OK; + } + ryControls.RySetting mySetting = new ryControls.RySetting(); + private void FrmSetting_Load(object sender, EventArgs e) + { + mySetting.FilePath = Soft_Info.UserDataFolder + "\\Setting.xml"; + mySetting.Add("AutoLogin", chkAutoLogin,false); + mySetting.Read(); + ryCommon.RyRegedit.RegRoot = Microsoft.Win32.RegistryHive.CurrentUser; + ChkAutoRun.Checked = ryCommon.RyRegedit.IsAutoRun(Soft_Info.Soft_Id, "\"" + Application.ExecutablePath.Replace("/", "\\") + "\" "+ Soft_Info.Soft_Pram); + } + } +} diff --git a/Source/Itrycn_Project2/frmSetting.resx b/Source/Itrycn_Project2/frmSetting.resx new file mode 100644 index 0000000..67eda94 --- /dev/null +++ b/Source/Itrycn_Project2/frmSetting.resx @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu+nQCUlIQAfXx1WoaF + eteGhXrXhoV614WEetN7enNGh4d7AHNxbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdFjcAHRY3AB0WNwAdFjcAHRY3AAAAAAA4MkgAZGFlAFpX + XguNjH+2lZWE/5WVhP+VlYT/lZWE/4uKfZ8pIj8EVFFbACkjPwAAAAAAHRY3AB0WNwAdFjcAHRY3AB0W + NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRY3AJiYhgB2dXAAkZCBAGZkZgAzLkUAFQ0yABQM + MQCoqZAAf352WpOTg/eVlYT/lZWE/5WVhP+VlYT/kpGC7nt5c0WQkIEAAAAAAA8ILgAyLEUAaWZoAIWE + egBhXmIAY2BkAB0WNwAAAAAAAAAAAAAAAAAAAAAAAAAAAB0WNwCkpY4AeHZxAGNgZBlzcW5XYV5iKCAZ + OQj///8A////AG5sazaOjX/XlZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/jIt+yGdlZyno7bkA///2ABkS + NAdiX2MqcG1sSExIVQlgXWIAYl9jAB0WNwAAAAAAAAAAAAAAAAAdFjcAo6SNAHh2cQBdWmAXh4Z7qZKR + gvuMjH7ihYR5tX59dpN/fXaUjIx+2pWVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/i4p9z3x6 + dIZ9fHWKhIN5so2Mf+KQkIHzgH93fCkiPwZfXGEAYV5jAB0WNwAAAAAAAAAAAAAAEwB/fnYAYF1iGIaG + e6mUlIP/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lJSD/5SUhP+VlYT/lZWE/5WVhP+SkoL3gH52ejgzSQddWmAAAAAAAAAAAAAAAAAAYl9jAAIA + JgGIiHyOlJSD/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+SkoL3g4J4YJmahwAxK0QAAAAAAAAA + AAB6eHIAoqOMAJOTg3mVlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhPuSkYJXl5eFAD45 + TAAAAAAAAAAAAIB+dgCRkYEAj4+ANJSUhO6VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lJSD/5SUg/+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lJSD2o2N + fxyNjX8ARUBQAAAAAAAAAAAAHRY3AIeGewCIh3sTk5OD0ZWVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+UlIP/lpaF/5ubi/+fn4//n5+P/5qaiv+VlYT/lJSD/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+TkoKzeXdyBXx6dAAAAAAAAAAAAAAAAAAjHTsAcG5sAHd2cQqSkYLDlZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/6Kikv+0tKf/vr6y/8HBtf/BwbX/vb2x/7KypP+fn4//lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/lZWE/5CQgaH///8AJyE+AB0WNwAAAAAAQj1PACkiPgCMjH4Ac3FuMZGRgeKVlYT/lZWE/5WV + hP+VlYT/lZWE/5aWhf+rq53/wcG1/8XFufzExLjZxMS4t8TEuLvExLjgxcW5/7+/s/+np5f/lZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/j46Ay2ViZRt5d3IAAAAaADAqQwByb20AAAAAAG1qajuKin3FlZWE/5WV + hP+VlYT/lZWE/5WVhP+VlYT/qama/8PDt//ExLjmw8O4bcPDtxvDw7cGw8O3B8PDtyPDw7iCxMS48cHB + tf+jo5T/lJSD/5WVhP+VlYT/lZWE/5WVhP+UlIP+h4Z7rmRhZCj5/8QAZ2VnAGdlZzN+fXWIjo6A5pWV + hP+VlYT/lZWE/5WVhP+VlYT/lZWE/5ycjP++vrH/xMS47sLCt1LGx7oAw8O3AMPDtwDDw7cAw8O3AAAA + AADCwrdvxcW5+bm5rP+YmIj/lZWE/5WVhP+VlYT/lZWE/5WVhP+UlIT/jIt+2Hp4c3RhXmMkjYx/3pSU + g/+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+UlIP/qama/8TEuP/CwraakpCRAby7sgDAwLUAAAAAACAZ + OQDBwbUAvr2zALm4rwvCwre6w8O3/6OjlP+UlIP/lZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/k5OD/4uK + fbuTk4PwlZWE/5WVhP+VlYT/lZWE/5WVhP+VlYT/lZWE/5WVhP+zs6X/xMS4+728slPCwrcAv7+0AAAA + AAAAAAAAAAAAAAAAAADb3MoAzc2/AL6+tHbExLj/rKyd/5SUg/+VlYT/lZWE/5WVhP+VlYT/lZWE/5WV + hP+VlYT/kpKC0Zybi+2fno3/n52N/p+djf6fnY3+n52N/p+djf6fnY3+n56N/rm4q//Dw7j2tbWtQLu7 + sQAhGjoAAAAAAAAAAAAAAAAAAAAAAFVQYgDGxroAubmwYcTEuP+zs6X/np2M/p+djf6fnY3+n52N/p+d + jf6fnY3+n52N/p+ejf+bmovPpKKR8aakk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/ubiq/8PD + uPyysapaxMS4AJybmQAdFjcAAAAAAAAAAAAdFjcA////AO7w2QC2tq19xMS4/7W0pf+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6OgkdOkopKgpqST6aakk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + kv+zsqP/xMS4/7a2rqhFQFYHcW14AGhkcQAdFjcAHRY3AIyKjQCIhooAgH2EFLu6scXDw7f/r62e/6ak + kv+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJPlpKKRiqalkwSlo5M1pqSTp6akk/qmpJP/pqST/6ak + k/+mpJP/pqST/6qomP/AwLP/wcC29aOin2kAAAACjYuOAFlVZgBfW2oAmpmYAC8pRQirqaSGw8O3/L29 + r/+oppX/pqST/6akk/+mpJP/pqST/6akk/+mpJP2pqSTmaWjky2oppQDpKKSAKakkwCjoZEJpaOSgaak + k/qmpJP/pqST/6akk/+mpJP/pqST/7Kxov/Dw7f/vr608KakoYyBfoQyXFhoFWFdaxeIhYk8q6qkn8HA + tfjCwrX/r62e/6akk/+mpJP/pqST/6akk/+mpJP/pqST86WjkmyioJAEpqOTAKSikgCal4sApaOSAJ6c + jgCZlooSpKKSzqakk/+mpJP/pqST/6akk/+mpJP/p6WU/7SzpP/Cwrb/w8O3/7q6seq0s6vRtLSs1Ly8 + su/ExLj/wcG0/7GvoP+mpJP/pqST/6akk/+mpJP/pqST/6akk/+joZGrj4yEBKGfkAClo5IAjYuCAAAA + AAAdFjcAgHx5AIJ/ewuioJDEpqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/66snP+6uav/wcCz/8PD + tv/Dw7b/wMCz/7i3qf+sqpr/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6Cdj5f//+8AAAAOAAAA + AAAAAAAAAAAAAB0WNwCLiIEAioeAHaKgkdumpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + lP+pqJf/rKqa/6yqmv+pp5f/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/oJ6Ptmhk + agdtaW0AHRY3AAAAAAAAAAAA/P3NAKOhkQCTkIZLpKKS96akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+ioJDhiYZ/Jo6LgwAdFjcAAAAAAAAAAABhXGUA////AJyajJOmpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6Wjkv6YlopdqKaUAB0WNwAAAAAAAAAAAIB9egDS0rEApKKSUqakk+empJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJP/pqST/6akk/+mpJP/pqSTwqOhkSWoppUAHRY3AAAAAAAAAAAAhIF8AJqYiwCoppQApaOSTqak + k+SmpJP/pqST/6akk/empJPnpqST5qakk/umpJP/pqST/6akk/+mpJP/pqST/6akk/+mpJP/pqST/6ak + k/mmpJPkpqST6aakk/mmpJP/pqST/6akk8KkopImpaOSAK+tmQAdFjcAAAAAAAAAAAAAAAAAoqCQAKKg + kACqqJUApaOSTaakk7+mpJOHpqSTR6akkyampJMkpaOTdaakk/OmpJP/pqST/6akk/+mpJP/pqST/6ak + k/+mpJPnpaOTYKakkyKmpJMppqSTTqakk5OmpJOspKKSJ6akkwCwr5oAm5mMAAAAAAAAAAAAAAAAAAAA + AAAAAAAAop+QAKKgkAD///8ApaOSDKimlQCmpJMApqSTAKWjkgCNioIBpaOShqakk/+mpJP/pqST/6ak + k/+mpJP/pqST+aSikmeqqJYApaOTAKakkwCmpJMAm5mMAKSikgimpJMAsK+aAJuZjAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAoqCRAKOhkQClo5IApaOSAKSikgB1cnIAo6GRAKKgkQChn5AZpaOSzqak + k/+mpJP/pqST/6akk/+lo5KynpyOCqGfkAChn5AAlZKHAKWjkgClo5IApKKSAJ+djgCcmo0AAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdFjcA////AK6s + mACkopJ2pqST+Kakk/ampJP2pqST8qOhkVWnpZMAqKaUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/+AH//BAAg/gAAAHwAAAA4AAAAGAAAABgAAAAYAAAAGAAAABgAAAA4AA + AAEAAAAAAAAAAAAAAAAAAQAAAAPAAAADwAAAAYAAAAAAAAAAAAAAAAAAAAAAAIAAAAOAAAABgAAAAYAA + AAGAAAABgAAAAcAAAAPgAAAH8AAAD//AB/8= + + + \ No newline at end of file diff --git a/Source/MyDb/DbManage/Authority.cs b/Source/MyDb/DbManage/Authority.cs new file mode 100644 index 0000000..2b3ab27 --- /dev/null +++ b/Source/MyDb/DbManage/Authority.cs @@ -0,0 +1,137 @@ +//--------------------------日期:2013-8-28 +//--------------------------版本:2.0.1.0 +//--------------------------作者:itrycn +using System; +using System.Collections.Generic; +using System.Text; +//权限控制 +namespace ryCommon +{ + /// + /// 基于XML实现的权限类 + /// + public class Authority + { + private Storage mStor = new Storage(); + private string m_username =""; + /// + /// 用户名 + /// + public string UserName + { + get { return m_username; } + set { m_username = value; } + } + private string m_userid = ""; + /// + /// 用户id + /// + public string UserId + { + get { return m_userid; } + set { m_userid = value; } + } + private string m_password = ""; + /// + /// 密码 + /// + public string PassWord + { + get { return m_password; } + set { m_password = value; } + } + private string m_AuthId = ""; + /// + /// 权限控制Id + /// + public string AuthId + { + get { return m_AuthId; } + set { m_AuthId = value; } + } + private string m_UserDes = ""; + /// + /// 用户备注 + /// + public string UserDes + { + get { return m_UserDes; } + set { m_UserDes = value; } + } + private int m_AdminAuth = 0; + /// + /// 是否是管理员权限 + /// + public int AdminAuth + { + get { return m_AdminAuth; } + set { m_AdminAuth = value; } + } + private int m_SuperAdmin = 0; + /// + /// 是否是超级管理员权限 + /// + public int SuperAdmin + { + get { return m_SuperAdmin; } + set { m_SuperAdmin = value; } + } + /// + /// 设置权限 + /// + /// 权限名称 + /// 权限值 + /// 返回是否设置成功 + public int SetAuthority(string name, string value) + { + mStor.SelectNode2("name", name); + return mStor.SetAttrValue("value", value); + } + /// + /// 获取权限 + /// + /// 权限名称 + /// 默认权限值 + /// 返回权限值 + public string GetAuthority(string name,string defValue) + { + mStor.SelectNode("name", name); + return mStor.GetAttrValue("value", defValue); + } + /// + /// 获取权限 + /// + /// 权限名称 + /// 返回权限值 + public string GetAuthority(string name) + { + mStor.SelectNode("name", name); + return mStor.GetAttrValue("value"); + } + /// + /// 批量导入权限 + /// + /// 权限相关的内容 + /// 返回是否执行成功 + public int PutAuthorityText(string XMLText) + { + return mStor.LoadFromXMLText(XMLText); + } + /// + /// 导出权限 + /// + /// 返回导出文本 + public string GetAuthorityText() + { + return mStor.GetXMLText(); + } + /// + /// 清除所有权限 + /// + /// 返回是否执行成功 + public int ClearAuthority() + { + return mStor.LoadEmptyXMLText(); + } + } +} diff --git a/Source/MyDb/DbManage/Ini.cs b/Source/MyDb/DbManage/Ini.cs new file mode 100644 index 0000000..8f62572 --- /dev/null +++ b/Source/MyDb/DbManage/Ini.cs @@ -0,0 +1,363 @@ +//--------------------------日期:2013-8-28 +//--------------------------版本:2.0.1.0 +//--------------------------作者:itrycn +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +namespace ryCommon +{ + /// + /// Ini操作类 + /// + public class Ini + { + // 声明INI文件的写操作函数 WritePrivateProfileString() +   [System.Runtime.InteropServices.DllImport("kernel32")] +   private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); + /// + /// 写入Ini + /// + /// + /// + /// + /// + /// + [DllImport("kernel32")] + public static extern bool WritePrivateProfileString(byte[] section, byte[] key, byte[] val, string filePath); + /// + /// 获取Ini + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("kernel32")] + public static extern int GetPrivateProfileString(byte[] section, byte[] key, byte[] def, byte[] retVal, int size, string filePath); + + /// + /// 声明INI文件的读操作函数 GetPrivateProfileString() + /// + /// + /// + /// + /// + /// + /// + /// + [System.Runtime.InteropServices.DllImport("kernel32")] +   private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath); + /// + /// 声明INI文件的读操作函数 GetPrivateProfileString() + /// + /// + /// + /// + /// + /// + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName); + /// + /// 声明INI文件的读操作函数 GetPrivateProfileString() + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("kernel32")] + private static extern int GetPrivateProfileString(string section, string key, string defVal, Byte[] retVal, int size, string filePath); + /// + /// 获取所有节点名称(Section) + /// + /// 存放节点名称的内存地址,每个节点之间用\0分隔 + /// 内存大小(characters) + /// Ini文件 + /// 内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够 + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + private static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string lpFileName); + private readonly string sPath = null; + /// + /// 编码 + /// + public Encoding Encoding { get; set; } = Encoding.Default; + /// + /// Ini操作类 + /// + /// + public Ini(string path) +   { +   this.sPath = path; + if(path!="" && !System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(path))) + { + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); + } +   } + /// + /// 根据section取所有key和值 + /// + /// + /// + public string[] GetAllKeysAndValue(string section) + { + UInt32 MAX_BUFFER = 32767; + string[] items = new string[0]; + IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char)); + UInt32 bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, sPath); + if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0)) + { + string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned); + items = returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); + } + Marshal.FreeCoTaskMem(pReturnedString); + return items; + } + /// + /// 读取INI文件中指定INI文件中的所有节点名称(Section) + /// + /// 所有节点,没有内容返回string[0] + public string[] GetAllSectionNames() + { + uint MAX_BUFFER = 32767; //默认为32767 + + string[] sections = new string[0]; //返回值 + + //申请内存 + IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char)); + uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, sPath); + if (bytesReturned != 0) + { + //读取指定内存的内容 + string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString(); + //每个节点之间用\0分隔,末尾有一个\0 + sections = local.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); + } + + //释放内存 + Marshal.FreeCoTaskMem(pReturnedString); + + return sections; + } + /// + /// 读取INI文件 + /// + /// 段,格式[] + /// 键 + /// 返回byte类型的section组或键值组 + public byte[] IniReadValues(string section, string key) + { + int size = 1000; + byte[] buffer = new byte[size]; + int count = GetPrivateProfileString(GetBytes(section), GetBytes(key), GetBytes(""), buffer, size, sPath); + return buffer; + } + /// + /// 根据section取所有key + /// + /// + /// + public string[] GetKey(string section) + { + byte[] allSection = IniReadValues(section, null); + //编码所有key的string类型 + string sections = Encoding.GetString(allSection).TrimEnd('\0'); + //获取key的数组 + return sections.Split(new char[1] { '\0' }); + } + //与ini交互必须统一编码格式 + private byte[] GetBytes(string s) + { + return null == s ? null :Encoding.GetBytes(s); + } + /// + /// 写入ini + /// + /// + /// + /// + public void WriteIni(string section, string key, string value) + { + WritePrivateProfileString(GetBytes(section), GetBytes(key), GetBytes(value), sPath); + } + + /// + /// 写入ini + /// + /// + /// + /// + public void WriteIni(string section, string key, int value) + { + WriteIni(section, key, value.ToString()); + } + /// + /// 写入ini + /// + /// + /// + /// + public void WriteIni(string section, string key, Int64 value) + { + WriteIni(section, key, value.ToString()); + } + /// + /// 写入ini + /// + /// + /// + /// + public void WriteIni(string section, string key, decimal value) + { + WriteIni(section, key, value.ToString()); + } + /// + /// 写入ini + /// + /// + /// + /// + public void WriteIni(string section, string key, double value) + { + WriteIni(section, key, value.ToString()); + } + /// + /// 写入Ini + /// + /// + /// + /// + public void WriteIni(string section, string key, bool value) + { + if (value) + { + WriteIni(section, key, "1"); + } + else + { + WriteIni(section, key, "0"); + } + } + /// + /// 读取Ini + /// + /// + /// + /// + public string ReadIni(string section, string key) + { + return ReadIni(section, key,"") ; + } + /// + /// 读取Ini + /// + /// + /// + /// + /// + public string ReadIni(string section, string key,string defValue) + { + int size = 255; + byte[] buffer = new byte[size]; + int count = GetPrivateProfileString(GetBytes(section), GetBytes(key), GetBytes(defValue), buffer, size, sPath); + return Encoding.GetString(buffer, 0, count).Trim(); + } + /// + /// 读取Ini + /// + /// + /// + /// + /// + public int ReadIni(string section, string key, int defValue) + { + try + { + return Convert.ToInt32(ReadIni(section, key, defValue.ToString())); + } + catch + { + return defValue; + } + } + /// + /// 读取Ini + /// + /// + /// + /// + /// + /// + /// + public int ReadIni(string section, string key, int min, int max, int defValue) + { + try + { + int resultI = ReadIni(section, key, defValue); + if (resultI >= min && resultI <= max) + { + return resultI; + } + else + { + return defValue; + } + } + catch + { + return defValue; + } + } + /// + /// 写入ini + /// + /// + /// + /// + /// + public bool ReadIni(string section, string key, bool defValue) + { + try + { + string tmpStr= ReadIni(section, key, defValue.ToString()); + if (tmpStr.ToLower() == "true" || tmpStr=="1") + { + return true; + } + else if (tmpStr.ToLower() == "false" || tmpStr == "0" || tmpStr == "-1") + { + return false; + } + else + { + return defValue; + } + } + catch + { + return defValue; + } + } + /// + /// 删除Ini的Key + /// + /// + /// + public void DelKey(string section, string key) + { + WritePrivateProfileString(GetBytes(section), GetBytes(key), null, sPath); + } + /// + /// 删除Ini节点 + /// + /// + public void DelSection(string section) + { + WritePrivateProfileString(GetBytes(section),null, null, sPath); + } + } +} diff --git a/Source/MyDb/DbManage/PinYin.cs b/Source/MyDb/DbManage/PinYin.cs new file mode 100644 index 0000000..a413916 --- /dev/null +++ b/Source/MyDb/DbManage/PinYin.cs @@ -0,0 +1,499 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace ryCommon +{ + /// + /// 汉字转拼音静态类,包括功能全拼和缩写,方法全部是静态的 + /// + public static class PinYin + { + #region 属性数据定义 + /// + /// 汉字的机内码数组 + /// + private static int[] pyValue = new int[] + { + -20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230,-20051,-20036, + -20032,-20026,-20002,-19990,-19986,-19982,-19976,-19805,-19784,-19775,-19774,-19763, + -19756,-19751,-19746,-19741,-19739,-19728,-19725,-19715,-19540,-19531,-19525,-19515, + -19500,-19484,-19479,-19467,-19289,-19288,-19281,-19275,-19270,-19263,-19261,-19249, + -19243,-19242,-19238,-19235,-19227,-19224,-19218,-19212,-19038,-19023,-19018,-19006, + -19003,-18996,-18977,-18961,-18952,-18783,-18774,-18773,-18763,-18756,-18741,-18735, + -18731,-18722,-18710,-18697,-18696,-18526,-18518,-18501,-18490,-18478,-18463,-18448, + -18447,-18446,-18239,-18237,-18231,-18220,-18211,-18201,-18184,-18183, -18181,-18012, + -17997,-17988,-17970,-17964,-17961,-17950,-17947,-17931,-17928,-17922,-17759,-17752, + -17733,-17730,-17721,-17703,-17701,-17697,-17692,-17683,-17676,-17496,-17487,-17482, + -17468,-17454,-17433,-17427,-17417,-17202,-17185,-16983,-16970,-16942,-16915,-16733, + -16708,-16706,-16689,-16664,-16657,-16647,-16474,-16470,-16465,-16459,-16452,-16448, + -16433,-16429,-16427,-16423,-16419,-16412,-16407,-16403,-16401,-16393,-16220,-16216, + -16212,-16205,-16202,-16187,-16180,-16171,-16169,-16158,-16155,-15959,-15958,-15944, + -15933,-15920,-15915,-15903,-15889,-15878,-15707,-15701,-15681,-15667,-15661,-15659, + -15652,-15640,-15631,-15625,-15454,-15448,-15436,-15435,-15419,-15416,-15408,-15394, + -15385,-15377,-15375,-15369,-15363,-15362,-15183,-15180,-15165,-15158,-15153,-15150, + -15149,-15144,-15143,-15141,-15140,-15139,-15128,-15121,-15119,-15117,-15110,-15109, + -14941,-14937,-14933,-14930,-14929,-14928,-14926,-14922,-14921,-14914,-14908,-14902, + -14894,-14889,-14882,-14873,-14871,-14857,-14678,-14674,-14670,-14668,-14663,-14654, + -14645,-14630,-14594,-14429,-14407,-14399,-14384,-14379,-14368,-14355,-14353,-14345, + -14170,-14159,-14151,-14149,-14145,-14140,-14137,-14135,-14125,-14123,-14122,-14112, + -14109,-14099,-14097,-14094,-14092,-14090,-14087,-14083,-13917,-13914,-13910,-13907, + -13906,-13905,-13896,-13894,-13878,-13870,-13859,-13847,-13831,-13658,-13611,-13601, + -13406,-13404,-13400,-13398,-13395,-13391,-13387,-13383,-13367,-13359,-13356,-13343, + -13340,-13329,-13326,-13318,-13147,-13138,-13120,-13107,-13096,-13095,-13091,-13076, + -13068,-13063,-13060,-12888,-12875,-12871,-12860,-12858,-12852,-12849,-12838,-12831, + -12829,-12812,-12802,-12607,-12597,-12594,-12585,-12556,-12359,-12346,-12320,-12300, + -12120,-12099,-12089,-12074,-12067,-12058,-12039,-11867,-11861,-11847,-11831,-11798, + -11781,-11604,-11589,-11536,-11358,-11340,-11339,-11324,-11303,-11097,-11077,-11067, + -11055,-11052,-11045,-11041,-11038,-11024,-11020,-11019,-11018,-11014,-10838,-10832, + -10815,-10800,-10790,-10780,-10764,-10587,-10544,-10533,-10519,-10331,-10329,-10328, + -10322,-10315,-10309,-10307,-10296,-10281,-10274,-10270,-10262,-10260,-10256,-10254 + }; + /// + /// 机内码对应的拼音数组 + /// + private static string[] pyName = new string[] + { + "A","Ai","An","Ang","Ao","Ba","Bai","Ban","Bang","Bao","Bei","Ben", + "Beng","Bi","Bian","Biao","Bie","Bin","Bing","Bo","Bu","Ba","Cai","Can", + "Cang","Cao","Ce","Ceng","Cha","Chai","Chan","Chang","Chao","Che","Chen","Cheng", + "Chi","Chong","Chou","Chu","Chuai","Chuan","Chuang","Chui","Chun","Chuo","Ci","Cong", + "Cou","Cu","Cuan","Cui","Cun","Cuo","Da","Dai","Dan","Dang","Dao","De", + "Deng","Di","Dian","Diao","Die","Ding","Diu","Dong","Dou","Du","Duan","Dui", + "Dun","Duo","E","En","Er","Fa","Fan","Fang","Fei","Fen","Feng","Fo", + "Fou","Fu","Ga","Gai","Gan","Gang","Gao","Ge","Gei","Gen","Geng","Gong", + "Gou","Gu","Gua","Guai","Guan","Guang","Gui","Gun","Guo","Ha","Hai","Han", + "Hang","Hao","He","Hei","Hen","Heng","Hong","Hou","Hu","Hua","Huai","Huan", + "Huang","Hui","Hun","Huo","Ji","Jia","Jian","Jiang","Jiao","Jie","Jin","Jing", + "Jiong","Jiu","Ju","Juan","Jue","Jun","Ka","Kai","Kan","Kang","Kao","Ke", + "Ken","Keng","Kong","Kou","Ku","Kua","Kuai","Kuan","Kuang","Kui","Kun","Kuo", + "La","Lai","Lan","Lang","Lao","Le","Lei","Leng","Li","Lia","Lian","Liang", + "Liao","Lie","Lin","Ling","Liu","Long","Lou","Lu","Lv","Luan","Lue","Lun", + "Luo","Ma","Mai","Man","Mang","Mao","Me","Mei","Men","Meng","Mi","Mian", + "Miao","Mie","Min","Ming","Miu","Mo","Mou","Mu","Na","Nai","Nan","Nang", + "Nao","Ne","Nei","Nen","Neng","Ni","Nian","Niang","Niao","Nie","Nin","Ning", + "Niu","Nong","Nu","Nv","Nuan","Nue","Nuo","O","Ou","Pa","Pai","Pan", + "Pang","Pao","Pei","Pen","Peng","Pi","Pian","Piao","Pie","Pin","Ping","Po", + "Pu","Qi","Qia","Qian","Qiang","Qiao","Qie","Qin","Qing","Qiong","Qiu","Qu", + "Quan","Que","Qun","Ran","Rang","Rao","Re","Ren","Reng","Ri","Rong","Rou", + "Ru","Ruan","Rui","Run","Ruo","Sa","Sai","San","Sang","Sao","Se","Sen", + "Seng","Sha","Shai","Shan","Shang","Shao","She","Shen","Sheng","Shi","Shou","Shu", + "Shua","Shuai","Shuan","Shuang","Shui","Shun","Shuo","Si","Song","Sou","Su","Suan", + "Sui","Sun","Suo","Ta","Tai","Tan","Tang","Tao","Te","Teng","Ti","Tian", + "Tiao","Tie","Ting","Tong","Tou","Tu","Tuan","Tui","Tun","Tuo","Wa","Wai", + "Wan","Wang","Wei","Wen","Weng","Wo","Wu","Xi","Xia","Xian","Xiang","Xiao", + "Xie","Xin","Xing","Xiong","Xiu","Xu","Xuan","Xue","Xun","Ya","Yan","Yang", + "Yao","Ye","Yi","Yin","Ying","Yo","Yong","You","Yu","Yuan","Yue","Yun", + "Za", "Zai","Zan","Zang","Zao","Ze","Zei","Zen","Zeng","Zha","Zhai","Zhan", + "Zhang","Zhao","Zhe","Zhen","Zheng","Zhi","Zhong","Zhou","Zhu","Zhua","Zhuai","Zhuan", + "Zhuang","Zhui","Zhun","Zhuo","Zi","Zong","Zou","Zu","Zuan","Zui","Zun","Zuo" + }; + #endregion + #region 把汉字转换成拼音(全拼)无间隔符号 + /// + /// 把汉字转换成拼音(全拼) + /// + /// 汉字字符串 + /// 转换后的拼音(全拼)字符串 + public static string Convert(string hzString) + { + // 匹配中文字符 + Regex regex = new Regex("^[\\u4e00-\\u9fa5]$"); + byte[] array = new byte[2]; + string pyString = ""; + int chrAsc = 0; + int i1 = 0; + int i2 = 0; + char[] noWChar = hzString.ToCharArray(); + for (int j = 0; j < noWChar.Length; j++) + { + // 中文字符 + if (regex.IsMatch(noWChar[j].ToString())) + { + array = System.Text.Encoding.Default.GetBytes(noWChar[j].ToString()); + i1 = (short)(array[0]); + i2 = (short)(array[1]); + chrAsc = i1 * 256 + i2 - 65536; + if (chrAsc > 0 && chrAsc < 160) + { + pyString += noWChar[j]; + } + else + { + // 修正部分文字 + if (chrAsc == -9254) // 修正“圳”字 + pyString += "Zhen"; + else + { + for (int i = (pyValue.Length - 1); i >= 0; i--) + { + if (pyValue[i] <= chrAsc) + { + pyString += pyName[i]; + break; + } + } + } + } + } + // 非中文字符 + else + { + pyString += noWChar[j].ToString(); + } + } + return pyString; + } + #endregion + #region 把汉字转换成拼音(全拼) 用空格间隔 + /// + /// 把汉字转换成拼音(全拼) + /// + /// 汉字字符串 + /// 转换后的拼音(全拼)字符串 + public static string ConvertWithBlank(string hzString) + { + // 匹配中文字符 + Regex regex = new Regex("^[u4e00-u9fa5]$"); + byte[] array = new byte[2]; + string pyString = ""; + int chrAsc = 0; + int i1 = 0; + int i2 = 0; + char[] noWChar = hzString.ToCharArray(); + for (int j = 0; j < noWChar.Length; j++) + { + // 中文字符 + if (regex.IsMatch(noWChar[j].ToString())) + { + array = System.Text.Encoding.Default.GetBytes(noWChar[j].ToString()); + i1 = (short)(array[0]); + i2 = (short)(array[1]); + chrAsc = i1 * 256 + i2 - 65536; + if (chrAsc > 0 && chrAsc < 160) + { + pyString = pyString + " " + noWChar[j]; + } + else + { + // 修正部分文字 + if (chrAsc == -9254) // 修正“圳”字 + pyString = pyString + " " + "Zhen"; + else + { + for (int i = (pyValue.Length - 1); i >= 0; i--) + { + if (pyValue[i] <= chrAsc) + { + pyString = pyString + " " + pyName[i]; + break; + } + } + } + } + } + // 非中文字符 + else + { + pyString = pyString + " " + noWChar[j].ToString(); + } + } + return pyString.Trim(); + } + #endregion + #region 把汉字转换成拼音(首拼)无间隔符号 + /// + /// 把汉字转换成拼音(首拼) + /// + /// 汉字字符串 + /// 转换后的拼音(首拼)字符串 + public static string ConvertFirstPY(string hzString) + { + // 匹配中文字符 + Regex regex = new Regex("^[\\u4e00-\\u9fa5]$"); + byte[] array = new byte[2]; + string pyString = ""; + int chrAsc = 0; + int i1 = 0; + int i2 = 0; + char[] noWChar = hzString.ToCharArray(); + for (int j = 0; j < noWChar.Length; j++) + { + // 中文字符 + if (regex.IsMatch(noWChar[j].ToString())) + { + array = System.Text.Encoding.Default.GetBytes(noWChar[j].ToString()); + i1 = (short)(array[0]); + i2 = (short)(array[1]); + chrAsc = i1 * 256 + i2 - 65536; + if (chrAsc > 0 && chrAsc < 160) + { + pyString += noWChar[j]; + } + else + { + // 修正部分文字 + if (chrAsc == -9254) // 修正“圳”字 + pyString += "z"; + else + { + for (int i = (pyValue.Length - 1); i >= 0; i--) + { + if (pyValue[i] <= chrAsc) + { + pyString += pyName[i].Substring(0, 1); + break; + } + } + } + } + } + // 非中文字符 + else + { + pyString += noWChar[j].ToString(); + } + } + return pyString; + } + #endregion + #region 把汉字转换成拼音(全拼) 用特定的字符间隔 + /// + /// 把汉字转换成拼音(全拼) + /// + /// 汉字字符串 + /// 用指定字符分隔 + /// 转换后的拼音(全拼)字符串 + public static string ConvertWithSplitChar(string hzString, string splitChar) + { + // 匹配中文字符 + Regex regex = new Regex("^[\\u4e00-\\u9fa5]$"); + byte[] array = new byte[2]; + string pyString = ""; + int chrAsc = 0; + int i1 = 0; + int i2 = 0; + char[] noWChar = hzString.ToCharArray(); + for (int j = 0; j < noWChar.Length; j++) + { + // 中文字符 + if (regex.IsMatch(noWChar[j].ToString())) + { + array = System.Text.Encoding.Default.GetBytes(noWChar[j].ToString()); + i1 = (short)(array[0]); + i2 = (short)(array[1]); + chrAsc = i1 * 256 + i2 - 65536; + if (chrAsc > 0 && chrAsc < 160) + { + pyString = pyString + splitChar + noWChar[j]; + } + else + { + // 修正部分文字 + if (chrAsc == -9254) // 修正“圳”字 + pyString = pyString + splitChar + "Zhen"; + else + { + for (int i = (pyValue.Length - 1); i >= 0; i--) + { + if (pyValue[i] <= chrAsc) + { + pyString = pyString + splitChar + pyName[i]; + break; + } + } + } + } + } + // 非中文字符 + else + { + pyString = pyString + splitChar + noWChar[j].ToString(); + } + } + char[] trimAChar = splitChar.ToCharArray(); + return pyString.TrimStart(trimAChar); + } + #endregion + #region 汉字转拼音缩写 (字符串) (小写) + /// + /// 汉字转拼音缩写 + /// + /// 要转换的汉字字符串 + /// 拼音缩写 + public static string GetSpellStringLower(string str) + { + string tempStr = ""; + foreach (char c in str) + { + if ((int)c >= 33 && (int)c <= 126) + { + //字母和符号原样保留 + tempStr += c.ToString(); + } + else + { + //累加拼音声母 + tempStr += GetSpellCharLower(c.ToString()); + } + } + return tempStr; + } + #endregion + + #region 汉字转拼音缩写 (字符串) (小写) (空格间隔) + /// + /// 汉字转拼音缩写 (字符串) (小写) (空格间隔) + /// + /// 要转换的汉字字符串 + /// 拼音缩写 + public static string GetSpellStringLowerSplitWithBlank(string str) + { + string tempStr = ""; + foreach (char c in str) + { + if ((int)c >= 33 && (int)c <= 126) + { + //字母和符号原样保留 + tempStr = tempStr + " " + c.ToString(); + } + else + { + //累加拼音声母 + tempStr = tempStr + " " + GetSpellCharLower(c.ToString()); + } + } + return tempStr.Trim(); + } + #endregion + #region 汉字转拼音缩写 (字符串)(大写) + /// + /// 汉字转拼音缩写 (大写) + /// + /// 要转换的汉字字符串 + /// 拼音缩写 + public static string GetSpellStringSupper(string str) + { + string tempStr = ""; + foreach (char c in str) + { + if ((int)c >= 33 && (int)c <= 126) + { + //字母和符号原样保留 + tempStr += c.ToString(); + } + else + { + //累加拼音声母 + tempStr += GetSpellCharSupper(c.ToString()); + } + } + return tempStr; + } + #endregion + #region 汉字转拼音缩写 (字符串)(大写)(空格间隔) + /// + /// 汉字转拼音缩写 (字符串)(大写)(空格间隔) + /// + /// 要转换的汉字字符串 + /// 拼音缩写 + public static string GetSpellStringSupperSplitWithBlank(string str) + { + string tempStr = ""; + foreach (char c in str) + { + if ((int)c >= 33 && (int)c <= 126) + { + //字母和符号原样保留 + tempStr = tempStr + " " + c.ToString(); + } + else + { + //累加拼音声母 + tempStr = tempStr + " " + GetSpellCharSupper(c.ToString()); + } + } + return tempStr.Trim(); + } + #endregion + #region 取单个字符的拼音声母(字符)(大写) + /// + /// 取单个字符的拼音声母 + /// + /// 要转换的单个汉字 + /// 拼音声母 + public static string GetSpellCharSupper(string c) + { + byte[] array = new byte[2]; + array = System.Text.Encoding.Default.GetBytes(c); + int i = (short)(array[0] - '0') * 256 + ((short)(array[1] - '0')); + if (i < 0xB0A1) return c; + if (i < 0xB0C5) return "A"; + if (i < 0xB2C1) return "B"; + if (i < 0xB4EE) return "C"; + if (i < 0xB6EA) return "D"; + if (i < 0xB7A2) return "E"; + if (i < 0xB8C1) return "F"; + if (i < 0xB9FE) return "G"; + if (i < 0xBBF7) return "H"; + if (i < 0xBFA6) return "J"; + if (i < 0xC0AC) return "K"; + if (i < 0xC2E8) return "L"; + if (i < 0xC4C3) return "M"; + if (i < 0xC5B6) return "N"; + if (i < 0xC5BE) return "O"; + if (i < 0xC6DA) return "P"; + if (i < 0xC8BB) return "Q"; + if (i < 0xC8F6) return "R"; + if (i < 0xCBFA) return "S"; + if (i < 0xCDDA) return "T"; + if (i < 0xCEF4) return "W"; + if (i < 0xD1B9) return "X"; + if (i < 0xD4D1) return "Y"; + if (i < 0xD7FA) return "Z"; + return c; + } + #endregion + #region 取单个字符的拼音声母(字符)(小写) + /// + /// 取单个字符的拼音声母 + /// + /// 要转换的单个汉字 + /// 拼音声母 + public static string GetSpellCharLower(string c) + { + byte[] array = new byte[2]; + array = System.Text.Encoding.Default.GetBytes(c); + if (array.Length <= 1) { return ""; } + int i = (short)(array[0] - '0') * 256 + ((short)(array[1] - '0')); + if (i < 0xB0A1) return c; + if (i < 0xB0C5) return "a"; + if (i < 0xB2C1) return "b"; + if (i < 0xB4EE) return "c"; + if (i < 0xB6EA) return "d"; + if (i < 0xB7A2) return "e"; + if (i < 0xB8C1) return "f"; + if (i < 0xB9FE) return "g"; + if (i < 0xBBF7) return "h"; + if (i < 0xBFA6) return "j"; + if (i < 0xC0AC) return "k"; + if (i < 0xC2E8) return "l"; + if (i < 0xC4C3) return "m"; + if (i < 0xC5B6) return "n"; + if (i < 0xC5BE) return "o"; + if (i < 0xC6DA) return "p"; + if (i < 0xC8BB) return "q"; + if (i < 0xC8F6) return "r"; + if (i < 0xCBFA) return "s"; + if (i < 0xCDDA) return "t"; + if (i < 0xCEF4) return "w"; + if (i < 0xD1B9) return "x"; + if (i < 0xD4D1) return "y"; + if (i < 0xD7FA) return "z"; + return c; + } + #endregion + } +} diff --git a/Source/MyDb/DbManage/Pram.cs b/Source/MyDb/DbManage/Pram.cs new file mode 100644 index 0000000..025123b --- /dev/null +++ b/Source/MyDb/DbManage/Pram.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryCommon.Pram +{ + /// + /// 控件信息 + /// + public class Control_Info + { + /// + /// id + /// + public string id = ""; + /// + /// 控件对象 + /// + public Control control; + /// + /// 控件值类型 + /// + public CValueType value_type = CValueType.Default; + /// + /// 默认值 + /// + public object defValue; + } + /// + /// 值类型 + /// + public enum CValueType + { + /// + /// 默认 + /// + Default, + /// + /// 取列表顺序值 + /// + ItemIndex, + /// + /// 取当前选择的列表值 + /// + ItemText, + /// + /// 取对象值 + /// + ObjectItem + } + /// + /// 保存的设置类型 + /// + public enum SettingType + { + /// + /// Ini + /// + Ini, + /// + /// XML + /// + XML + } + /// + ///对象值 + /// + public class ObjectItem + { + /// + /// 显示的文本 + /// + public string Text = ""; + /// + /// 图片序号 + /// + public int ImageIndex = -1; + /// + /// id + /// + public string Id = ""; + /// + /// Tag值 + /// + public object Tag = null; + /// + /// 显示文本值 + /// + /// + public override string ToString() + { + return Text; + } + } + /// + /// 星期数据 + /// + public class WeekInfo + { + /// + /// 一周的开始时间 + /// + public DateTime startDate; + /// + /// 一周的结束时间 + /// + public DateTime endDate; + } +} diff --git a/Source/MyDb/DbManage/RySetting.cs b/Source/MyDb/DbManage/RySetting.cs new file mode 100644 index 0000000..8192fe7 --- /dev/null +++ b/Source/MyDb/DbManage/RySetting.cs @@ -0,0 +1,493 @@ +using ryCommon.Pram; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 设置管理类,快速添加设置。 + /// + public class RySetting + { + /// + /// 设置管理类,快速添加设置。 + /// + public RySetting() + { + } + /// + /// 设置管理类,快速添加设置。 + /// + /// + public RySetting(string _FilePath) + { + FilePath = _FilePath; + } + /// + /// 存储类型 + /// + public SettingType FileType = SettingType.XML; + /// + /// 配置存储路径 + /// + public string FilePath = ""; + /// + /// 设置XML内容 + /// + public string SettingXML = ""; + private string Section = "Setting"; + private List list = new List(); + /// + /// 添加控件 + /// + /// + /// + /// + public int Add(string _id,Control ctl) + { + return Add(_id, ctl, CValueType.Default,""); + } + /// + /// 设置值 + /// + /// + /// + /// + public int Add(string _id,string value) + { + return Add(_id, null, CValueType.Default,value); + } + /// + /// 添加控件 + /// + /// + /// + /// + /// + /// + public int Add(string _id, Control ctl,CValueType valuetype,object _defValue) + { + if(_id.ToLower()== Section.ToLower()) { return -1; } + list.Add(new Control_Info() { id = _id, control = ctl, value_type= valuetype, defValue= _defValue }); + return 1; + } + /// + /// 添加控件 + /// + /// + /// + /// + /// + public int Add(string _id, NumericUpDown ctl, decimal _defValue) + { + return Add(_id, ctl, CValueType.Default, _defValue); + } + /// + /// 添加控件 + /// + /// + /// + /// + /// + public int Add(string _id, DateTimePicker ctl, DateTime _defValue) + { + return Add(_id, ctl, CValueType.Default, _defValue); + } + /// + /// 添加控件 + /// + /// + /// + /// + /// + public int Add(string _id, CheckBox ctl, bool _defValue) + { + return Add(_id, ctl, CValueType.Default, _defValue); + } + /// + /// 添加控件 + /// + /// + /// + /// + /// + public int Add(string _id, ComboBox ctl, int _defValue) + { + return Add(_id, ctl, CValueType.ItemIndex, _defValue); + } + /// + /// 添加控件 + /// + /// + /// + /// + /// + public int Add(string _id, ComboBox ctl, string _defValue) + { + return Add(_id, ctl, CValueType.ItemText, _defValue); + } + /// + /// 添加控件 + /// + /// + /// + /// + /// + public int Add(string _id, TextBox ctl, string _defValue) + { + return Add(_id, ctl, CValueType.Default, _defValue); + } + /// + /// 读取配置 + /// + public void Read() + { + string filepath = FilePath; + if (FileType==SettingType.XML) + { + ryCommon.Storage myXML = new Storage(); + if (filepath == "") + { + myXML.LoadFromXMLText(SettingXML); + } + else + { + myXML.LoadFromFile(filepath); + } + myXML.SelectNode2("id", Section); + for(int i=0;i value && value >= 0) + { + cbb.SelectedIndex = value; + } + else + { + if (cbb.Items.Count > def_value && def_value >= 0) + cbb.SelectedIndex = def_value; + else + cbb.SelectedIndex = 0; + } + } + else if (item.value_type == CValueType.ItemText) + { + try + { + cbb.Text = myXML.GetAttrValue(item.id, item.defValue.ToString()); + } + catch { cbb.Text = item.defValue.ToString(); } + } + else if (item.value_type == CValueType.ObjectItem) + { + #region ObjectItem + string _id = myXML.GetAttrValue(item.id, item.defValue.ToString()); + bool haveRecord = false; + for (int m = 0; m < cbb.Items.Count; m++) + { + switch (cbb.Items[m]) + { + case ObjectItem c_item: + if (c_item.Id == _id) + { + cbb.SelectedIndex = m; + haveRecord = true; + break; + } + break; + } + } + if (!haveRecord) + { + cbb.SelectedIndex = 0; + } + #endregion + } + break; + #endregion + default: + var type = item.control.GetType().Name; + if (type == "HotkeyTextBox") + { + dynamic cc = item.control; + cc.HotKey = myXML.GetAttrValue(item.id, item.defValue.ToString()); + } + else + { + item.control.Text = myXML.GetAttrValue(item.id, item.defValue.ToString()); + } + break; + } + } + } + else if (FileType == SettingType.Ini) + { + ryCommon.Ini myIni = new ryCommon.Ini(filepath); + for (int i = 0; i < list.Count; i++) + { + Control_Info item = list[i]; + switch (item.control) + { + case CheckBox chk: + chk.Checked = myIni.ReadIni(Section, item.id, item.defValue.ToBool()); + break; + case TextBox txt: + txt.Text = myIni.ReadIni(Section, item.id, item.defValue.ToString()); + break; + case NumericUpDown num: + num.Value = myIni.ReadIni(Section, item.id, item.defValue.ToString()).ToDecimal(num.Minimum,num.Maximum, (decimal)item.defValue); + break; + case DateTimePicker dt_picker: + try + { + dt_picker.Value = RyDate.UnixTimeToDateTime(myIni.ReadIni(Section, item.id, RyDate.DateTimeToUnixTime((DateTime)item.defValue).ToString())); + } + catch + { + dt_picker.Value = (DateTime)item.defValue; + } + break; + case ComboBox cbb: + #region ComboBox + if (item.value_type == CValueType.ItemIndex || item.value_type == CValueType.Default) + { + int def_value = item.defValue.ToInt(0); + int value = myIni.ReadIni(Section, item.id, item.defValue.ToInt(0)); + if (cbb.Items.Count > value && value >= 0) + { + cbb.SelectedIndex = value; + } + else + { + if (cbb.Items.Count > def_value && def_value >= 0) + cbb.SelectedIndex = def_value; + else + cbb.SelectedIndex = 0; + } + } + else if (item.value_type == CValueType.ItemText) + { + try + { + cbb.Text = myIni.ReadIni(Section, item.id, item.defValue.ToString()); + } + catch { cbb.Text = item.defValue.ToString(); } + } + else if (item.value_type == CValueType.ObjectItem) + { + #region ObjectItem + string _id = myIni.ReadIni(Section, item.id, item.defValue.ToString()); + bool haveRecord = false; + for (int m = 0; m < cbb.Items.Count; m++) + { + switch (cbb.Items[m]) + { + case ObjectItem c_item: + if (c_item.Id == _id) + { + cbb.SelectedIndex = m; + haveRecord = true; + break; + } + break; + } + } + if (!haveRecord) + { + cbb.SelectedIndex = 0; + } + #endregion + } + break; + #endregion + default: + var type = item.control.GetType().Name; + if (type == "HotkeyTextBox") + { + dynamic cc = item.control; + cc.HotKey = myIni.ReadIni(Section, item.id, item.defValue.ToString()); + } + else + { + item.control.Text = myIni.ReadIni(Section, item.id, item.defValue.ToString()); + } + break; + } + } + } + } + /// + /// 保存配置 + /// + public void Save() + { + string filepath = FilePath; + if (FileType == SettingType.XML) + { + ryCommon.Storage myXML = new Storage(); + if (filepath == "") + { + myXML.LoadFromXMLText(SettingXML); + } + else + { + myXML.LoadFromFile(filepath); + } + myXML.SelectNode2("id", Section); + for (int i = 0; i < list.Count; i++) + { + Control_Info item = list[i]; + switch (item.control) + { + case CheckBox chk: + myXML.SetAttrValue(item.id, chk.Checked); + break; + case TextBox txt: + myXML.SetAttrValue(item.id, txt.Text); + break; + case NumericUpDown num: + myXML.SetAttrValue(item.id, num.Value); + break; + case DateTimePicker dt_picker: + myXML.SetAttrValue(item.id, RyDate.DateTimeToUnixTime(dt_picker.Value).ToString()); + break; + case ComboBox cbb: + #region ComboBox + if (item.value_type == CValueType.ItemIndex || item.value_type == CValueType.Default) + { + myXML.SetAttrValue(item.id, cbb.SelectedIndex); + } + else if (item.value_type == CValueType.ItemText) + { + myXML.SetAttrValue(item.id, cbb.Text); + } + else if (item.value_type == CValueType.ObjectItem) + { + switch (cbb.SelectedItem) + { + case ObjectItem c_item: + myXML.SetAttrValue(item.id, c_item.Id); + break; + } + } + break; + #endregion + case null: + myXML.SetAttrValue(item.id, item.defValue.ToString()); + break; + default: + var type = item.control.GetType().Name; + if (type == "HotkeyTextBox") + { + dynamic cc = item.control; + myXML.SetAttrValue(item.id, cc.HotKey); + } + else + { + myXML.SetAttrValue(item.id, item.control.Text); + } + break; + } + } + if (filepath == "") + { + SettingXML=myXML.XMLText; + } + else + { + myXML.SaveToFile(filepath); + } + } + else if (FileType == SettingType.Ini) + { + ryCommon.Ini myIni = new ryCommon.Ini(filepath); + for (int i = 0; i < list.Count; i++) + { + Control_Info item = list[i]; + switch (item.control) + { + case CheckBox chk: + myIni.WriteIni(Section, item.id, chk.Checked); + break; + case TextBox txt: + myIni.WriteIni(Section, item.id, txt.Text); + break; + case NumericUpDown num: + myIni.WriteIni(Section, item.id, num.Value); + break; + case DateTimePicker dt_picker: + myIni.WriteIni(Section, item.id, RyDate.DateTimeToUnixTime(dt_picker.Value).ToString()); + break; + case ComboBox cbb: + #region ComboBox + if (item.value_type == CValueType.ItemIndex || item.value_type == CValueType.Default) + { + myIni.WriteIni(Section, item.id, cbb.SelectedIndex); + } + else if (item.value_type == CValueType.ItemText) + { + myIni.WriteIni(Section, item.id, cbb.Text); + } + else if (item.value_type == CValueType.ObjectItem) + { + switch (cbb.SelectedItem) + { + case ObjectItem c_item: + myIni.WriteIni(Section, item.id, c_item.Id); + break; + } + } + break; + #endregion + case null: + myIni.WriteIni(Section, item.id, item.defValue.ToString()); + break; + default: + var type = item.control.GetType().Name; + if (type == "HotkeyTextBox") + { + dynamic cc = item.control; + myIni.WriteIni(Section, item.id, cc.HotKey); + + } + else + { + myIni.WriteIni(Section, item.id, item.control.Text); + } + break; + } + } + } + } + } +} diff --git a/Source/MyDb/DbManage/Storage.cs b/Source/MyDb/DbManage/Storage.cs new file mode 100644 index 0000000..7e4d679 --- /dev/null +++ b/Source/MyDb/DbManage/Storage.cs @@ -0,0 +1,974 @@ +//--------------------------日期:2017-04-07 +//--------------------------版本:2.0.0 .0 +//--------------------------作者:itrycn +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; +//XML存储类 +namespace ryCommon +{ + /// + /// XML操作类 + /// + public class Storage + { + private XmlDocument xmlDoc = new XmlDocument(); + private XmlNode xmlNode; + private XmlElement element; + //private System.Xml.XmlNodeList NodeList2; + /// + /// XML操作类 + /// + public Storage() + { + string strXMLText = ""; + xmlDoc.LoadXml(strXMLText); + } + /// + /// 从XML文本中加载数据 + /// + /// + public Storage(string XMLText) //从XML文本中加载数据 + { + try + { + xmlDoc.LoadXml(XMLText); + } + catch + { + xmlDoc.LoadXml(""); + } + } + #region 从指定的XML文本中加载 + /// + /// 从指定的XML文本中加载 + /// + /// XML文本 + /// 如为1,表示加载成功,为0为失败 + public int LoadFromXMLText(string XMLText) + { + try + { + xmlDoc.LoadXml(XMLText); + return 1; + } + catch + { + xmlDoc.LoadXml(""); + return 0; + } + } + #endregion + #region 加载空的XML文本 + /// + /// 载入空的XML文档 + /// + /// 如为1,表示加载成功,为0为失败 + public int LoadEmptyXMLText() + { + try + { + xmlDoc.LoadXml(""); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 从指定的文件中加载 + /// + /// 从指定的文件中加载 + /// + /// XML文件路径 + /// 如为1,表示加载成功,为0为失败 + public int LoadFromFile(string FilePath) + { + try + { + xmlDoc.Load(FilePath); + return 1; + } + catch + { + xmlDoc.LoadXml(""); + return 0; + } + } + #endregion + #region 保存到指定文件中 + /// + /// 保存到指定文件中 + /// + /// 文件路径 + /// 如为1,表示保存成功,为0为失败 + public int SaveToFile(string sFilePath) + { + try + { + if (sFilePath != "" && !System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(sFilePath))) + { + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(sFilePath)); + } + xmlDoc.Save(sFilePath); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 判断节点是否存在 + /// + /// 判断节点是否存在 + /// + /// 属性名 + /// 属性值 + /// 返回1,表示存在,其它表示不存在 + public int HaveNode(string AttrName, string sValue) + { + try + { + //根据指定路径获取节点 + XmlNode xmlNode2 = null; + xmlNode2 = xmlDoc.SelectSingleNode("root/list[@" + AttrName + "='" + sValue + "']"); + if (xmlNode2 == null) + { + return 0; + } + else + { + return 1; + } + } + catch + { + return 0; + } + } + #endregion + #region 定位节点 + /// + /// 定位节点 + /// + /// 属性名 + /// 属性值 + /// 返回第一个符合要求的结果 + public int SelectNode(string AttrName, string sValue) + { + try + { + //根据指定路径获取节点 + element = null; + xmlNode = xmlDoc.SelectSingleNode("root/list[@" + AttrName + "='" + sValue + "']"); + element = (XmlElement)xmlNode; + if (element == null) + { + return 0; + } + else + { + return 1; + } + } + catch + { + return 0; + } + } + #endregion + #region 定位节点2 + /// + /// 定位节点,如果找不到节点,就新建一个节点 + /// + /// 属性名 + /// 属性值 + /// 返回第一个符合要求的结果 + public int SelectNode2(string AttrName, string sValue) + { + try + { + //根据指定路径获取节点 + element = null; + xmlNode = xmlDoc.SelectSingleNode("root/list[@" + AttrName + "='" + sValue + "']"); + element = (XmlElement)xmlNode; + if (element == null) + { + return AddNode2(AttrName, sValue); + } + else + { + return 1; + } + } + catch + { + return 0; + } + } + #endregion + #region 定位节点3 + /// + /// 根据用户的节点定位节点,输入节点时,一定要注意节点是属于类内部的,否则可能出错。 + /// + /// 返回第一个符合要求的结果 + public int SelectNode3(XmlNode m_xmlNode) + { + try + { + //根据指定路径获取节点 + element = null; + xmlNode = m_xmlNode; + element = (XmlElement)xmlNode; + if (element == null) + { + return 0; + } + else + { + return 1; + } + } + catch + { + return 0; + } + } + #endregion + #region 定位设置节点 + /// + /// 定位设置节点 + /// + /// 返回第一个符合要求的结果 + public int SelectNodeBySet() + { + return SelectNode2("id", "Setting"); + } + /// + /// 在节点后插入数据 + /// + /// + /// + public XmlNode InsertAfter(int index) + { + XmlNode root = xmlDoc.SelectSingleNode("root"); + XmlNode refChild = xmlDoc.SelectSingleNode("root//list[" + index + "]"); + return root.InsertAfter(xmlNode, refChild); + } + /// + /// 在节点前插入数据 + /// + /// + /// + public XmlNode InsertBefore(int index) + { + XmlNode root = xmlDoc.SelectSingleNode("root"); + XmlNode refChild = xmlDoc.SelectSingleNode("root//list["+index+"]"); + return root.InsertBefore(xmlNode, refChild); + } + #endregion + #region 获取节点数量 + /// + /// 获取节点数量 + /// + /// 属性名 + /// 属性值 + /// 返回符合要求的结果数量 + public int GetSelectNodeCount(string AttrName, string sValue) + { + try + { + //根据指定路径获取节点 + return xmlDoc.SelectNodes("root/list[@" + AttrName + "='" + sValue + "']").Count; + } + catch + { + return 0; + } + } + #endregion + #region 获取节点数量 + /// + /// 获取节点数量 + /// + /// 返回符合要求的结果数量 + public int GetNodeCount() + { + try + { + //根据指定路径获取节点 + return xmlDoc.SelectNodes("root/list").Count; + } + catch + { + return 0; + } + } + #endregion + private int ConvertInt(string str, int defValue) + { + try + { + return Convert.ToInt32(str); + } + catch + { + return defValue; + } + } + #region 获取节点数量 + /// + /// 获取节点数量 + /// + /// 属性名 + /// 属性值 + /// + /// + /// + /// 返回符合要求的结果数量 + public int GetSelectNodeCount(string AttrName, string sValue, string AttrName2, string Relation, int sValue2) + { + try + { + //根据指定路径获取节点 + XmlNodeList nodelist = xmlDoc.SelectNodes("root/list[@" + AttrName + "='" + sValue + "']"); + int icount = 0; + for (int i = 0; i < nodelist.Count; i++) + { + XmlAttribute attr = nodelist.Item(i).Attributes[AttrName2]; + if (attr != null) + { + switch (Relation) + { + case "<": + if (ConvertInt(attr.Value, 0) < sValue2) + { + icount++; + } + break; + case ">": + if (ConvertInt(attr.Value, 0) > sValue2) + { + icount++; + } + break; + case "=": + if (ConvertInt(attr.Value, 0) == sValue2) + { + icount++; + } + break; + case "<>": + if (ConvertInt(attr.Value, 0) != sValue2) + { + icount++; + } + break; + case ">=": + if (ConvertInt(attr.Value, 0) >= sValue2) + { + icount++; + } + break; + case "<=": + if (ConvertInt(attr.Value, 0) <= sValue2) + { + icount++; + } + break; + } + } + } + return icount; + } + catch + { + return 0; + } + } + #endregion + #region 设置节点值 + /// + /// 设置节点值 + /// + /// 属性名 + /// 属性值 + /// 如为1,表示加载成功,为0为失败 + public int SetAttrValue(string strName, string strValue) + { + try + { //设置节点值 + element.SetAttribute(strName, strValue); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 设置节点值(布尔类型) + /// + /// 设置节点值 + /// + /// 属性名 + /// 属性值 + /// 如为1,表示加载成功,为0为失败 + public int SetAttrValue(string strName, bool strValue) + { + try + { //设置节点值 + string m_value = "0"; + if (strValue == true) { m_value = "1"; } + element.SetAttribute(strName, m_value); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 设置节点值(int类型) + /// + /// 设置节点值 + /// + /// 属性名 + /// 属性值 + /// 如为1,表示加载成功,为0为失败 + public int SetAttrValue(string strName, int strValue) + { + try + { //设置节点值 + element.SetAttribute(strName, strValue.ToString()); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 设置节点值(decimal类型) + /// + /// 设置节点值 + /// + /// 属性名 + /// 属性值 + /// 如为1,表示加载成功,为0为失败 + public int SetAttrValue(string strName, decimal strValue) + { + try + { //设置节点值 + element.SetAttribute(strName, strValue.ToString()); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 设置节点值(double类型) + /// + /// 设置节点值 + /// + /// 属性名 + /// 属性值 + /// 如为1,表示加载成功,为0为失败 + public int SetAttrValue(string strName, double strValue) + { + try + { //设置节点值 + element.SetAttribute(strName, strValue.ToString()); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 设置节点值(日期类型) + /// + /// 设置节点值 + /// + /// 属性名 + /// 属性值 + /// 如为1,表示加载成功,为0为失败 + public int SetAttrValue(string strName, DateTime strValue) + { + try + { //设置节点值 + element.SetAttribute(strName, strValue.ToDateTimeStr()); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 读取指定节点的值 + /// + /// 读取指定节点的值 + /// + /// + /// + public string GetAttrValue(string strNode) + { + try + { + if (element == null) { return ""; } + //根据路径获取节点 + return element.GetAttribute(strNode); + } + catch + { + return ""; + } + } + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public string GetAttrValueByBase64(string strNode,string defValue) + { + try + { + //根据路径获取节点 + string str= element.GetAttribute(strNode); + ryCommon.Strings cStr = new Strings(); + string base64 = cStr.Base64ToStr(str); + if (base64 == "") { return defValue; } + return base64; + } + catch + { + return defValue; + } + } + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public bool GetAttrValue(string strNode, bool defValue) + { + return GetAttrValueByBool(strNode, defValue); + } + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public int GetAttrValue(string strNode, int defValue) + { + return GetAttrValueByInt(strNode, defValue); + } + /// + /// 获取属性值 + /// + /// + /// + /// + public Int64 GetAttrValue(string strNode, Int64 defValue) + { + try + { + //根据路径获取节点 + string strTemp = element.GetAttribute(strNode); + return Convert.ToInt64(strTemp); + } + catch + { + return defValue; + } + } + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public decimal GetAttrValue(string strNode, decimal defValue) + { + return GetAttrValueByDecimal(strNode, defValue); + } + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public double GetAttrValue(string strNode, double defValue) + { + try + { + //根据路径获取节点 + string strTemp = element.GetAttribute(strNode); + return Convert.ToDouble(strTemp); + } + catch + { + return defValue; + } + } + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public DateTime GetAttrValue(string strNode, DateTime defValue) + { + return GetAttrValueByDate(strNode, defValue); + } + #endregion + #region 读取指定节点的值 + /// + /// 读取所有的节点名称 + /// + /// + public string[] GetAttrNames() + { + try + { + if (element == null) { return null; } + string[] items = new string[element.Attributes.Count]; + for (int i = 0; i < items.Length; i++) + { + items[i] = element.Attributes.Item(i).Name; + } + //根据路径获取节点 + return items; + } + catch + { + return null; + } + } + #endregion + #region 读取指定节点的值2 + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public string GetAttrValue(string strNode, string defValue) + { + try + { + //根据路径获取节点 + if (element == null) { return defValue; } + string strTemp = element.GetAttribute(strNode); + if (strTemp == "") + { + return defValue; + } + else + { + return strTemp; + } + } + catch + { + return defValue; + } + } + #endregion + #region 读取指定节点的值3 + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public int GetAttrValueByInt(string strNode, int defValue) + { + try + { + //根据路径获取节点 + if (element == null) { return defValue; } + string strTemp = element.GetAttribute(strNode); + return Convert.ToInt32(strTemp); + } + catch + { + return defValue; + } + } + #endregion + #region 读取指定节点的值4 + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public decimal GetAttrValueByDecimal(string strNode, decimal defValue) + { + try + { + if (element == null) { return defValue; } + //根据路径获取节点 + string strTemp = element.GetAttribute(strNode); + return Convert.ToDecimal(strTemp); + } + catch + { + return defValue; + } + } + #endregion + #region 读取指定节点的值5(布尔值) + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public bool GetAttrValueByBool(string strNode, bool defValue) + { + try + { + if (element == null) { return defValue; } + //根据路径获取节点 + if (!element.HasAttribute(strNode)) { return defValue; } + string strTemp = element.GetAttribute(strNode); + if (strTemp == "1") + { + return true; + } + else + { + return false; + } + } + catch + { + return defValue; + } + } + #endregion + #region 读取指定节点的值6(日期值) + /// + /// 读取指定节点的值 + /// + /// + /// + /// + public DateTime GetAttrValueByDate(string strNode, DateTime defValue) + { + try + { + if (element == null) { return defValue; } + //根据路径获取节点 + string strTemp = element.GetAttribute(strNode); + return Convert.ToDateTime(strTemp); + } + catch + { + return defValue; + } + } + #endregion + /// + /// 获取XML文件的根元素 + /// + public XmlNode GetXmlRoot() + { + return xmlDoc.DocumentElement; + } + #region 获取所有列表 + /// + /// 获取所有列表 + /// + /// 如为1,表示获取成功,为0为失败 + public XmlNodeList GetList() + { + try + { + return xmlDoc.DocumentElement.SelectNodes("child::list"); + } + catch + { + return null; + } + } + #endregion + #region 获取所有列表 + /// + /// 获取所有列表 + /// + /// 如为1,表示获取成功,为0为失败 + public XmlNodeList GetList(string xpath) + { + try + { + return xmlDoc.DocumentElement.SelectNodes(xpath); + } + catch + { + return null; + } + } + #endregion + #region 新增节点 + /// + /// 新增节点 + /// + /// + /// + /// + public int AddNode(string strName, string strValue) + { + try + { + XmlNode xmlNode2 = xmlDoc.SelectSingleNode("root"); + XmlNode childXmlNode = xmlDoc.CreateElement("list"); + xmlNode2.AppendChild(childXmlNode); + XmlElement element2 = (XmlElement)childXmlNode; + element2.SetAttribute(strName, strValue); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 新增节点并定位到新节点 + /// + /// 新增节点并定位到新节点 + /// + /// + /// + /// + public int AddNode2(string strName, string strValue) + { + try + { + XmlNode xmlNode2 = xmlDoc.SelectSingleNode("root"); + xmlNode = xmlDoc.CreateElement("list"); + xmlNode2.AppendChild(xmlNode); + element = (XmlElement)xmlNode; + element.SetAttribute(strName, strValue); + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 新增设置节点并定位 + /// + /// 新增设置节点并定位 + /// + /// + public int AddNodeBySet() + { + return AddNode2("id", "Setting"); + } + #endregion + #region 新增节点并定位到新节点 + /// + /// 在指定节点前新增节点并定位到新节点 + /// + /// + /// + /// + /// + public int AddNodeBefore(string strName, string strValue, XmlNode xn) + { + try + { + XmlNode xmlNode2 = xmlDoc.SelectSingleNode("root"); + xmlNode = xmlDoc.CreateElement("list"); + xmlNode2.InsertBefore(xmlNode, xn); + element = (XmlElement)xmlNode; + element.SetAttribute(strName, strValue); + return 1; + } + catch + { + return 0; + } + } + #endregion + /// + /// 获取当前节点 + /// + /// + public XmlNode GetNowXMLNode() + { + return xmlNode; + } + #region 删除节点 + /// + /// 删除节点 + /// + /// + public int DeleteNode() + { + try + { + //element.RemoveAll(); + GetXmlRoot().RemoveChild(xmlNode); + xmlNode = null; + element = null; + return 1; + } + catch + { + return 0; + } + } + #endregion + #region 获取XML文本 + /// + /// 获取XML文本 + /// + /// + public string GetXMLText() + { + return xmlDoc.OuterXml; + } + /// + /// 获取XML文本 + /// + /// + public string XMLText + { + get { return xmlDoc.OuterXml; } + } + #endregion + #region 获取XML文本 + /// + /// 获取文本 + /// + /// + public string GetText() + { + return xmlDoc.ToString(); ; + } + /// + /// 获取文本 + /// + /// + public string Text + { + get { return xmlDoc.ToString(); } + } + #endregion + } +} diff --git a/Source/MyDb/DbManage/Strings.cs b/Source/MyDb/DbManage/Strings.cs new file mode 100644 index 0000000..0f6b172 --- /dev/null +++ b/Source/MyDb/DbManage/Strings.cs @@ -0,0 +1,367 @@ +//--------------------------日期:2013-8-28 +//--------------------------版本:2.0.1.0 +//--------------------------作者:itrycn +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +//字符串操作类 +namespace ryCommon +{ + /// + /// 字符串操作类 + /// + public class Strings + { + /// + /// 字符串转Base64 + /// + /// + /// + public string StrToBase64(string input) + { + System.Text.Encoding encode = System.Text.Encoding.Default; + byte[] bytedata = encode.GetBytes(input); + return Convert.ToBase64String(bytedata, 0, bytedata.Length); + } + /// + /// Base64转字符串 + /// + /// + /// + public string Base64ToStr(string input) + { + try + { + byte[] bpath = Convert.FromBase64String(input); + return System.Text.Encoding.Default.GetString(bpath); + } + catch { return ""; } + } + /// + /// 转换指定字符串为布尔类型 + /// + public bool StrToBool(string Str,bool defValue) + { + try + { + if (Str == "1" || Str.ToLower()=="true") + { + return true; + } + else + { + return false; + } + } + catch { return defValue; } + } + /// + /// 转换指定字符串为Double类型 + /// + public double StrToDouble(string Str, double defValue) + { + try + { + return Convert.ToDouble(Str); + } + catch { return defValue; } + } + /// + /// 已重载.计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + /// + /// 第一个日期和时间 + /// 第二个日期和时间 + /// + public string DateDiff(DateTime DateTime1, DateTime DateTime2) + { + string dateDiff = ""; + try + { + TimeSpan ts1 = new TimeSpan(DateTime1.Ticks); + TimeSpan ts2 = new TimeSpan(DateTime2.Ticks); + TimeSpan ts = ts1.Subtract(ts2).Duration(); + if(ts.Days!=0) + { + dateDiff = ts.Days.ToString() + "天"; + } + if (ts.Hours != 0) + { + dateDiff += ts.Hours.ToString() + "小时"; + } + if (ts.Minutes != 0) + { + dateDiff += ts.Minutes.ToString() + "分钟"; + } + if (ts.Seconds != 0) + { + dateDiff += ts.Seconds.ToString() + "秒"; + } + } + catch + { + + } + if (dateDiff == "") { dateDiff = "0秒"; } + return dateDiff; + } + /// + /// 已重载.计算一个时间与当前本地日期和时间的时间间隔,返回的是时间间隔的日期差的绝对值. + /// + /// 一个日期和时间 + /// + public string DateDiff(DateTime DateTime1) + { + return this.DateDiff(DateTime1, DateTime.Now); + } + /// + /// 转换指定字符串为Int类型 + /// + public int StrToInt(string Str, int defValue) + { + try + { + return Convert.ToInt32(Str); + } + catch { return defValue; } + } + /// + /// 转换指定字符串为Int类型 + /// + public int StrToInt(string Str, int minValue, int maxValue, int defValue) + { + try + { + int tmpI=Convert.ToInt32(Str); + if (tmpI < minValue || tmpI > maxValue) + { + return defValue; + } + else + { + return tmpI; + } + } + catch { return defValue; } + } + /// + /// 转换指定布尔类型为Int类型,true为1,false为0 + /// + public int BoolToInt(bool sValue) + { + try + { + if (sValue ==true) + { + return 1; + } + else + { + return 0; + } + } + catch { return 0; } + } + /// + /// 判断指定字符串是否是布尔类型 + /// + public bool IsBool(string sValue) + { + try + { + Convert.ToBoolean(sValue); + return true; + } + catch { return false; } + } + /// + /// 判断指定字符串是否是Double类型 + /// + public bool IsDouble(string sValue) + { + try + { + Convert.ToDouble(sValue); + return true; + } + catch { return false; } + } + /// + /// 判断指定字符串是否是Int类型 + /// + public bool IsInt(string sValue) + { + try + { + Convert.ToInt64(sValue); + if (sValue.IndexOf(".")>=0) + { + return false; + } + else + { + return true; + } + } + catch { return false; } + } + /// + /// 根据年月日转换成日期 + /// + /// + /// + /// + /// + public DateTime ToDate(int year, int month, int day) + { + try + { + return Convert.ToDateTime(year.ToString() + "-" + month.ToString() + "-" + day.ToString()); + } + catch { return Convert.ToDateTime("2000-1-1"); } + } + /// + /// 追加字符 + /// + public string AppendStr(string str, string addstr) + { + if (str == "") + { + return addstr; + } + else + { + if (addstr == "") + { + return str; + } + else + { + return str + "\r\n" + addstr; + } + } + } + /// + /// 获取2个字符串中间的内容,point1为空表示从首位开始算,point2为空表示算到结尾。 + /// + public string GetStr(string str, string point1, string point2, int iPos1,out int endPos, string defValue) + { + int iIndex = 0; + endPos = 0; + if(iPos1>= str.Length) + { + return defValue; + } + if (point1 != "") + { iIndex = str.IndexOf(point1, iPos1); } + if (iIndex == -1) { return defValue; } + int iIndex2 = 0; + if (point2 == "") { iIndex2 = str.Length; } + else { iIndex2 = str.IndexOf(point2, iIndex + point1.Length); } + string tmpStr = str; + if (iIndex < iIndex2 && iIndex >= 0) + { + tmpStr = str.Substring(iIndex + point1.Length, iIndex2 - iIndex - point1.Length); + endPos = iIndex2 + point2.Length; + } + else + { + return defValue; + } + return tmpStr; + } + /// + /// 判断字符串是否只包含数字或英文 + /// + /// + /// + public static bool IsEngOrNum(string str) + { + return !Regex.IsMatch(str, "[^0-9a-zA-Z]"); + } + /// + /// 判断字符串是否匹配,支持?*通配符 + /// + /// 待匹配的字符串 + /// 匹配的通配符 + /// + public static bool IsMatchStr(string str, string likestr) + { + Regex replace = new Regex("[.$^{\\[(|)*+?\\\\]"); + string a = replace.Replace(likestr, + delegate (Match m) + { + switch (m.Value) + { + case "?": + return ".?"; + case "*": + return ".*"; + default: + return "\\" + m.Value; + } + }); + Regex strP = new Regex(a); + return strP.IsMatch(str); + //return replace.IsMatch(wildcardStr1); + } + /// + /// 通配符替换 + /// + /// + /// + /// + /// + public static string ReplaceByMatch(string str, string likestr, string replacement) + { + Regex replace = new Regex("[.$^{\\[(|)*+?\\\\]"); + string a = replace.Replace(likestr, + delegate (Match m) + { + switch (m.Value) + { + case "?": + return ".?"; + case "*": + return ".*"; + default: + return "\\" + m.Value; + } + }); + Regex strP = new Regex(a); + return strP.Replace(str, replacement); + //return replace.IsMatch(wildcardStr1); + } + /// + /// 获取匹配的内容 + /// + /// + /// + /// + /// + public static string GetMatchStr(string str, string likestr,bool isRegex) + { + string _likestr = likestr; + if (!isRegex) + { + Regex replace = new Regex("[.$^{\\[(|)*+?\\\\]"); + _likestr = replace.Replace(likestr, + delegate (Match m) + { + switch (m.Value) + { + case "?": + return ".?"; + case "*": + return ".*"; + default: + return "\\" + m.Value; + } + }); + } + Match match = Regex.Match(str, _likestr); + return match.Value; + //return replace.IsMatch(wildcardStr1); + } + } +} diff --git a/Source/MyDb/DbManage/VarExtension.cs b/Source/MyDb/DbManage/VarExtension.cs new file mode 100644 index 0000000..0f8aec8 --- /dev/null +++ b/Source/MyDb/DbManage/VarExtension.cs @@ -0,0 +1,580 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ryCommon +{ + /// + /// 对变量的拓展 + /// + public static class VarExtension + { + /// + /// 替换文本(忽略大小写) + /// + /// + /// 需要替换的内容 + /// 替换后的内容 + /// + static public string ReplaceEx(this string original, string pattern, string replacement) + { + int count, position0, position1; + count = position0 = position1 = 0; + string upperString = original.ToUpper(); + string upperPattern = pattern.ToUpper(); + int inc = (original.Length / pattern.Length) * (replacement.Length - pattern.Length); + char[] chars = new char[original.Length + Math.Max(0, inc)]; + while ((position1 = upperString.IndexOf(upperPattern, position0)) != -1) + { + for (int i = position0; i < position1; ++i) chars[count++] = original[i]; + for (int i = 0; i < replacement.Length; ++i) chars[count++] = replacement[i]; + position0 = position1 + pattern.Length; + } + if (position0 == 0) return original; + for (int i = position0; i < original.Length; ++i) chars[count++] = original[i]; + return new string(chars, 0, count); + } + /// + /// 替换文本(忽略大小写),可支持通配符 + /// + /// + /// + /// + /// 是否是通配符表达式,不是,则普通替换,忽略大小写,是,则启用通配符替换 + /// + static public string ReplaceEx(this string original, string pattern, string replacement,bool isLike) + { + if(isLike) + { + return Strings.ReplaceByMatch(original, pattern, replacement); + } + else + { + return ReplaceEx(original, pattern, replacement); + } + } + /// + /// 获取符合要求的第一个结果 + /// + /// + /// + /// 是否是正则 + /// + static public string GetMatchStr(this string input, string value, bool isRegex) + { + return Strings.GetMatchStr(input,value,isRegex); + } + /// + /// 查找字符串,忽略大小写 + /// + /// + /// + /// + /// + static public int IndexOfEx(this string input, string value, int startindex) + { + return input.IndexOf(value,startindex,StringComparison.OrdinalIgnoreCase); + } + /// + /// 查找字符串,忽略大小写 + /// + /// + /// + /// + static public int IndexOfEx(this string input, string value) + { + return input.IndexOf(value, StringComparison.OrdinalIgnoreCase); + } + /// + /// 判断字符串是否是数字或英文 + /// + /// + /// + static public bool IsEngOrNum(this string input) + { + return Strings.IsEngOrNum(input); + } + /// + /// 是否在指定范围内 + /// + /// + /// + /// + /// + static public bool IsInRange(this decimal input, decimal min, decimal max) + { + return (input >= min && input <= max); + } + /// + /// 是否在指定范围内 + /// + /// + /// + /// + /// + static public bool IsInRange(this int input, int min, int max) + { + return (input >= min && input <= max); + } + /// + /// 转换指定字符串为Int类型 + /// + /// + /// 最小值 + /// 最大值 + /// 如果字符串不在范围内,则使用本默认值 + /// + static public int ToInt(this object input, int minValue, int maxValue, int defValue) + { + try + { + int tmpI = Convert.ToInt32(input); + if (tmpI < minValue || tmpI > maxValue) + { + return defValue; + } + else + { + return tmpI; + } + } + catch { return defValue; } + } + /// + /// 转换指定布尔类型到Int类型,true为1,false为0 + /// + /// + /// + static public int ToInt(this bool input) + { + return input?1:0; + } + /// + /// 将指定类型转换成整型 + /// + /// + /// + /// + static public int ToInt(this object input, int defValue) + { + try + { + return Convert.ToInt32(input); + } + catch + { return defValue; } + } + /// + /// 将指定类型转换成整型 + /// + /// + /// + static public int ToInt(this object input) + { + try + { + if(input is string) + { + if(input.IsDouble()) + { + return Convert.ToInt32(Math.Round(Convert.ToDouble(input))); + } + } + return Convert.ToInt32(input); + } + catch(Exception) + { return 0; } + } + /// + /// 将指定类型转换成长整型 + /// + /// + /// + /// + static public Int64 ToInt64(this object input, Int64 defValue) + { + try + { + if (input == null) { return defValue; } + return Convert.ToInt64(input); + } + catch + { return defValue; } + } + /// + /// 将指定类型转换成长整型 + /// + /// + /// + static public Int64 ToInt64(this object input) + { + return ToInt64(input,0); + } + /// + /// 转换指定类型为Double类型 + /// + /// + /// + /// + static public double ToDouble(this object input, double defValue) + { + try + { + return Convert.ToDouble(input); + } + catch { return defValue; } + } + /// + /// 转换指定类型为Double类型 + /// + /// + /// + static public double ToDouble(this object input) + { + try + { + return Convert.ToDouble(input); + } + catch { return 0d; } + } + /// + /// 转换DateTime类型到日期时间字符串 + /// + /// + /// + static public string ToDateTimeStr(this DateTime input) + { + return input.ToString("yyyy-MM-dd HH:mm:ss"); + } + /// + /// 转换DateTime类型到日期字符串 + /// + /// + /// + static public string ToDateStr(this DateTime input) + { + return input.ToString("yyyy-MM-dd"); + } + /// + /// 转换DateTime类型到日期星期字符串 + /// + /// + /// + static public string ToDateWeekStr(this DateTime input) + { + return input.ToString("yyyy-MM-dd dddd"); + } + /// + /// 转换DateTime类型到Unix时间戳 + /// + /// + /// + static public Int64 ToTimeStamp(this DateTime input) + { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 + long timeStamp = (long)(input - startTime).TotalSeconds; // 相差秒数 + return timeStamp; + } + /// + /// 转换Unix时间戳到DateTime类型 + /// + /// + /// + static public DateTime ToDateTime(this Int64 input) + { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 + return startTime.AddSeconds(input); + } + /// + /// 判断字符串是否与内容匹配 + /// + /// + /// + /// + static public bool IsMatchStr(this string input, string likestr) + { + return Strings.IsMatchStr(input,likestr); + } + /// + /// 将变量值转换成Double类型,如果不在指定区域范围内,则使用默认值 + /// + /// + /// + /// + /// + /// + static public double ToDouble(this object input, double minValue, double maxValue, double defValue) + { + try + { + double tmpI = Convert.ToDouble(input); + if (tmpI < minValue || tmpI > maxValue) + { + return defValue; + } + else + { + return tmpI; + } + } + catch { return defValue; } + } + /// + /// 转换到文件大小字符串 + /// + /// + /// + static public string ToFileSizeStr(this Int64 input) + { + return RyFiles.GetFileSizeStr(input); + } + /// + /// 转换到文件大小字符串 + /// + /// + /// + static public string ToFileSizeStr(this UInt64 input) + { + return RyFiles.GetFileSizeStr(input.ToInt64(0)); + } + /// + /// 转换指定类型为Decimal类型 + /// + /// + /// + /// + static public decimal ToDecimal(this object input, decimal defValue) + { + try + { + return Convert.ToDecimal(input); + } + catch { return defValue; } + } + /// + /// 将变量值转换成Decimal类型 + /// + /// + /// + static public decimal ToDecimal(this object input) + { + try + { + return Convert.ToDecimal(input); + } + catch { return 0; } + } + /// + /// 将变量值转换成Decimal类型,如果不在指定区域范围内,则使用默认值 + /// + /// + /// + /// + /// + /// + static public decimal ToDecimal(this object input, decimal minValue, decimal maxValue, decimal defValue) + { + try + { + decimal tmpI = Convert.ToDecimal(input); + if (tmpI < minValue || tmpI > maxValue) + { + return defValue; + } + else + { + return tmpI; + } + } + catch { return defValue; } + } + /// + /// 转换指定类型为DateTime类型 + /// + /// + /// + /// + static public DateTime ToDateTime(this object input, DateTime defValue) + { + try + { + return Convert.ToDateTime(input); + } + catch { return defValue; } + } + /// + /// 将变量值转换成DateTime类型 + /// + /// + /// + static public DateTime ToDateTime(this object input) + { + try + { + return Convert.ToDateTime(input); + } + catch { return Convert.ToDateTime("2000-1-1"); } + } + /// + /// 转换指定类型为布尔类型 + /// + /// + /// + static public bool ToBool(this object input) + { + return (input.ToString() == "1" || input.ToString().ToLower() == "true" || input is true); + } + /// + /// 追加字符 + /// + /// + /// + /// + static public string AppendStr(this string input,string addstr) + { + if (input == "") + { + return addstr; + } + else + { + if (addstr == "") + { + return input; + } + else + { + return input + "\r\n" + addstr; + } + } + } + /// + /// 获取指定字符串之间的内容 + /// + /// + /// + /// + /// + static public string GetStr(this string input, string point1, string point2) + { + return GetStr(input, point1, point2, 0,out int pos1, ""); + } + /// + /// 获取指定字符串之间的内容 + /// + /// + /// + /// + /// + /// + /// + /// + static public string GetStr(this string input, string point1, string point2, int iPos1, out int endPos, string defValue) + { + endPos = -1; + if (input == null) { return defValue; } + int iIndex = iPos1; + if (iPos1 < 0) { return defValue; } + if (iPos1>input.Length-1) { return defValue; } + if (point1 != "") + { iIndex = input.IndexOf(point1, iPos1); } + if (iIndex == -1) { return defValue; } + int iIndex2 = 0; + if (point2 == "") { iIndex2 = input.Length; } + else { iIndex2 = input.IndexOf(point2, iIndex + point1.Length); } + string tmpStr = input; + if (iIndex < iIndex2 && iIndex >= 0) + { + tmpStr = input.Substring(iIndex + point1.Length, iIndex2 - iIndex - point1.Length); + endPos = iIndex2 + point2.Length; + } + else + { + return defValue; + } + return tmpStr; + } + /// + /// 判断指定字符串是否是Int类型 + /// + /// + /// + static public bool IsInt(this object input) + { + try + { + Convert.ToInt64(input); + return input.ToString().IndexOf(".") >= 0?false:true; + } + catch { return false; } + } + /// + /// 判断指定字符串是否是Double类型 + /// + /// + /// + static public bool IsDouble(this object input) + { + try + { + Convert.ToDouble(input); + return true; + } + catch { return false; } + } + /// + /// 判断是否是布尔类型 + /// + /// + /// + static public bool IsBool(this object input) + { + try + { + Convert.ToBoolean(input); + return true; + } + catch { return false; } + } + /// + /// 将字符串转换为Base64类型 + /// + /// + /// + static public string ToBase64(this string input) + { + System.Text.Encoding encode = System.Text.Encoding.Default; + byte[] bytedata = encode.GetBytes(input); + return Convert.ToBase64String(bytedata, 0, bytedata.Length); + } + /// + /// 判断字符串是否在指定长度 + /// + /// + /// + /// + /// + static public bool InLength(this string input,int min,int max) + { + if (input.Length >= min && input.Length <= max) + { return true; } + else + return false; + } + /// + /// 判断能否转换成日期格式 + /// + /// + /// + static public bool IsDateTime(this object input) + { + try + { + Convert.ToDateTime(input); + return true; + } + catch { return false; } + } + } +} diff --git a/Source/MyDb/DbManage/sType.cs b/Source/MyDb/DbManage/sType.cs new file mode 100644 index 0000000..ee560ab --- /dev/null +++ b/Source/MyDb/DbManage/sType.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ryCommon.sType +{ + /// + /// 文件时间 + /// + public class FileTime + { + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } = new DateTime(1970, 1, 1); + /// + /// 最后修改时间 + /// + public DateTime LastWriteTime { get; set; } = new DateTime(1970, 1, 1); + /// + /// 访问时间 + /// + public DateTime AccessTime { get; set; } = new DateTime(1970, 1, 1); + } + /// + /// 图片类型 + /// + public enum ImageType + { + /// + /// Bmp图片 + /// + Bmp, + /// + /// Jpeg图片 + /// + Jpeg, + /// + /// Png图片 + /// + Png, + /// + /// Gif动态图片 + /// + Gif, + /// + /// Tiff图片 + /// + Tiff + } +} diff --git a/Source/MyDb/FileFuns/ElevatedDragDropManager.cs b/Source/MyDb/FileFuns/ElevatedDragDropManager.cs new file mode 100644 index 0000000..59ddf15 --- /dev/null +++ b/Source/MyDb/FileFuns/ElevatedDragDropManager.cs @@ -0,0 +1,204 @@ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +/// +/// 给控件增加拖放功能的类 +/// +public class ElevatedDragDropManager : IMessageFilter +{ + + #region "P/Invoke" + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, ChangeWindowMessageFilterExAction action, ref CHANGEFILTERSTRUCT changeInfo); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags); + + [DllImport("shell32.dll")] + private static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept); + + [DllImport("shell32.dll")] + private static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out()] + StringBuilder lpszFile, uint cch); + + [DllImport("shell32.dll")] + private static extern bool DragQueryPoint(IntPtr hDrop, ref POINT lppt); + + [DllImport("shell32.dll")] + private static extern void DragFinish(IntPtr hDrop); + + [StructLayout(LayoutKind.Sequential)] + private struct POINT + { + public int X; + + public int Y; + public POINT(int newX, int newY) + { + X = newX; + Y = newY; + } + + public static implicit operator System.Drawing.Point(POINT p) + { + return new System.Drawing.Point(p.X, p.Y); + } + + public static implicit operator POINT(System.Drawing.Point p) + { + return new POINT(p.X, p.Y); + } + } + + private enum MessageFilterInfo : uint + { + None, + AlreadyAllowed, + AlreadyDisAllowed, + AllowedHigher + } + + private enum ChangeWindowMessageFilterExAction : uint + { + Reset, + Allow, + Disallow + } + + private enum ChangeWindowMessageFilterFlags : uint + { + Add = 1, + Remove = 2 + } + + [StructLayout(LayoutKind.Sequential)] + private struct CHANGEFILTERSTRUCT + { + public uint cbSize; + public MessageFilterInfo ExtStatus; + } + #endregion + /// + /// 拖放实例 + /// + public static ElevatedDragDropManager Instance = new ElevatedDragDropManager(); + /// + /// 高级拖放事件 + /// + public event EventHandler ElevatedDragDrop; + + private const uint WM_DROPFILES = 0x233; + private const uint WM_COPYDATA = 0x4a; + + private const uint WM_COPYGLOBALDATA = 0x49; + private readonly bool IsVistaOrHigher = Environment.OSVersion.Version.Major >= 6; + + private readonly bool Is7OrHigher = (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major > 6; + /// + /// + /// + protected ElevatedDragDropManager() + { + Application.AddMessageFilter(this); + } + /// + /// 使支持拖放属性 + /// + /// + public void EnableDragDrop(IntPtr hWnd) + { + if (Is7OrHigher) + { + CHANGEFILTERSTRUCT changeStruct = new CHANGEFILTERSTRUCT(); + changeStruct.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(CHANGEFILTERSTRUCT))); + ChangeWindowMessageFilterEx(hWnd, WM_DROPFILES, ChangeWindowMessageFilterExAction.Allow, ref changeStruct); + ChangeWindowMessageFilterEx(hWnd, WM_COPYDATA, ChangeWindowMessageFilterExAction.Allow, ref changeStruct); + ChangeWindowMessageFilterEx(hWnd, WM_COPYGLOBALDATA, ChangeWindowMessageFilterExAction.Allow, ref changeStruct); + } + else if (IsVistaOrHigher) + { + ChangeWindowMessageFilter(WM_DROPFILES, ChangeWindowMessageFilterFlags.Add); + ChangeWindowMessageFilter(WM_COPYDATA, ChangeWindowMessageFilterFlags.Add); + ChangeWindowMessageFilter(WM_COPYGLOBALDATA, ChangeWindowMessageFilterFlags.Add); + } + DragAcceptFiles(hWnd, true); + } + /// + /// + /// + /// + /// + public bool PreFilterMessage(ref Message m) + { + if (m.Msg == WM_DROPFILES) + { + HandleDragDropMessage(m); + return true; + } + + return false; + } + + private void HandleDragDropMessage(Message m) + { + var sb = new StringBuilder(260); + uint numFiles = DragQueryFile(m.WParam, 0xffffffffu, sb, 0); + var list = new List(); + + for (uint i = 0; i <= numFiles - 1; i++) + { + if (DragQueryFile(m.WParam, i, sb, Convert.ToUInt32(sb.Capacity) * 2) > 0) + { + list.Add(sb.ToString()); + } + } + + POINT p = default(POINT); + DragQueryPoint(m.WParam, ref p); + DragFinish(m.WParam); + + var args = new ElevatedDragDropArgs(); + args.HWnd = m.HWnd; + args.Files = list; + args.X = p.X; + args.Y = p.Y; + + ElevatedDragDrop?.Invoke(this, args); + } +} + +/// +/// +/// +public class ElevatedDragDropArgs : EventArgs +{ + /// + /// + /// + public IntPtr HWnd { get; set; } + + /// + /// + /// + public List Files { get; set; } + /// + /// + /// + public int X { get; set; } + /// + /// + /// + public int Y { get; set; } + /// + /// + /// + public ElevatedDragDropArgs() + { + Files = new List(); + } +} \ No newline at end of file diff --git a/Source/MyDb/FileFuns/FileInfo.cs b/Source/MyDb/FileFuns/FileInfo.cs new file mode 100644 index 0000000..b9b03a5 --- /dev/null +++ b/Source/MyDb/FileFuns/FileInfo.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 文件信息 + /// + public class RySoft + { + /// + /// 获取版本号 + /// + public static string VersionStr + { + get + { + //Version ver = Assembly.LoadFile(Application.ExecutablePath).GetName().Version; + //Version ver = Assembly.GetEntryAssembly().GetName().Version; + //return ver.Major.ToString() + "." + ver.Minor.ToString() + "." + ver.Build.ToString() + "." + ver.; + return GetVersionStr(Application.ExecutablePath); + } + } + /// + /// 获取版本号 + /// + /// + /// + public static string GetVersionStr(string exe_path) + { + try + { + System.Diagnostics.FileVersionInfo info = System.Diagnostics.FileVersionInfo.GetVersionInfo(exe_path); + return info.ProductVersion; + } + catch { return ""; } + //Version ver = Assembly.LoadFile(exe_path).GetName().Version; + //return ver.Major.ToString() + "." + ver.Minor.ToString() + "." + ver.Build.ToString() + "." + ver.Revision.ToString(); + } + /// + /// 判断是否是管理员方式运行 + /// + /// + public static bool IsAdministrator() + { + System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); + System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity); + return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator); + } + } +} diff --git a/Source/MyDb/FileFuns/Hosts.cs b/Source/MyDb/FileFuns/Hosts.cs new file mode 100644 index 0000000..bde7d30 --- /dev/null +++ b/Source/MyDb/FileFuns/Hosts.cs @@ -0,0 +1,238 @@ +using ryCommon; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ryCommon +{ + /// + /// Hosts操作类 + /// + public static class Hosts + { + /// + /// 获取并转换hosts内容 + /// + /// hosts内容 + /// + public static List GetHosts(string content) + { + var list = new List(); + var from_list = content.Replace("\r", "").Replace("\t", " ").Split('\n'); + for (int i = 0; i < from_list.Length; i++) + { + var item = from_list[i].Trim(); + if (item.IndexOfEx("#") == 0) { list.Add(new HostInfo() { Comment=item }); continue; } + int pos = item.IndexOfEx(" "); + if (pos <= 0) { + if (item.StartsWith("!", StringComparison.OrdinalIgnoreCase)) + { + list.Add(new HostInfo() { IP = "", Domain = item.Substring(1), IsDel = true }); + } + continue; + } + var ip = item.Substring(0, pos);//ip + bool isDel = false; + if(ip.StartsWith("!", StringComparison.OrdinalIgnoreCase)) + { + isDel = true;ip = ip.Substring(1); + } + var domain = item.Substring(pos + 1).Trim();//域名 + list.Add(new HostInfo() {IP=ip,Domain=domain,IsDel=isDel }); + } + return list; + } + /// + /// 获取hosts并转换hosts内容 + /// + /// hosts内容 + /// + public static List GetHosts() + { + var hosts_path = ryCommon.RyFiles.GetRealPath("\\drivers\\etc\\hosts"); + var content = ryCommon.RyFiles.ReadAllText(hosts_path).Trim(); + return GetHosts(content); + } + /// + /// 追加内容到hosts里 + /// + /// 要追加的内容列表,每一行为ip 域名的格式 + /// 0表示无需新增,-1表示添加失败,1表示追加成功 + public static int AddHosts(string list) + { + var hosts_path= ryCommon.RyFiles.GetRealPath("\\drivers\\etc\\hosts"); + var content = ryCommon.RyFiles.ReadAllText(hosts_path).Trim(); + var from_list = GetHosts(content); + var _list = GetHosts(list); + bool isAdd = false;//是否有增加数据到hosts里 + for (int i = 0; i < _list.Count; i++) + { + bool HaveRecord = false; + for (int m = from_list.Count-1; m>0; m--) //去host文件里查找是否已含有该内容 + { + if (from_list[m].Comment.Length > 0) { continue; } + if(_list[i].Domain.ToLower()== from_list[m].Domain.ToLower()) + { + if (_list[i].IP.Length == 0 && _list[i].IsDel) + { + from_list.RemoveAt(m); + HaveRecord = true; + } + else + { + if (_list[i].IP != from_list[m].IP) //如果同样域名对应的ip不一样,则删除该项,然后再插入新的ip + { + from_list.RemoveAt(m); + HaveRecord = false; + } + else + { + if (_list[i].IsDel) //如果ip和网址一致,并且标注为删除,则删除 + { + from_list.RemoveAt(m); + } + HaveRecord = true; + } + } + } + } + if(!HaveRecord) + { + isAdd = true; + from_list.Add(_list[i]); + } + } + if (isAdd) + { + try + { + content = ""; + for (int i = 0; i < from_list.Count; i++) + { + if (content.Length > 0) { content += "\r\n"; } + if (from_list[i].Comment.Length > 0) + { + content += from_list[i].Comment; + } + else + { + content += from_list[i].IP + "\t" + from_list[i].Domain; + } + } + ryCommon.RyFiles.WriteAllText(hosts_path, content, Encoding.UTF8); + } + catch + { + return -1; + } + } + else + { return 0; } + return 1; + } + /// + /// 追加内容到hosts里 + /// + /// 要追加的内容 + /// 0表示无需新增,-1表示添加失败,1表示追加成功 + public static int AddHosts(HostInfo item) + { + return AddHosts(item.IP + "\t" + item.Domain); + } + /// + /// 追加内容到hosts里 + /// + /// ip地址 + /// 域名 + /// 0表示无需新增,-1表示添加失败,1表示追加成功 + public static int AddHosts(string ip,string domain) + { + return AddHosts(ip + "\t" + domain); + } + /// + /// 从hosts文件里删除内容 + /// + /// 要删除的内容 + /// 0表示无需删除,-1表示添加失败,1表示删除成功 + public static int DelHosts(HostInfo item) + { + var hosts_path = ryCommon.RyFiles.GetRealPath("\\drivers\\etc\\hosts"); + var content = ryCommon.RyFiles.ReadAllText(hosts_path).Trim(); + var from_list = GetHosts(content); + bool IsDel = false; + for (int i = from_list.Count-1; i>=0; i++) + { + if(from_list[i].IP==item.IP && from_list[i].Domain.ToLower()==item.Domain.ToLower()) + { + from_list.RemoveAt(i); + IsDel = true; + } + else if (item.IP.Length==0 && from_list[i].Domain.ToLower() == item.Domain.ToLower()) + { + from_list.RemoveAt(i); + IsDel = true; + } + } + var text = ""; + for (int i = 0; i < from_list.Count; i++) + { + if (text.Length > 0) { text += "\r\n"; } + if(from_list[i].Comment.Length>0) + { + text += from_list[i].Comment; + } + else + { + text += from_list[i].IP+"\t"+ from_list[i].Domain; + } + } + if (IsDel) + { + try + { + ryCommon.RyFiles.WriteAllText(hosts_path, text, Encoding.UTF8); + } + catch + { + return -1; + } + } + else + { return 0; } + return 1; + } + /// + /// 从hosts文件里删除内容 + /// + /// ip地址 + /// 域名 + /// 0表示无需删除,-1表示添加失败,1表示删除成功 + public static int DelHosts(string ip, string domain) + { + return DelHosts(new HostInfo() {IP=ip,Domain=domain }); + } + } + /// + /// Host信息 + /// + public class HostInfo + { + /// + /// IP + /// + public string IP { get; set; } = ""; + /// + /// 域名 + /// + public string Domain { get; set; } = ""; + /// + /// 注释 + /// + public string Comment { get; set; } = ""; + /// + /// 是否要删除 + /// + public bool IsDel { get; set; } = false; + } +} diff --git a/Source/MyDb/FileFuns/RyFiles.cs b/Source/MyDb/FileFuns/RyFiles.cs new file mode 100644 index 0000000..90a6270 --- /dev/null +++ b/Source/MyDb/FileFuns/RyFiles.cs @@ -0,0 +1,1081 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 文件操作类 + /// + public class RyFiles + { + #region 【内部类型定义】 + private struct SHFILEOPSTRUCT + { + public IntPtr hwnd; //父窗口句柄 + public WFunc wFunc; //要执行的动作 + public string pFrom; //源文件路径,可以是多个文件,以结尾符号"\0"结束 + public string pTo; //目标路径,可以是路径或文件名 + public FILEOP_FLAGS fFlags; //标志,附加选项 + public bool fAnyOperationsAborted; //是否可被中断 + public IntPtr hNameMappings; //文件映射名字,可在其它 Shell 函数中使用 + public string lpszProgressTitle; // 只在 FOF_SIMPLEPROGRESS 时,指定对话框的标题。 + } + + private enum WFunc + { + FO_MOVE = 0x0001, //移动文件 + FO_COPY = 0x0002, //复制文件 + FO_DELETE = 0x0003, //删除文件,只是用pFrom + FO_RENAME = 0x0004 //文件重命名 + } + + private enum FILEOP_FLAGS + { + FOF_MULTIDESTFILES = 0x0001, //pTo 指定了多个目标文件,而不是单个目录 + FOF_CONFIRMMOUSE = 0x0002, + FOF_SILENT = 0x0044, // 不显示一个进度对话框 + FOF_RENAMEONCOLLISION = 0x0008, // 碰到有抵触的名字时,自动分配前缀 + FOF_NOCONFIRMATION = 0x10, // 不对用户显示提示 + FOF_WANTMAPPINGHANDLE = 0x0020, // 填充 hNameMappings 字段,必须使用 SHFreeNameMappings 释放 + FOF_ALLOWUNDO = 0x40, // 允许撤销 + FOF_FILESONLY = 0x0080, // 使用 *.* 时, 只对文件操作 + FOF_SIMPLEPROGRESS = 0x0100, // 简单进度条,意味者不显示文件名。 + FOF_NOCONFIRMMKDIR = 0x0200, // 建新目录时不需要用户确定 + FOF_NOERRORUI = 0x0400, // 不显示出错用户界面 + FOF_NOCOPYSECURITYATTRIBS = 0x0800, // 不复制 NT 文件的安全属性 + FOF_NORECURSION = 0x1000 // 不递归目录 + } + #endregion 【内部类型定义】 + #region 【DllImport】 + + [DllImport("shell32.dll")] + private static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp); + /// + /// + /// + public enum ShowCommands : int + { + SW_HIDE = 0, + SW_SHOWNORMAL = 1, + SW_NORMAL = 1, + SW_SHOWMINIMIZED = 2, + SW_SHOWMAXIMIZED = 3, + SW_MAXIMIZE = 3, + SW_SHOWNOACTIVATE = 4, + SW_SHOW = 5, + SW_MINIMIZE = 6, + SW_SHOWMINNOACTIVE = 7, + SW_SHOWNA = 8, + SW_RESTORE = 9, + SW_SHOWDEFAULT = 10, + SW_FORCEMINIMIZE = 11, + SW_MAX = 11 + } + [DllImport("shell32.dll", CharSet = CharSet.Unicode)] + static extern int ShellExecute( + IntPtr hwnd, + string lpOperation, + string lpFile, + string lpParameters, + string lpDirectory, + ShowCommands nShowCmd); + #endregion 【DllImport】 + #region 【删除文件操作】 + /// + /// 删除单个文件。 + /// + /// 删除的文件名 + /// 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + /// 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + /// 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + /// 反馈错误消息的字符串 + /// 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + public static int DeleteFile(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg) + { + try + { + string fName = fileName; + if (fileName.IndexOf("*") < 0 && fileName.IndexOf("?") < 0) + { + fName = GetFullName(fileName); + } + return ToDelete(fName, toRecycle, showDialog, showProgress, ref errorMsg); + } + catch (Exception ex) + { + errorMsg = ex.Message; + return -200; + } + } + /// + /// 删除单个文件。 + /// + /// 删除的文件名 + /// 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + /// 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + public static int DeleteFile(string fileName, bool toRecycle) + { + string errorMsg = ""; + return DeleteFile(fileName,toRecycle,false,false,ref errorMsg); + } + /// + /// 永久删除单个文件。 + /// + /// 永久删除的文件名 + /// 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + public static int DeleteFile(string fileName) + { + return DeleteFile(fileName, false); + } + /// + /// 删除一组文件。 + /// + /// 字符串数组,表示一组文件名 + /// 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + /// 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + /// 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + /// 反馈错误消息的字符串 + /// 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + public static int DeleteFiles(string[] fileNames, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg) + { + try + { + string fName = ""; + foreach (string str in fileNames) + { + fName += GetFullName(str) + "\0"; //组件文件组字符串 + } + + return ToDelete(fName, toRecycle, showDialog, showProgress, ref errorMsg); + } + catch (Exception ex) + { + errorMsg = ex.Message; + return -200; + } + } + #endregion 【删除文件操作】 + + #region 【移动文件操作】 + /// + /// 移动文件到指定路径下 + /// + /// 要移动的文件名 + /// 移动到的目的路径 + /// + public static int MoveFile(string sourceFileName, string destinationPath) + { + string errorMsg = ""; + return MoveFile(sourceFileName, destinationPath,false,false,false,ref errorMsg); + } + /// + /// 移动一个文件到指定路径下 + /// + /// 要移动的文件名 + /// 移动到的目的路径 + /// 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + /// 指示是否显示进度对话框 + /// 指示当文件名重复时,是否自动为新文件加上后缀名 + /// 反馈错误消息的字符串 + /// 返回移动操作是否成功的标识,成功返回0,失败返回错误代码 + public static int MoveFile(string sourceFileName, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) + { + try + { + string sfName = GetFullName(sourceFileName); + string dfName = GetFullName(destinationPath); + + return ToMoveOrCopy(WFunc.FO_MOVE, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); + } + catch (Exception ex) + { + errorMsg = ex.Message; + return -200; + } + } + + /// + /// 移动一组文件到指定的路径下 + /// + /// 要移动的文件名数组 + /// 移动到的目的路径 + /// 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + /// 指示是否显示进度对话框 + /// 指示当文件名重复时,是否自动为新文件加上后缀名 + /// 反馈错误消息的字符串 + /// 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + public static int MoveFiles(string[] sourceFileNames, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) + { + try + { + string sfName = ""; + foreach (string str in sourceFileNames) + { + sfName += GetFullName(str) + "\0"; //组件文件组字符串 + } + string dfName = GetFullName(destinationPath); + + return ToMoveOrCopy(WFunc.FO_MOVE, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); + } + catch (Exception ex) + { + errorMsg = ex.Message; + return -200; + } + } + #endregion 【移动文件操作】 + + #region 【复制文件操作】 + /// + /// 复制文件到指定的文件名或路径 + /// + /// 要复制的文件名 + /// 复制到的目的文件名或路径 + /// + public static int CopyFile(string sourceFileName, string destinationFileName) + { + string errorMsg = ""; + return CopyFile(sourceFileName, destinationFileName,false,false,false,ref errorMsg); + } + /// + /// 复制文件到指定的文件名或路径 + /// + /// 要复制的文件名 + /// 复制到的目的文件名或路径 + /// 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + /// 指示是否显示进度对话框 + /// 指示当文件名重复时,是否自动为新文件加上后缀名 + /// 返回错误信息 + /// 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + public static int CopyFile(string sourceFileName, string destinationFileName, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) + { + try + { + string sfName = sourceFileName; + string dfName = destinationFileName; + + return ToMoveOrCopy(WFunc.FO_COPY, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); + } + catch (Exception ex) + { + errorMsg = ex.Message; + return -200; + } + } + + /// + /// 复制一组文件到指定的路径 + /// + /// 要复制的文件名数组 + /// 复制到的目的路径 + /// 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + /// 指示是否显示进度对话框 + /// 指示当文件名重复时,是否自动为新文件加上后缀名 + /// 返回错误信息 + /// 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + public static int CopyFiles(string[] sourceFileNames, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) + { + try + { + string sfName = ""; + foreach (string str in sourceFileNames) + { + sfName += GetFullName(str) + "\0"; //组件文件组字符串 + } + string dfName = GetFullName(destinationPath); + + return ToMoveOrCopy(WFunc.FO_COPY, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); + } + catch (Exception ex) + { + errorMsg = ex.Message; + return -200; + } + } + #endregion 【复制文件操作】 + + #region 【重命名文件】 + /// + /// 重命名一个文件为新名称,建议您使用更方便的Microsoft.VisualBasic.FileSystem.ReName();替换该方法 + /// + /// 要复制的文件名 + /// 复制到的目的文件名或路径 + /// 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + /// 返回错误信息 + /// 返回移动操作是否成功的标识,成功返回0,失败返回错误代码,-200:表示其他异常 + [Obsolete("建议使用 Microsoft.VisualBasic.FileSystem.ReName()方法")] + public static int ReNameFile(string sourceFileName, string destinationFileName, bool showDialog, ref string errorMsg) + { + + try + { + SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT() + { + wFunc = WFunc.FO_RENAME, + pFrom = GetFullName(sourceFileName) + "\0\0", //将文件名以结尾字符"\0\0"结束 + pTo = GetFullName(destinationFileName) + "\0\0", + fFlags = FILEOP_FLAGS.FOF_NOERRORUI + }; + if (!showDialog) + lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION; //设定不显示提示对话框 + + + lpFileOp.fAnyOperationsAborted = true; + + int n = SHFileOperation(ref lpFileOp); + if (n == 0) + return 0; + + string tmp = GetErrorString(n); + + errorMsg = string.Format("{0}({1})", tmp, sourceFileName); + + return n; + } + catch (Exception ex) + { + errorMsg = ex.Message; + return -200; + } + } + + + #endregion 【重命名文件】 + + /// + /// 删除单个或多个文件 + /// + /// 删除的文件名,如果是多个文件,文件名之间以字符串结尾符'\0'隔开 + /// 指示是将文件放入回收站还是永久删除,true-放入回收站,false-永久删除 + /// 指示是否显示确认对话框,true-显示确认删除对话框,false-不显示确认删除对话框 + /// 指示是否显示进度对话框,true-显示,false-不显示。该参数当指定永久删除文件时有效 + /// 反馈错误消息的字符串 + /// 操作执行结果标识,删除文件成功返回0,否则,返回错误代码 + private static int ToDelete(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg) + { + SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT() + { + wFunc = WFunc.FO_DELETE, + pFrom = fileName + "\0" //将文件名以结尾字符"\0"结束 + }; + lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI; + if (!showDialog) + lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION; //设定不显示提示对话框 + if (!showProgress) + lpFileOp.fFlags |= FILEOP_FLAGS.FOF_SILENT; //设定不显示进度对话框 + if (!toRecycle) + lpFileOp.fFlags &= ~FILEOP_FLAGS.FOF_ALLOWUNDO; //设定删除到回收站 + lpFileOp.fAnyOperationsAborted = true; + + int n = SHFileOperation(ref lpFileOp); + if (n == 0) + return 0; + + string tmp = GetErrorString(n); + + //.av 文件正常删除了但也提示 402 错误,不知道为什么。屏蔽之。 + if ((fileName.ToLower().EndsWith(".av") && n.ToString("X") == "402")) + return 0; + + errorMsg = string.Format("{0}({1})", tmp, fileName); + + return n; + } + + /// + /// 移动或复制一个或多个文件到指定路径下 + /// + /// 操作类型,是移动操作还是复制操作 + /// 要移动或复制的文件名,如果是多个文件,文件名之间以字符串结尾符'\0'隔开 + /// 移动到的目的位置 + /// 指示是否显示确认对话框,true-显示确认对话框,false-不显示确认对话框 + /// 指示是否显示进度对话框 + /// 指示当文件名重复时,是否自动为新文件加上后缀名 + /// 反馈错误消息的字符串 + /// 返回移动操作是否成功的标识,成功返回0,失败返回错误代码 + private static int ToMoveOrCopy(WFunc flag, string sourceFileName, string destinationFileName, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) + { + SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT() + { + wFunc = flag, + pFrom = sourceFileName + "\0", //将文件名以结尾字符"\0\0"结束 + pTo = destinationFileName + "\0\0" + }; + lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI; + lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMMKDIR; //指定在需要时可以直接创建路径 + if (!showDialog) + lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION; //设定不显示提示对话框 + if (!showProgress) + lpFileOp.fFlags |= FILEOP_FLAGS.FOF_SILENT; //设定不显示进度对话框 + if (autoRename) + lpFileOp.fFlags |= FILEOP_FLAGS.FOF_RENAMEONCOLLISION; //自动为重名文件添加名称后缀 + + lpFileOp.fAnyOperationsAborted = true; + + int n = SHFileOperation(ref lpFileOp); + if (n == 0) + return 0; + + string tmp = GetErrorString(n); + + errorMsg = string.Format("{0}({1})", tmp, sourceFileName); + + return n; + } + /// + /// 如果指定文件夹不存在,则创建文件夹 + /// + /// + public static void CreateDirectory(string path) + { + if(!System.IO.Directory.Exists(path)) + { + System.IO.Directory.CreateDirectory(path); + } + } + /// + /// 获取一个文件的全名 + /// + /// 文件名 + /// 返回生成文件的完整路径名 + private static string GetFullName(string fileName) + { + FileInfo fi = new FileInfo(fileName); + return fi.FullName; + } + /// + /// 获取一个文件的全名 + /// + /// 文件名 + /// 返回生成文件的完整路径名 + public static sType.FileTime GetFileDate(string fileName) + { + var result = new sType.FileTime(); + FileInfo fi = new FileInfo(fileName); + result.AccessTime = fi.LastAccessTime; + result.CreateTime = fi.CreationTime; + result.LastWriteTime = fi.LastWriteTime; + return result; + } + /// + /// 解释错误代码 + /// + /// 代码号 + /// 返回关于错误代码的文字描述 + private static string GetErrorString(int n) + { + if (n == 0) return string.Empty; + + switch (n) + { + case 2: + return "系统找不到指定的文件。"; + case 7: + return "存储控制块被销毁。您是否选择的“取消”操作?"; + case 113: + return "文件已存在!"; + case 115: + return "重命名文件操作,原始文件和目标文件必须具有相同的路径名。不能使用相对路径。"; + case 117: + return "I/O控制错误"; + case 123: + return "指定了重复的文件名"; + case 116: + return "The source is a root directory, which cannot be moved or renamed."; + case 118: + return "Security settings denied access to the source."; + case 124: + return "The path in the source or destination or both was invalid."; + case 65536: + return "An unspecified error occurred on the destination."; + case 1026: + return "在试图移动或拷贝一个不存在的文件."; + case 1223: + return "操作被取消!"; + default: + return "未识别的错误代码:" + n; + } + } + /// + /// 运行文件 + /// + /// + /// + /// + public static int RunFile(string FilePath, string PramCom) + { + return RunFile(FilePath, PramCom,""); + } + /// + /// /运行文件 + /// + /// + /// + /// + public static int RunFile(string FilePath, string PramCom,string lpDirectory) + { + try + { + return ShellExecute(IntPtr.Zero, "open", FilePath, PramCom, lpDirectory, ShowCommands.SW_SHOWNORMAL); + //System.Diagnostics.Process.Start(FilePath, PramCom); + //return 1; + } + catch { return 0; } + } + /// + /// 运行程序 + /// + /// + /// + public static int RunProc(string FilePath) + { + return RunFile(FilePath, ""); + } + /// + /// 打开文件 + /// + /// + /// + public static int OpenFile(string FilePath) + { + return RunFile(FilePath, ""); + } + [DllImport("Kernel32", CharSet = CharSet.Unicode)] + private static extern Int32 GetShortPathName(String path, StringBuilder shortPath, Int32 shortPathLength); + /// + /// 打开文件夹并定位文件 + /// + /// + /// + public static int OpenFolderGotoFile(string FilePath) + { + StringBuilder shortpath = new StringBuilder(260); + int result = GetShortPathName(FilePath, shortpath, shortpath.Capacity); + return RunFile("explorer.exe", "/select,\""+ shortpath.ToString()+ "\""); + } + /// + /// 打开网址 + /// + /// + /// + public static int OpenUrl(string url) + { + return RunFile(url, ""); + } + /// + /// 判断文件名是否有效 + /// + /// + /// + public static bool IsValidFileName(string filename) + { + char[] no_validstr = @":\/|*?<>""".ToCharArray(); + for(int i=0;i=0) + { + return false; + } + } + return true; + } + /// + /// 转换到有效文件名 + /// + /// + /// + public static string ConvertToValidFileName(string filename) + { + char[] no_validstr = @":\/|*?<>""".ToCharArray(); + string _file = filename; + for (int i = 0; i < no_validstr.Length; i++) + { + _file = _file.Replace(no_validstr[i].ToString(), ""); + } + return _file; + } + /// + /// 追加日志 + /// + /// + public void AppendLogs(string path, string content) + { + AppendAllText(path, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t" + content); + } + /// + /// 追加文件 + /// + /// + public void AppendAllText(string path, string content) + { + if (!System.IO.File.Exists(path)) + { + RyFiles.WriteAllText(path, content, Encoding.UTF8); + } + else + { + System.IO.File.AppendAllText(path, "\r\n" +content, Encoding.UTF8); + } + } + /// + /// 读取文件内容,可以自动识别文件编码 + /// + /// + /// + public static string ReadAllText(string path) + { + if (System.IO.File.Exists(path)) + { + try + { + return System.IO.File.ReadAllText(path, ryCommon.TxtFileEncoder.GetEncoding(path)); + } + catch { return ""; } + } + return ""; + } + /// + /// 读取文件所有行,可以自动识别文件编码 + /// + /// + /// + public static string[] ReadAllLines(string path) + { + if (System.IO.File.Exists(path)) + { + return System.IO.File.ReadAllLines(path, ryCommon.TxtFileEncoder.GetEncoding(path)); + } + return null; + } + //static void ReadFile(string path,FileAccess fileAccess, FileShare fileShare) + //{ + // FileStream fs = new FileStream(path, FileMode.Open, fileAccess, fileShare); + // var buffer = new byte[fs.Length]; + // fs.Position = 0; + // fs.Read(buffer, 0, buffer.Length); + // Console.WriteLine(Encoding.Default.GetString(buffer)); + //} + /// + /// 写入所有文本行到文件,如果文件夹不存在,会自动创建 + /// + /// + /// + /// + public static void WriteAllLines(string path,string[] content,Encoding encoding) + { + if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(path))) + { + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); + } + System.IO.File.WriteAllLines(path, content, encoding); + } + /// + /// 写入所有文本到文件,如果文件夹不存在,会自动创建 + /// + /// + /// + /// + public static void WriteAllText(string path, string content, Encoding encoding) + { + if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(path))) + { + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); + } + System.IO.File.WriteAllText(path, content, encoding); + } + /// + /// 从文件中加载图片,使用本方法,不会导致图片文件被占用。 + /// + /// + public static Image LoadPicFromFile(string path) + { + if(!System.IO.File.Exists(path)) + { return null; } + try + { + FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); + //把文件读取到字节数组 + byte[] data = new byte[fs.Length]; + fs.Read(data, 0, data.Length); + fs.Close(); + + //实例化一个内存流--->把从文件流中读取的内容[字节数组]放到内存流中去 + MemoryStream ms = new MemoryStream(data); + //设置图片框 pictureBox1中的图片 + return Image.FromStream(ms); + } + catch { return null; } + } + /// + /// 获取文件大小 + /// + /// + /// + public static Int64 GetFileSize(string path) + { + try + { + FileInfo fileInfo = new FileInfo(path); + return fileInfo.Length; + } + catch { return -1; } + } + /// + /// 添加文件到指定文件夹,会进行自动重命名,并返回重命名后的文件名(含路径) + /// + /// 要添加的文件路径 + /// 要添加到的文件夹 + /// 是否根据时间进行重命名 + /// 返回是否成功执行 + /// 成功执行则返回路径,否则返回空 + public static string AddFileToFolder(string filepath,string toFolder,bool RenameByTime, out bool OK) + { + OK = false; + var _toFolder = toFolder.TrimEnd('\\'); + CreateDirectory(_toFolder); + if (!System.IO.Directory.Exists(_toFolder)) { return ""; } + if (!System.IO.File.Exists(filepath) && !System.IO.Directory.Exists(filepath)) { return ""; } + var filename = System.IO.Path.GetFileName(filepath); + if (RenameByTime) { filename = DateTime.Now.ToString("yyyyMMddHHmmss") + System.IO.Path.GetExtension(filepath); } + if(!System.IO.File.Exists(_toFolder+"\\"+ filename) && !System.IO.Directory.Exists(_toFolder + "\\" + filename)) { + string errorMsg = ""; + if (ToMoveOrCopy(WFunc.FO_COPY, filepath, _toFolder + "\\" + filename, false, false, false, ref errorMsg) == 0) + { + OK = true; + return _toFolder + "\\" + filename; + } + return "";//如果复制失败,则返回空路径 + } + else //如果目标路径已经存在同名文件 + { + int index = 0; + string filename_noext; + if (RenameByTime) { filename_noext = DateTime.Now.ToString("yyyyMMddHHmmss"); } + else { filename_noext = System.IO.Path.GetFileNameWithoutExtension(filepath); } + var ext= System.IO.Path.GetExtension(filepath); + while (index<20) //最多重试20次 + { + Random rd = new Random(Guid.NewGuid().GetHashCode()); + if (RenameByTime) { filename_noext = DateTime.Now.ToString("yyyyMMddHHmmss"); } + var to_path = _toFolder + "\\" + filename_noext+"_"+ rd.Next(1000, 9999)+ ext; + if(!System.IO.File.Exists(to_path) && !System.IO.Directory.Exists(to_path)) + { + string errorMsg = ""; + if (ToMoveOrCopy(WFunc.FO_COPY, filepath, to_path, false, false, false, ref errorMsg) == 0) + { + OK = true; + return to_path; + } + return ""; + } + index++; + } + return ""; + } + } + /// + /// 获取文件大小字符串 + /// + /// + /// + public static string GetFileSizeStr(long size) + { + if (size == -1) { return "未知"; } + string s = ""; + string[] u = new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "NB", "DB" }; + double i = size; + int n = 0; + while (i > 1024) + { + i = i / 1024.0; + n++; + if (n == 4) break; + } + s = i.ToString("F2") + u[n]; + return s; + } + /// + /// 获取文件大小字符串 + /// + /// + /// + public static string GetFileSizeStr(string filepath) + { + return GetFileSizeStr(GetFileSize(filepath)); + } + /// + /// 复制内容到剪切板 + /// + /// + public static void CopyToClip(string text) + { + try + { + Clipboard.Clear(); + Clipboard.SetText(text); + } + catch { } + } + private static ImageCodecInfo GetEncoderInfo(String mimeType) + { + int j; + ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); + for (j = 0; j < encoders.Length; ++j) + { + if (encoders[j].MimeType == mimeType) + return encoders[j]; + } + return null; + } + private static ImageCodecInfo GetEncoderInfo(ryCommon.sType.ImageType type) + { + #region 图片格式 + ImageCodecInfo myImageCodecInfo; + string type_str = "image/jpeg"; + switch (type) + { + case sType.ImageType.Bmp: + type_str = "image/bmp"; + break; + case sType.ImageType.Jpeg: + type_str = "image/jpeg"; + break; + case sType.ImageType.Gif: + type_str = "image/gif"; + break; + case sType.ImageType.Tiff: + type_str = "image/tiff"; + break; + case sType.ImageType.Png: + type_str = "image/png"; + break; + } + myImageCodecInfo = GetEncoderInfo(type_str); + #endregion + return myImageCodecInfo; + } + private static EncoderParameters GetEncoderParameters(ryCommon.sType.ImageType type) + { + System.Drawing.Imaging.Encoder myEncoder; + EncoderParameter myEncoderParameter; + EncoderParameters myEncoderParameters; + + myEncoder = System.Drawing.Imaging.Encoder.Quality; + myEncoderParameters = new EncoderParameters(1); + // Save the bitmap as a JPEG file with quality level 100. + myEncoderParameter = new EncoderParameter(myEncoder, 100L); + myEncoderParameters.Param[0] = myEncoderParameter; + return myEncoderParameters; + } + /// + /// 添加某个控件为支持拖放属性 + /// + /// + /// + public static ElevatedDragDropManager AddDropDrag(IntPtr handle) + { + ElevatedDragDropManager.Instance.EnableDragDrop(handle); + return ElevatedDragDropManager.Instance; + } + /// + /// 保存高质量不失真照片 + /// + /// + /// + /// + public static void SaveHighQualityImage(Bitmap m,string path,ryCommon.sType.ImageType type) + { + m.Save(path, GetEncoderInfo(type), GetEncoderParameters(type)); + } + /// + /// 保存高质量不失真照片 + /// + /// + /// + /// + public static void SaveHighQualityImage(Bitmap m, MemoryStream ms, ryCommon.sType.ImageType type) + { + m.Save(ms, GetEncoderInfo(type), GetEncoderParameters(type)); + } + /// + /// 保存高质量不失真照片 + /// + /// + /// + /// + public static void SaveHighQualityImage(Image m, string path, ryCommon.sType.ImageType type) + { + m.Save(path, GetEncoderInfo(type), GetEncoderParameters(type)); + } + /// + /// 获取绝对路径 + /// + /// + /// + public static string GetRealPath(string _path) + { + string _tmp_path = _path.Replace("", Application.StartupPath); + _tmp_path = _tmp_path.Replace("", Environment.GetFolderPath(Environment.SpecialFolder.System)); + _tmp_path = _tmp_path.Replace("", Environment.GetFolderPath(Environment.SpecialFolder.SystemX86)); + _tmp_path = _tmp_path.Replace("", Environment.GetEnvironmentVariable("ProgramW6432")); + _tmp_path = _tmp_path.Replace("", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)); + _tmp_path = _tmp_path.Replace("", Environment.GetFolderPath(Environment.SpecialFolder.Windows)); + _tmp_path = _tmp_path.Replace("", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); + _tmp_path = _tmp_path.Replace("", Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)); + _tmp_path = _tmp_path.Replace("", Environment.GetFolderPath(Environment.SpecialFolder.Fonts)); + _tmp_path = Environment.ExpandEnvironmentVariables(_tmp_path); + if(_tmp_path.IndexOf("%")>=0) + { + foreach (int i in Enum.GetValues(typeof(Environment.SpecialFolder))) + { + string value = Environment.GetFolderPath((Environment.SpecialFolder)i); + string key= Enum.GetName(typeof(Environment.SpecialFolder), i); + if (_tmp_path.IndexOfEx(key) >= 0) + { + _tmp_path = _tmp_path.ReplaceEx("%"+key+"%", value); + } + } + } + _tmp_path = _tmp_path.Replace("\\\\", "\\"); + return _tmp_path; + } + /// + /// 获取相对路径 + /// + /// + /// + public static string GetRelativePath(string _path) + { + string _tmp_path = _path.Replace(Application.StartupPath, ""); + _tmp_path = _tmp_path.Replace(Environment.GetFolderPath(Environment.SpecialFolder.System), ""); + _tmp_path = _tmp_path.Replace(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), ""); + _tmp_path = _tmp_path.Replace(Environment.GetEnvironmentVariable("ProgramW6432"), ""); + _tmp_path = _tmp_path.Replace(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), ""); + _tmp_path = _tmp_path.Replace(Environment.GetFolderPath(Environment.SpecialFolder.Windows), ""); + _tmp_path = _tmp_path.Replace(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), ""); + _tmp_path = _tmp_path.Replace(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), ""); + _tmp_path = _tmp_path.Replace(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), ""); + string wait_replace_value = ""; + string wait_replace_key = ""; + int max_length = 0; + foreach (int i in Enum.GetValues(typeof(Environment.SpecialFolder))) + { + string value = Environment.GetFolderPath((Environment.SpecialFolder)i); + if (value == "x86") { continue; } + if (_tmp_path.IndexOfEx(value) >= 0) + { + if (value.Length > max_length) + { + wait_replace_value = value; + wait_replace_key = Enum.GetName(typeof(Environment.SpecialFolder), i); ; + max_length = value.Length; + } + } + } + if (max_length > 0) + { + _tmp_path = _tmp_path.ReplaceEx(wait_replace_value, "%" + wait_replace_key + "%"); + } + max_length = 0; + foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) + { + string value = de.Value.ToString(); + if (value == "x86") { continue; } + if (value.IndexOfEx(":")<0) { continue; } + if (_tmp_path.IndexOfEx(value) >= 0 && !value.IsInt()) + { + if (value.Length > max_length) + { + wait_replace_value = value; + wait_replace_key = de.Key.ToString(); + max_length = value.Length; + } + } + } + if (max_length>0) + { + _tmp_path = _tmp_path.ReplaceEx(wait_replace_value, "%" + wait_replace_key + "%"); + } + return _tmp_path; + } + /// + /// 获取图标 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("User32.dll")] + public static extern int PrivateExtractIcons( + string lpszFile, //file name + int nIconIndex, //The zero-based index of the first icon to extract. + int cxIcon, //The horizontal icon size wanted. + int cyIcon, //The vertical icon size wanted. + IntPtr[] phicon, //(out) A pointer to the returned array of icon handles. + int[] piconid, //(out) A pointer to a returned resource identifier. + int nIcons, //The number of icons to extract from the file. Only valid when *.exe and *.dll + int flags //Specifies flags that control this function. + ); + /// + /// 销毁图标 + /// + /// + /// + [DllImport("User32.dll")] + public static extern bool DestroyIcon( + IntPtr hIcon //A handle to the icon to be destroyed. The icon must not be in use. + ); + /// + /// 获取文件图标 + /// + /// + /// + /// + /// + /// + public static Bitmap GetFileIcon(string _path,int index,out int count,int size) + { + var file = _path; + //选中文件中的图标总数 + var iconTotalCount = PrivateExtractIcons(file, 0, 0, 0, null, null, 0, 0); + //用于接收获取到的图标指针 + IntPtr[] hIcons = new IntPtr[iconTotalCount]; + //对应的图标id + int[] ids = new int[iconTotalCount]; + //成功获取到的图标个数 + var successCount = PrivateExtractIcons(file, 0, size, size, hIcons, ids, iconTotalCount, 0); + count = successCount; + Bitmap bmp = null; + if(index>=0 && index< successCount) + { + if (hIcons[index] == IntPtr.Zero) { bmp = null; } + else + { + bmp = Icon.FromHandle(hIcons[index]).ToBitmap(); + } + //内存回收 + for (var i = 0; i < successCount; i++) + { + //指针为空,跳过 + if (hIcons[i] == IntPtr.Zero) continue; + //内存回收 + DestroyIcon(hIcons[i]); + } + } + return bmp; + } + } + +} diff --git a/Source/MyDb/FileFuns/SoundPlay.cs b/Source/MyDb/FileFuns/SoundPlay.cs new file mode 100644 index 0000000..5040cdd --- /dev/null +++ b/Source/MyDb/FileFuns/SoundPlay.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace ryCommon +{ + /// + /// 音频播放类 + /// + public class SoundPlay + { + [DllImport("winmm.dll", SetLastError = true)] + static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound); + [DllImport("winmm.dll")] + static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback); + /// + /// 临时音频文件 + /// + private String m_musicPath = ""; + /// + ///父窗口句柄 + /// + private IntPtr m_Handle; + /// + /// 声音标签 + /// + [Flags] + public enum SoundFlags + { + /// play synchronously (default) + SND_SYNC = 0x0000, + /// play asynchronously + SND_ASYNC = 0x0001, + /// silence (!default) if sound not found + SND_NODEFAULT = 0x0002, + /// pszSound points to a memory file + SND_MEMORY = 0x0004, + /// loop the sound until next sndPlaySound + SND_LOOP = 0x0008, + /// don’t stop any currently playing sound + SND_NOSTOP = 0x0010, + /// Stop Playing Wave + SND_PURGE = 0x40, + /// don’t wait if the driver is busy + SND_NOWAIT = 0x00002000, + /// name is a registry alias + SND_ALIAS = 0x00010000, + /// alias is a predefined id + SND_ALIAS_ID = 0x00110000, + /// name is file name + SND_FILENAME = 0x00020000, + /// name is resource name or atom + SND_RESOURCE = 0x00040004 + } + /// + /// 音频播放类 + /// + /// embedded music file + /// 临时保存的文件位置 + /// 父窗口句柄 + public SoundPlay(Byte[] Music, string folder_path, IntPtr Handle) + { + try + { + m_Handle = Handle; + m_musicPath = Path.Combine(folder_path, "temp.mp3"); + FileStream fs = new FileStream(m_musicPath, FileMode.Create); + fs.Write(Music, 0, Music.Length); + fs.Close(); + } + catch (Exception) + { + } + } + /// + ///音频播放类 + /// + /// 要播放的音频位置 + /// 父窗口句柄 + public SoundPlay(String musicPath, IntPtr Handle) + { + m_musicPath = musicPath; + m_Handle = Handle; + } + /// + /// 音频播放类 + /// + /// + /// 父窗口句柄 + public SoundPlay(Byte[] Music, IntPtr Handle) : this(Music, @"C:\Windows\",Handle) + { + } + [DllImport("Kernel32", CharSet = CharSet.Auto)] + static extern Int32 GetShortPathName(String path, StringBuilder shortPath, Int32 shortPathLength); + /// + /// 播放音频 + /// + /// + public void Play(string path) + { + if(path != "" && System.IO.File.Exists(path)) + { + try + { + string ext = System.IO.Path.GetExtension(path).ToLower(); + if (ext == ".mp3") + { + StringBuilder shortpath = new StringBuilder(260); + int result = GetShortPathName(path, shortpath, shortpath.Capacity); + mciSendString(@"close all", null, 0, m_Handle); + mciSendString("open " + shortpath.ToString() + " alias song", null, 0, m_Handle); + mciSendString("play song", null, 0, m_Handle); + } + else if (ext == ".wav") + { + PlaySound(path, m_Handle,(uint)(SoundFlags.SND_FILENAME | SoundFlags.SND_SYNC | SoundFlags.SND_NOSTOP)); + + } + } + catch (Exception) + { + } + } + } + /// + /// 播放音频 + /// + public void Play() + { + Play(m_musicPath); + } + /// + /// 关闭音频 + /// + void CloseMedia() + { + try + { + mciSendString("Close ALL", null, 0, m_Handle); + } + catch (Exception) + { + } + } + } +} diff --git a/Source/MyDb/FileFuns/TxtFileEncoder.cs b/Source/MyDb/FileFuns/TxtFileEncoder.cs new file mode 100644 index 0000000..1952a2f --- /dev/null +++ b/Source/MyDb/FileFuns/TxtFileEncoder.cs @@ -0,0 +1,255 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace ryCommon +{ + /// + /// 用于取得一个文本文件的编码方式(Encoding)。 + /// + public class TxtFileEncoder + { + /// + /// 用于取得一个文本文件的编码方式(Encoding)。 + /// + public TxtFileEncoder() + { + // + // TODO: 在此处添加构造函数逻辑 + // + } + /// + /// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,Encoding.Default将被返回。 + /// + /// 文件名。 + /// + public static Encoding GetEncoding(string fileName) + { + return GetEncoding(fileName, Encoding.Default); + } + /// + /// 取得一个文本文件流的编码方式。 + /// + /// 文本文件流。 + /// + public static Encoding GetEncoding(FileStream stream) + { + return GetEncoding(stream, Encoding.Default); + } + /// + /// 取得一个文本文件的编码方式。 + /// + /// 文件名。 + /// 默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。 + /// + public static Encoding GetEncoding(string fileName, Encoding defaultEncoding) + { + Encoding targetEncoding = defaultEncoding; + try + { + FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); + try + { + targetEncoding = GetEncoding(fs, defaultEncoding); + } + catch { } + fs.Close(); + } + catch + { + return defaultEncoding; + } + return targetEncoding; + } + /// + /// 取得一个文本文件流的编码方式。 + /// + /// 文本文件流。 + /// 默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。 + /// + public static Encoding GetEncoding(FileStream stream, Encoding defaultEncoding) + { + Encoding targetEncoding = defaultEncoding; + if (stream != null && stream.Length >= 2) + { + //保存文件流的前4个字节 + byte byte1 = 0; + byte byte2 = 0; + byte byte3 = 0; + byte byte4 = 0; + //保存当前Seek位置 + long origPos = stream.Seek(0, SeekOrigin.Begin); + stream.Seek(0, SeekOrigin.Begin); + + int nByte = stream.ReadByte(); + byte1 = Convert.ToByte(nByte); + byte2 = Convert.ToByte(stream.ReadByte()); + if (stream.Length >= 3) + { + byte3 = Convert.ToByte(stream.ReadByte()); + } + if (stream.Length >= 4) + { + byte4 = Convert.ToByte(stream.ReadByte()); + } + //根据文件流的前4个字节判断Encoding + //Unicode {0xFF, 0xFE}; + //BE-Unicode {0xFE, 0xFF}; + //UTF8 = {0xEF, 0xBB, 0xBF}; + if (byte1 == 0xFE && byte2 == 0xFF)//UnicodeBe + { + targetEncoding = Encoding.BigEndianUnicode; + } + else if (byte1 == 0xFF && byte2 == 0xFE && byte3 != 0xFF)//Unicode + { + targetEncoding = Encoding.Unicode; + } + else if (byte1 == 0xEF && byte2 == 0xBB && byte3 == 0xBF)//UTF8 + { + targetEncoding = Encoding.UTF8; + } + else + { + int index =0; + byte[] bytes = new byte[100]; + stream.Seek(origPos, SeekOrigin.Begin); + while (stream.CanRead) + { + index++; if (index >= 100) { break; } + bytes[index - 1] = Convert.ToByte(stream.ReadByte()); + } + if (GetBytesEncoding(bytes)==Encoding.UTF8) { targetEncoding = Encoding.UTF8; } + } + //恢复Seek位置 + stream.Seek(origPos, SeekOrigin.Begin); + } + return targetEncoding; + } + + + + // 新增加一个方法,解决了不带BOM的 UTF8 编码问题 + + /// + /// 通过给定的文件流,判断文件的编码类型 + /// + /// 文件流 + /// 文件的编码类型 + public static System.Text.Encoding GetEncoding(Stream fs) + { + byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 }; + byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 }; + byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM + Encoding reVal = Encoding.Default; + + BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default); + byte[] ss = r.ReadBytes(4); + if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) + { + reVal = Encoding.BigEndianUnicode; + } + else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) + { + reVal = Encoding.Unicode; + } + else + { + if (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF) + { + reVal = Encoding.UTF8; + } + else + { + int.TryParse(fs.Length.ToString(), out int i); + ss = r.ReadBytes(i); + + if (GetBytesEncoding(ss)==Encoding.UTF8) + reVal = Encoding.UTF8; + } + } + r.Close(); + return reVal; + + } + private static Encoding GetBytesEncoding(byte[] bs) + { + int len = bs.Length; + if (len >= 3 && bs[0] == 0xEF && bs[1] == 0xBB && bs[2] == 0xBF) + { + return Encoding.UTF8; + } + int[] cs = { 7, 5, 4, 3, 2, 1, 0, 6, 14, 30, 62, 126 }; + for (int i = 0; i < len; i++) + { + int bits = -1; + for (int j = 0; j < 6; j++) + { + if (bs[i] >> cs[j] == cs[j + 6]) + { + bits = j; + break; + } + } + if (bits == -1) + { + return Encoding.Default; + } + while (bits-- > 0) + { + i++; + if (i == len || bs[i] >> 6 != 2) + { + return Encoding.Default; + } + } + } + return Encoding.UTF8; + } + /// + /// 判断是否是不带 BOM 的 UTF8 格式 + /// + /// + /// + private static bool IsUTF8Bytes(byte[] data) + { + int charByteCounter = 1;  //计算当前正分析的字符应还有的字节数 + byte curByte; //当前分析的字节. + for (int i = 0; i < data.Length; i++) + { + curByte = data[i]; + if (charByteCounter == 1) + { + if (curByte >= 0x80) + { + //判断当前 + while (((curByte <<= 1) & 0x80) != 0) + { + charByteCounter++; + } + //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X  + if (charByteCounter == 1 || charByteCounter > 6) + { + return false; + } + } + } + else + { + //若是UTF-8 此时第一位必须为1 + if ((curByte & 0xC0) != 0x80) + { + return false; + } + charByteCounter--; + } + } + if (charByteCounter > 1) + { + throw new Exception("非预期的byte格式!"); + } + return true; + } + } +} diff --git a/Source/MyDb/HardWare/Network.cs b/Source/MyDb/HardWare/Network.cs new file mode 100644 index 0000000..e9450d7 --- /dev/null +++ b/Source/MyDb/HardWare/Network.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Text; + +namespace RyHardWare +{ + /// + /// 网络操作类 + /// + public class Network + { + /// + /// 通过NetworkInterface读取网卡Mac + /// + /// + public static string GetMacs() + { + string macs = ""; + NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); + foreach (NetworkInterface ni in interfaces) + { + macs += ni.GetPhysicalAddress().ToString()+"|"; + } + return macs; + } + /// + /// 通过NetworkInterface读取网卡Mac + /// + /// + public static List GetMacByNetworkInterface() + { + List macs = new List(); + NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); + foreach (NetworkInterface ni in interfaces) + { + macs.Add(ni.GetPhysicalAddress().ToString()); + } + return macs; + } + /// + /// 根据mac字符串来获取最终的mac地址,可以是各种MAC地址格式,非法的内容将返回null + /// + /// + /// + public static byte[] GetMac(string _mac) + { + try + { + if (_mac.Length == 12) + { + #region 无任何分隔符的MAC地址 + byte[] mac = new byte[6]; + for (int z = 0; z < 6; z++) + { + mac[z] = + byte.Parse(_mac.Substring(z * 2, 2), + NumberStyles.HexNumber); + } + return mac; + #endregion + } + else if (_mac.Length == 17) + { + #region 带分隔符的MAC地址 + byte[] mac = new byte[6]; + for (int z = 0; z < 6; z++) + { + mac[z] = + byte.Parse(_mac.Substring(z * 3, 2), + NumberStyles.HexNumber); + } + return mac; + #endregion + } + else + { + return null; + } + } + catch + { + return null; + } + } + /// + /// 远程唤醒 + /// + /// + /// + /// + public static int WakeUp(string _ip, string _mac) + { + try + { + if (_ip == "127.0.0.1") + { + _ip = "192.168.1.1"; + } + byte[] mac = GetMac(_mac); + if (mac == null) + { + return -2; + } + IPAddress ipe = IPAddress.Parse(_ip); + UdpClient client = new UdpClient(); + byte[] ipbyte = ipe.GetAddressBytes(); + ipbyte[ipbyte.Length - 1] = 255; + IPAddress ip = new IPAddress(ipbyte); + client.Connect(ip, 7); + byte[] packet = new byte[17 * 6]; + + for (int i = 0; i < 6; i++) + packet[i] = 0xFF; + + for (int i = 1; i <= 16; i++) + for (int j = 0; j < 6; j++) + packet[i * 6 + j] = mac[j]; + + int result = client.Send(packet, packet.Length); + if (result != packet.Length) + { + return 0; + } + return 1; + } + catch { return -1; } + } + /// + /// 远程唤醒 + /// + /// + /// + /// + /// + public static int WakeUpByHostname(string _hostname,int port, string _mac) + { + try + { + byte[] mac = GetMac(_mac); + if (mac == null) + { + return -2; + } + UdpClient client = new UdpClient(); + client.Connect(_hostname, port); + byte[] packet = new byte[17 * 6]; + + for (int i = 0; i < 6; i++) + packet[i] = 0xFF; + + for (int i = 1; i <= 16; i++) + for (int j = 0; j < 6; j++) + packet[i * 6 + j] = mac[j]; + + int result = client.Send(packet, packet.Length); + if (result != packet.Length) + { + return 0; + } + return 1; + } + catch { return -1; } + } + } +} diff --git a/Source/MyDb/Msg/CustomMsg.cs b/Source/MyDb/Msg/CustomMsg.cs new file mode 100644 index 0000000..b5ff52e --- /dev/null +++ b/Source/MyDb/Msg/CustomMsg.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace QuickMsg +{ + /// + /// 消息服务器 + /// + public class CustomMsg + { + readonly IntPtr handle; + /// + /// 消息事件 + /// + /// + /// + public delegate void MsgEventHandler(object sender, MsgArgs e); + /// + /// 大小改变事件 + /// + /// + /// + /// + public delegate void SizeEventHandler(object sender, int Width,int Height); + /// + /// 即将关闭事件 + /// + /// + /// + public delegate void ClosingEventHandler(object sender, bool cancel); + private delegate IntPtr WndProcDelegate(IntPtr hwnd, int Msg, IntPtr wParam, IntPtr lParam); + private readonly WndProcDelegate wndProcDelegate; + [DllImport("User32.dll", CharSet= CharSet.Auto, SetLastError= true)] + private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, WndProcDelegate wndProcDelegate); + private readonly IntPtr oldWndFunc; + /// + /// 当收到消息时激发 + /// + public event MsgEventHandler OnMsg; + /// + /// 消息处理类 + /// + /// + public CustomMsg(Form _form) + { + handle = _form.Handle; + wndProcDelegate = new WndProcDelegate(WndProc); + oldWndFunc = SetWindowLong(handle, MyDb.RyWin32.GWL_WNDPROC, wndProcDelegate); + //System.Windows.Forms.Application.AddMessageFilter(this); + } + /// + /// + /// + ~CustomMsg() + { + MyDb.RyWin32.SetWindowLong(handle, MyDb.RyWin32.GWL_WNDPROC, oldWndFunc); + //System.Windows.Forms.Application.RemoveMessageFilter(this); + } + /// + /// + /// + /// + protected virtual void WndProc(ref System.Windows.Forms.Message msg) + { + DefWndProc(ref msg); + } + /// + /// + /// + /// + public void DefWndProc(ref System.Windows.Forms.Message m) + { + m.Result = MyDb.RyWin32.CallWindowProc(oldWndFunc, m.HWnd, m.Msg, m.WParam, m.LParam); + if (m.Msg == MyDb.RyWin32.WM_COPYDATA) + { + var msg = MyDb.RyWin32.GetMsg(m, out IntPtr handle); + MsgArgs msg_args2 = new MsgArgs + { + From_handle = handle, + WParam = m.WParam.ToInt32(), + Msg_text = msg + }; + Thread th = new Thread(delegate(){ Start(msg_args2); }); + th.Start(); + void Start(MsgArgs msg_args) + { + OnMsg?.Invoke(this, msg_args); + if (msg_args.Reply_Text != "") + { + Send(handle, msg_args.WParam, msg_args.Reply_Text); + } + } + } + } + private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam) + { + System.Windows.Forms.Message m = System.Windows.Forms.Message.Create(hWnd, msg, wParam, lParam); + WndProc(ref m); + return m.Result; + } + /// + /// 发送消息,采用单线程发送 + /// + /// 要发送到的句柄 + /// 编号 + /// 消息内容 + public int Send2(IntPtr to_handle,int wParam, string msg) + { + return MyDb.RyWin32.SendMsg(handle, to_handle, wParam, msg); + } + /// + /// 发送消息,采用多线程发送 + /// + /// 要发送到的句柄 + /// 编号 + /// 消息内容 + public void Send(IntPtr to_handle, int wParam, string msg) + { + Thread th = new Thread(delegate () { + MyDb.RyWin32.SendMsg(handle, to_handle, wParam, msg); + }); + th.Start(); + } + } + /// + /// 消息类 + /// + public class MsgArgs + { + /// + /// 是否取消 + /// + public bool Cancel { get; internal set; } = false; + /// + /// 来源句柄 + /// + public IntPtr From_handle { get; internal set; } = IntPtr.Zero; + /// + /// + /// + public int WParam {get; set;} = 0; + /// + /// 消息文本 + /// + public string Msg_text { get; internal set; } = ""; + /// + /// 需要回复的内容 + /// + public string Reply_Text { get; set; } = ""; + } +} diff --git a/Source/MyDb/Msg/MsgClient.cs b/Source/MyDb/Msg/MsgClient.cs new file mode 100644 index 0000000..892615d --- /dev/null +++ b/Source/MyDb/Msg/MsgClient.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace QuickMsg +{ + /// + /// 消息客户端类 + /// + public class MsgClient + { + readonly CustomMsg MSG; + /// + /// 判断当前消息主服务器是否创建成功 + /// + public bool IsOk + { + get; private set; + } + /// + /// 最后一次接收消息的时间,可用来判断服务端是否有响应 + /// + public DateTime Last_RecvTime { get; set; } = DateTime.Now.AddDays(-10); + /// + /// 主句柄 + /// + public IntPtr main_handle = IntPtr.Zero; + /// + /// 当收到消息时激发 + /// + public event CustomMsg.MsgEventHandler OnMsg; + /// + /// 连接上主服务器时触发 + /// + public event EventHandler OnConnected; + /// + /// 收到服务端关闭通知 + /// + public event EventHandler OnClose; + /// + /// 收到服务端关闭通知,即将关闭 + /// + public event CustomMsg.ClosingEventHandler OnClosing; + /// + /// 服务端大小改变时激发 + /// + public event CustomMsg.SizeEventHandler OnResize; + private readonly string client_id=""; + /// + /// 实例化客户端 + /// + /// 服务端ID + /// 当前客户端ID,会向服务器报告当前ID + /// 客户端 + public MsgClient(string main_id,string client_id, Form _form) + { + object mainHandle = RyMemoryShare.ReadFromMemory(1024, typeof(Int64), main_id); + this.client_id = client_id; + if (mainHandle == null) + { + IsOk = false; + } + else + { + main_handle = new IntPtr((Int64)mainHandle); + MSG = new CustomMsg(_form);//创建消息通道 + MSG.OnMsg += MSG_OnMsg; + ryCommon.Storage Stor = new ryCommon.Storage(); + Stor.SelectNodeBySet(); + Stor.SetAttrValue("op", "connect"); + Stor.SetAttrValue("clientid", client_id); + MSG.Send(main_handle, MyDb.RyWin32.Sys_chanel_id, "xml" + Stor.XMLText);//向服务端发起连接请求 + } + } + /// + /// + /// + ~MsgClient() + { + DisConnect(); + } + /// + /// 断开服务端连接 + /// + public void DisConnect() + { + if (IsOk) + MSG.Send(main_handle, MyDb.RyWin32.Sys_chanel_id, "disconnect");//向服务端发起断开连接请求 + IsOk = false; + } + /// + /// 发送消息,采用多线程发送 + /// + /// + /// + public void Send(int wParam, string msg) + { + MSG.Send(main_handle, wParam, msg);//发送消息 + } + /// + /// 向服务端发送心跳包 + /// + public void SendHeart() + { + MSG.Send2(main_handle, MyDb.RyWin32.Sys_chanel_id, "heart");//发送消息 + } + /// + /// 判断服务端句柄是否存在。 + /// + /// + public bool MainExist() + { + return MyDb.RyWin32.IsWindow(main_handle); + } + private void MSG_OnMsg(object sender, MsgArgs e) + { + Last_RecvTime = DateTime.Now; + OnMsg?.Invoke(this,e); + if (e.WParam == MyDb.RyWin32.Sys_chanel_id) //如果是系统通道请求 + { + switch (e.Msg_text) + { + case "connected"://与服务端连接成功 + IsOk = true; + OnConnected?.Invoke(this,new EventArgs()); + break; + case "close"://服务端关闭通知 + IsOk = false; + bool cancel = false; + OnClosing?.Invoke(this,cancel); + if (!cancel) + { + OnClose?.Invoke(this, new EventArgs()); + } + break; + default: + #region 如果是xml消息 + if (e.Msg_text.StartsWith("xml")) + { + ryCommon.Storage Stor = new ryCommon.Storage(e.Msg_text.Substring(3)); + Stor.SelectNodeBySet(); + switch (Stor.GetAttrValue("op")) + { + case "resize"://服务端大小改变 + OnResize?.Invoke(this, Stor.GetAttrValue("width", 0), Stor.GetAttrValue("height", 0)); + break; + } + } + break; + #endregion + } + } + } + } +} diff --git a/Source/MyDb/Msg/MsgMain.cs b/Source/MyDb/Msg/MsgMain.cs new file mode 100644 index 0000000..f9abbe9 --- /dev/null +++ b/Source/MyDb/Msg/MsgMain.cs @@ -0,0 +1,287 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace QuickMsg +{ + /// + /// 消息服务端类 + /// + public class MsgMain + { + readonly CustomMsg MSG; + /// + /// 判断当前消息主服务器是否创建成功 + /// + public bool IsOk + { + get;private set; + } + /// + /// 当收到消息时激发 + /// + public event CustomMsg.MsgEventHandler OnMsg; + /// + /// 当收到自定义消息时(非系统消息)激发 + /// + public event CustomMsg.MsgEventHandler OnCustomMsg; + /// + /// 有消息客户端发起连接请求时激发 + /// + public event CustomMsg.MsgEventHandler OnConnect; + /// + /// 有消息客户端连接成功时激发 + /// + public event CustomMsg.MsgEventHandler OnConnected; + /// + /// 有消息客户端断开连接时激发 + /// + public event CustomMsg.MsgEventHandler OnDisConnect; + + private readonly Form form=null; + /// + /// + /// + /// 服务端ID,需要唯一性,共客户端识别 + /// 服务端 + public MsgMain(string id,Form _form) + { + object mainHandle = RyMemoryShare.ReadFromMemory(1024, typeof(Int64), id); + if (mainHandle == null) + { + RyMemoryShare.WriteToMemory(1024, _form.Handle.ToInt64(), id); + form = _form; + MSG = new CustomMsg(_form);//创建消息通道 + MSG.OnMsg += MSG_OnMsg; + IsOk = true; + } + else { IsOk = false; } + } + /// + /// 释放资源 + /// + public void Free() + { + if(form!=null) + { + // RyMemoryShare.WriteToMemory(1024, form.Handle.ToInt64(), id); + } + } + /// + /// 判断是否包含指定客户端 + /// + /// + /// + public bool HaveClient(IntPtr handle) + { + bool isHave = false; + for (int i = 0; i < Client_list.Count; i++) + { + if (Client_list[i].Handle == handle) { isHave = true; break; } + } + return isHave; + } + /// + /// + /// + public List Client_list { get;private set; } = new List(); + /// + /// 设置客户端大小 + /// + public void Resize(int width,int height) + { + ryCommon.Storage Stor = new ryCommon.Storage(); + Stor.SelectNodeBySet(); + Stor.SetAttrValue("op", "resize"); + Stor.SetAttrValue("width", width); + Stor.SetAttrValue("height", height); + SendAll(MyDb.RyWin32.Sys_chanel_id, "xml"+Stor.XMLText); + } + /// + /// 根据客户端ID,获取客户端对象 + /// + /// + /// + public ClientItem GetClientItem(string ClientId) + { + for (int i = Client_list.Count - 1; i >= 0; i--) + { + if (Client_list[i].ClientId == ClientId) + { + return Client_list[i]; + } + } + return null; + } + /// + /// 根据客户端句柄,获取客户端对象 + /// + /// + /// + public ClientItem GetClientItem(IntPtr Handle) + { + for (int i = Client_list.Count - 1; i >= 0; i--) + { + if (Client_list[i].Handle == Handle) + { + return Client_list[i]; + } + } + return null; + } + /// + /// 关闭所有客户端 + /// + public void CloseClient() + { + SendAll(MyDb.RyWin32.Sys_chanel_id, "close"); + Client_list.Clear(); + } + /// + /// 关闭指定客户端 + /// + /// + public void CloseClient(IntPtr handle) + { + MSG.Send(handle, MyDb.RyWin32.Sys_chanel_id, "close"); + } + /// + /// 关闭指定客户端 + /// + /// + public void CloseClient(ClientItem item) + { + MSG.Send(item.Handle, MyDb.RyWin32.Sys_chanel_id, "close"); + for (int i = Client_list.Count-1; i >=0; i--) + { + if(Client_list[i].Handle== item.Handle) + { + Client_list.RemoveAt(i); + } + } + } + /// + /// 向所有客户端发送消息,单线程 + /// + /// + /// + public void SendAll(int wParam, string msg) + { + for (int i = 0; i < Client_list.Count; i++) + { + MSG.Send2(Client_list[i].Handle, wParam, msg);//发送消息 + } + } + /// + /// 向指定客户端发送消息 + /// + /// + /// + /// + public void Send(IntPtr handle, int wParam, string msg) + { + MSG.Send(handle, wParam, msg);//发送消息 + } + /// + /// 关闭在指定时间前失去响应的子客户端 + /// + /// + public void CloseLoseClient(DateTime dt) + { + for (int i = Client_list.Count - 1; i >= 0; i--) + { + if (Client_list[i].HeartTime<= dt) + { Client_list.RemoveAt(i); } + } + } + private void MSG_OnMsg(object sender, MsgArgs e) + { + OnMsg?.Invoke(this,e); + if(e.WParam== MyDb.RyWin32.Sys_chanel_id) //如果是系统通道请求 + { + switch(e.Msg_text) + { + case "disconnect"://断开连接 + #region 断开连接 + for (int i = Client_list.Count - 1; i >= 0; i--) + { + if (Client_list[i].Handle == e.From_handle) { Client_list.RemoveAt(i); break; } + } + OnDisConnect?.Invoke(this, e); + break; + #endregion + case "heart"://心跳包 + #region 更新心跳时间 + MSG.Send(e.From_handle, MyDb.RyWin32.Sys_chanel_id,"heart");//回应给客户端 + for (int i = Client_list.Count - 1; i >= 0; i--) + { + if (Client_list[i].Handle == e.From_handle) + { Client_list[i].HeartTime=DateTime.Now; break; } + } + break; + #endregion + default: + #region 如果是xml消息 + if (e.Msg_text.StartsWith("xml")) + { + ryCommon.Storage Stor = new ryCommon.Storage(e.Msg_text.Substring(3)); + Stor.SelectNodeBySet(); + switch (Stor.GetAttrValue("op")) + { + case "connect"://连接请求 + #region 连接请求 + OnConnect?.Invoke(this, e); + if (!e.Cancel)//如果允许连接 + { + bool isHave = false; + for (int i = 0; i < Client_list.Count; i++) + { + if (Client_list[i].Handle == e.From_handle) { Client_list[i].ConnectTime = DateTime.Now; isHave = true; break; } + } + if (!isHave) + { + Client_list.Add(new ClientItem() { Handle = e.From_handle, ClientId= Stor.GetAttrValue("clientid") });//加入到客户端列表里 + } + MSG.Send(e.From_handle, e.WParam, "connected");//发送连接成功的通知 + OnConnected?.Invoke(this, e); + } + break; + #endregion + } + } + break; + #endregion + } + } + else + { + OnCustomMsg?.Invoke(this, e); + } + } + } + /// + /// 客户端信息 + /// + public class ClientItem + { + /// + /// 客户端句柄 + /// + public IntPtr Handle { get; set; } = IntPtr.Zero; + /// + /// 客户端ID + /// + public string ClientId { get; set; } =""; + /// + /// 客户端连接时间 + /// + public DateTime ConnectTime { get; set; } = DateTime.Now; + /// + /// 心跳时间 + /// + public DateTime HeartTime { get; set; } = DateTime.Now; + + } +} diff --git a/Source/MyDb/Msg/RyMemoryShare.cs b/Source/MyDb/Msg/RyMemoryShare.cs new file mode 100644 index 0000000..baf6f54 --- /dev/null +++ b/Source/MyDb/Msg/RyMemoryShare.cs @@ -0,0 +1,224 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace QuickMsg +{ + /// + /// 共享内存 + /// + public class RyMemoryShare + { + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam); + + [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName); + + [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr OpenFileMapping(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName); + + [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap); + + [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] + private static extern bool UnmapViewOfFile(IntPtr pvBaseAddress); + + [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] + private static extern bool CloseHandle(IntPtr handle); + [DllImport("kernel32", EntryPoint = "GetLastError")] + private static extern int GetLastError(); + [DllImport("user32.dll", EntryPoint = "FindWindow")] + private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + [DllImport("User32.dll")] + private static extern bool PostMessage(IntPtr hWnd, uint uMsg, int wParam, int lParam); + const int ERROR_ALREADY_EXISTS = 183; + + const int FILE_MAP_COPY = 0x0001; + const int FILE_MAP_WRITE = 0x0002; + const int FILE_MAP_READ = 0x0004; + const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004; + + const int PAGE_READONLY = 0x02; + const int PAGE_READWRITE = 0x04; + const int PAGE_WRITECOPY = 0x08; + const int PAGE_EXECUTE = 0x10; + const int PAGE_EXECUTE_READ = 0x20; + const int PAGE_EXECUTE_READWRITE = 0x40; + + const int SEC_COMMIT = 0x8000000; + const int SEC_IMAGE = 0x1000000; + const int SEC_NOCACHE = 0x10000000; + const int SEC_RESERVE = 0x4000000; + const int INVALID_HANDLE_VALUE = -1; + /// + /// 写共享内存 + /// + /// 需要映射的文件的字节数量 + /// 映射对象(简单类型、结构体等) + /// 文件映射对象的名称 + /// + public static int WriteToMemory(uint structSize, Object obj, string fileName) + { + return WriteToMemory(structSize, obj, fileName, null, 0); + } + /// + /// 写共享内存 + /// + /// 需要映射的文件的字节数量 + /// 映射对象(简单类型、结构体等) + /// 文件映射对象的名称 + /// 发送消息的窗口句柄 + /// 发送消息 + /// + public static int WriteToMemory(uint structSize, Object obj, string fileName, string windowName, uint Msg) + { + IntPtr hShareMemoryHandle = IntPtr.Zero; + IntPtr hVoid = IntPtr.Zero; + + //判断参数的合法性 + if (structSize > 0 && fileName.Length > 0) + { + hShareMemoryHandle = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)structSize, fileName); + if (hShareMemoryHandle == IntPtr.Zero) + { + //创建共享内存失败,记log + // MessageBox.Show("创建共享内存失败" + publicInfo.GetLastError().ToString()); + return -2; + } + else + { + if (ERROR_ALREADY_EXISTS == GetLastError()) + { + //共享内存已经存在,记log + //MessageBox.Show("共享内存已经存在"); + return -3; + } + } + hVoid = MapViewOfFile(hShareMemoryHandle, FILE_MAP_WRITE, 0, 0, structSize); + if (hVoid == IntPtr.Zero) + { + CloseHandle(hShareMemoryHandle); + //文件映射失败,记log + //MessageBox.Show("文件映射失败"); + return -4; + } + Marshal.StructureToPtr(obj, hVoid, false); + //发送消息,通知接收 + if (windowName != null) + { + IntPtr handle = FindWindow(null, windowName.Trim()); + if (handle == IntPtr.Zero) + { + //查找窗口失败,记log + //MessageBox.Show("查找窗口失败"); + return -5; + } + else + { + if (PostMessage(handle, (uint)Msg, 0, 0)) + { + //发送消息成功 + //MessageBox.Show("写共享内存,通知发送消息成功"); + } + } + } + } + else + { + //参数不合法,记log + //MessageBox.Show("共享内存已经存在"); + return -1; + } + return 0; + } + /// + /// 读共享内存 + /// + /// 需要映射的文件的字节数量 + /// 类型 + /// 文件映射对象的名称 + /// 返回读到的映射对象 + public static Object ReadFromMemory(uint structSize, Type type, string fileName) + { + + IntPtr hMappingHandle = IntPtr.Zero; + IntPtr hVoid = IntPtr.Zero; + + hMappingHandle = OpenFileMapping((uint)FILE_MAP_READ, false, fileName); + if (hMappingHandle == IntPtr.Zero) + { + //打开共享内存失败,记log + //MessageBox.Show("打开共享内存失败:" + publicInfo.GetLastError().ToString()); + return null; + } + hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize); + if (hVoid == IntPtr.Zero) + { + //文件映射失败,记log + // MessageBox.Show("文件映射失败——读共享内存"); + return null; + } + + Object obj = Marshal.PtrToStructure(hVoid, type); + + if (hVoid != IntPtr.Zero) + { + UnmapViewOfFile(hVoid); + hVoid = IntPtr.Zero; + } + if (hMappingHandle != IntPtr.Zero) + { + CloseHandle(hMappingHandle); + hMappingHandle = IntPtr.Zero; + } + return obj; + } + /// + /// 读共享内存 + /// + /// 需要映射的文件的字节数量 + /// 类型 + /// 文件映射对象的名称 + /// 返回读到的映射字节数据 + public static byte[] ReadFromMemory2(uint structSize, Type type, string fileName) + { + + IntPtr hMappingHandle = IntPtr.Zero; + IntPtr hVoid = IntPtr.Zero; + + hMappingHandle = OpenFileMapping((uint)FILE_MAP_READ, false, fileName); + if (hMappingHandle == IntPtr.Zero) + { + //打开共享内存失败,记log + //MessageBox.Show("打开共享内存失败:" + publicInfo.GetLastError().ToString()); + return null; + } + hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize); + if (hVoid == IntPtr.Zero) + { + //文件映射失败,记log + //MessageBox.Show("文件映射失败——读共享内存"); + return null; + } + + //Object obj = Marshal.PtrToStructure(hVoid, type); + byte[] bytes = new byte[structSize]; + Marshal.Copy(hVoid, bytes, 0, bytes.Length); + + if (hVoid != IntPtr.Zero) + { + UnmapViewOfFile(hVoid); + hVoid = IntPtr.Zero; + } + if (hMappingHandle != IntPtr.Zero) + { + CloseHandle(hMappingHandle); + hMappingHandle = IntPtr.Zero; + } + return bytes; + } + } +} diff --git a/Source/MyDb/MyDb/DataProvider.cs b/Source/MyDb/MyDb/DataProvider.cs new file mode 100644 index 0000000..c5d4b12 --- /dev/null +++ b/Source/MyDb/MyDb/DataProvider.cs @@ -0,0 +1,172 @@ +using ryCommon; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; + +namespace ryCommonDb +{ + /// + /// 数据库引擎 + /// + public class DataProvider + { + /// + /// 数据库枚举类型 + /// + public enum DataProviderType + { + /// + /// Odbc引擎 + /// + OdbcDataProvider = 0, + /// + /// OleDb引擎 + /// + OleDbDataProvider = 1, + /// + /// Oracle引擎 + /// + OracleDataProvider = 2, + /// + /// MSSQL引擎 + /// + SqlDataProvider = 3, + /// + /// SQLite引擎 + /// + SQLiteDataProvider = 4, + /// + /// MySql引擎 + /// + MySqlDataProvider =5 + } + /// + /// 判断DataSet是否包含数据 + /// + /// + /// + public bool HaveData(DataSet ds) + { + if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) + { + return true; + } + return false; + } + /// + /// 获取首行数据 + /// + /// + /// + public DataRow GetData(DataSet ds) + { + if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) + { + return ds.Tables[0].Rows[0]; + } + return null; + } + /// + /// 获取第一行第一列的值 + /// + /// + /// + public int GetValue(DataSet ds) + { + if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) + { + return ds.Tables[0].Rows[0][0].ToInt(0); + } + return 0; + } + /// + /// 将DataSet类型转换为RyQuickSQL列表类型 + /// + /// + /// + public List GetInsert(System.Data.DataSet ds) + { + return GetInsert(ds,";id;"); + } + /// + /// 将DataSet类型转换为RyQuickSQL列表类型 + /// + /// + /// + /// + public List GetInsert(System.Data.DataSet ds,string no_insert_list) + { + List list = new List(); + if (HaveData(ds)) + { + for (int i = 0; i < ds.Tables[0].Rows.Count; i++) + { + RyQuickSQL mySQL = new RyQuickSQL(ds.Tables[0].TableName); + for (int m = 0; m < ds.Tables[0].Columns.Count; m++) + { + DataColumn col = ds.Tables[0].Columns[m]; + if (col.AutoIncrement) { continue; } + if((";"+no_insert_list.ToLower()+";").IndexOf(";"+ col.ColumnName.ToLower()+";")>=0) { continue; } + #region 转换 + if (col.DataType == typeof(string)) + { + mySQL.AddField(col.ColumnName, ds.Tables[0].Rows[i][col].ToString()); + } + else if (col.DataType == typeof(int) || col.DataType == typeof(Int32)) + { + mySQL.AddField(col.ColumnName, ds.Tables[0].Rows[i][col].ToInt(0)); + } + else if (col.DataType == typeof(Int64)) + { + mySQL.AddField(col.ColumnName, ds.Tables[0].Rows[i][col].ToInt64(0)); + } + else if (col.DataType == typeof(decimal)) + { + mySQL.AddField(col.ColumnName, ds.Tables[0].Rows[i][col].ToDecimal(0)); + } + else if (col.DataType == typeof(DateTime)) + { + mySQL.AddField(col.ColumnName, ds.Tables[0].Rows[i][col].ToDateTime(Convert.ToDateTime("2000-1-1"))); + } + else if (col.DataType == typeof(double)) + { + mySQL.AddField(col.ColumnName, ds.Tables[0].Rows[i][col].ToDouble(0)); + } + else if (col.DataType == typeof(bool)) + { + mySQL.AddField(col.ColumnName, ds.Tables[0].Rows[i][col].ToBool()); + } + #endregion + } + list.Add(mySQL); + } + } + return list; + } + ///// + ///// 建立访问数据库的实例 + ///// + ///// 数据库枚举类型 + ///// + //public IDbInterface CreateDataProvider(DataProviderType dataProviderType) + //{ + // switch (dataProviderType) + // { + // //case DataProviderType.OdbcDataProvider: + // // return new OdbcDataProvider(); + // //case DataProviderType.OleDbDataProvider: + // // return new OleDbDataProvider(); + // //case DataProviderType.OracleDataProvider: + // // return new OracleDataProvider(); + // case DataProviderType.SqlDataProvider: + // return new SqlDataProvider(); + // case DataProviderType.SQLiteDataProvider: + // return new SQLiteDataProvider(); + // default: + // return null; + // } + //} + } +} diff --git a/Source/MyDb/MyDb/DbInterface.cs b/Source/MyDb/MyDb/DbInterface.cs new file mode 100644 index 0000000..2a03c8c --- /dev/null +++ b/Source/MyDb/MyDb/DbInterface.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ryCommonDb +{ + /// + /// 数据库操作接口 + /// + public interface IDbInterface + { + /// + /// 连接数据库 + /// + /// + int ConnDb(string sql); + /// + /// 断开数据库 + /// + /// + int CloseDb(); + /// + /// 获取数量 + /// + /// + /// + /// + int GetCount(string tableName, string wheresql); + /// + /// 获取分页语句 + /// + /// + /// + /// + /// + string GetPageSQL(string tableName, string wheresql, string orderSQL); + /// + /// 获取分页语句 + /// + /// + /// + /// + /// + string GetPageSQL2(string tableName, string wheresql, string orderSQL); + /// + /// 获取分页语句 + /// + /// + /// + /// + /// + /// + string GetPageSQL(string field, string tableName, string wheresql, string orderSQL); + /// + /// 获取分页语句 + /// + /// + /// + /// + /// + /// + string GetPageSQL2(string field, string tableName, string wheresql, string orderSQL); + /// + /// 添加Parameter参数 + /// + /// + /// + void AddParameter(string name, object value); + /// + /// 清空Parameter参数 + /// + /// + /// + void ClearParameter(object name, object value); + /// + /// 获取Parameter值 + /// + /// + object[] GetParameter(); + /// + /// 根据RyQuickSQL类来获取Parameter值 + /// + /// + /// + object[] GetParameter(RyQuickSQL mySQL); + /// + /// 开始执行事务 + /// + void BeginTransaction(); + /// + /// 提交事务 + /// + void Commit(); + /// + /// 判断是否包含数据 + /// + /// + /// + /// + bool ContainsData(string sql, object[] Parameter); + /// + /// 返回-1000表示该数据库不支持本接口 + /// + /// + /// + int ChangePwd(string newPwd); + /// + /// 读取数据 + /// + /// + /// + System.Data.DataSet ReadData(string sql); + /// + /// 读取数据 + /// + /// + /// + /// + System.Data.DataSet ReadData(string sql, object[] Parameter); + /// + /// 读取数据 + /// + /// + /// + /// + System.Data.DataSet ReadData(string sql, RyQuickSQL mySQL); + /// + /// 根据id号获取数据 + /// + /// + /// + /// + System.Data.DataSet ReadData(string tableName, string id); + /// + /// 执行SQL语句 + /// + /// + /// + /// + int ExecuteNonQuery(string sql, object[] Parameter); + /// + /// 执行SQL语句 + /// + /// + /// + /// + int ExecuteNonQuery(string sql, RyQuickSQL mySQL); + /// + /// 执行SQL语句 + /// + /// + /// + int ExecuteNonQuery(string sql); + /// + /// 根据id号删除数据 + /// + /// + /// + /// + int DelById(string tableName, string id); + /// + /// 创建数据库 + /// + /// + /// + int CreateDb(RyQuickSQL mySQL); + /// + /// 释放资源 + /// + void Free(); + } +} diff --git a/Source/MyDb/MyDb/ryQuickSQL.cs b/Source/MyDb/MyDb/ryQuickSQL.cs new file mode 100644 index 0000000..f47036c --- /dev/null +++ b/Source/MyDb/MyDb/ryQuickSQL.cs @@ -0,0 +1,336 @@ +using System; +using System.Collections.Generic; + +namespace ryCommonDb +{ + /// + /// SQL字段类型 + /// + public class SQLIitem + { + /// + /// SQL字段类型 + /// + /// + /// + public SQLIitem(string _field,object _value) + { + Field = _field; + value = _value; + len = 0; + } + /// + /// SQL字段类型 + /// + /// + /// + /// + public SQLIitem(string _field, object _value,int _len) + { + Field = _field; + value = _value; + len = _len; + } + /// + /// SQL字段名 + /// + public string Field = ""; + /// + /// SQL字段值 + /// + public object value; + /// + /// SQL字段长度 + /// + public int len = 0; + /// + /// 不是真的值,而是用于计算的值 + /// + public bool isNoValue = false; + } + /// + /// SQL快速操作类 + /// + public class RyQuickSQL + { + /// + /// SQL快速操作类 + /// + /// + public RyQuickSQL(string _tableName) + { TableName = _tableName; } + /// + /// 表名 + /// + public string TableName{get;set;} + /// + /// 操作字段列表 + /// + public List List { get; } = new List(); + /// + /// 清理使用资源 + /// + public void Free() + { + Clear(); + } + /// + /// 清理使用资源 + /// + public void Dispose() + { + Free(); + } + /// + /// 操作参数列表 + /// + public List List_param { get; } = new List(); + /// + /// 操作参数列表 + /// + private List List_Nullparam { get; } = new List(); + private void ListAdd(SQLIitem item) + { + if(!List.Contains(item)) + List.Add(item); + } + /// + /// 添加字符串字段 + /// + /// + /// + public void AddField(string field,string value) + { + ListAdd(new SQLIitem(field, value)); + } + /// + /// 添加null值字段 + /// + /// + public void AddNullField(string field) + { + if (!List_Nullparam.Contains(field)) + List_Nullparam.Add(field); + } + /// + /// 添加日期字段 + /// + /// + /// + public void AddField(string field, DateTime value) + { + ListAdd(new SQLIitem(field, value)); + } + /// + /// 添加int字段 + /// + /// + /// + public void AddField(string field, int value) + { + ListAdd(new SQLIitem(field, value)); + } + /// + /// 添加double字段 + /// + /// + /// + public void AddField(string field, double value) + { + ListAdd(new SQLIitem(field, value)); + } + /// + /// 添加decimal字段 + /// + /// + /// + public void AddField(string field, decimal value) + { + ListAdd(new SQLIitem(field, value)); + } + /// + /// 添加bool字段 + /// + /// + /// + public void AddField(string field, bool value) + { + ListAdd(new SQLIitem(field, value)); + } + /// + /// 添加用于计算的值 + /// + /// + /// + public void AddFieldCalc(string field, string value) + { + List_calcparam.Add(new SQLIitem(field, value) { isNoValue=true }); + } + /// + /// 添加Int64字段 + /// + /// + /// + public void AddField(string field, Int64 value) + { + ListAdd(new SQLIitem(field, value)); + } + /// + /// 清空内容 + /// + public void Clear() + { + List.Clear(); + List_param.Clear(); + List_calcparam.Clear(); + List_Nullparam.Clear(); + } + /// + /// 数量 + /// + public int Count + { + get { return List.Count + List_param.Count; } + } + /// + /// + /// + public List List_calcparam { get; set; } = new List(); + + /// + /// 输出多条件搜索。 + /// + /// 字段名,多个字段请用逗号分隔。 + /// 多个条件之间请用空格隔开 + /// + public string GetSearchSQL(string Fields, string SearchText) + { + string tmpSQL = ""; + string tmpFieldSQL = "("; + string[] m_name = Fields.Split(",,".ToCharArray()); + string[] tmpFieldNames = new string[m_name.Length]; + for (int i = 0; i < m_name.Length; i++) + { + #region 提取字段信息 + tmpFieldNames[i] = m_name[i]; + if (i == 0) + { + tmpFieldSQL += tmpFieldNames[i] + " like @SearchText"; + } + else + { + tmpFieldSQL += " or " + tmpFieldNames[i] + " like @SearchText"; + } + #endregion + } + tmpFieldSQL += ")"; + string[] m_SearchText = SearchText.Split(' '); + string tmpSearchSQL = ""; + for (int i = 0; i < m_SearchText.Length; i++) + { + if (i == 0) + { + tmpSearchSQL = tmpFieldSQL.Replace("@SearchText", "@st_ry" + i.ToString()); + } + else + { + tmpSearchSQL += " and " + tmpFieldSQL.Replace("@SearchText", "@st_ry" + i.ToString()); + } + AddParameter("@st_ry" + i.ToString(), "%" + m_SearchText[i] + "%"); + } + return tmpSQL + tmpSearchSQL; + } + /// + /// 获取插入SQL语句 + /// + /// + public string GetInsertSQL() + { + string tmpSQL = "insert into " + TableName + " "; + string tmpFieldSQL = "("; + string valueSQL = "("; + for (int i = 0; i + /// 获取更新SQL语句 + /// + /// + public string GetUpdateSQL() + { + string tmpSQL = "update " + TableName + " set "; + for (int i = 0; i < List.Count; i++) + { + SQLIitem item = (SQLIitem)List[i]; + tmpSQL += item.Field + "=" + "@" + item.Field.TrimStart('[').TrimEnd(']') + ","; + } + for (int i = 0; i < List_calcparam.Count; i++) + { + SQLIitem item = (SQLIitem)List_calcparam[i]; + tmpSQL += item.Field + "=" + item.value + ","; + } + for (int i = 0; i < List_Nullparam.Count; i++) + { + tmpSQL += List_Nullparam[i] + "=" + "null,"; + } + return tmpSQL.Substring(0, tmpSQL.Length - 1); + } + /// + /// 添加参数 + /// + /// + /// + public void AddParameter(string name,object value) + { + List_param.Add(new SQLIitem(name.TrimStart('@'), value)); + } + /// + /// 获取Ole参数 + /// + /// + public System.Data.OleDb.OleDbParameter[] GetOleParameters() + { + System.Data.OleDb.OleDbParameter[] defPar = new System.Data.OleDb.OleDbParameter[List.Count+ List_param.Count]; + for (int i = 0; i < List.Count; i++) + { + SQLIitem item = (SQLIitem)List[i]; + defPar[i] =new System.Data.OleDb.OleDbParameter("@"+item.Field, item.value); + } + for (int i = List.Count; i < List.Count + List_param.Count; i++) + { + SQLIitem item = (SQLIitem)List_param[i- List.Count]; + defPar[i] = new System.Data.OleDb.OleDbParameter("@" + item.Field.TrimStart('@'), item.value); + } + return defPar; + } + /// + /// 获取SQL参数 + /// + /// + public System.Data.SqlClient.SqlParameter[] GetSqlParameter() + { + System.Data.SqlClient.SqlParameter[] defPar = new System.Data.SqlClient.SqlParameter[List.Count + List_param.Count]; + for (int i = 0; i < List.Count; i++) + { + SQLIitem item = (SQLIitem)List[i]; + defPar[i] = new System.Data.SqlClient.SqlParameter("@" + item.Field, item.value); + } + for (int i = List.Count; i < List.Count + List_param.Count; i++) + { + SQLIitem item = (SQLIitem)List_param[i - List.Count]; + defPar[i] = new System.Data.SqlClient.SqlParameter("@" + item.Field.TrimStart('@'), item.value); + } + return defPar; + } + } +} diff --git a/Source/MyDb/MyDbV35.csproj b/Source/MyDb/MyDbV35.csproj new file mode 100644 index 0000000..0e6fcd3 --- /dev/null +++ b/Source/MyDb/MyDbV35.csproj @@ -0,0 +1,79 @@ + + + + + Debug + AnyCPU + {B0F80073-D661-42D8-A512-8488D980B87E} + Library + Properties + MyDb + MyDb + v3.5 + 512 + + + true + full + false + ..\输出dll\.NET3.5\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\输出dll\.NET3.5\Release\ + TRACE + prompt + 4 + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/MyDb/MyDbV4.csproj b/Source/MyDb/MyDbV4.csproj new file mode 100644 index 0000000..bb6c39b --- /dev/null +++ b/Source/MyDb/MyDbV4.csproj @@ -0,0 +1,111 @@ + + + + + Debug + AnyCPU + {9DF20D86-A56E-4CF6-A3D8-F30421297B1B} + Library + Properties + MyDb + MyDb + v4.0 + 512 + + + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\..\Bin\Release\CommonControls\.NET4\ + TRACE + prompt + 4 + ..\..\Bin\Release\CommonControls\.NET4\MyDb.xml + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/MyDb/MyDbV4.csproj.user b/Source/MyDb/MyDbV4.csproj.user new file mode 100644 index 0000000..5283ef1 --- /dev/null +++ b/Source/MyDb/MyDbV4.csproj.user @@ -0,0 +1,6 @@ + + + + ShowAllFiles + + \ No newline at end of file diff --git a/Source/MyDb/Properties/AssemblyInfo.cs b/Source/MyDb/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8a1ac78 --- /dev/null +++ b/Source/MyDb/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("MyDb")] +[assembly: AssemblyDescription("基于乘黄V1架构")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("睿元网络工作室")] +[assembly: AssemblyProduct("MyDb")] +[assembly: AssemblyCopyright("Copyright © 2010-2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +//将 ComVisible 设置为 false 将使此程序集中的类型 +//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("9df20d86-a56e-4cf6-a3d8-f30421297b1b")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.1.2011.0901")] +[assembly: AssemblyFileVersion("2.1.2011.0901")] \ No newline at end of file diff --git a/Source/MyDb/SafeCheck/AES.cs b/Source/MyDb/SafeCheck/AES.cs new file mode 100644 index 0000000..8644e4e --- /dev/null +++ b/Source/MyDb/SafeCheck/AES.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Security.Cryptography; +using System.IO; +namespace rySafe +{ + /// + /// AES加密解密类 + /// + public class AES + { + //默认密钥向量 + private static readonly byte[] _key1 = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; + /// + /// AES加密算法 + /// + /// 明文字符串 + /// 密钥 + /// 返回加密后的密文字节数组 + public static byte[] AESEncrypt(string plainText, string strKey) + { + //分组加密算法 + SymmetricAlgorithm des = Rijndael.Create(); + byte[] inputByteArray = Encoding.UTF8.GetBytes(plainText);//得到需要加密的字节数组 + //设置密钥及密钥向量 + des.Key = Encoding.UTF8.GetBytes(strKey); + des.IV = _key1; + MemoryStream ms = new MemoryStream(); + CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); + cs.Write(inputByteArray, 0, inputByteArray.Length); + cs.FlushFinalBlock(); + byte[] cipherBytes = ms.ToArray();//得到加密后的字节数组 + cs.Close(); + ms.Close(); + return cipherBytes; + } + + /// + /// AES解密 + /// + /// 密文字节数组 + /// 密钥 + /// 返回解密后的字符串 + public static byte[] AESDecrypt(byte[] cipherText, string strKey) + { + SymmetricAlgorithm des = Rijndael.Create(); + des.Key = Encoding.UTF8.GetBytes(strKey); + des.IV = _key1; + byte[] decryptBytes = new byte[cipherText.Length]; + MemoryStream ms = new MemoryStream(cipherText); + CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read); + cs.Read(decryptBytes, 0, decryptBytes.Length); + cs.Close(); + ms.Close(); + return decryptBytes; + } + /// + /// 加密 + /// + /// + /// + /// + public static string Encode(string data,string pass) + { + byte[] encryptBytes = AESEncrypt(data, ConvertKey(pass)); + return Convert.ToBase64String(encryptBytes); + //将加密后的密文转换为Base64编码,以便显示,可以查看下结果 + } + /// + /// 解码 + /// + /// + /// + /// + public static string Decode(string data, string pass) + { + try + { + //解密 + byte[] decryptBytes = AESDecrypt(Convert.FromBase64String(data), ConvertKey(pass)); + //将解密后的结果转换为字符串,也可以将该步骤封装在解密算法中 + string result = Encoding.UTF8.GetString(decryptBytes); + return result.Replace("\0", ""); + } + catch + { + return ""; + } + } + /// + /// 转换密钥到合法密钥 + /// + /// + /// + public static string ConvertKey(string pass) + { + string sxStr = MD5Sha1.GetMD5(pass); + if (sxStr.Length > 32) + { + return sxStr.Substring(0, 32); + } + else + { + return (sxStr + sxStr).Substring(0, 32); + } + } + } +} diff --git a/Source/MyDb/SafeCheck/Base64.cs b/Source/MyDb/SafeCheck/Base64.cs new file mode 100644 index 0000000..9625846 --- /dev/null +++ b/Source/MyDb/SafeCheck/Base64.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Text; +//字符串编码 +namespace rySafe +{ + /// + /// Base64编码类 + /// + public class Base64 + { + /// + /// 编码 + /// + /// + /// + public static string Encode(string Message) + { + return Encode(Message, System.Text.Encoding.Default); + } + /// + /// 把字符串编码成Base64字符串 + /// + /// + /// + /// + public static string Encode(string Message, Encoding encoding) + { + char[] Base64Code = new char[] + { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', '=' + }; + byte empty = (byte)0; + System.Collections.ArrayList byteMessage = new + System.Collections.ArrayList(encoding.GetBytes + (Message)); + System.Text.StringBuilder outmessage; + int messageLen = byteMessage.Count; + int page = messageLen / 3; + int use = 0; + if ((use = messageLen % 3) > 0) + { + for (int i = 0; i < 3 - use; i++) + byteMessage.Add(empty); + page++; + } + outmessage = new System.Text.StringBuilder(page * 4); + for (int i = 0; i < page; i++) + { + byte[] instr = new byte[3]; + instr[0] = (byte)byteMessage[i * 3]; + instr[1] = (byte)byteMessage[i * 3 + 1]; + instr[2] = (byte)byteMessage[i * 3 + 2]; + int[] outstr = new int[4]; + outstr[0] = instr[0] >> 2; + outstr[1] = ((instr[0] & 0x03) << 4) ^ (instr[1] >> 4); + if (!instr[1].Equals(empty)) + outstr[2] = ((instr[1] & 0x0f) << 2) ^ (instr[2] >> 6); + else + outstr[2] = 64; + if (!instr[2].Equals(empty)) + outstr[3] = (instr[2] & 0x3f); + else + outstr[3] = 64; + outmessage.Append(Base64Code[outstr[0]]); + outmessage.Append(Base64Code[outstr[1]]); + outmessage.Append(Base64Code[outstr[2]]); + outmessage.Append(Base64Code[outstr[3]]); + } + return outmessage.ToString(); + } + /// + /// 解码 + /// + /// + /// + public static string Decode(string Message) + { + string Base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + int page = Message.Length / 4; + System.Collections.ArrayList outMessage = new System.Collections.ArrayList(page * 3); + char[] message = Message.ToCharArray(); + for (int i = 0; i < page; i++) + { + byte[] instr = new byte[4]; + instr[0] = (byte)Base64Code.IndexOf(message[i * 4]); + instr[1] = (byte)Base64Code.IndexOf(message[i * 4 + 1]); + instr[2] = (byte)Base64Code.IndexOf(message[i * 4 + 2]); + instr[3] = (byte)Base64Code.IndexOf(message[i * 4 + 3]); + byte[] outstr = new byte[3]; + outstr[0] = (byte)((instr[0] << 2) ^ ((instr[1] & 0x30) >> 4)); + if (instr[2] != 64) + { + outstr[1] = (byte)((instr[1] << 4) ^ ((instr[2] & 0x3c) >> 2)); + } + else + { + outstr[2] = 0; + } + if (instr[3] != 64) + { + outstr[2] = (byte)((instr[2] << 6) ^ instr[3]); + } + else + { + outstr[2] = 0; + } + outMessage.Add(outstr[0]); + if (outstr[1] != 0) + outMessage.Add(outstr[1]); + if (outstr[2] != 0) + outMessage.Add(outstr[2]); + } + byte[] outbyte = (byte[])outMessage.ToArray(Type.GetType("System.Byte")); + return System.Text.Encoding.Default.GetString(outbyte); + } + } + +} diff --git a/Source/MyDb/SafeCheck/MD5Sha1.cs b/Source/MyDb/SafeCheck/MD5Sha1.cs new file mode 100644 index 0000000..3e9a6f5 --- /dev/null +++ b/Source/MyDb/SafeCheck/MD5Sha1.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; +namespace rySafe +{ + /// + /// MD5和SHA1操作类 + /// + public class MD5Sha1 + { + /// + /// 获取MD5 + /// + /// + /// + public static string GetMD5(string str) + { + StringBuilder sb = new StringBuilder(); + foreach (byte b in System.Security.Cryptography.MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(str))) + { + sb.Append(b.ToString("X2")); + } + return sb.ToString().Trim(); + } + /// + /// 获取MD5 + /// + /// + /// + public static string GetMD5(byte[] str) + { + StringBuilder sb = new StringBuilder(); + foreach (byte b in System.Security.Cryptography.MD5.Create().ComputeHash(str)) + { + sb.Append(b.ToString("X2")); + } + return sb.ToString().Trim(); + } + /// + /// 获取SHA1 + /// + /// + /// + public static string GetSHA1(string str) + { + StringBuilder sb = new StringBuilder(); + foreach (byte b in System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(str))) + { + sb.Append(b.ToString("X2")); + } + return sb.ToString(); + } + /// + /// 获取SHA1 + /// + /// + /// + public static string GetSHA1(byte[] str) + { + StringBuilder sb = new StringBuilder(); + foreach (byte b in System.Security.Cryptography.SHA1.Create().ComputeHash(str)) + { + sb.Append(b.ToString("X2")); + } + return sb.ToString(); + } + /// + /// 获取HmacSHA1 + /// + /// + /// + /// + public static string GetSHA1(string data, string pwd) + { + var myHMACSHA = new HMACSHA1(Encoding.UTF8.GetBytes(pwd)); + byte[] hash = myHMACSHA.ComputeHash(Encoding.UTF8.GetBytes(data)); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < hash.Length; i++) + { + builder.Append(hash[i].ToString("X2")); + } + return builder.ToString(); + } + /// + /// 获取SHA256 + /// + /// + /// + public static string GetSHA256(string data) + { + byte[] bytes = Encoding.UTF8.GetBytes(data); + byte[] hash = SHA256Managed.Create().ComputeHash(bytes); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < hash.Length; i++) + { + builder.Append(hash[i].ToString("X2")); + } + return builder.ToString(); + } + /// + /// 获取HmacSHA256 + /// + /// + /// + public static string GetSHA256(string data, string pwd) + { + var myHMACSHA = new HMACSHA256(Encoding.UTF8.GetBytes(pwd)); + byte[] hash = myHMACSHA.ComputeHash(Encoding.UTF8.GetBytes(data)); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < hash.Length; i++) + { + builder.Append(hash[i].ToString("X2")); + } + return builder.ToString(); + } + /// + /// 获取SHA224 + /// + /// + /// + public string GetSHA224(string str) + { + SHA256 sha = new SHA256Managed(); // 用来计算 SHA256 哈希值 + UTF8Encoding uen = new UTF8Encoding(); // 用来把char[]转换成byte[] + byte[] bytestr = uen.GetBytes(str.ToCharArray()); + sha.ComputeHash(bytestr); // 计算哈希值 + String sha224 = ""; + for (int i = 0; i < 28; ++i) + { + int dec = int.Parse(sha.Hash.GetValue(i).ToString()); // 十进制 + String bin = Convert.ToString(dec, 2).PadLeft(8, '0'); // 转成二进制数,是8位的,不足8位前面补0 + sha224 += bin; + } + return sha224; + } + /// + /// 获取SHA512 + /// + /// + /// + public static string GetSHA512(string data) + { + byte[] bytes = Encoding.UTF8.GetBytes(data); + byte[] hash = SHA512.Create().ComputeHash(bytes); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < hash.Length; i++) + { + builder.Append(hash[i].ToString("X2")); + } + return builder.ToString(); + } + /// + /// 获取HmacSHA512 + /// + /// + /// + /// + public static string GetSHA512(string data, string pwd) + { + var myHMACSHA = new HMACSHA512(Encoding.UTF8.GetBytes(pwd)); + byte[] hash = myHMACSHA.ComputeHash(Encoding.UTF8.GetBytes(data)); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < hash.Length; i++) + { + builder.Append(hash[i].ToString("X2")); + } + return builder.ToString(); + } + } +} diff --git a/Source/MyDb/SafeCheck/UsingLock.cs b/Source/MyDb/SafeCheck/UsingLock.cs new file mode 100644 index 0000000..004330e --- /dev/null +++ b/Source/MyDb/SafeCheck/UsingLock.cs @@ -0,0 +1,165 @@ +using System; +using System.Threading; + +namespace rySafe +{ + + /// 使用using代替lock操作的对象,可指定写入和读取锁定模式 + /// + public class UsingLock + { + #region 内部类 + + /// 利用IDisposable的using语法糖方便的释放锁定操作 + /// 内部类 + /// + private struct Lock : IDisposable + { + /// 读写锁对象 + /// + private ReaderWriterLockSlim _Lock; + /// 是否为写入模式 + /// + private readonly bool _IsWrite; + /// 利用IDisposable的using语法糖方便的释放锁定操作 + /// 构造函数 + /// + /// 读写锁 + /// 写入模式为true,读取模式为false + public Lock(ReaderWriterLockSlim rwl, bool isWrite) + { + _Lock = rwl; + _IsWrite = isWrite; + } + /// 释放对象时退出指定锁定模式 + /// + public void Dispose() + { + if (_IsWrite) + { + if (_Lock.IsWriteLockHeld) + { + _Lock.ExitWriteLock(); + } + } + else + { + if (_Lock.IsReadLockHeld) + { + _Lock.ExitReadLock(); + } + } + } + } + + /// 空的可释放对象,免去了调用时需要判断是否为null的问题 + /// 内部类 + /// + private class Disposable : IDisposable + { + /// 空的可释放对象 + /// + public static readonly Disposable Empty = new Disposable(); + /// 空的释放方法 + /// + public void Dispose() { } + } + + #endregion + + /// 读写锁 + /// + private ReaderWriterLockSlim _LockSlim = new ReaderWriterLockSlim(); + + /// 保存数据 + /// + private T _Data; + + /// 使用using代替lock操作的对象,可指定写入和读取锁定模式 + /// 构造函数 + /// + public UsingLock() + { + Enabled = true; + } + + /// 使用using代替lock操作的对象,可指定写入和读取锁定模式 + /// 构造函数 + /// 为Data属性设置初始值 + /// + public UsingLock(T data) + { + Enabled = true; + _Data = data; + } + + /// 获取或设置当前对象中保存数据的值 + /// + /// 获取数据时未进入读取或写入锁定模式 + /// 设置数据时未进入写入锁定模式 + public T Data + { + get + { + if (_LockSlim.IsReadLockHeld || _LockSlim.IsWriteLockHeld) + { + return _Data; + } + throw new MemberAccessException("请先进入读取或写入锁定模式再进行操作"); + } + set + { + if (_LockSlim.IsWriteLockHeld == false) + { + throw new MemberAccessException("只有写入模式中才能改变Data的值"); + } + _Data = value; + } + } + + /// 是否启用,当该值为false时,Read()和Write()方法将返回 Disposable.Empty + /// + public bool Enabled { get; set; } + + /// 进入读取锁定模式,该模式下允许多个读操作同时进行 + /// 退出读锁请将返回对象释放,建议使用using语块 + /// Enabled为false时,返回Disposable.Empty; + /// 在读取或写入锁定模式下重复执行,返回Disposable.Empty; + /// + public IDisposable Read() + { + if (Enabled == false || _LockSlim.IsReadLockHeld || _LockSlim.IsWriteLockHeld) + { + return Disposable.Empty; + } + else + { + _LockSlim.EnterReadLock(); + return new Lock(_LockSlim, false); + } + } + + /// 进入写入锁定模式,该模式下只允许同时执行一个读操作 + /// 退出读锁请将返回对象释放,建议使用using语块 + /// Enabled为false时,返回Disposable.Empty; + /// 在写入锁定模式下重复执行,返回Disposable.Empty; + /// + /// 读取模式下不能进入写入锁定状态 + public IDisposable Write() + { + if (Enabled == false || _LockSlim.IsWriteLockHeld) + { + return Disposable.Empty; + } + else if (_LockSlim.IsReadLockHeld) + { + throw new NotImplementedException("读取模式下不能进入写入锁定状态"); + } + else + { + _LockSlim.EnterWriteLock(); + return new Lock(_LockSlim, true); + } + } + } +} \ No newline at end of file diff --git a/Source/MyDb/SysFuns/ChinaDate.cs b/Source/MyDb/SysFuns/ChinaDate.cs new file mode 100644 index 0000000..f0d5000 --- /dev/null +++ b/Source/MyDb/SysFuns/ChinaDate.cs @@ -0,0 +1,1816 @@ +using System.Globalization; +using System.Collections; +using System; +using System.Collections.Generic; +using ryCommon; + +/// +/// 中国农历类,最大支持公元0-9999年 +/// +/// 日期:2019-02-09 +/// 作者:http://www.cnblogs.com/zjfree/ +public static class ChinaDate +{ + /// + /// 日历类型 + /// + public enum TCalendarType + { + /// + /// 无效 + /// + ctinvalid, + /// + /// Julian 日历 + /// + ctJulian, + /// + /// Gregorian 日历 + /// + ctGregorian, + /// + /// 有效 + /// + ctInvalid + } + private static ChineseLunisolarCalendar china = new ChineseLunisolarCalendar(); + /// + /// 公历节日 + /// + private static readonly Hashtable gHoliday = new Hashtable(); + /// + /// 农历节日 + /// + private static readonly Hashtable nHoliday = new Hashtable(); + /// + /// 某个月第n个星期几 + /// + private static readonly Hashtable wHoliday = new Hashtable(); + private static readonly int[] SCnLeapNumber = + { + 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, + 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, + 15, 16, 16, 16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, + 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, + 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34, + 34, 34, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 40, 40, + 40, 41, 41, 41, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 46, 46, 46, + 47, 47, 47, 48, 48, 48, 49, 49, 50, 50, 50, 51, 51, 52, 52, 52, 53, + 53, 53, 54, 54, 54, 55, 55, 56, 56, 56, 56, 57, 57, 57, 58, 58, 59, + 59, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 64, 64, 65, 65, + 65, 65, 66, 66, 66, 67, 67, 68, 68, 69, 69, 69, 69, 70, 71, 71, 71, + 71, 71, 71, 72, 72, 73, 73, 74, 74, 74, 75, 75, 75, 75, 76, 76, 77, + 77, 77, 77, 78, 79, 79, 79, 79, 79, 80, 80, 80, 81, 82, 82, 82, 83, + 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 86, 87, 87, 87, 87, 88, 88, + 89, 89, 90, 90, 91, 91, 91, 92, 92, 93, 93, 94, 94, 94, 94, 95, 95, + 96, 96, 96, 96, 97, 97, 98, 98, 98, 99, 99, 100, 100, 100, 101, 101, + 101, 102, 102, 102, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, + 106, 107, 107, 107, 108, 108, 109, 109, 109, 110, 110, 111, 111, 111, + 112, 112, 112, 113, 113, 114, 114, 114, 115, 115, 116, 116, 116, 117, + 117, 117, 117, 118, 118, 119, 119, 119, 120, 120, 121, 121, 121, 122, + 122, 122, 123, 123, 124, 124, 124, 124, 125, 125, 126, 126, 126, 126, + 127, 127, 128, 128, 129, 129, 130, 130, 130, 130, 131, 131, 132, 132, + 132, 133, 133, 133, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, + 137, 138, 138, 139, 139, 139, 140, 140, 141, 141, 141, 142, 142, 142, + 143, 143, 143, 144, 144, 144, 145, 145, 146, 146, 146, 147, 147, 147, + 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 153, + 153, 153, 154, 154, 154, 155, 155, 156, 156, 156, 157, 157, 157, 158, + 158, 158, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 163, 163, + 163, 164, 164, 164, 165, 165, 165, 166, 166, 167, 167, 167, 168, 168, + 168, 169, 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173, + 174, 174, 174, 175, 175, 175, 176, 176, 177, 177, 177, 178, 178, 178, + 179, 179, 179, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 184, + 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 188, 188, 188, 189, + 189, 189, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194, + 194, 195, 195, 195, 196, 196, 196, 197, 197, 198, 198, 198, 199, 199, + 199, 200, 200, 200, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, + 205, 205, 205, 206, 206, 206, 207, 207, 207, 208, 208, 209, 209, 209, + 210, 210, 210, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214, + 214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 218, 218, 218, 219, + 219, 219, 220, 220, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224, + 224, 225, 225, 225, 226, 226, 226, 227, 227, 228, 228, 228, 229, 229, + 229, 230, 230, 230, 231, 231, 232, 232, 232, 233, 233, 233, 234, 234, + 235, 235, 235, 236, 236, 236, 237, 237, 237, 238, 238, 239, 239, 239, + 240, 240, 240, 241, 241, 242, 242, 242, 243, 243, 243, 244, 244, 244, + 245, 245, 246, 246, 246, 247, 247, 247, 248, 248, 249, 249, 249, 250, + 250, 250, 251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255, + 255, 256, 256, 256, 257, 257, 257, 258, 258, 259, 259, 259, 260, 260, + 260, 261, 261, 261, 262, 262, 263, 263, 263, 264, 264, 264, 265, 265, + 266, 266, 266, 267, 267, 267, 268, 268, 268, 269, 269, 270, 270, 270, + 271, 271, 271, 272, 272, 273, 273, 273, 274, 274, 274, 275, 275, 276, + 276, 276, 277, 277, 277, 278, 278, 278, 279, 279, 280, 280, 280, 281, + 281, 281, 282, 282, 283, 283, 283, 284, 284, 284, 285, 285, 285, 286, + 286, 287, 287, 287, 288, 288, 288, 289, 289, 290, 290, 290, 291, 291, + 291, 292, 292, 292, 293, 293, 294, 294, 294, 295, 295, 295, 296, 296, + 297, 297, 297, 298, 298, 298, 299, 299, 299, 300, 300, 301, 301, 301, + 302, 302, 302, 303, 303, 304, 304, 304, 305, 305, 305, 306, 306, 306, + 307, 307, 308, 308, 308, 309, 309, 309, 310, 310, 311, 311, 312, 312, + 312, 313, 313, 313, 314, 314, 315, 315, 315, 316, 316, 316, 317, 317, + 317, 318, 318, 319, 319, 319, 320, 320, 320, 321, 321, 322, 322, 322, + 323, 323, 323, 324, 324, 325, 325, 325, 326, 326, 326, 327, 327, 327, + 328, 328, 329, 329, 329, 330, 330, 330, 331, 331, 332, 332, 332, 333, + 333, 333, 334, 334, 334, 335, 335, 336, 336, 336, 337, 337, 337, 338, + 338, 339, 339, 339, 340, 340, 340, 341, 341, 341, 342, 342, 343, 343, + 343, 344, 344, 344, 345, 345, 346, 346, 346, 347, 347, 347, 348, 348, + 348, 349, 349, 350, 350, 350, 351, 351, 351, 352, 352, 353, 353, 353, + 354, 354, 354, 355, 355, 355, 356, 356, 357, 357, 357, 358, 358, 358, + 359, 359, 360, 360, 360, 361, 361, 361, 362, 362, 362, 363, 363, 364, + 364, 364, 365, 365, 365, 366, 366, 367, 367, 367, 368, 368, 368, 369, + 369, 369, 370, 370, 371, 371, 371, 372, 372, 372, 373, 373, 374, 374, + 374, 375, 375, 375, 376, 376, 376, 377, 377, 378, 378, 378, 379, 379, + 379, 380, 380, 381, 381, 381, 382, 382, 382, 383, 383, 383, 384, 384, + 385, 385, 385, 386, 386, 386, 387, 387, 388, 388, 388, 389, 389, 389, + 390, 390, 390, 391, 391, 392, 392, 392, 393, 393, 393, 394, 394, 395, + 395, 395, 396, 396, 396, 397, 397, 397, 398, 398, 399, 399, 399, 400, + 400, 400, 401, 401, 402, 402, 402, 403, 403, 403, 404, 404, 404, 405, + 405, 406, 406, 406, 407, 407, 407, 408, 408, 409, 409, 409, 410, 410, + 410, 411, 411, 411, 412, 412, 413, 413, 413, 414, 414, 414, 415, 415, + 416, 416, 416, 417, 417, 417, 418, 418, 418, 419, 419, 420, 420, 420, + 421, 421, 421, 422, 422, 423, 423, 423, 424, 424, 424, 425, 425, 425, + 426, 426, 427, 427, 427, 428, 428, 428, 429, 429, 430, 430, 430, 431, + 431, 431, 432, 432, 432, 433, 433, 434, 434, 434, 435, 435, 435, 436, + 436, 437, 437, 437, 438, 438, 438, 439, 439, 439, 440, 440, 441, 441, + 441, 442, 442, 442, 443, 443, 444, 444, 444, 445, 445, 445, 446, 446, + 446, 447, 447, 448, 448, 448, 449, 449, 449, 450, 450, 451, 451, 451, + 452, 452, 452, 453, 453, 453, 454, 454, 455, 455, 455, 456, 456, 456, + 457, 457, 458, 458, 458, 459, 459, 459, 460, 460, 460, 461, 461, 462, + 462, 462, 463, 463, 463, 464, 464, 465, 465, 465, 466, 466, 466, 467, + 467, 467, 468, 468, 469, 469, 469, 470, 470, 470, 471, 471, 472, 472, + 472, 473, 473, 473, 474, 474, 474, 475, 475, 475, 476, 476, 477, 477, + 477, 478, 478, 478, 479, 479, 480, 480, 480, 481, 481, 481, 482, 482, + 482, 483, 483, 484, 484, 484, 485, 485, 485, 486, 486, 487, 487, 487, + 488, 488, 488, 489, 489, 489, 490, 490, 491, 491, 491, 492, 492, 492, + 493, 493, 494, 494, 494, 495, 495, 495, 496, 496, 496, 497, 497, 498, + 498, 498, 499, 499, 499, 500, 500, 501, 501, 501, 502, 502, 502, 503, + 503, 503, 504, 504, 505, 505, 505, 506, 506, 506, 507, 507, 508, 508, + 508, 509, 509, 509, 510, 510, 510, 511, 511, 512, 512, 512, 513, 513, + 513, 514, 514, 515, 515, 515, 516, 516, 516, 517, 517, 517, 518, 518, + 519, 519, 519, 520, 520, 520, 521, 521, 522, 522, 522, 523, 523, 523, + 524, 524, 524, 525, 525, 526, 526, 526, 527, 527, 527, 528, 528, 529, + 529, 529, 530, 530, 530, 531, 531, 531, 532, 532, 533, 533, 533, 534, + 534, 534, 535, 535, 536, 536, 536, 537, 537, 537, 538, 538, 538, 539, + 539, 540, 540, 540, 541, 541, 541, 542, 542, 543, 543, 543, 544, 544, + 544, 545, 545, 545, 546, 546, 547, 547, 547, 548, 548, 548, 549, 549, + 550, 550, 550, 551, 551, 551, 552, 552, 552, 553, 553, 554, 554, 554, + 555, 555, 555, 556, 556, 557, 557, 557, 558, 558, 558, 559, 559, 559, + 560, 560, 561, 561, 561, 562, 562, 562, 563, 563, 563, 564, 564, 565, + 565, 565, 566, 566, 566, 567, 567, 568, 568, 568, 569, 569, 569, 570, + 570, 570, 571, 571, 572, 572, 572, 573, 573, 573, 574, 574, 575, 575, + 575, 576, 576, 576, 577, 577, 578, 578, 578, 579, 579, 579, 580, 580, + 580, 581, 581, 582, 582, 582, 583, 583, 583, 584, 584, 584, 585, 585, + 586, 586, 586, 587, 587, 587, 588, 588, 589, 589, 589, 590, 590, 590, + 591, 591, 591, 592, 592, 593, 593, 593, 594, 594, 594, 595, 595, 596, + 596, 596, 597, 597, 597, 598, 598, 598, 599, 599, 600, 600, 600, 601, + 601, 601, 602, 602, 603, 603, 603, 604, 604, 604, 605, 605, 605, 606, + 606, 607, 607, 607, 608, 608, 608, 609, 609, 610, 610, 610, 611, 611, + 611, 612, 612, 612, 613, 613, 614, 614, 614, 615, 615, 615, 616, 616, + 617, 617, 617, 618, 618, 618, 619, 619, 619, 620, 620, 621, 621, 621, + 622, 622, 622, 623, 623, 624, 624, 624, 625, 625, 625, 626, 626, 626, + 627, 627, 628, 628, 628, 629, 629, 629, 630, 630, 631, 631, 631, 632, + 632, 632, 633, 633, 633, 634, 634, 635, 635, 635, 636, 636, 636, 637, + 637, 638, 638, 638, 639, 639, 639, 640, 640, 640, 641, 641, 642, 642, + 642, 643, 643, 643, 644, 644, 645, 645, 645, 646, 646, 646, 647, 647, + 647, 648, 648, 649, 649, 649, 650, 650, 650, 651, 651, 652, 652, 652, + 653, 653, 653, 654, 654, 654, 655, 655, 656, 656, 656, 657, 657, 657, + 658, 658, 659, 659, 659, 660, 660, 660, 661, 661, 661, 662, 662, 663, + 663, 663, 664, 664, 664, 665, 665, 666, 666, 666, 667, 667, 667, 668, + 668, 668, 669, 669, 670, 670, 670, 671, 671, 671, 672, 672, 673, 673, + 673, 674, 674, 674, 675, 675, 675, 676, 676, 677, 677, 677, 678, 678, + 678, 679, 679, 680, 680, 680, 681, 681, 681, 682, 682, 682, 683, 683, + 684, 684, 684, 685, 685, 685, 686, 686, 687, 687, 687, 688, 688, 688, + 689, 689, 689, 690, 690, 691, 691, 691, 692, 692, 692, 693, 693, 694, + 694, 694, 695, 695, 695, 696, 696, 696, 697, 697, 698, 698, 698, 699, + 699, 699, 700, 700, 701, 701, 701, 702, 702, 702, 703, 703, 703, 704, + 704, 705, 705, 705, 706, 706, 706, 707, 707, 707, 708, 708, 709, 709, + 709, 710, 710, 710, 711, 711, 712, 712, 712, 713, 713, 713, 714, 714, + 714, 715, 715, 716, 716, 716, 717, 717, 717, 718, 718, 719, 719, 719, + 720, 720, 720, 721, 721, 721, 722, 722, 723, 723, 723, 724, 724, 724, + 725, 725, 726, 726, 726, 727, 727, 727, 728, 728, 728, 729, 729, 730, + 730, 730, 731, 731, 731, 732, 732, 733, 733, 733, 734, 734, 734, 735, + 735, 736, 736, 736, 737, 737, 737, 738, 738, 738, 739, 739, 740, 740, + 740, 741, 741, 741, 742, 742, 742, 743, 743, 744, 744, 744, 745, 745, + 745, 746, 746, 747, 747, 747, 748, 748, 748, 749, 749, 749, 750, 750, + 751, 751, 751, 752, 752, 752, 754, 754, 755, 755, 755, 756, 756, 756, + 757, 757, 757, 758, 758, 759, 759, 759, 760, 760, 760, 761, 761, 762, + 762, 762, 763, 763, 763, 764, 764, 764, 765, 765, 766, 766, 766, 767, + 767, 767, 768, 768, 769, 769, 769, 770, 770, 770, 771, 771, 771, 772, + 772, 773, 773, 773, 774, 774, 774, 775, 775, 776, 776, 776, 777, 777, + 777, 778, 778, 778, 779, 779, 780, 780, 780, 781, 781, 781, 782, 782, + 783, 783, 783, 784, 784, 784, 785, 785, 785, 786, 786, 787, 787, 787, + 788, 788, 788, 789, 789, 790, 790, 790, 791, 791, 791, 792, 792, 792, + 793, 793, 794, 794, 794, 795, 795, 795, 796, 796, 796, 797, 797, 798, + 798, 798, 799, 799, 799, 800, 800, 801, 801, 801, 802, 802, 802, 803, + 803, 804, 804, 804, 805, 805, 805, 806, 806, 806, 807, 807, 808, 808, + 808, 809, 809, 809, 810, 810, 810, 811, 811, 812, 812, 812, 813, 813, + 813, 814, 814, 815, 815, 815, 816, 816, 816, 817, 817, 818, 818, 818, + 819, 819, 819, 820, 820, 820, 821, 821, 822, 822, 822, 823, 823, 823, + 824, 824, 825, 825, 825, 826, 826, 826, 827, 827, 827, 828, 828, 829, + 829, 829, 830, 830, 830, 831, 831, 832, 832, 832, 833, 833, 833, 834, + 834, 834, 835, 835, 836, 836, 836, 837, 837, 837, 838, 838, 839, 839, + 839, 840, 840, 840, 841, 841, 841, 842, 842, 843, 843, 843, 844, 844, + 844, 845, 845, 845, 846, 846, 847, 847, 847, 848, 848, 848, 849, 849, + 850, 850, 850, 851, 851, 851, 852, 852, 852, 853, 853, 854, 854, 854, + 855, 855, 855, 856, 856, 857, 857, 857, 858, 858, 858, 859, 859, 859, + 860, 860, 861, 861, 861, 862, 862, 862, 863, 863, 864, 864, 863, 864, + 864, 864, 865, 865, 865, 866, 866, 867, 867, 867, 868, 868, 868, 869, + 869, 870, 870, 870, 871, 871, 871, 872, 872, 873, 873, 873, 874, 874, + 874, 875, 875, 875, 876, 876, 877, 877, 877, 878, 878, 878, 879, 879, + 879, 880, 880, 881, 881, 881, 882, 882, 882, 883, 883, 884, 884, 884, + 885, 885, 885, 886, 886, 886, 887, 887, 888, 888, 888, 889, 889, 889, + 890, 890, 891, 891, 891, 892, 892, 892, 893, 893, 893, 894, 894, 895, + 895, 895, 896, 896, 896, 897, 897, 898, 898, 898, 899, 899, 899, 900, + 900, 900, 901, 901, 902, 902, 902, 903, 903, 903, 904, 904, 905, 905, + 905, 906, 906, 906, 907, 907, 907, 908, 908, 909, 909, 909, 910, 910, + 910, 911, 911, 912, 912, 912, 913, 913, 913, 914, 914, 914, 915, 915, + 916, 916, 916, 917, 917, 917, 918, 918, 919, 919, 919, 920, 920, 920, + 921, 921, 921, 922, 922, 923, 923, 923, 924, 924, 924, 925, 925, 925, + 926, 926, 927, 927, 927, 928, 928, 928, 929, 929, 930, 930, 930, 931, + 931, 931, 932, 932, 932, 933, 933, 934, 934, 934, 935, 935, 935, 936, + 936, 937, 937, 937, 938, 938, 938, 939, 939, 939, 940, 940, 941, 941, + 941, 942, 942, 942, 943, 943, 944, 944, 944, 945, 945, 945, 946, 946, + 946, 947, 947, 948, 948, 948, 949, 949, 949, 950, 950, 951, 951, 951, + 952, 952, 952, 953, 953, 953, 954, 954, 955, 955, 955, 956, 956, 956, + 957, 957, 958, 958, 958, 959, 959, 959, 960, 960, 960, 961, 961, 962, + 962, 962, 963, 963, 963, 964, 964, 965, 965, 965, 966, 966, 966, 967, + 967, 967, 968, 968, 969, 969, 969, 970, 970, 970, 971, 971, 971, 972, + 972, 973, 973, 973, 974, 974, 974, 975, 975, 976, 976, 976, 977, 977, + 977, 978, 978, 978, 979, 979, 980, 980, 980, 981, 981, 981, 982, 982, + 983, 983, 983, 984, 984, 984, 985, 985, 986, 986, 986, 987, 987, 987, + 988, 988, 988, 989, 989, 990, 990, 990, 991, 991, 991, 992, 992, 993, + 993, 993, 994, 994, 994, 995, 995, 995, 996, 996, 997, 997, 997, 998, + 998, 998, 999, 999, 1000, 1000, 1000, 1001, 1001, 1001, 1002, 1002, + 1002, 1003, 1003, 1004, 1004, 1004, 1005, 1005, 1005, 1006, 1006, + 1006, 1007, 1007, 1008, 1008, 1008, 1009, 1009, 1009, 1010, 1010, + 1011, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1013, 1014, 1014, + 1015, 1015, 1015, 1016, 1016, 1016, 1017, 1017, 1018, 1018, 1018, + 1019, 1019, 1019, 1020, 1020, 1020, 1021, 1021, 1022, 1022, 1022, + 1023, 1023, 1023, 1024, 1024, 1025, 1025, 1025, 1026, 1026, 1026, + 1027, 1027, 1027, 1028, 1028, 1029, 1029, 1029, 1030, 1030, 1030, + 1031, 1031, 1032, 1032, 1032, 1033, 1033, 1033, 1034, 1034, 1034, + 1035, 1035, 1036, 1036, 1036, 1037, 1037, 1037, 1038, 1038, 1039, + 1039, 1039, 1040, 1040, 1040, 1041, 1041, 1042, 1042, 1042, 1043, + 1043, 1043, 1044, 1044, 1044, 1045, 1045, 1046, 1046, 1046, 1047, + 1047, 1047, 1048, 1048, 1048, 1049, 1049, 1050, 1050, 1050, 1051, + 1051, 1051, 1052, 1052, 1053, 1053, 1053, 1054, 1054, 1054, 1055, + 1055, 1055, 1056, 1056, 1057, 1057, 1057, 1058, 1058, 1058, 1059, + 1059, 1060, 1060, 1060, 1061, 1061, 1061, 1062, 1062, 1062, 1063, + 1063, 1064, 1064, 1064, 1065, 1065, 1065, 1066, 1066, 1067, 1067, + 1067, 1068, 1068, 1068, 1069, 1069, 1069, 1070, 1070, 1071, 1071, + 1071, 1072, 1072, 1072, 1073, 1073, 1074, 1074, 1074, 1075, 1075, + 1075, 1076, 1076, 1076, 1077, 1077, 1078, 1078, 1078, 1079, 1079, + 1079, 1080, 1080, 1081, 1081, 1081, 1082, 1082, 1082, 1083, 1083, + 1083, 1084, 1084 + }; + private static readonly string SCnLeapMonth = + "0c0080050010a0070030c0080050010a0070030c0080050020a0070030c0080050020a" + + "0070030c0090050020a0070030c0090050020a0060030c0060030c00900600c0c0060c" + + "00c00c00c0c000600c0c0006090303030006000c00c060c0006c00000c0c0c00600030" + + "30006c00009009c0090c00c009000300030906030030c0c00060c00090c0060600c003" + + "0060c00c003006009060030c0060060c0090900c00090c0090c00c0060300060600030" + + "30c0c00030c0060030c0090060030c0090300c0080050020a0060030c0080050020b00" + + "70030c0090050010a0070030b0090060020a0070040c0080050020a0060030c0080050" + + "020b0070030c0090050010a0070030b0090060020a0070040c0080050020a0060030c0" + + "080050020b0070030c0090050000c00900909009009090090090090900900909009009" + + "0090900900909009009009090090090900900900909009009090090090900900900909" + + "00900909009009009090090090900900900909009009090060030c0090050010a00700" + + "30b008005001090070040c0080050020a0060030c0090040010a0060030c0090050010" + + "a0070030b0080050010a008005001090050020a0060030c0080040010a0060030c0090" + + "050010a0070030b0080050010a0070030b008005001090070040c0080050020a006003" + + "0c0080040010a0060030c0090050010a0070030b008005001090070040c0080050020a" + + "0060030c0080040010a0060030c0090050010a0060030c0090050010a0070030b00800" + + "5001090070040c0080050020a0060030c0080040010a0070030b0080050010a0070040" + + "c0080050020a0060030c0080040010a0070030c0090050010a0070030b0080050020a0" + + "060030c0080040010a0060030c0090050050020a0060030c0090050010b0070030c009" + + "0050010a0070040c0080040020a0060030c0080050020a0060030c0090050010a00700" + + "30b0080040020a0060040c0090050020b0070030c00a0050010a0070030b0090050020" + + "a0070030c0080040020a0060030c0090050010a0070030c0090050030b007005001090" + + "050020a007004001090060020c0070050c0090060030b0080040020a0060030b008004" + + "0010a0060030b0080050010a0050040c0080050010a0060030c0080050010b0070030c" + + "007005001090070030b0070040020a0060030c0080040020a0070030b0090050010a00" + + "60040c0080050020a0060040c0080050010b0070030c007005001090070030c0080050" + + "020a0070030c0090050020a0070030c0090050020a0060040c0090050020a0060040c0" + + "090050010b0070030c0080050030b007004001090060020c008004002090060020a008" + + "004001090050030b0080040020a0060040b0080040c00a0060020b0070050010900600" + + "30b0070050020a0060020c008004002090070030c008005002090070040c0080040020" + + "a0060040b0090050010a0060030b0080050020a0060040c0080050010b007003001080" + + "05001090070030c0080050020a007003001090050030a0070030b0090050020a006004" + + "0c0090050030b0070040c0090050010c0070040c0080060020b00700400a090060020b" + + "007003002090060020a005004001090050030b007004001090050040c0080040c00a00" + + "60020c007005001090060030b0070050020a0060020c008004002090060030b0080040" + + "02090060030b0080040020a0060040b0080040010b0060030b0070050010a006004002" + + "0700500308006004003070050030700600400307005003080060040030700500409006" + + "0040030700500409006005002070050030a00600500307005004002060040020600500" + + "30020600400307005004090060040030700500408007005003080050040a0060050030" + + "7005004002060050030800500400206005002070050040020600500307006004002070" + + "050030800600400307005004080060040a006005003080050040020700500409006004" + + "002060050030b006005002070050030800600400307005004080060040030700500408" + + "0060040020" + + "700500409006004003070050040b006005002070050040b006005003070060040a0060" + + "0500307006004002060050030700600409006004003070050040900700500308005004" + + "0b00600500307006005001070050030800600400206005003070060040020600500307" + + "0060040a00700500308006004003070050040800600500107005004080060050020700" + + "50040a0060040020600500308006005002070050030800600400307005004080070050" + + "030800500408006005003070050040a006005003070050040a00600500207005004001" + + "0600500307006004001070050030700600408007005004070060040900600400307005" + + "0040a007005003080060040b0060050030800600500107005003080060040020700500" + + "3070060040030700500307006004003070050030800600400307005004090060050b00" + + "7005004090060050020700600408006005003070060030800600500307006003080060"; + //{ * 自公元前 850 年开始的农历闰月信息 -849~2100,移植自中国日历类,2100 后罗建仁计算补充} + private static readonly string[] JQ = { "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒" }; + private static readonly int[] MonthDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + private static readonly int[] MonthDays2 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + static ChinaDate() + { + //公历节日 + gHoliday.Add("0101", "元旦"); + gHoliday.Add("0210", "气象节:1991"); + gHoliday.Add("0214", "情人节"); + gHoliday.Add("0303", "全国爱耳日:1999"); + gHoliday.Add("0305", "雷锋日:1963"); + gHoliday.Add("0308", "妇女节:1975"); + gHoliday.Add("0312", "植树节:1979"); + gHoliday.Add("0315", "消权日:1983"); + gHoliday.Add("0322", "世界水日:1993"); + gHoliday.Add("0401", "愚人节:1564"); + gHoliday.Add("0422", "地球日:1970"); + gHoliday.Add("0501", "劳动节:1890"); + gHoliday.Add("0504", "青年节:1949"); + gHoliday.Add("0512", "护士节:1912"); + gHoliday.Add("0515", "家庭日:1989"); + gHoliday.Add("0517", "世界电信日:1932"); + gHoliday.Add("0531", "无烟日:1988"); + gHoliday.Add("0601", "儿童节:1950"); + gHoliday.Add("0605", "环境日:1972"); + gHoliday.Add("0606", "全国爱眼日:1996"); + gHoliday.Add("0608", "海洋日:2009"); + gHoliday.Add("0614", "世界献血日:2005"); + gHoliday.Add("0626", "禁毒日:1987"); + gHoliday.Add("0701", "建党节:1921"); + gHoliday.Add("0706", "国际接吻日:1991"); + gHoliday.Add("0707", "七七事变:1937"); + gHoliday.Add("0711", "人口日:1989"); + gHoliday.Add("0801", "建军节:1933"); + gHoliday.Add("0910", "教师节:1985"); + gHoliday.Add("0920", "爱牙日:1989"); + gHoliday.Add("0921", "和平日:2002"); + gHoliday.Add("0922", "世界无车日:1998"); + gHoliday.Add("0927", "世界旅游日:1979"); + gHoliday.Add("0929", "心脏日:2011"); + gHoliday.Add("1001", "国庆节:1949"); + gHoliday.Add("1009", "世界邮政日:1969"); + gHoliday.Add("1013", "保健日:1950"); + gHoliday.Add("1016", "粮食日:1981"); + gHoliday.Add("1028", "男性健康日:2000"); + gHoliday.Add("1031", "万圣节:600"); + gHoliday.Add("1111", "光棍节"); + gHoliday.Add("1116", "宽容日:1996"); + gHoliday.Add("1201", "艾滋病日:1988"); + gHoliday.Add("1224", "平安夜"); + gHoliday.Add("1225", "圣诞节"); + + //农历节日 + nHoliday.Add("0101", "春节"); + nHoliday.Add("0115", "元宵节"); + nHoliday.Add("0202", "龙抬头"); + nHoliday.Add("0505", "端午节"); + nHoliday.Add("0624", "火把节"); + nHoliday.Add("0707", "七夕"); + nHoliday.Add("0715", "中元节"); + nHoliday.Add("0722", "财神节"); + nHoliday.Add("0815", "中秋节"); + nHoliday.Add("0909", "重阳节"); + nHoliday.Add("1001", "祭祖节"); + nHoliday.Add("1208", "腊八节"); + nHoliday.Add("1223", "小年(北方)"); + nHoliday.Add("1224", "小年(南方)"); + //某个月第n个星期几 + wHoliday.Add("0527", "国际母亲节:1908"); + wHoliday.Add("0637", "父亲节:1972"); + wHoliday.Add("0907", "心脏日:2000-2010");//9月最后一个周日 + wHoliday.Add("1011", "住房日:1986"); + wHoliday.Add("1144", "感恩节:1941");//11月的第四个星期四 + } + + /// + /// 获取农历 + /// + /// + /// + public static string GetChinaDate(DateTime dt) + { + string str = string.Format("{0} {1}{2}", GetYear(dt), GetMonth(dt), GetDay(dt)); + string strJQ = GetSolarTerm(dt); + if (strJQ != "") + { + str += " (" + strJQ + ")"; + } + //string strHoliday = GetHoliday(dt); + //string strChinaHoliday = GetChinaHoliday(dt); + //if (strHoliday != "") + //{ + // str += " " + strHoliday; + //} + //if (strChinaHoliday != "") + //{ + // str += " " + strChinaHoliday; + //} + + return str; + } + /// + /// 获取农历 + /// + /// + /// + /// + /// + public static string GetChinaDate(int AYear, int AMonth, int ADay) + { + string str = string.Format("{0} {1}{2}", GetYear(AYear, AMonth, ADay), GetMonth(AYear, AMonth, ADay), GetDay(AYear, AMonth, ADay)); + string strJQ = GetSolarTerm(AYear, AMonth, ADay); + if (strJQ != "") + { + str += " (" + strJQ + ")"; + } + //string strHoliday = GetHoliday(dt); + //string strChinaHoliday = GetChinaHoliday(dt); + //if (strHoliday != "") + //{ + // str += " " + strHoliday; + //} + //if (strChinaHoliday != "") + //{ + // str += " " + strChinaHoliday; + //} + + return str; + } + // 移植自中国日历类 + private static int GetLeapMonth(int AYear) + { + char C = SCnLeapMonth[AYear + 849]; + if (C >= 48 && C <= 57) //0-9 + { return (int)C - 48; } + else if (C >= 97 && C <= 122) //a-z + { + return 10 + (int)C - 97; + } + else { return -1; } + } + // 移植自中国日历类 + private static int GetLeapNum(int AYear) + { + if (AYear < 0) + { + return SCnLeapNumber[AYear + 849]; + } + else { return SCnLeapNumber[AYear - 1 + 849]; } + } + /// + /// 获得某农历年的闰月,返回 1~12 对应一月到十二月,返回 0 表示无闰月 + /// + /// + /// + public static int GetLunarLeapMonth(int AYear) + { + int result = GetLeapMonth(AYear); + if (result < 0) { result = 0; } + return result; + } + /// + /// 农历搜索方向 + /// + public enum TLunarSearchDirection + { + /// + /// 无效 + /// + lsdInvalid, + /// + /// 向上 + /// + lsdUp, + /// + /// 向下 + /// + lsdDown + } + /// + /// {* 日月食类型, 无, 日食, 月全食, 月偏食 } + /// + public enum TEclipseType + { + /// + /// 无 + /// + etNone, + /// + /// 日食 + /// + etSolar, + /// + /// 月全食 + /// + etMoonFull, + /// + /// 月偏食 + /// + etMoonHalf + } + /// + /// {* 月相, 无, 朔, 望} + /// + public enum TMoonPhase + { + /// + /// 无 + /// + mpNone, + /// + /// 朔 + /// + mpShuo, + /// + /// 望 + /// + mpWang + } + // 获得一大于零的数的小数部分 + private static double GetTail(double X) + { + if (X > 0) { return X - Math.Truncate(X); } + else { return X + Math.Truncate(X); } + } + // 某角度计算函数,移植自中国日历类 + private static double GetAng(double X, double T, double C1, double T0, double T2, double T3) + { + return GetTail(C1 * X) * 2 * Math.PI + T0 - T2 * T * T - T3 * T * T * T; + } + /// + /// 获得某公历年月日的农历日数和该日月相以及日月食类型和时刻 + /// + /// + /// + /// + /// + /// + /// + /// + public static double GetLunarMoon(int AYear, int AMonth, int ADay, out TEclipseType EclipseType, out TMoonPhase MoonPhase, out double theTime) + { + double T = (AYear - 1899.5) / 100; + int Ms = Convert.ToInt32(Math.Floor((AYear - 1900) * 12.3685)); + double Rpi = 180 / Math.PI; + double Zone = 8; + double F0 = GetAng(Ms, T, 0, 0.75933, 2.172e-4, 1.55e-7) + + 0.53058868 * Ms - 8.37e-4 * T + Zone / 24 + 0.5; + double Fc = 0.1734 - 3.93e-4 * T; + double J0 = 693595 + 29 * Ms; + double Aa0 = GetAng(Ms, T, 0.08084821133, 359.2242 / Rpi, 0.0000333 / Rpi, 0.00000347 / Rpi); + double Ab0 = GetAng(Ms, T, 7.171366127999999e-2, 306.0253 / Rpi, -0.0107306 / Rpi, -0.00001236 / Rpi); + double Ac0 = GetAng(Ms, T, 0.08519585128, 21.2964 / Rpi, 0.0016528 / Rpi, 0.00000239 / Rpi); + EclipseType = TEclipseType.etNone; + int LunDay = -1; + double ShuoTime = 0; + int WangDay = 0; + double WangTime = 0; + double K1 = -1; double K = -1; + int StdDays = GetEquStandardDays(AYear, AMonth, ADay); + while (K <= 13) + { + double Aa = Aa0 + 0.507984293 * K; + double Ab = Ab0 + 6.73377553 * K; + double Ac = Ac0 + 6.818486628 * K; + double F1 = F0 + 1.53058868 * K + Fc * Math.Sin(Aa) - 0.4068 * Math.Sin(Ab) + + 0.0021 * Math.Sin(2 * Aa) + 0.0161 * Math.Sin(2 * Ab) + 0.0104 * Math.Sin(2 * Ac) + - 0.0074 * Math.Sin(Aa - Ab) - 0.0051 * Math.Sin(Aa + Ab); + double J = J0 + 28 * K + F1; + int LunDay0 = StdDays - (int)Math.Floor(J); + if ((K == Math.Floor(K)) && (LunDay0 >= 0) && (LunDay0 <= 29)) + { + K1 = K; + ShuoTime = GetTail(J); + LunDay = LunDay0 + 1; + } + if (K == K1 + 0.5) + { + WangTime = GetTail(J); + WangDay = (int)Math.Floor(J) - (StdDays - LunDay + 1) + 1; + } + if (((LunDay == 1) && (K == K1)) || ((LunDay == WangDay) && (K == K1 + 0.5))) + { + if (Math.Abs(Math.Sin(Ac)) <= 0.36) + { + double S = 5.19595 - 0.0048 * Math.Cos(Aa) + 0.002 * Math.Cos(2 * Aa) - 0.3283 * Math.Cos(Ab) + - 0.006 * Math.Cos(Aa + Ab) + 0.0041 * Math.Cos(Aa - Ab); + double R = 0.207 * Math.Sin(Aa) + 0.0024 * Math.Sin(2 * Aa) - 0.039 * Math.Sin(Ab) + + 0.0115 * Math.Sin(2 * Ab) - 0.0073 * Math.Sin(Aa + Ab) - 0.0067 * Math.Sin(Aa - Ab) + + 0.0117 * Math.Sin(2 * Ac); + double P = Math.Abs(S * Math.Sin(Ac) + R * Math.Cos(Ac)); + double Q = 0.0059 + 0.0046 * Math.Cos(Ac) - 0.0182 * Math.Cos(Ab) + 0.0004 * Math.Cos(2 * Ab) + - 0.0005 * Math.Cos(Aa + Ab); + if (P - Q <= 1.5572) + { + EclipseType = TEclipseType.etSolar; // 日食 + if (K != Math.Floor(K)) + { + if (P + Q >= 1.0129) + { + EclipseType = TEclipseType.etMoonHalf; //月偏食 + } + else + { + EclipseType = TEclipseType.etMoonFull; //月全食 + } + } + } + } + } + K = K + 0.5; + } + // 1924.3.5 ~ 4.3 少一天 + //if ((AYear == 1) && (((AMonth == 9) && (ADay >= 6)) || ((AMonth == 10) && (ADay <= 4)))) + //{ + // LunDay--; + // if (LunDay <1) { LunDay = LunDay + 30; } + //} + // 1924.3.5 ~ 4.3 少一天 + if ((AYear == 1924) && (((AMonth == 3) && (ADay >= 5)) || ((AMonth == 4) && (ADay <= 3)))) + { + LunDay++; + if (LunDay > 30) { LunDay = LunDay - 30; } + } + // 2018.11.7 ~ 12.6 多一天 + if ((AYear == 2018) && (((AMonth == 11) && (ADay >= 7)) || ((AMonth == 12) && (ADay <= 6)))) + { + LunDay--; + if (LunDay < 1) { LunDay = LunDay + 30; } + } + //2025.4.27 ~ 5.26 少一天 + if ((AYear == 2025) && (((AMonth == 4) && (ADay >= 7)) || ((AMonth == 5) && (ADay <= 26)))) + { + LunDay++; + if (LunDay > 30) { LunDay = LunDay - 30; } + } + double Result = LunDay; + if (LunDay == 1)// 朔日 + { + MoonPhase = TMoonPhase.mpShuo; + theTime = ShuoTime; + } + else if (LunDay == WangDay) + { + MoonPhase = TMoonPhase.mpWang; + theTime = WangTime; + } + else + { + MoonPhase = TMoonPhase.mpNone; + theTime = -1; + } + return Result; + } + /// + /// 获得某公历年月日的农历月数 + /// + /// + /// + /// + /// + public static double GetLunarMonth(int AYear, int AMonth, int ADay) + { + double LunDay = GetLunarMoon(AYear, AMonth, ADay, out TEclipseType aEclipsType, out TMoonPhase aMoonPhase, out double aTime); + if (aTime != -1) { LunDay = LunDay + aTime; } + LunDay = Math.Floor(LunDay - Math.Floor(LunDay / 100) * 100); + int LeapMons = GetLeapNum(AYear); + int NMonth = (int)Math.Round((GetEquStandardDays(AYear, AMonth, ADay) + - GetEquStandardDays(-849, 1, 21) - LunDay) / 29.530588) - LeapMons; + //历史上的修改月建 + if (AYear <= 240) NMonth++; + if (AYear <= 237) NMonth--; + if (AYear < 24) NMonth++; + if (AYear < 9) NMonth--; + if (AYear <= -255) NMonth++; + if (AYear <= -256) NMonth += 2; + if (AYear <= -722) NMonth++; + double Result = Math.Round(GetRemain(NMonth - 3, 12) + 1); + if ((Result == GetLeapMonth(AYear - 1)) && (AMonth == 1) && (ADay < LunDay)) + { + Result = -Result; //如果 AYear - 1年末是闰月且该月接到了 AYear 年,则 AYear 年年初也是闰月 + } + else if (Result == GetLeapMonth(AYear)) + { + // 如果得到的月份数与当年所闰的月相同,比如1612年1月31号。 + // 上面计算所得的是11月,并且1612年年底有个闰11月,这俩不能混淆 + if (AMonth.IsInRange(1, 2) && (GetLeapMonth(AYear) != 12)) + { + // 粗略判断,如果月份在年初,且今年闰月不是12月,就说明两个月不是一个年的, + // 所以不是闰月,修正为普通月。但这个修正可能不是太准确 + + // 比如1984年有闰10月,而1984.1.1的农历月为10, + // 但这是从1983年阴历接过来的,所以不是1984年的闰10月 + Result = Result + 1; + } + else { Result = -Result; } + } + else + { + if (Result < GetLeapMonth(AYear) || (AMonth < Result) && (GetLeapMonth(AYear) > 0)) + { + Result = Result + 1; //如果 AYear 年是闰月但当月未过闰月则前面多扣除了本年的闰月,这里应当补偿 + } + Result = Math.Round(GetRemain(Result - 1, 12) + 1); + } + return Result; + } + // 小数的求余数 + static double GetRemain(double X, double W) + { + return GetTail(X / W) * W; + } + /// + /// 获取阳历日期对应的农历日期 + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static bool GetLunarFromDay(int AYear, int AMonth, int ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMonth) + { + bool Result = false; + LunarYear = 0; + LunarMonth = 0; + LunarDay = 0; + IsLeapMonth = false; + if ((AYear >= -849) && (AYear <= 2100)) + { + LunarDay = (int)Math.Floor(GetLunarMoon(AYear, AMonth, ADay, out TEclipseType aEclipsType, out TMoonPhase aMoonPhase, out double aTime)); + LunarMonth = (int)Math.Floor(GetLunarMonth(AYear, AMonth, ADay)); + IsLeapMonth = LunarMonth < 0; + if (IsLeapMonth) + { LunarMonth = -LunarMonth; } + LunarYear = AYear; + // 农历在下半年,公历在上半年,则农历应为上一年 + if ((LunarMonth > 6) && (AMonth < 6)) + { + LunarYear--; + } + Result = true; + } + return Result; + } + /// + /// 获得某公历年月日的农历月日和是否闰月的信息 + /// + /// + /// + /// + /// + /// + /// + /// + public static bool GetLunarMonthDayFromDay(int AYear, int AMonth, int ADay, out int LunarMonth, out int LunarDay, out bool IsLeapMonth) + { + bool Result = false; + LunarMonth = 0; + LunarDay = 0; + IsLeapMonth = false; + if ((AYear >= -849) && (AYear <= 2100)) + { + LunarDay = (int)Math.Floor(GetLunarMoon(AYear, AMonth, ADay, out TEclipseType aEclipsType, out TMoonPhase aMoonPhase, out double aTime)); + LunarMonth = (int)Math.Floor(GetLunarMonth(AYear, AMonth, ADay)); + IsLeapMonth = LunarMonth < 0; + if (IsLeapMonth) + LunarMonth = -LunarMonth; + Result = true; + } + return Result; + } + /// + /// 获得等效标准日数对应的某公历日,倒推而来 + /// + /// + /// + /// + /// + /// + private static bool GetDayFromEquStandardDays(int EquDays, out int AYear, out int AMonth, out int ADay) + { + const int D1 = 365; + const int D4 = D1 * 4 + 1; + const int D100 = D4 * 25 - 1; + const int D400 = D100 * 4 + 1; + bool result = false; + AYear = 0; AMonth = 0; ADay = 0; + if (EquDays < 0) { return result; }// 暂不处理公元前的等效标准日 + if (EquDays <= 577735)// 如果是 1582.10.4 (577735) 及之前为Julian历,需要修正 + { + int Diff = EquDays / (365 * 100) - EquDays / (365 * 400); + EquDays -= 10;// Gregorian 删去的 10 天 + EquDays += 12 - Diff; // 补上多闰的 12 天中多闰的部分 + } + int T = EquDays; + int Y = 1; + while (T >= D400) + { + + T -= D400; + Y += 400; + } + int I = T / D100; + int D = T % D100; + if (I == 4) + { + I--; + D += D100; + } + Y += I * 100; + I = D / D4; + D = D % D4; + Y += I * 4; + I = D / D1; + D = D % D1; + if (I == 4) + { + I--; + D += D1; + } + Y += I; + int[] DayTable = null; + if (GetIsLeapYear(Y)) { DayTable = MonthDays2; } else { DayTable = MonthDays; } + int M = 0; + while (true) + { + I = DayTable[M]; + if (D < I) break; + D -= I; + M++; + } + AYear = Y; + AMonth = M + 1; + ADay = D + 1; + result = true; + return result; + } + /// + /// 比较两个农历日期(包括闰月信息),1 大于2返回1、1等于2返回0、1小于2返回-1 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static int Compare2LunarDay(int Year1, int Month1, int Day1, bool IsLeap1, int Year2, int Month2, int Day2, bool IsLeap2) + { + if (Year1 > Year2) + { + return 1; + } + else if (Year1 == Year2) + { + if (Month1 > Month2) + { + return 1; + } + else if (Month1 == Month2) + { + if (IsLeap1 == IsLeap2) + { + if (Day1 > Day2) + { + return 1; + } + else if (Day1 == Day2) + { + return 0; + } + else { return -1; } + } + else if (IsLeap1 && !IsLeap2) + { + return 1; + } + else { return -1; } + } + else + { + return -1; + } + } + else { return -1; } + } + /// + /// 获得某农历年月日(加是否闰月)的公历年月日 + /// 该函数采用反向二分法查找 + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static bool GetDayFromLunar(int ALunarYear, int ALunarMonth, int ALunarDay, bool IsLeapMonth, out int AYear, out int AMonth, out int ADay) + { + AYear = -1; AMonth = -1; ADay = 1; + bool result = false; + if (IsLeapMonth && (GetLunarLeapMonth(ALunarYear) != ALunarMonth)) { return result; } // 该年无此闰月则退出 + // 初始范围为本公历年一月一日到次年十二月三十一日,这样做的前提是历史上正月初一 + // 没有落到公历年年前去。如果有这样的情况,可考虑适当扩大搜索范围,比如从 + // 上一公历年一月一日到次年十二月三十一日,但又可能引发下面对搜索范围判断的错 + int StartYear = ALunarYear; + int StartMonth = 1; + int StartDay = 1; + int StartDays = GetEquStandardDays(StartYear, StartMonth, StartDay); + int EndYear = ALunarYear + 1; + int EndMonth = 12; + int EndDay = 31; + int EndDays = GetEquStandardDays(EndYear, EndMonth, EndDay); + bool Only2 = false; + TLunarSearchDirection Lsd = TLunarSearchDirection.lsdInvalid; + int TempYear = StartYear; + int TempLunarYear = StartYear; + int OldTempLunarMonth = 0; + int Count = 0; + while (StartDays < EndDays) + { + Count++; + if (Count > 100) { break; } // 避免陷入死循环 + int InterDays = (StartDays + EndDays) / 2; + if (Only2) + { InterDays++; } + if (EndDays - StartDays == 1) + { Only2 = true; } + GetDayFromEquStandardDays(InterDays, out TempYear, out int TempMonth, out int TempDay); + GetLunarMonthDayFromDay(TempYear, TempMonth, TempDay, out int TempLunarMonth, out int TempLunarDay, out bool TempIsLeap); + switch (Lsd) + { + case TLunarSearchDirection.lsdUp: + // 往未来搜索时如果农历月由大变小了,说明跨了年,年份得加一 + if (TempLunarMonth < OldTempLunarMonth) + TempLunarYear++; + break; + case TLunarSearchDirection.lsdDown: + // 往过去搜索时如果农历月由小变大了,说明跨了年,年份得减一 + if (TempLunarMonth > OldTempLunarMonth) + TempLunarYear--; + break; + } + switch (Compare2LunarDay(TempLunarYear, TempLunarMonth, TempLunarDay, TempIsLeap, + ALunarYear, ALunarMonth, ALunarDay, IsLeapMonth)) + { + case -1: + StartDays = InterDays; + Lsd = TLunarSearchDirection.lsdUp; // 往未来搜索 + break; + case 0: + AYear = TempYear; + AMonth = TempMonth; + ADay = TempDay; + return true; + case 1: + EndDays = InterDays; + Lsd = TLunarSearchDirection.lsdDown; // 往过去搜索 + break; + } + OldTempLunarMonth = TempLunarMonth; + } + return false; + } + /// + /// 获取农历某一个月的总天数 + /// + /// + /// + /// + /// + public static int GetLunarMonthDays(int ALunarYear, int ALunarMonth, bool IsLeapMonth = false) + { + // 该年无此闰月则退出 + if (IsLeapMonth && (GetLunarLeapMonth(ALunarYear) != ALunarMonth)) { return -1; } + if (!GetDayFromLunar(ALunarYear, ALunarMonth, 1, IsLeapMonth, out int AYear, out int AMonth, out int ADay)) { return -1; } + //if(ALunarYear==1 && ALunarMonth == 9) { return 29; } + int EquDay1 = GetEquStandardDays(AYear, AMonth, ADay); + bool ALeap = false; + if (GetLunarLeapMonth(ALunarYear) == ALunarMonth) + { + if (IsLeapMonth)// 如果输入就是闰月,则后推一个月 + { + ALunarMonth++; + if (ALunarMonth > 12) + { ALunarMonth -= 12; ALunarYear++; } + } + else { ALeap = true; } + } + else + { + ALunarMonth++; + if (ALunarMonth > 12) + { + ALunarMonth -= 12; ALunarYear++; + } + } + if (!GetDayFromLunar(ALunarYear, ALunarMonth, 1, ALeap, out AYear, out AMonth, out ADay)) { return -1; } + int EquDay2 = GetEquStandardDays(AYear, AMonth, ADay); + return EquDay2 - EquDay1; + } + /// + /// 获取农历年份,范围约1901-2101年 + /// + /// + /// + public static string GetYear(DateTime dt) + { + return GetYear(dt.Year,dt.Month,dt.Day); + } + /// + /// 获取农历年份,范围约0-9999年 + /// + /// + /// + /// + /// + public static string GetYear(int AYear, int AMonth, int ADay) + { + GetLunarFromDay(AYear, AMonth, ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMonth); + string yearTG = "甲乙丙丁戊己庚辛壬癸"; + string yearDZ = "子丑寅卯辰巳午未申酉戌亥"; + string yearSX = "鼠牛虎兔龙蛇马羊猴鸡狗猪"; + int year = LunarYear; + int yTG = (LunarYear-3)%10; + if (yTG == 0) { yTG = 10; } + int yDZ = (AYear - 3) % 12; + if (yDZ == 0) { yDZ = 12; } + if (AMonth == 2) + { + GetJieQiInAYear(AYear, 2, out int _Month, out int _ADay, out int _, out int _); + if(ADay< _ADay) { yDZ--; if (yDZ == 0) { yDZ = 12; } } + } + else if (AMonth < 2) { yDZ--; if (yDZ == 0) { yDZ = 12; } } + string str = string.Format("[{0}]{1}{2}年", yearSX[yDZ-1], yearTG[yTG-1], yearDZ[yDZ-1]); + return str; + } + /// + /// 获取农历月份,范围约1901-2101年 + /// + /// + /// + public static string GetMonth(DateTime dt) + { + return GetMonth(dt.Year,dt.Month,dt.Day); + } + /// + /// 获取农历月份,范围约0-9999年 + /// + /// + /// + /// + /// + public static string GetMonth(int AYear, int AMonth, int ADay) + { + GetLunarMonthDayFromDay(AYear, AMonth, ADay, out int iMonth, out int TempLunarDay, out bool isLeapMonth); + string strMonth = isLeapMonth ? "闰" : ""; + return strMonth + GetMonth(iMonth); + } + /// + /// 获取中文表示的农历月份 + /// + /// + /// + public static string GetMonth(int iMonth) + { + string szText = "正二三四五六七八九十"; + var strMonth = ""; + if (iMonth <= 10) + { + strMonth += szText.Substring(iMonth - 1, 1); + } + else if (iMonth == 11) + { + strMonth += "冬"; + } + else + { + strMonth += "腊"; + } + return strMonth + "月"; + } + /// + /// 获取农历日,范围约1901-2101年 + /// + /// + /// + public static string GetDay(DateTime dt) + { + return GetDay(dt.Year,dt.Month,dt.Day); + } + /// + /// 获取农历日,范围约0-9999年 + /// + /// + /// + /// + /// + public static string GetDay(int AYear, int AMonth, int ADay) + { + GetLunarFromDay(AYear, AMonth, ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMont); + return GetDay(LunarDay); + } + /// + /// 获取农历日,范围约0-9999年 + /// + /// + /// + public static string GetDay(int iDay) + { + string szText1 = "初十廿三"; + string szText2 = "一二三四五六七八九十"; + string strDay=""; + if (iDay == 20) + { + strDay = "二十"; + } + else if (iDay == 30) + { + strDay = "三十"; + } + else if (iDay>0) + { + strDay = szText1.Substring((iDay - 1) / 10, 1); + strDay = strDay + szText2.Substring((iDay - 1) % 10, 1); + } + return strDay; + } + /// + /// 获取节气,范围约1901-2101年 + /// + /// + /// + public static string GetSolarTerm(DateTime dt) + { + int index = GetJieQiFromDay(dt.Year, dt.Month, dt.Day); + if (index == -1) + { return ""; } + return JQ[index]; + } + /// + /// 获取节气,范围约0-9999年 + /// + /// + /// + /// + /// + public static string GetSolarTerm(int AYear, int AMonth, int ADay) + { + int index = GetJieQiFromDay(AYear, AMonth, ADay); + if (index == -1) + { return ""; } + return JQ[index]; + } + /// + /// 返回y年第n个节气(如小寒为1)的日差天数值(pd取值真假,分别表示平气和定气) + /// + /// + /// + /// pd取值真假,分别表示平气和定气 + /// + public static double GetJieQiDayTimeFromYear(int AYear, int N, bool pd) + { + double juD, tht, yrD, shuoD; + if (AYear <= 0) { AYear++; } // 对没有公元 0 年的调整 + juD = AYear * (365.2423112 - 6.4e-14 * (AYear - 100) * (AYear - 100) + - 3.047e-8 * (AYear - 100)) + 15.218427 * N + 1721050.71301; + tht = 3e-4 * AYear - 0.372781384 - 0.2617913325 * N; + yrD = (1.945 * Math.Sin(tht) - 0.01206 * Math.Sin(2 * tht)) * (1.048994 - 2.583e-5 * AYear); + shuoD = -18e-4 * Math.Sin(2.313908653 * AYear - 0.439822951 - 3.0443 * N); + return (pd) ?(juD + yrD + shuoD - GetEquStandardDays(AYear, 1, 0) - 1721425):(juD - GetEquStandardDays(AYear, 1, 0) - 1721425); // 定气 + } + private static TCalendarType GetCalendarType(int AYear, int AMonth, int ADay) + { + if (AYear > 1582) + return TCalendarType.ctGregorian; + else if (AYear < 1582) + return TCalendarType.ctJulian; + else if (AMonth < 10) + return TCalendarType.ctJulian; + else if ((AMonth == 10) && (ADay <= 4)) + return TCalendarType.ctJulian; + else if ((AMonth == 10) && (ADay >= 5 && ADay <= 14)) + return TCalendarType.ctInvalid; + else + return TCalendarType.ctGregorian; + } + /// + /// 获取等效标准日数 + /// + /// + /// + /// + /// + public static int GetEquStandardDays(int AYear, int AMonth, int ADay) + { + TCalendarType AType = GetCalendarType(AYear, AMonth, ADay); + if (AType == TCalendarType.ctGregorian) + { + int aa = (AYear - 1) * 365 + ((AYear - 1) / 4) - ((AYear - 1) / 100) + + ((AYear - 1) / 400); + return (AYear - 1) * 365 + ((AYear - 1) / 4) - ((AYear - 1) / 100) + + ((AYear - 1) / 400) + GetDayFromYearBegin(AYear, AMonth, ADay); + } + else if (AType == TCalendarType.ctJulian) + { + return (AYear - 1) * 365 + ((AYear - 1) / 4) + + GetDayFromYearBegin(AYear, AMonth, ADay) - 2; + } + return 0; + } + private static int GetDayFromYearBegin(int AYear, int AMonth, int ADay) + { + int[] JQData1 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + int[] JQData2 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; + bool IsLeapYear = GetIsLeapYear(AYear); + if (IsLeapYear) + { + return JQData2[AMonth - 1] + ADay; + } + else + { + return JQData1[AMonth - 1] + ADay; + } + } + /// + /// 取本月天数,不考虑 1582 年 10 月的特殊情况 + /// + /// + /// + /// + private static int GetMonthDays(int AYear, int AMonth) + { + switch (AMonth) + { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return 31; + case 4: + case 6: + case 9: + case 11: + return 30; + case 2: + if (GetIsLeapYear(AYear)) + { return 29; } + else { return 28; } + default: + return 0; + } + } + /// + /// 获取节气,范围约1901-2101年 + /// + /// + /// + public static int GetJieQiFromDay(DateTime dt) + { + return GetJieQiFromDay(dt.Year, dt.Month, dt.Day); + } + /// + /// 获取节气,范围约0-9999年 + /// + /// + /// + /// + /// + public static int GetJieQiFromDay(int AYear, int AMonth, int ADay) + { + int Idx; + int result = -1; + Idx = (AMonth - 1) * 2; + if (ADay >= 15) { Idx++; } + if (GetJieQiInAYear(AYear, Idx, out int Month, out int Day, out int DummyHour, out int DummyMinute)) + { + if ((AMonth == Month) && (ADay == Day)) + { + // 此时 I 表示 0 是小寒 + result = Idx - 2; + // 转换成 0 是立春 + if (result < 0) + result += 24; + return result; + } + } + return result; + } + /// + /// 获取节气 + /// + /// + /// + /// + /// + /// + /// + /// + public static bool GetJieQiInAYear(int AYear, int N, out int AMonth, out int ADay, out int AHour, out int AMinitue) + { + double Days; + int Day; + bool Result = N >= 0 && N <= 23; + AMonth = 1; + if (Result) + { + Days = GetJieQiDayTimeFromYear(AYear, N + 1,true); + for (int i = 1; i <= 12; i++) + { + Day = GetMonthDays(AYear, i); + if (Days > Day) + { + Days = Days - Day; + } + else + { + AMonth = i; break; + } + } + ADay = Convert.ToInt32(Math.Floor(Days)); + Days = Days - ADay; + AHour = Convert.ToInt32(Math.Floor(Days * 24)); + Days = Days * 24 - AHour; + AMinitue = Convert.ToInt32(Math.Round(Days * 60)); + // 如果分恰好等于 60,则小时数要加一,如果小时恰好到了 24,则天数要加一 + if (AMinitue >= 60) + { + AMinitue -= 60; AHour++; + if (AHour >= 24) { AHour -= 24; ADay++; } + // 节气不在月底,因此一般不用考虑天数加一后月份改变的情况 + } + } + else + { + AMonth = 0; + ADay = 0; + AHour = 0; + AMinitue = 0; + } + return Result; + } + private static bool GetIsLeapYear(int AYear) + { + if (GetCalendarType(AYear, 1, 1) == TCalendarType.ctGregorian) + { + return (AYear % 4 == 0) && ((AYear % 100 != 0) || (AYear % 400 == 0)); + } + else if (AYear >= 0) + { + return (AYear % 4 == 0); + } + else // 需要独立判断公元前的原因是没有公元 0 年 + { + return (AYear - 3) % 4 == 0; + } + } + /// + /// 获取公历节日 + /// + /// + /// + public static string GetHoliday(DateTime dt) + { + return GetHoliday(dt.Year, dt.Month,dt.Day); + } + /// + /// 获取公历节日 + /// + /// + /// + /// + /// + public static string GetHoliday(int AYear, int AMonth, int ADay) + { + string strReturn = ""; + object g = gHoliday[AMonth.ToString("00") + ADay.ToString("00")]; + if (g != null) + { + strReturn = GetHolidayStr(g.ToString(), new DateTime(AYear, AMonth, ADay)); + } + return strReturn; + } + private static string GetHolidayStr(string str,DateTime dt) + { + if (str.IndexOf(":") > 0) + { + string[] g_split = str.Split(':'); + string[] year_split = g_split[1].Split('-'); + if (year_split.Length == 1) + { + if (dt.Year >= year_split[0].ToInt()) + { return g_split[0]; } + else { return ""; } + } + else if (year_split.Length == 2) { if (dt.Year >= year_split[0].ToInt() && dt.Year <= year_split[1].ToInt()) { return g_split[0]; } else { return ""; } } + } + return str; + } + /// + /// 获取指定月份的第n个星期几的节日 + /// + /// + /// + public static string GetWeekHoliday(DateTime dt) + { + string strReturn = ""; + int week= RyDate.GetWeek_index(dt); + int week_num = (dt.Day / 7) + 1; + if(dt.Day % 7 == 0) { week_num--; } + object g = wHoliday[dt.Month.ToString("00") + week_num.ToString()+ week.ToString()]; + if (g != null) + { + strReturn = GetHolidayStr(g.ToString(),dt); + } + if(dt.AddDays(7).Month!=dt.Month) + { + object g1 = wHoliday[dt.Month.ToString("00") + "0" + week.ToString()]; + if (g1 != null) + { + strReturn +=" "+ GetHolidayStr(g1.ToString(), dt); + } + } + return strReturn.Trim(); + } + /// + /// 返回星座,范围约1901-2101年 + /// + public static string GetXingzuo(DateTime solarDateTime) + { + return GetXingzuo(solarDateTime.Month, solarDateTime.Day); + } + /// + /// 返回星座,范围约0-9999年 + /// + public static string GetXingzuo(int AMonth, int ADay) + { + int constellation = -1; + int Y = AMonth * 100 + ADay; + if (((Y >= 321) && (Y <= 419))) { constellation = 0; } + else if ((Y >= 420) && (Y <= 520)) { constellation = 1; } + else if ((Y >= 521) && (Y <= 620)) { constellation = 2; } + else if ((Y >= 621) && (Y <= 722)) { constellation = 3; } + else if ((Y >= 723) && (Y <= 822)) { constellation = 4; } + else if ((Y >= 823) && (Y <= 922)) { constellation = 5; } + else if ((Y >= 923) && (Y <= 1022)) { constellation = 6; } + else if ((Y >= 1023) && (Y <= 1121)) { constellation = 7; } + else if ((Y >= 1122) && (Y <= 1221)) { constellation = 8; } + else if ((Y >= 1222) || (Y <= 119)) { constellation = 9; } + else if ((Y >= 120) && (Y <= 218)) { constellation = 10; } + else if ((Y >= 219) && (Y <= 320)) { constellation = 11; } + + string con = "白羊金牛双子巨蟹狮子处女天秤天蝎射手摩羯水瓶双鱼"; + return con.Substring(2 * constellation, 2) + "座"; + } + /// + /// 获取农历节日 + /// + /// + /// + /// + /// + public static string GetChinaHoliday(int AYear, int AMonth, int ADay) + { + string strReturn = ""; + GetLunarFromDay(AYear, AMonth, ADay, out int LunarYear, out int LunarMonth, out int LunarDay, out bool IsLeapMonth); + int year = LunarYear; + int iMonth = LunarMonth; + int iDay = LunarDay; + if (iMonth == 12 && GetLunarMonthDays(LunarYear, LunarMonth, IsLeapMonth) == iDay) + { + strReturn = "除夕"; + } + else if (!IsLeapMonth) + { + object n = nHoliday[iMonth.ToString("00") + iDay.ToString("00")]; + if (n != null) + { + if (strReturn == "") + { + strReturn = GetHolidayStr(n.ToString(), new DateTime(AYear, AMonth, ADay)); + } + else + { + strReturn += " " + GetHolidayStr(n.ToString(), new DateTime(AYear, AMonth, ADay)); + } + } + } + + return strReturn; + } + /// + /// 获取农历节日 + /// + /// + /// + public static string GetChinaHoliday(DateTime dt) + { + return GetChinaHoliday(dt.Year,dt.Month,dt.Day); + } + /// + /// 判断y年m月(1,2,..,12,下同)d日是Gregorian历还是Julian历(opt=1,2,3分别表示标准日历,Gregorge历和Julian历),是则返回1,是Julian历则返回0,若是Gregorge历所删去的那10天则返回-1 + /// + private static int IfGregorian(int y, int m, int d, int opt) + { + if (opt == 1) + { + if (y > 1582 || (y == 1582 && m > 10) || (y == 1582 && m == 10 && d > 14)) + return (1); //Gregorian + else + if (y == 1582 && m == 10 && d >= 5 && d <= 14) + return (-1); //空 + else + return (0); //Julian + } + + if (opt == 2) + return (1); //Gregorian + if (opt == 3) + return (0); //Julian + return (-1); + } + /// + /// 返回阳历y年m月d日的日差天数(在y年年内所走过的天数,如2000年3月1日为61) + /// + private static int DayDifference(int y, int m, int d) + { + int ifG = IfGregorian(y, m, d, 1); + int[] monL = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + if (ifG == 1) + if ((y % 100 != 0 && y % 4 == 0) || (y % 400 == 0)) + monL[2] += 1; + else + if (y % 4 == 0) + monL[2] += 1; + int v = 0; + for (int i = 0; i <= m - 1; i++) + { + v += monL[i]; + } + v += d; + if (y == 1582) + { + if (ifG == 1) + v -= 10; + if (ifG == -1) + v = 0; //infinity + } + return v; + } + /// + /// 返回阳历y年日差天数为x时所对应的月日数(如y=2000,x=274时,返回1001(表示10月1日,即返回100*m+d)) + /// + private static double AntiDayDifference(int y, double x) + { + int m = 1; + for (int j = 1; j <= 12; j++) + { + int mL = DayDifference(y, j + 1, 1) - DayDifference(y, j, 1); + if (x <= mL || j == 12) + { + m = j; + break; + } + else + x -= mL; + } + return 100 * m + x; + } + /// + /// 获取指定日期的节气。 + /// + /// 要获取的年 + /// 要获取的月 + /// + /// + /// 立春:立是开始的意思,春是蠢动,表示万物开始有生气,这一天春天开始。 + /// 雨水:降雨开始,雨水将多。 + /// 惊蛰:春雷响动,惊动蛰伏地下冬眠的生物,它们将开始出土活动。 + /// 春分:这是春季九十天的中分点,这一天昼夜相等,所以古代曾称春分秋分为昼夜分。 + /// 清明:明洁晴朗,气候温暖,草木开始萌发繁茂。 + /// 谷雨:雨生百谷的意思。雨水增多,适时的降雨对谷物生长很为有利。 + /// 立夏:夏天开始,万物渐将随温暖的气候而生长。 + /// 小满:满指籽粒饱满,麦类等夏热作物这时开始结籽灌浆,即将饱满。 + /// 芒种:有芒作物开始成熟,此时也是秋季作物播种的最繁忙时节。 + /// 夏至:白天最长,黑夜最短,这一天中午太阳位置最高,日影短至终极,古代又称这一天为日北至或长日至。 + /// 小暑:暑是炎热,此时还未到达最热。 + /// 大暑:炎热的程度到达高峰。 + /// 立秋:秋天开始,植物快成熟了。 + /// 处暑:处是住的意思,表示暑气到此为止。 + /// 白露:地面水气凝结为露,色白,是天气开始转凉了。 + /// 秋分:秋季九十天的中间,这一天昼夜相等,同春分一样,太阳从正东升起正西落下。 + /// 寒露:水露先白而后寒,是气候将逐渐转冷的意思。 + /// 霜降:水气开始凝结成霜。 + /// 立冬:冬是终了,作物收割后要收藏起来的意思,这一天起冬天开始。 + /// 小雪:开始降雪,但还不多。 + /// 大雪:雪量由小增大。 + /// 冬至:这一天中午太阳在天空中位置最低,日影最长,白天最短, 黑夜最长,古代又称短日至或日南至。 + /// 小寒:冷气积久而为寒,此时尚未冷到顶点。 + /// 大寒:天候达到最寒冷的程度 + /// + public static SolarTerm[] GetSolarTerm(int year, int month) + { + string[] lunarHoliDayName ={ + "小寒", "大寒", "立春", "雨水","惊蛰", "春分", "清明", "谷雨","立夏", "小满", "芒种", "夏至", + "小暑", "大暑", "立秋", "处暑","白露", "秋分", "寒露", "霜降","立冬", "小雪", "大雪", "冬至"}; + SolarTerm[] solarTerm = new SolarTerm[2]; + + for (int n = month * 2 - 1; n <= month * 2; n++) + { + SolarTerm st = new SolarTerm(); + double dd = GetJieQiDayTimeFromYear(year, n, true); + double sd1 = AntiDayDifference(2005, Math.Floor(dd)); + double sm1 = Math.Floor(sd1 / 100); + int h = (int)Math.Floor(GetTail(dd) * 24); + int min = (int)Math.Floor((GetTail(dd) * 24 - h) * 60); + int mmonth = (int)Math.Ceiling((double)n / 2); + int day = (int)sd1 % 100; + st.SolarTermDateTime = new DateTime(year, mmonth, day, h, min, 0); + st.Name = lunarHoliDayName[n - 1]; + solarTerm[n - month * 2 + 1] = st; + } + return solarTerm; + } + #region 天干地支 + /// + /// 获取年柱。 + /// + public static int GetEraYear(DateTime solarDateTime) + { + int g = (solarDateTime.Year - 1900 + 36) % 60; + if ((DayDifference(solarDateTime.Year, solarDateTime.Month, solarDateTime.Day) + solarDateTime.Hour / 24) < GetJieQiDayTimeFromYear(solarDateTime.Year, 3, true) - 1) + {//判断是否过立春 + g -= 1; + } + return g + 1; + } + /// + /// 获得月柱 + /// + /// + /// + public static int GetEraMonth(DateTime solarDateTime) + { + int v = ((solarDateTime.Year - 1900) * 12 + solarDateTime.Month + 12) % 60; + if (solarDateTime.Day <= GetSolarTerm(solarDateTime.Year, solarDateTime.Month)[0].SolarTermDateTime.Day) + v -= 1; + return v + 1; + } + /// + /// 获取日柱。 + /// + public static int GetEraDay(DateTime solarDateTime) + { + double gzD = (solarDateTime.Hour < 23) ? GetEquStandardDays(solarDateTime.Year, solarDateTime.Month, solarDateTime.Day) : GetEquStandardDays(solarDateTime.Year, solarDateTime.Month, solarDateTime.Day) + 1; + return (int)Math.Round((double)GetRemain((int)gzD + 15, 60)); + } + /// + /// 返回甲子数x对应的天干数(如33为3) + /// + private static int Gan(int x) + { + return x % 10; + } + /// + /// 返回甲子数x对应的地支数(如33为9) + /// + private static int Zhi(int x) + { + return x % 12; + } + /// + /// 获取日的天干地支 + /// + /// + /// + public static string GetDayTGDZ(DateTime solarDateTime) + { + string yearTG = "甲乙丙丁戊己庚辛壬癸"; + string yearDZ = "子丑寅卯辰巳午未申酉戌亥"; + int dG = Gan(GetEraDay(solarDateTime)); + int dZ = Zhi(GetEraDay(solarDateTime)); + if (dG == 0) { dG = 10; } + if (dZ == 0) { dZ = 12; } + return yearTG.Substring(dG - 1, 1) + yearDZ.Substring(dZ - 1, 1); + } + /// + /// 返回甲子数x对应的天干字符串 + /// + public static string ToStringWithCelestialStem(int x) + { + return "癸甲乙丙丁戊己庚辛壬".Substring(x % 10, 1); + } + + /// + /// 返回甲子数x对应的地支字符串 + /// + public static string ToStringWithTerrestrialBranch(int x) + { + return "亥子丑寅卯辰巳午未申酉戌".Substring(x % 12, 1); + } + /// + /// 返回甲子数x对应的干支字符串 + /// + /// + /// + public static string ToStringWithSexagenary(int x) + { + return ToStringWithCelestialStem(x) + ToStringWithTerrestrialBranch(x); + } + #endregion + /// + /// 获取三伏开始时间 + /// + /// + /// 0表示1伏,1表示2伏,2表示3伏 + /// + public static DateTime Get3Fu(int Year, int index) + { + if (index <= 1) + { + var day_count = GetJieQiDayTimeFromYear(Year, 12, true); + var xiazhi_date = new DateTime(Year, 1, 1).AddDays(day_count - 1).Date; //获取夏至 //ToStringWithSexagenary(GetEraDay(xiazhi_date)); + var first_geng_date = xiazhi_date.AddDays(1);//获取夏至后的首个庚日 + for (int i = 0; i < 20; i++) + { + if (ToStringWithCelestialStem(GetEraDay(first_geng_date.AddDays(i))) == "庚") + { + first_geng_date = first_geng_date.AddDays(i); break; + } + } + if (index == 0) { return first_geng_date.AddDays(20); } + else if (index == 1) { return first_geng_date.AddDays(30); } + } + else if (index == 2)//末伏开始的时间是立秋后的第一个庚日 + { + var day_count = GetJieQiDayTimeFromYear(Year, 15, true);//立秋 + var liqiu_date = new DateTime(Year, 1, 1).AddDays(day_count - 1).Date; //获取立秋 //ToStringWithSexagenary(GetEraDay(xiazhi_date)); + var first_geng_date = liqiu_date.AddDays(1);//获取立秋后的首个庚日 + for (int i = 0; i < 20; i++) + { + if (ToStringWithCelestialStem(GetEraDay(first_geng_date.AddDays(i))) == "庚") + { + first_geng_date = first_geng_date.AddDays(i); break; + } + } + return first_geng_date; + } + return new DateTime(2000, 1, 1); + } +} +/// +/// 节气 +/// +public class SolarTerm +{ + private DateTime solarTermDate; + private string name; + /// + /// 节气的时间。 + /// + public DateTime SolarTermDateTime + { + get + { + return solarTermDate; + } + set + { + solarTermDate = value; + } + } + + /// + /// 节气名。 + /// + public string Name + { + get + { + return name; + } + set + { + name = value; + } + } +} diff --git a/Source/MyDb/SysFuns/HotkeyValue.cs b/Source/MyDb/SysFuns/HotkeyValue.cs new file mode 100644 index 0000000..92b7459 --- /dev/null +++ b/Source/MyDb/SysFuns/HotkeyValue.cs @@ -0,0 +1,308 @@ +using ryCommon; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace SysFuns +{ + /// + /// 热键转换类 + /// + public class HotkeyValue + { + /// + /// 功能键。 + /// + public Keys Modifiers { get; private set; } = Keys.None; + /// + /// 修改键。 + /// + public int Modifiers_Int { get; private set; } = 0; + /// + /// 转换功能键到谷歌浏览器专用 + /// + public int Chrome_Modifiers + { + get + { + int Pb_Modifiers = 0; + try + { + if ((Modifiers_Int & 4) == 4) { Pb_Modifiers += 2; } + if ((Modifiers_Int & 2) == 2) { Pb_Modifiers += 4; } + if ((Modifiers_Int & 1) == 1) { Pb_Modifiers += 8; } + } + catch { } + return Pb_Modifiers; + } + } + /// + /// 将chrome功能键转换为普通功能键 + /// + /// + /// + public int Modifiers_FromChrome(int _Modifiers) + { + int Pb_Modifiers = 0; + try + { + if ((_Modifiers & 2) == 2) { Pb_Modifiers += 4; } + if ((_Modifiers & 4) == 4) { Pb_Modifiers += 2; } + if ((_Modifiers & 8) == 8) { Pb_Modifiers += 1; } + } + catch { } + return Pb_Modifiers; + } + /// + /// 按键值。 + /// + public Keys KeyCode { get; private set; } = Keys.None; + /// + /// 初始化类 的新实例。 + /// + /// The modifiers. + /// The key code. + public HotkeyValue(Keys modifiers, Keys keyCode) + { + LoadHotKey(modifiers, keyCode); + } + /// + /// + /// + /// + /// + public HotkeyValue(int Modifiers, int T_Key) + { + this.Modifiers = ConvertModifier(Modifiers); + this.Modifiers_Int = Modifiers; + this.KeyCode = (Keys)T_Key; + } + /// + /// + /// + /// + public HotkeyValue(string hotkey) + { + LoadHotKey(hotkey); + } + /// + /// 初始化类 的新实例。 + /// + public HotkeyValue() + { + LoadHotKey(Keys.None, Keys.None); + } + /// + /// 加载热键 + /// + /// + /// + public void LoadHotKey(Keys modifiers, Keys keyCode) + { + this.Modifiers = modifiers; + this.KeyCode = keyCode; + int m_key = 0; + Keys m_Modifiers = Modifiers; + if ((m_Modifiers & Keys.Alt) != 0) + { m_key |= 1; } + else if ((m_Modifiers & Keys.Control) != 0) + { m_key |= 2; } + else if ((m_Modifiers & Keys.Shift) != 0) + { m_key |= 4; } + else if ((m_Modifiers & Keys.LWin) != 0) + { m_key |= 8; } + this.Modifiers_Int = m_key; + } + /// + /// 加载热键 + /// + /// + public void LoadHotKey(string hotkey) + { + int T_Modifiers = 0; + Keys T_Key = Keys.None; + try + { + string[] item = hotkey.Split('+'); + if (item.Length == 1 && item[0].IsInt()) + { + T_Modifiers = 0; + T_Key = (Keys)item[0].ToInt(0); + } + else if (item.Length == 2 && item[0].IsInt() && item[1].IsInt()) + { + T_Modifiers = item[0].ToInt(0); + T_Key = (Keys)item[1].ToInt(0); + } + } + catch + { + + } + this.Modifiers_Int = T_Modifiers; + this.Modifiers = ConvertModifier(T_Modifiers); + this.KeyCode = T_Key; + } + /// + /// 加载热键 + /// + /// + public void LoadHotKeyStr(string hotkey) + { + int T_Modifiers = 0; + Keys T_Key = Keys.None; + try + { + string[] item = hotkey.Split('+'); + if (item.Length == 1) + { + T_Modifiers = 0; + var key = item[0]; + if(key.Length==1) + { + T_Key = Keys.None; + } + else + { + GetKey(key); + } + } + else if (item.Length == 2) + { + if (!IsModifiersKey(item[0])) + { T_Modifiers = 0; T_Key = Keys.None; } + else + { + var mkeys = Enum.Parse(typeof(SysFuns.KeyModifiers), item[0]); + T_Modifiers = (int)mkeys; + GetKey(item[1]); + } + } + else if (item.Length == 3) + { + if (!IsModifiersKey(item[0]) || !IsModifiersKey(item[1]) || item[0] == item[1]) + { T_Modifiers = 0; T_Key = Keys.None; } + else + { + var mkeys1 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[0]); + var mkeys2 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[1]); + T_Modifiers = (int)mkeys1 + (int)mkeys2; + GetKey(item[2]); + } + } + else if (item.Length ==4) + { + if (!IsModifiersKey(item[0]) || !IsModifiersKey(item[1]) || !IsModifiersKey(item[2]) + || item[0] == item[1] || item[1] == item[2] || item[2] == item[3]) + { T_Modifiers = 0; T_Key = Keys.None; } + else + { + var mkeys1 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[0]); + var mkeys2 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[1]); + var mkeys3 = Enum.Parse(typeof(SysFuns.KeyModifiers), item[1]); + T_Modifiers = (int)mkeys1 + (int)mkeys2 + (int)mkeys3; + GetKey(item[3]); + } + } + } + catch + { + + } + bool IsModifiersKey(string _key) + { + return Enum.TryParse(_key, out KeyModifiers mkey); + } + void GetKey(string _key) + { + if (_key == "Enter") { T_Key = Keys.Enter; } + else if (_key == "Esc") { T_Key = Keys.Escape; } + else if (_key == "PgDn") { T_Key = Keys.PageDown; } + else + { + try + { + + if (!Enum.TryParse(_key, out T_Key)) + { T_Modifiers = 0; T_Key = Keys.None; } + else + { + var keys = Enum.Parse(typeof(Keys), _key); + T_Key = (Keys)keys; + } + } + catch { + } + } + } + this.Modifiers_Int = T_Modifiers; + this.Modifiers = ConvertModifier(T_Modifiers); + this.KeyCode = T_Key; + } + private Keys ConvertModifier(int Modifiers) + { + Keys m_Modifiers = Keys.None; + if ((Modifiers & 1) != 0) + { m_Modifiers |= Keys.Alt; } + if ((Modifiers & 2) != 0) + { m_Modifiers |= Keys.Control; } + if ((Modifiers & 4) != 0) + { m_Modifiers |= Keys.Shift; } + if ((Modifiers & 8) != 0) + { m_Modifiers |= Keys.LWin; } + return m_Modifiers; + } + /// + /// 判断是否是热键 + /// + public bool IsHotKey => KeyCode != Keys.None || (Modifiers == Keys.None && KeyCode > Keys.A && KeyCode < Keys.Z); + /// + /// 获取当前热键 + /// + public string HotKey + { + get + { + if (KeyCode == Keys.None) + { return "0"; } + return Modifiers_Int.ToString() + "+" + ((int)KeyCode).ToString(); + } + } + /// + /// 已重载,返回“Ctrl+Alt+A”格式的字符串。 + /// + /// 类似“Ctrl+Alt+A”格式的字符串 + public override string ToString() + { + string sbt = ""; + if ((this.Modifiers & Keys.Control) != 0) + { sbt += "Ctrl+"; } + if ((this.Modifiers & Keys.Shift) != 0) + { sbt += "Shift+"; } + if ((this.Modifiers & Keys.Alt) != 0) + { sbt += "Alt+"; } + if ((this.Modifiers & Keys.LWin) != 0 || (this.Modifiers & Keys.RWin) != 0) + { sbt += "Win+"; } + if (this.KeyCode != Keys.None) + sbt += this.KeyCode.ToString(); + if (sbt.Length != 0) + { + return sbt; + } + else + { + return "无热键"; + } + } + /// + /// 返回“Ctrl+Alt+A”格式的字符串。 + /// + /// 类似“Ctrl+Alt+A”格式的字符串 + public string ToStr() + { + return ToString(); + } + } +} diff --git a/Source/MyDb/SysFuns/ModalResult.cs b/Source/MyDb/SysFuns/ModalResult.cs new file mode 100644 index 0000000..fdb6885 --- /dev/null +++ b/Source/MyDb/SysFuns/ModalResult.cs @@ -0,0 +1,240 @@ +using System; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 新模态窗体 + /// + public class ModalForm + { + /// + /// 设置窗体返回的结果值,并关闭窗体。 + /// + /// 当前窗体 + /// 模态变量 + /// 防止 + public static void SetDialogResult(Form frm, ModalForm mr,DialogResult dr) + { + if(mr==null) + { + if(frm.Modal) + { + frm.DialogResult = dr; + } + else { frm.Close(); } + } + else + { mr.Form_Result = dr; } + } + /// + /// 窗体返回的结果事件 + /// + /// + /// + public delegate void DialogResultHandler(object sender, DialogResult e); + /// + /// 当打开的窗体返回结果时激发 + /// + public event DialogResultHandler OnDialogResult; + DialogResult dg = DialogResult.None; + /// + /// 窗体返回的状态 + /// + public DialogResult Form_Result + { + set { dg = value; sub_Form.Close(); } + get { return dg; } + } + private Form parent; + private Form sub_Form; + /// + /// 实例化类 + /// + /// 父窗体,如果为null,则取桌面为父窗体 + /// + public ModalForm(Form parent,Form sub_Form) + { + this.parent = parent; + this.sub_Form = sub_Form; + } + /// + /// 获取最顶级的父窗口 + /// + /// + private Form GetTopParentForm() + { + var _parent = parent; + while(_parent!=null) + { + if (_parent.Parent != null) { _parent = _parent.Parent.FindForm(); } + else { break; } + } + return _parent; + } + /// + /// 显示新模态窗体,会暂时禁用父窗体,关闭当前窗体后,父窗体会恢复。 + /// + public void ShowModal() + { + var _parent = GetTopParentForm(); + if (_parent != null) { _parent.Enabled = false; } + sub_Form.FormClosing += new FormClosingEventHandler((object t, FormClosingEventArgs e1) => + { + if (_parent != null){ _parent.Enabled = true; } + OnDialogResult?.Invoke(sub_Form, dg); + }); + if (_parent != null) + { + sub_Form.StartPosition = FormStartPosition.Manual; + MyDb.RyWin32.GetWindowRect(_parent.Handle, out var rect); + sub_Form.Top = rect.Top + (rect.Bottom- rect.Top - sub_Form.Height) / 2; + sub_Form.Left = rect.Left + (rect.Right- rect.Left - sub_Form.Width) / 2; + if (_parent.TopMost) { sub_Form.TopMost = true; } + sub_Form.Show(_parent); + } + else + { + sub_Form.StartPosition = FormStartPosition.CenterScreen; + sub_Form.Show(); + } + } + /// + /// 只运行一个实例,打开后,所有窗体都依然有效。 + /// + /// + public bool ShowOnce() + { + try + { + foreach (Form frm in Application.OpenForms) + { + if (frm.GetType() == sub_Form.GetType()) + { + frm.WindowState = FormWindowState.Normal; + frm.BringToFront(); + return true; + } + } + sub_Form.StartPosition = FormStartPosition.CenterScreen; + if (parent != null) + { + if (parent.TopMost) { sub_Form.TopMost = true; } + sub_Form.Show(parent); + } + else { sub_Form.Show(); } + } + catch { } + return false; + } + /// + /// 显示窗体 + /// + /// 显示的位置 + public void Show(FormLocation location) + { + int x = 0; + int y = 0; + switch(location) + { + case FormLocation.BottomLeft: + x =0; + y = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height - sub_Form.Height; + break; + case FormLocation.BottomMiddle: + x = (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - sub_Form.Width)/2; + y = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height - sub_Form.Height; + break; + case FormLocation.BottomRight: + x = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - sub_Form.Width; + y = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height - sub_Form.Height; + break; + case FormLocation.DesktopMiddle: + x = (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - sub_Form.Width)/2; + y = (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height - sub_Form.Height)/2; + break; + case FormLocation.ParentMiddle: + if (parent != null) + { + MyDb.RyWin32.GetWindowRect(parent.Handle, out var rect); + x = rect.Left + (rect.Right- rect.Left - sub_Form.Width) / 2; + y = rect.Top + (rect.Bottom- rect.Top - sub_Form.Height) / 2; + } + else + { + x = (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - sub_Form.Width) / 2; + y = (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height - sub_Form.Height) / 2; + } + break; + case FormLocation.TopLeft: + x =0; + y =0; + break; + case FormLocation.TopMiddle: + x = (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - sub_Form.Width) / 2; ; + y = 0; + break; + case FormLocation.TopRight: + x = (System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - sub_Form.Width); ; + y = 0; + break; + } + sub_Form.Load += new EventHandler((object t, EventArgs e) => + { + sub_Form.SetDesktopLocation(x, y); + try + { + sub_Form.BringToFront(); + } + catch { } + }); + if (parent != null) { if (parent.TopMost) { sub_Form.TopMost = true; } } + sub_Form.Show(); + } + /// + /// 显示在父窗体中间 + /// + public void Show() + { + Show(FormLocation.ParentMiddle); + } + } + /// + /// 窗体显示位置 + /// + public enum FormLocation + { + /// + /// 右上角 + /// + TopLeft, + /// + /// 顶部中间 + /// + TopMiddle, + /// + /// 顶部右边 + /// + TopRight, + /// + /// 中间 + /// + DesktopMiddle, + /// + /// 左下角 + /// + BottomLeft, + /// + /// 底部中间 + /// + BottomMiddle, + /// + /// 右下角 + /// + BottomRight, + /// + /// 父窗体居中 + /// + ParentMiddle, + } +} diff --git a/Source/MyDb/SysFuns/RyDate.cs b/Source/MyDb/SysFuns/RyDate.cs new file mode 100644 index 0000000..7cef68e --- /dev/null +++ b/Source/MyDb/SysFuns/RyDate.cs @@ -0,0 +1,283 @@ +using ryCommon.Pram; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ryCommon +{ + /// + /// 日期时间的操作类 + /// + public class RyDate + { + /// + /// 获取当前是周几,周一到周日,分别是1-7. + /// + /// + /// + public static int GetWeek_index(DateTime dt) + { + int week_index = dt.DayOfWeek.ToInt(); if (week_index == 0) { week_index = 7; }//获取当前是周几 + return week_index; + } + /// + /// 获取当前是周几,1-7,分别是返回一到日. + /// + /// + /// + public static string GetWeekName(int index) + { + string[] week = "一,二,三,四,五,六,日".Split(','); + if (index.IsInRange(1, 7)) + { + return week[index - 1]; + } + else + return "" ; + } + /// + /// 获取当前是周几,输入日期,根据周几,分别是返回一到日. + /// + /// + /// + public static string GetWeekName(DateTime dt) + { + return GetWeekName(GetWeek_index(dt)); + } + /// + /// 获取一周的开始和结束,开始时间为第一天的0点,结束时间以最后一天的0点为结束时间 + /// + /// + /// + public static WeekInfo GetWeekInfo(DateTime dt) + { + int week_index = GetWeek_index(dt);//获取当前是周几 + WeekInfo info = new WeekInfo() { startDate = dt.Date.AddDays(-week_index + 1), endDate = dt.Date.AddDays(7 - week_index) }; + return info; + } + /// + /// 获取2个日期相差几周 + /// + /// + /// + /// + public static int GetWeekCount(DateTime dt1, DateTime dt2) + { + return (GetWeekInfo(dt2).startDate - GetWeekInfo(dt1).startDate).TotalDays.ToInt() / 7; + } + /// + /// 获取2个日期相差几个月 + /// + /// + /// + /// + public static int GetMonthCount(DateTime dt1, DateTime dt2) + { + return dt2.Year * 12 + dt2.Month - dt1.Year * 12 - dt1.Month; + } + /// + /// 获取一个月的开始 + /// + /// + /// + public static DateTime GetMonthStart(DateTime dt) + { + return dt.AddDays(-dt.Day+1).Date; + } + /// + /// 判断是否在同一个星期。 + /// + /// + /// + /// + public static bool InSameWeek(DateTime dt1, DateTime dt2) + { + return GetWeekInfo(dt2).startDate==GetWeekInfo(dt1).startDate; + } + /// + /// 判断是否在同一个月。 + /// + /// + /// + /// + public static bool InSameMonth(DateTime dt1, DateTime dt2) + { + return dt2.Year==dt1.Year && dt2.Month==dt1.Month; + } + /// + /// 判断是否在同一天 + /// + /// + /// + /// + public static bool InSameDay(DateTime dt1, DateTime dt2) + { + return dt2.Date == dt1.Date; + } + + /// + /// 计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + /// + /// 第一个日期和时间 + /// 第二个日期和时间 + /// + public static string DateDiff(DateTime DateTime1, DateTime DateTime2) + { + return DateDiff(DateTime1, DateTime2, true); + } + /// + /// 计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值. + /// + /// 第一个日期和时间 + /// 第二个日期和时间 + /// 是否显示秒 + /// + public static string DateDiff(DateTime DateTime1, DateTime DateTime2,bool seconds) + { + string dateDiff = ""; + try + { + TimeSpan ts1 = new TimeSpan(DateTime1.Ticks); + TimeSpan ts2 = new TimeSpan(DateTime2.Ticks); + TimeSpan ts = ts1.Subtract(ts2).Duration(); + if (ts.Days != 0) + { + dateDiff = ts.Days.ToString() + "天"; + } + if (ts.Hours != 0) + { + dateDiff += ts.Hours.ToString() + "小时"; + } + if (ts.Minutes != 0) + { + dateDiff += ts.Minutes.ToString() + "分钟"; + } + if (ts.Seconds != 0 && seconds) + { + dateDiff += ts.Seconds.ToString() + "秒"; + } + } + catch + { + + } + if (dateDiff == "") { dateDiff = "0"+ (seconds?"秒": "分钟"); } + return dateDiff; + } + /// + /// 计算一个时间与当前本地日期和时间的时间间隔,返回的是时间间隔的日期差的绝对值. + /// + /// 一个日期和时间 + /// + public static string DateDiff(DateTime DateTime1) + { + return DateDiff(DateTime1, DateTime.Now); + } + /// + /// 将c# DateTime时间格式转换为Unix时间戳格式 + /// + /// 时间 + /// long + public static long DateTimeToUnixTime(System.DateTime time) + { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 + long timeStamp = (long)(time - startTime).TotalSeconds; // 相差秒数 + return timeStamp; + } + /// + /// 时间戳转为C#格式时间 + /// + /// + /// + public static DateTime UnixTimeToDateTime(string timeStamp) + { + try + { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 + DateTime dt = startTime.AddSeconds(timeStamp.ToInt64(0)); + return dt; + } + catch { return new System.DateTime(1970, 1, 1); } + } + /// + /// 将c# DateTime时间格式转换为js时间戳格式 + /// + /// 时间 + /// long + public static long DateTimeToJSTime(System.DateTime time) + { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 + long timeStamp = (long)(time - startTime).TotalMilliseconds; // 相差毫秒数 + return timeStamp; + } + /// + /// JS时间戳转为C#格式时间 + /// + /// + /// + public static DateTime JSTimeToDateTime(string timeStamp) + { + try + { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 + DateTime dt = startTime.AddMilliseconds(timeStamp.ToInt64(0)); + return dt; + } + catch { return new System.DateTime(1970, 1, 1); } + } + /// + /// 根据年月日转换成日期 + /// + /// + /// + /// + /// + public static DateTime ToDate(int year, int month, int day) + { + try + { + return new DateTime(year, month, day); + } + catch { return new DateTime(2000, 1, 1); } + } + /// + /// 根据日期和时间转换成日期时间 + /// + /// + /// + /// + public static DateTime ToDateTime(DateTime date,DateTime time) + { + return new DateTime(date.Year, date.Month, date.Day, time.Hour, time.Minute, time.Second, time.Millisecond); + } + /// + /// 将时间转换成当前分钟开始的时间 + /// + /// + /// + public static DateTime StartMinute(DateTime dt) + { + return dt.AddMilliseconds(-dt.Millisecond).AddSeconds(-dt.Second); + } + /// + /// 将时间转换成当前秒钟开始的时间 + /// + /// + /// + public static DateTime StartSecond(DateTime dt) + { + return dt.AddMilliseconds(-dt.Millisecond); + } + /// + /// 当前时间在这一天里的秒数 + /// + /// + /// + public static Int64 DaySecond(DateTime dt) + { + return dt.Hour*3600+dt.Minute*60+dt.Second; + } + } + +} diff --git a/Source/MyDb/SysFuns/RyForm.cs b/Source/MyDb/SysFuns/RyForm.cs new file mode 100644 index 0000000..97451a8 --- /dev/null +++ b/Source/MyDb/SysFuns/RyForm.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 窗体操作类 + /// + public class RyForm + { + /// + /// 设置Comobox的行间距 + /// + /// + /// + public static void CmbBind(ComboBox list, int itemHeight) + { + list.DropDownStyle = ComboBoxStyle.DropDownList; + list.ItemHeight = itemHeight; + list.DrawMode = DrawMode.OwnerDrawFixed; + list.DrawItem += new DrawItemEventHandler(delegate (object sender, DrawItemEventArgs e) + { + if (e.Index < 0) + { + return; + } + e.DrawBackground(); + e.DrawFocusRectangle(); + e.Graphics.DrawString(list.Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds.X, e.Bounds.Y + 3); + }); + } + /// + /// 移除关闭按钮。返回值,非零表示成功,零表示失败。 + /// + /// 窗口的句柄 + /// 是否成功 + public static int RemoveXButton(IntPtr iHWND) + { + int iSysMenu; + const int MF_BYCOMMAND = 0x400; //0x400-关闭 + iSysMenu = MyDb.RyWin32.GetSystemMenu(iHWND, 0); + return MyDb.RyWin32.RemoveMenu(iSysMenu, 6, MF_BYCOMMAND); + } + /// + /// 把窗体放到最前 + /// + /// + public static void BringToTop(IntPtr iHWND) + { + MyDb.RyWin32.SetForegroundWindow(iHWND); + } + /// + /// 显示窗体 + /// + /// + /// + /// + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern bool ShowWindow(HandleRef hWnd, int nCmdShow); + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags); + private const int HWND_TOPMOST = -1; + private const int HWND_NOTOPMOST = -2; + private const int SWP_NOACTIVATE = 0x10; + private const int SWP_NOMOVE = 0x2; + private const int SWP_NOSIZE = 0x1; + /// + /// 设置窗体是否置顶 + /// + /// + /// + public static void SetTopMost(IntPtr iHWND,bool TopMost) + { + SetWindowPos(iHWND, (TopMost?HWND_TOPMOST: HWND_NOTOPMOST), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + /// + /// 显示没有焦点的窗口 + /// + /// + public static void ShowNoActiveWindow(Form frm) + { + ShowWindow(new HandleRef(frm, frm.Handle), 4); + } + /// + /// 根据句柄获取窗口文本 + /// + /// + /// + public static string GetWinText(IntPtr Handle) + { + StringBuilder WinTitle = new StringBuilder(200); + int len = MyDb.RyWin32.GetWindowText(Handle.ToInt32(), WinTitle, 200); + return WinTitle.ToString(); + } + + /// + /// 根据句柄获取窗口类 + /// + /// + /// + public static string GetWinClass(IntPtr Handle) + { + StringBuilder WinClass = new StringBuilder(200); + int len = MyDb.RyWin32.GetClassName(Handle.ToInt32(), WinClass, 200); + return WinClass.ToString(); + } + /// + /// 获取当前活动的窗口句柄 + /// + /// + public static IntPtr GetActiveWindow() + { + return MyDb.RyWin32.GetActiveWindow(); + } + /// + /// 设置为当前活动窗口 + /// + /// + /// + public static IntPtr SetActiveWindow(IntPtr hwnd) + { + return MyDb.RyWin32.SetActiveWindow(hwnd); + } + /// + /// 根据窗口句柄来获得进程id + /// + /// + /// + public static int GetProcessId(IntPtr hwnd) + { + MyDb.RyWin32.GetWindowThreadProcessId(hwnd, out int ID); + return ID; + } + /// + /// 显示窗体 + /// + /// + public static void Show(Form frm) + { + bool topmost = frm.TopMost; + frm.BringToFront(); + frm.TopMost = true; + frm.TopMost = topmost; + frm.Show(); + } + /// + /// 设置窗体父窗体为桌面,不会随着显示桌面而最小化,但无法设置窗体透明度 + /// + /// + public static void SetDesktopForm(IntPtr handle) + { + //在构造函数中或者Load中 + IntPtr hDeskTop = MyDb.RyWin32.FindWindow("Progman", null); + MyDb.RyWin32.SetParent(handle, hDeskTop); + } + /// + /// 结束进程 + /// + /// + /// + public static long KillPorc(int pid) + { + return MyDb.RyWin32.TerminateProcess(pid,1); + } + /// + /// 打开窗体,只打开一个实例(非模态) + /// + /// + /// + public static Form ShowOne(Form type) + { + try + { + foreach (Form frm in Application.OpenForms) + { + if (frm.GetType() == type.GetType()) + { + frm.WindowState = FormWindowState.Normal; + frm.BringToFront(); + return frm; + } + } + type.StartPosition = FormStartPosition.CenterScreen; + type.Show(); + return type; + } + catch { } + return null; + } + } +} diff --git a/Source/MyDb/SysFuns/RyRegedit.cs b/Source/MyDb/SysFuns/RyRegedit.cs new file mode 100644 index 0000000..691fb14 --- /dev/null +++ b/Source/MyDb/SysFuns/RyRegedit.cs @@ -0,0 +1,249 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Win32; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 设置注册表操作,部分功能需要管理员权限 + /// + public class RyRegedit + { + /// + /// 访问的注册表位置(64位还是32位) + /// + public static RegistryView UseSystemBit = RegistryView.Default; + /// + /// 访问的注册表节点 + /// + public static RegistryHive RegRoot = RegistryHive.LocalMachine; + /// + /// 设置是否开机启动 + /// + /// 是否开机启动 + /// 开机启动名称 + /// 启动命令 + /// + public static bool SetAutoRun(bool AutoRun, string StartName, string StartCommand) + { + try + { + RegistryKey LMach = RegistryKey.OpenBaseKey(RegRoot, UseSystemBit); + RegistryKey softwareRun = LMach.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); + if (AutoRun) + { softwareRun.SetValue(StartName, StartCommand, RegistryValueKind.String); } + else + { + if (softwareRun.GetValue(StartName) != null) + { + softwareRun.DeleteValue(StartName); + } + } + softwareRun.Close(); + LMach.Close(); + return true; + } + catch + { + return false; + } + } + /// + /// 设置是否开机启动 + /// + /// 是否开机启动 + /// 开机启动名称 + /// + public static bool SetAutoRun(bool AutoRun, string StartName) + { + return SetAutoRun(AutoRun, StartName, "\"" + Application.ExecutablePath + "\" q"); + } + /// + /// 把指定文件设置为开机启动或取消开机启动 + /// + /// 是否开机启动 + /// 开机启动名称 + /// 要开机启动的文件路径 + /// + public static bool SetAutoRunByPath(bool AutoRun, string StartName, string Path) + { + return SetAutoRun(AutoRun, StartName, "\"" + Path + "\" q"); + } + /// + /// 检查是否开机启动 + /// + /// 开机启动名称 + /// 开机启动命令 + /// + public static bool IsAutoRun(string StartName, string StartCommand) + { + try + { + bool sxResult = false; + RegistryKey LMach = RegistryKey.OpenBaseKey(RegRoot, UseSystemBit); + RegistryKey softwareRun = LMach.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + if (softwareRun.GetValue(StartName, "").ToString() == StartCommand) + { sxResult = true; } + else { sxResult = false; } + softwareRun.Close(); + LMach.Close(); + return sxResult; + } + catch + { + return false; + } + } + /// + /// 检查是否开机启动 + /// + /// 开机启动名称 + /// + public static bool IsAutoRun(string StartName) + { + try + { + bool sxResult = false; + RegistryKey LMach = RegistryKey.OpenBaseKey(RegRoot, UseSystemBit); + RegistryKey softwareRun = LMach.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + if (softwareRun.GetValue(StartName, "").ToString() != "") + { sxResult = true; } + else { sxResult = false; } + softwareRun.Close(); + LMach.Close(); + return sxResult; + } + catch + { + return false; + } + } + /// + /// 判断指定文件是否是开机启动 + /// + /// 开机启动名称 + /// 文件路径 + /// + public static bool IsAutoRunByPath(string StartName, string Path) + { + return IsAutoRun(StartName, "\"" + Path + "\" q"); + } + /// + /// 判断当前程序是否是开机启动 + /// + /// 开机启动名称 + /// + public static bool IsAutoRunByMe(string StartName) + { + return IsAutoRun(StartName, "\"" + Application.ExecutablePath + "\" q"); + } + /// + /// 判断当前程序是否是开机启动 + /// + /// 开机启动名称 + /// 启动命令行 + /// + public static bool IsAutoRunByMe(string StartName, string Cmd) + { + return IsAutoRun(StartName, "\"" + Application.ExecutablePath + "\" " + Cmd); + } + /// + /// 设置指定文件的浏览器控件内核版本 + /// + /// 文件名,要求不带路径 + /// 7000 表示IE7兼容视图模式;8000 表示IE8 标准模式 ;8888 表示IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + /// + public static bool SetIE_EMULATION(string filename, uint IEMode) + { + try + { + RegistryKey LMach = RegistryKey.OpenBaseKey(RegRoot, UseSystemBit); + RegistryKey softwareRun = LMach.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", true); + softwareRun.SetValue(filename, IEMode, RegistryValueKind.DWord); + softwareRun.Close(); + LMach.Close(); + return true; + } + catch + { + return false; + } + } + /// + /// 采用的IE模式 + /// + public enum IeMode + { + /// + /// IE7兼容视图 + /// + IE7CompatibleView = 7000, + /// + /// IE8 标准模式 + /// + IE8StandardMode = 8000, + /// + /// IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + /// + IE8Forced = 8888, + /// + /// IE9 标准模式 + /// + IE9StandardMode = 9000, + /// + /// IE9 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + /// + IE9Forced = 9999, + /// + /// IE10 标准模式 + /// + IE10StandardMode = 10000, + /// + /// IE10 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + /// + IE10Forced = 10001 + } + /// + /// 设置当前软件的浏览器控件内核版本 + /// + /// 7000 表示IE7兼容视图模式;8000 表示IE8 标准模式 ;8888 表示IE8 强制标准模式,在渲染失败的情况下不尝试用兼容视图模式 + /// + public static bool SetIE_EMULATION(uint IEMode) + { + return SetIE_EMULATION(System.IO.Path.GetFileName(Application.ExecutablePath), IEMode); + } + /// + /// 设置指定文件的浏览器控件内核版本 + /// + /// 文件名,要求不带路径 + /// IE内核版本 + /// + public static bool SetIE_EMULATION(string filename, IeMode IEMode) + { + try + { + RegistryKey LMach = RegistryKey.OpenBaseKey(RegRoot, UseSystemBit); + RegistryKey softwareRun = LMach.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", true); + softwareRun.SetValue(filename, IEMode, RegistryValueKind.DWord); + softwareRun.Close(); + LMach.Close(); + return true; + } + catch + { + return false; + } + } + /// + /// 设置当前软件的浏览器控件内核版本 + /// + /// IE内核版本 + /// + public static bool SetIE_EMULATION(IeMode IEMode) + { + return SetIE_EMULATION(System.IO.Path.GetFileName(Application.ExecutablePath), IEMode); + } + } +} diff --git a/Source/MyDb/SysFuns/RySysSound.cs b/Source/MyDb/SysFuns/RySysSound.cs new file mode 100644 index 0000000..39d9eb4 --- /dev/null +++ b/Source/MyDb/SysFuns/RySysSound.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ryCommon +{ + /// + /// 系统音量操作类 + /// + public class RySysSound + { + /// + /// 判断系统是否正处于静音 + /// + /// + public static bool IsMute() + { + var osversion = Environment.OSVersion; + if(osversion.Version.Major<6 || (osversion.Version.Major== 6 && osversion.Version.Minor==0)) + { + var mi = SoundControl_XP.GetMixerControls(); + return SoundControl_XP.IsMuted(mi); + } + else + { + var mi = SoundControl.GetMixerControls(); + return SoundControl.IsMuted(mi); + } + } + } +} diff --git a/Source/MyDb/SysFuns/RySystem.cs b/Source/MyDb/SysFuns/RySystem.cs new file mode 100644 index 0000000..23989bb --- /dev/null +++ b/Source/MyDb/SysFuns/RySystem.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace ryCommon +{ + /// + /// 系统函数 + /// + public class RySystem + { + /// + /// + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct RAMP + { + /// + /// 红 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public UInt16[] Red; + /// + /// 绿 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public UInt16[] Green; + /// + /// 蓝 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public UInt16[] Blue; + } + /// + /// 获取屏幕伽马值 + /// + /// + /// + /// + [DllImport("gdi32.dll", SetLastError = true)] + public static extern bool GetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp); + /// + /// 设置屏幕伽马值 + /// + /// + /// + /// + [DllImport("gdi32.dll", SetLastError = true)] + public static extern bool SetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp); + + private static readonly double[] _gammas = { 1, 1, 1 }; + private static short _brightness = 100; + // 创建结构体用于返回捕获时间 + [StructLayout(LayoutKind.Sequential)] + struct LASTINPUTINFO + { + // 设置结构体块容量 + [MarshalAs(UnmanagedType.U4)] + public int cbSize; + // 捕获的时间 + [MarshalAs(UnmanagedType.U4)] + public uint dwTime; + } + [DllImport("user32.dll")] + private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); + /// + /// 获取键盘和鼠标没有操作的时间 + /// + /// + public static long GetLastInputTime() + { + LASTINPUTINFO vLastInputInfo = new LASTINPUTINFO(); + vLastInputInfo.cbSize = Marshal.SizeOf(vLastInputInfo); + // 捕获时间 + if (!GetLastInputInfo(ref vLastInputInfo)) + return 0; + else + return Environment.TickCount - (long)vLastInputInfo.dwTime; + } + /// + /// 设置屏幕 Gamma值 + /// + /// + /// + /// + /// + public static bool SetGamma(double gammaRed, double gammaGreen, double gammaBlue) + { + _gammas[0] = gammaRed; + _gammas[1] = gammaGreen; + _gammas[2] = gammaBlue; + + return UpdateRamps(); + } + /// + /// 设置屏幕亮度 + /// + /// + /// + public static bool SetBrightness(short brightness) + { + if (brightness > 100) + brightness = 100; + + if (brightness < 0) + brightness = 0; + + _brightness = brightness; + + return UpdateRamps(); + } + + private static bool UpdateRamps() + { + double brightness = (double)_brightness / 100f; + RAMP ramp = new RAMP + { + Red = new UInt16[256], + Green = new UInt16[256], + Blue = new UInt16[256] + }; + for (int i = 0; i < 256; i++) + { + ramp.Red[i] = (ushort)GetGamma(_gammas[0]); + ramp.Green[i] = (ushort)GetGamma(_gammas[1]); + ramp.Blue[i] = (ushort)GetGamma(_gammas[2]); + double GetGamma(double gamma) + { + var r = (Math.Pow(i / 256.0, 1.0 / gamma) * 65535 + 0.5); + r *= brightness; + if (r > 65535) + r = 65535; + if (r < 0) + r = 0; + return r; + } + } + var retVal = SetDeviceGammaRamp(Graphics.FromHwnd(IntPtr.Zero).GetHdc(), ref ramp); + + //Memory allocated through stackalloc is automatically free'd + //by the CLR. + + return retVal; + } + /// + /// 获取系统 + /// + /// + public static string GetOSystemVer() + { + switch (System.Environment.OSVersion.Version.Major + "." + System.Environment.OSVersion.Version.Minor) + { + case "5.0": + return "Windows2000"; + case "5.1": + return "WindowsXP"; + case "5.2": + return "Windows2003"; + case "6.0": + return "Windows2008"; + case "6.1": + return "Windows7"; + case "6.2": + return "Windows8 Or Windows8.1"; + case "6.3": + return "Windows8.1"; + case "10.0": + return "Windows10"; + default: + return "未知"; + } + } + } +} diff --git a/Source/MyDb/SysFuns/RyWin32.cs b/Source/MyDb/SysFuns/RyWin32.cs new file mode 100644 index 0000000..d197c04 --- /dev/null +++ b/Source/MyDb/SysFuns/RyWin32.cs @@ -0,0 +1,286 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace MyDb +{ + /// + /// Win32 API + /// + public class RyWin32 + { + /// + /// + /// + /// + /// + /// + [DllImport("USER32.DLL")] + public static extern int GetSystemMenu(IntPtr hwnd, int bRevert); + /// + /// + /// + /// + /// + /// + /// + [DllImport("USER32.DLL")] + public static extern int RemoveMenu(int hMenu, int nPosition, int wFlags); + /// + /// + /// + /// + /// + [DllImport("user32.dll")] + public static extern bool SetForegroundWindow(IntPtr hWnd); + /// + /// 获取当前前台窗口句柄 + /// + /// + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern IntPtr GetForegroundWindow(); + /// + /// 获得当前活动窗体 + /// + /// + [DllImport("user32.dll")] + public static extern IntPtr GetActiveWindow();//获得当前活动窗体 + /// + /// 设置活动窗体 + /// + /// + /// + [DllImport("user32.dll")] + public static extern IntPtr SetActiveWindow(IntPtr hwnd);//设置活动窗体 + /// + /// 获取类名 + /// + /// + /// + /// + /// + [DllImport("user32", EntryPoint = "GetClassName", SetLastError = false, + CharSet = CharSet.Auto, ExactSpelling = false, + CallingConvention = CallingConvention.StdCall)] + public static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount); + /// + /// 获取当前线程对应的进程ID + /// + /// + /// + /// + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); + /// + /// 判断指定句柄是否是一个窗口 + /// + /// + /// + [DllImport("user32.dll", EntryPoint = "IsWindow")] + public static extern bool IsWindow(IntPtr hWnd); + /// + /// 获取窗口标题 + /// + /// + /// + /// + /// + [DllImport("user32", SetLastError = true)] + public static extern int GetWindowText( + int hWnd,//窗口句柄 + StringBuilder lpString,//标题 + int nMaxCount //最大值 + ); + /// + /// 查找窗口 + /// + /// + /// + /// + [DllImport("User32.dll", EntryPoint = "FindWindow")] + public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + /// + /// 设置父窗口 + /// + /// + /// + /// + [DllImport("user32.dll")] + public static extern int SetParent(IntPtr hWndChild, IntPtr hWndParent); + /// + /// 移动窗口 + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint); + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("User32.dll")] + public extern static IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam); + /// + /// + /// + /// + /// + /// + /// + [DllImport("User32.dll")] + public static extern IntPtr SetWindowLong(IntPtr hwnd, int nIndex, IntPtr dwNewLong); + /// + /// + /// + public const int GWL_WNDPROC = (-4); + /// + /// 结束进程 + /// + /// + /// + /// + [DllImport("kernel32")] + public static extern long TerminateProcess(int handle, int exitCode); + /// + /// 发送消息 + /// + /// + /// + /// + /// + /// + [DllImport("User32.dll", EntryPoint = "SendMessage")] + private static extern int SendMessage(IntPtr hwnd, int msg, int wParam, ref COPYDATASTRUCT IParam); + /// + /// 发送消息 + /// + /// + /// + /// + /// + [DllImport("user32.dll")] + public static extern void PostMessage(IntPtr hWnd, int msg, int wParam, ref COPYDATASTRUCT IParam); + /// + /// 获取窗口位置和大小 + /// + /// + /// + /// + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + /// + /// 矩形 + /// + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + /// + /// 最左坐标 + /// + public int Left; + /// + /// 最上坐标 + /// + public int Top; + /// + /// 最右坐标 + /// + public int Right; + /// + /// 最下坐标 + /// + public int Bottom; + } + /// + /// WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。 + /// + public const int WM_COPYDATA = 0x004A; + /// + /// 系统通道ID + /// + public const int Sys_chanel_id = 1000; + /// + /// 用户通道ID + /// + public const int User_chanel_id = 1001; + /// + /// + /// + public struct COPYDATASTRUCT + { + /// + /// + /// + public IntPtr dwData; + /// + /// + /// + public int cData; + /// + /// + /// + [MarshalAs(UnmanagedType.LPStr)] + public string lpData; + } + /// + /// 获取消息 + /// + /// + /// + /// + public static string GetMsg(Message m,out IntPtr handle) + { + COPYDATASTRUCT cdata = new COPYDATASTRUCT(); + Type mytype = cdata.GetType(); + cdata = (COPYDATASTRUCT)m.GetLParam(mytype); + handle = cdata.dwData; + return cdata.lpData; + } + /// + /// 发送消息 + /// + /// + /// + /// + /// + /// + public static int SendMsg(IntPtr from_handle, IntPtr to_handle, int wParam, string str) + { + byte[] arr = System.Text.Encoding.Default.GetBytes(str); + int len = arr.Length; + COPYDATASTRUCT cdata; + cdata.dwData = from_handle; + cdata.lpData = str; + cdata.cData = len + 1; + return SendMessage(to_handle, WM_COPYDATA, wParam, ref cdata); + } + /// + /// 设置父窗口 + /// + /// + /// + /// + /// + public static bool SetParentWin(IntPtr sub_form, IntPtr parent_form,Size size) + { + SetParent(sub_form, parent_form); + MoveWindow(sub_form, 0, 0, size.Width, size.Height, false); + return true; + } + } +} diff --git a/Source/MyDb/SysFuns/SoundControl.cs b/Source/MyDb/SysFuns/SoundControl.cs new file mode 100644 index 0000000..bd6c3c4 --- /dev/null +++ b/Source/MyDb/SysFuns/SoundControl.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace ryCommon +{ + /// + /// SOURCE CODE FROM THE WEBSITE. + /// LAST UPDATE:WWW.VJSDN.COMѧ̳,2009/08/03 by Jonny Sun + /// + class SoundControl + { + #region declarations + + const int MAXPNAMELEN = 32; + const int MIXER_SHORT_NAME_CHARS = 16; + const int MIXER_LONG_NAME_CHARS = 64; + + [Flags] + enum MIXERLINE_LINEF : uint + { + ACTIVE = 0x00000001, + DISCONNECTED = 0x00008000, + SOURCE = 0x80000000 + } + + [Flags] + enum MIXER : uint + { + GETLINEINFOF_DESTINATION = 0x00000000, + GETLINEINFOF_SOURCE = 0x00000001, + GETLINEINFOF_LINEID = 0x00000002, + GETLINEINFOF_COMPONENTTYPE = 0x00000003, + GETLINEINFOF_TARGETTYPE = 0x00000004, + GETLINEINFOF_QUERYMASK = 0x0000000F, + + GETLINECONTROLSF_ALL = 0x00000000, + GETLINECONTROLSF_ONEBYID = 0x00000001, + GETLINECONTROLSF_ONEBYTYPE = 0x00000002, + GETLINECONTROLSF_QUERYMASK = 0x0000000F, + + GETCONTROLDETAILSF_VALUE = 0x00000000, + GETCONTROLDETAILSF_LISTTEXT = 0x00000001, + GETCONTROLDETAILSF_QUERYMASK = 0x0000000F, + + OBJECTF_MIXER = 0x00000000, + OBJECTF_WAVEOUT = 0x10000000, + OBJECTF_WAVEIN = 0x20000000, + OBJECTF_MIDIOUT = 0x30000000, + OBJECTF_MIDIIN = 0x40000000, + OBJECTF_AUX = 0x50000000, + OBJECTF_HANDLE = 0x80000000, + OBJECTF_HMIXER = OBJECTF_HANDLE | OBJECTF_MIXER, + OBJECTF_HWAVEOUT = OBJECTF_HANDLE | OBJECTF_WAVEOUT, + OBJECTF_HWAVEIN = OBJECTF_HANDLE | OBJECTF_WAVEIN, + OBJECTF_HMIDIOUT = OBJECTF_HANDLE | OBJECTF_MIDIOUT, + OBJECTF_HMIDIIN = OBJECTF_HANDLE | OBJECTF_MIDIIN + } + + [Flags] + enum MIXERCONTROL_CT : uint + { + CLASS_MASK = 0xF0000000, + CLASS_CUSTOM = 0x00000000, + CLASS_METER = 0x10000000, + CLASS_SWITCH = 0x20000000, + CLASS_NUMBER = 0x30000000, + CLASS_SLIDER = 0x40000000, + CLASS_FADER = 0x50000000, + CLASS_TIME = 0x60000000, + CLASS_LIST = 0x70000000, + + SUBCLASS_MASK = 0x0F000000, + + SC_SWITCH_BOOLEAN = 0x00000000, + SC_SWITCH_BUTTON = 0x01000000, + + SC_METER_POLLED = 0x00000000, + + SC_TIME_MICROSECS = 0x00000000, + SC_TIME_MILLISECS = 0x01000000, + + SC_LIST_SINGLE = 0x00000000, + SC_LIST_MULTIPLE = 0x01000000, + + UNITS_MASK = 0x00FF0000, + UNITS_CUSTOM = 0x00000000, + UNITS_BOOLEAN = 0x00010000, + UNITS_SIGNED = 0x00020000, + UNITS_UNSIGNED = 0x00030000, + UNITS_DECIBELS = 0x00040000, /* in 10ths */ + UNITS_PERCENT = 0x00050000, /* in 10ths */ + } + + [Flags] + public enum MIXERCONTROL_CONTROLTYPE : uint + { + CUSTOM = MIXERCONTROL_CT.CLASS_CUSTOM | MIXERCONTROL_CT.UNITS_CUSTOM, + BOOLEANMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_BOOLEAN, + SIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_SIGNED, + PEAKMETER = SIGNEDMETER + 1, + UNSIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_UNSIGNED, + BOOLEAN = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BOOLEAN | MIXERCONTROL_CT.UNITS_BOOLEAN, + ONOFF = BOOLEAN + 1, + MUTE = BOOLEAN + 2, + MONO = BOOLEAN + 3, + LOUDNESS = BOOLEAN + 4, + STEREOENH = BOOLEAN + 5, + BASS_BOOST = BOOLEAN + 0x00002277, + BUTTON = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BUTTON | MIXERCONTROL_CT.UNITS_BOOLEAN, + DECIBELS = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_DECIBELS, + SIGNED = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_SIGNED, + UNSIGNED = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_UNSIGNED, + PERCENT = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_PERCENT, + SLIDER = MIXERCONTROL_CT.CLASS_SLIDER | MIXERCONTROL_CT.UNITS_SIGNED, + PAN = SLIDER + 1, + QSOUNDPAN = SLIDER + 2, + FADER = MIXERCONTROL_CT.CLASS_FADER | MIXERCONTROL_CT.UNITS_UNSIGNED, + VOLUME = FADER + 1, + BASS = FADER + 2, + TREBLE = FADER + 3, + EQUALIZER = FADER + 4, + SINGLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_SINGLE | MIXERCONTROL_CT.UNITS_BOOLEAN, + MUX = SINGLESELECT + 1, + MULTIPLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_MULTIPLE | MIXERCONTROL_CT.UNITS_BOOLEAN, + MIXER = MULTIPLESELECT + 1, + MICROTIME = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MICROSECS | MIXERCONTROL_CT.UNITS_UNSIGNED, + MILLITIME = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MILLISECS | MIXERCONTROL_CT.UNITS_UNSIGNED + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + struct MIXERLINE + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct TargetInfo + { + public uint dwType; + public uint dwDeviceID; + public ushort wMid; + public ushort wPid; + public uint vDriverVersion; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)] + public string szPname; + } + + public uint cbStruct; + public uint dwDestination; + public uint dwSource; + public uint dwLineID; + public MIXERLINE_LINEF fdwLine; + public uint dwUser; + public uint dwComponentType; + public uint cChannels; + public uint cConnection; + public uint cControls; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_SHORT_NAME_CHARS)] + public string szShortName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_LONG_NAME_CHARS)] + public string szName; + public TargetInfo Target; + } + + public struct MIXERCONTROL + { + public int cbStruct; + public uint dwControlID; + public MIXERCONTROL_CONTROLTYPE dwControlType; + public int fdwControl; + public int cMultipleItems; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_SHORT_NAME_CHARS)] + public string szShortName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_LONG_NAME_CHARS)] + public string szName; + public int lMinimum; + public int lMaximum; + [MarshalAs(UnmanagedType.U4, SizeConst = 10)] + public int reserved; + } + + + [StructLayout(LayoutKind.Explicit)] + struct MIXERLINECONTROLS + { + [FieldOffset(0)] + public uint cbStruct; + [FieldOffset(4)] + public uint dwLineID; + [FieldOffset(8)] + public uint dwControlID; + [FieldOffset(8)] // not a typo! overlaps previous field + public uint dwControlType; + [FieldOffset(12)] + public uint cControls; + [FieldOffset(16)] + public uint cbmxctrl; + [FieldOffset(20)] + public IntPtr pamxctrl; + } + + [StructLayout(LayoutKind.Explicit)] + struct MIXERCONTROLDETAILS + { + [FieldOffset(0)] + public uint cbStruct; + [FieldOffset(4)] + public uint dwControlID; + [FieldOffset(8)] + public uint cChannels; + [FieldOffset(12)] + public IntPtr hwndOwner; + [FieldOffset(12)] // not a typo! + public uint cMultipleItems; + [FieldOffset(16)] + public uint cbDetails; + [FieldOffset(20)] + public IntPtr paDetails; + } + + [StructLayout(LayoutKind.Sequential)] + struct VOLUME + { + public int left; + public int right; + } + + public struct MixerInfo + { + public uint volumeCtl; + public uint muteCtl; + public int minVolume; + public int maxVolume; + } + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerGetLineInfo(IntPtr hmxobj, ref MIXERLINE pmxl, MIXER flags); + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerGetLineControls(IntPtr hmxobj, ref MIXERLINECONTROLS pmxlc, MIXER flags); + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerGetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags); + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerSetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags); + + #endregion declarations + + #region private methods + + public static MixerInfo GetMixerControls() + { + MIXERLINE mxl = new MIXERLINE(); + MIXERLINECONTROLS mlc = new MIXERLINECONTROLS(); + mxl.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINE)); + mlc.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINECONTROLS)); + + mixerGetLineInfo(IntPtr.Zero, ref mxl, MIXER.OBJECTF_MIXER | MIXER.GETLINEINFOF_DESTINATION); + + mlc.dwLineID = mxl.dwLineID; + mlc.cControls = mxl.cControls; + mlc.cbmxctrl = (uint)Marshal.SizeOf(typeof(MIXERCONTROL)); + mlc.pamxctrl = Marshal.AllocHGlobal((int)(mlc.cbmxctrl * mlc.cControls)); + + mixerGetLineControls(IntPtr.Zero, ref mlc, MIXER.OBJECTF_MIXER | MIXER.GETLINECONTROLSF_ALL); + + MixerInfo rtn = new MixerInfo(); + + for (int i = 0; i < mlc.cControls; i++) + { + MIXERCONTROL mxc = (MIXERCONTROL)Marshal.PtrToStructure((IntPtr)((int)mlc.pamxctrl + (int)mlc.cbmxctrl * i), typeof(MIXERCONTROL)); + switch (mxc.dwControlType) + { + case MIXERCONTROL_CONTROLTYPE.VOLUME: + rtn.volumeCtl = mxc.dwControlID; + rtn.minVolume = mxc.lMinimum; + rtn.maxVolume = mxc.lMaximum; + break; + case MIXERCONTROL_CONTROLTYPE.MUTE: + rtn.muteCtl = mxc.dwControlID; + break; + } + } + + Marshal.FreeHGlobal(mlc.pamxctrl); + + return rtn; + } + static VOLUME GetVolume(MixerInfo mi) + { + MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); + mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); + mcd.dwControlID = mi.volumeCtl; + mcd.cMultipleItems = 0; + mcd.cChannels = 2; + mcd.cbDetails = (uint)Marshal.SizeOf(typeof(VOLUME)); + mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails); + + mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); + + VOLUME rtn = (VOLUME)Marshal.PtrToStructure(mcd.paDetails, typeof(VOLUME)); + + Marshal.FreeHGlobal(mcd.paDetails); + + return rtn; + } + public static bool IsMuted(MixerInfo mi) + { + MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); + mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); + mcd.dwControlID = mi.muteCtl; + mcd.cMultipleItems = 0; + mcd.cChannels = 1; + mcd.cbDetails = 4; + mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails); + + mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); + + int rtn = Marshal.ReadInt32(mcd.paDetails); + + Marshal.FreeHGlobal(mcd.paDetails); + + return rtn != 0; + } + + static void MuteIt(MixerInfo mi, bool left, bool right) + { + VOLUME volume = GetVolume(mi); + if (!left && !right) // mute off + { + volume.left = 65530; + volume.right = 65530; + } + else if (left) //mute left channel + { + volume.left = 0; + volume.right = 65530; + } + else if (right) // mute right channel + { + volume.left = 65530; + volume.right = 0; + } + + SetVolume(mi, volume); + } + + static void SetVolume(MixerInfo mi, VOLUME volume) + { + MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); + mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); + mcd.dwControlID = mi.volumeCtl; + mcd.cMultipleItems = 0; + mcd.cChannels = 2; + mcd.cbDetails = (uint)Marshal.SizeOf(typeof(VOLUME)); + mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails); + + Marshal.StructureToPtr(volume, mcd.paDetails, false); + + mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); + + Marshal.FreeHGlobal(mcd.paDetails); + } + + #endregion private methods + + #region public methods + + /// + /// Mutes the left hand channel and transfers audio fully to the right + /// + public void MuteLeftChannel() + { + MixerInfo mi = GetMixerControls(); + MuteIt(mi, false, true); + } + + /// + /// Mutes the right hand channel and transfers audio fully to the left + /// + public void MuteRightChannel() + { + MixerInfo mi = GetMixerControls(); + MuteIt(mi, true, false); + } + + public void MuteOff() + { + MixerInfo mi = GetMixerControls(); + MuteIt(mi, false, false); + } + + #endregion public methods + } +} \ No newline at end of file diff --git a/Source/MyDb/SysFuns/SoundControl_XP.cs b/Source/MyDb/SysFuns/SoundControl_XP.cs new file mode 100644 index 0000000..8c3313d --- /dev/null +++ b/Source/MyDb/SysFuns/SoundControl_XP.cs @@ -0,0 +1,417 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace ryCommon +{ + /// + /// SOURCE CODE FROM THE WEBSITE. + /// LAST UPDATE:WWW.VJSDN.COMѧ̳,2009/08/03 by Jonny Sun + /// + class SoundControl_XP + { + #region declarations + const int MAXPNAMELEN = 32; + const int MIXER_SHORT_NAME_CHARS = 16; + const int MIXER_LONG_NAME_CHARS = 64; + + [Flags] + enum MIXERLINE_LINEF : uint + { + ACTIVE = 0x00000001, + DISCONNECTED = 0x00008000, + SOURCE = 0x80000000 + } + + [Flags] + enum MIXER : uint + { + GETLINEINFOF_DESTINATION = 0x00000000, + GETLINEINFOF_SOURCE = 0x00000001, + GETLINEINFOF_LINEID = 0x00000002, + GETLINEINFOF_COMPONENTTYPE = 0x00000003, + GETLINEINFOF_TARGETTYPE = 0x00000004, + GETLINEINFOF_QUERYMASK = 0x0000000F, + + GETLINECONTROLSF_ALL = 0x00000000, + GETLINECONTROLSF_ONEBYID = 0x00000001, + GETLINECONTROLSF_ONEBYTYPE = 0x00000002, + GETLINECONTROLSF_QUERYMASK = 0x0000000F, + + GETCONTROLDETAILSF_VALUE = 0x00000000, + GETCONTROLDETAILSF_LISTTEXT = 0x00000001, + GETCONTROLDETAILSF_QUERYMASK = 0x0000000F, + + OBJECTF_MIXER = 0x00000000, + OBJECTF_WAVEOUT = 0x10000000, + OBJECTF_WAVEIN = 0x20000000, + OBJECTF_MIDIOUT = 0x30000000, + OBJECTF_MIDIIN = 0x40000000, + OBJECTF_AUX = 0x50000000, + OBJECTF_HANDLE = 0x80000000, + OBJECTF_HMIXER = OBJECTF_HANDLE | OBJECTF_MIXER, + OBJECTF_HWAVEOUT = OBJECTF_HANDLE | OBJECTF_WAVEOUT, + OBJECTF_HWAVEIN = OBJECTF_HANDLE | OBJECTF_WAVEIN, + OBJECTF_HMIDIOUT = OBJECTF_HANDLE | OBJECTF_MIDIOUT, + OBJECTF_HMIDIIN = OBJECTF_HANDLE | OBJECTF_MIDIIN + } + + [Flags] + enum MIXERCONTROL_CT : uint + { + CLASS_MASK = 0xF0000000, + CLASS_CUSTOM = 0x00000000, + CLASS_METER = 0x10000000, + CLASS_SWITCH = 0x20000000, + CLASS_NUMBER = 0x30000000, + CLASS_SLIDER = 0x40000000, + CLASS_FADER = 0x50000000, + CLASS_TIME = 0x60000000, + CLASS_LIST = 0x70000000, + + SUBCLASS_MASK = 0x0F000000, + + SC_SWITCH_BOOLEAN = 0x00000000, + SC_SWITCH_BUTTON = 0x01000000, + + SC_METER_POLLED = 0x00000000, + + SC_TIME_MICROSECS = 0x00000000, + SC_TIME_MILLISECS = 0x01000000, + + SC_LIST_SINGLE = 0x00000000, + SC_LIST_MULTIPLE = 0x01000000, + + UNITS_MASK = 0x00FF0000, + UNITS_CUSTOM = 0x00000000, + UNITS_BOOLEAN = 0x00010000, + UNITS_SIGNED = 0x00020000, + UNITS_UNSIGNED = 0x00030000, + UNITS_DECIBELS = 0x00040000, /* in 10ths */ + UNITS_PERCENT = 0x00050000, /* in 10ths */ + } + + [Flags] + enum MIXERCONTROL_CONTROLTYPE : uint + { + CUSTOM = MIXERCONTROL_CT.CLASS_CUSTOM | MIXERCONTROL_CT.UNITS_CUSTOM, + BOOLEANMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_BOOLEAN, + SIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_SIGNED, + PEAKMETER = SIGNEDMETER + 1, + UNSIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_UNSIGNED, + BOOLEAN = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BOOLEAN | MIXERCONTROL_CT.UNITS_BOOLEAN, + ONOFF = BOOLEAN + 1, + MUTE = BOOLEAN + 2, + MONO = BOOLEAN + 3, + LOUDNESS = BOOLEAN + 4, + STEREOENH = BOOLEAN + 5, + BASS_BOOST = BOOLEAN + 0x00002277, + BUTTON = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BUTTON | MIXERCONTROL_CT.UNITS_BOOLEAN, + DECIBELS = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_DECIBELS, + SIGNED = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_SIGNED, + UNSIGNED = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_UNSIGNED, + PERCENT = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_PERCENT, + SLIDER = MIXERCONTROL_CT.CLASS_SLIDER | MIXERCONTROL_CT.UNITS_SIGNED, + PAN = SLIDER + 1, + QSOUNDPAN = SLIDER + 2, + FADER = MIXERCONTROL_CT.CLASS_FADER | MIXERCONTROL_CT.UNITS_UNSIGNED, + VOLUME = FADER + 1, + BASS = FADER + 2, + TREBLE = FADER + 3, + EQUALIZER = FADER + 4, + SINGLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_SINGLE | MIXERCONTROL_CT.UNITS_BOOLEAN, + MUX = SINGLESELECT + 1, + MULTIPLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_MULTIPLE | MIXERCONTROL_CT.UNITS_BOOLEAN, + MIXER = MULTIPLESELECT + 1, + MICROTIME = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MICROSECS | MIXERCONTROL_CT.UNITS_UNSIGNED, + MILLITIME = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MILLISECS | MIXERCONTROL_CT.UNITS_UNSIGNED + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + struct MIXERLINE + { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct TargetInfo + { + public uint dwType; + public uint dwDeviceID; + public ushort wMid; + public ushort wPid; + public uint vDriverVersion; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)] + public string szPname; + } + + public uint cbStruct; + public uint dwDestination; + public uint dwSource; + public uint dwLineID; + public MIXERLINE_LINEF fdwLine; + public uint dwUser; + public uint dwComponentType; + public uint cChannels; + public uint cConnection; + public uint cControls; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_SHORT_NAME_CHARS)] + public string szShortName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_LONG_NAME_CHARS)] + public string szName; + public TargetInfo Target; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + struct MIXERCONTROL + { + [StructLayout(LayoutKind.Explicit)] + public struct BoundsInfo + { + [FieldOffset(0)] + public int lMinimum; + [FieldOffset(4)] + public int lMaximum; + [FieldOffset(0)] + public uint dwMinimum; + [FieldOffset(4)] + public uint dwMaximum; + [FieldOffset(8), MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public uint[] dwReserved; + } + [StructLayout(LayoutKind.Explicit)] + public struct MetricsInfo + { + [FieldOffset(0)] + public uint cSteps; + [FieldOffset(0)] + public uint cbCustomData; + [FieldOffset(4), MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] + public uint[] dwReserved; + } + + public uint cbStruct; + public uint dwControlID; + public MIXERCONTROL_CONTROLTYPE dwControlType; + public uint fdwControl; + public uint cMultipleItems; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_SHORT_NAME_CHARS)] + public string szShortName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MIXER_LONG_NAME_CHARS)] + public string szName; + public BoundsInfo Bounds; + public MetricsInfo Metrics; + } + + [StructLayout(LayoutKind.Explicit)] + struct MIXERLINECONTROLS + { + [FieldOffset(0)] + public uint cbStruct; + [FieldOffset(4)] + public uint dwLineID; + [FieldOffset(8)] + public uint dwControlID; + [FieldOffset(8)] // not a typo! overlaps previous field + public uint dwControlType; + [FieldOffset(12)] + public uint cControls; + [FieldOffset(16)] + public uint cbmxctrl; + [FieldOffset(20)] + public IntPtr pamxctrl; + } + + [StructLayout(LayoutKind.Explicit)] + struct MIXERCONTROLDETAILS + { + [FieldOffset(0)] + public uint cbStruct; + [FieldOffset(4)] + public uint dwControlID; + [FieldOffset(8)] + public uint cChannels; + [FieldOffset(12)] + public IntPtr hwndOwner; + [FieldOffset(12)] // not a typo! + public uint cMultipleItems; + [FieldOffset(16)] + public uint cbDetails; + [FieldOffset(20)] + public IntPtr paDetails; + } + + [StructLayout(LayoutKind.Sequential)] + struct VOLUME + { + public int left; + public int right; + } + + public struct MixerInfo + { + public uint volumeCtl; + public uint muteCtl; + public int minVolume; + public int maxVolume; + } + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerGetLineInfo(IntPtr hmxobj, ref MIXERLINE pmxl, MIXER flags); + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerGetLineControls(IntPtr hmxobj, ref MIXERLINECONTROLS pmxlc, MIXER flags); + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerGetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags); + + [DllImport("WinMM.dll", CharSet = CharSet.Auto)] + static extern uint mixerSetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags); + + #endregion declarations + + #region private methods + + public static MixerInfo GetMixerControls() + { + MIXERLINE mxl = new MIXERLINE(); + MIXERLINECONTROLS mlc = new MIXERLINECONTROLS(); + mxl.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINE)); + mlc.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINECONTROLS)); + + mixerGetLineInfo(IntPtr.Zero, ref mxl, MIXER.OBJECTF_MIXER | MIXER.GETLINEINFOF_DESTINATION); + + mlc.dwLineID = mxl.dwLineID; + mlc.cControls = mxl.cControls; + mlc.cbmxctrl = (uint)Marshal.SizeOf(typeof(MIXERCONTROL)); + mlc.pamxctrl = Marshal.AllocHGlobal((int)(mlc.cbmxctrl * mlc.cControls)); + + mixerGetLineControls(IntPtr.Zero, ref mlc, MIXER.OBJECTF_MIXER | MIXER.GETLINECONTROLSF_ALL); + + MixerInfo rtn = new MixerInfo(); + + for (int i = 0; i < mlc.cControls; i++) + { + MIXERCONTROL mxc = (MIXERCONTROL)Marshal.PtrToStructure((IntPtr)((int)mlc.pamxctrl + (int)mlc.cbmxctrl * i), typeof(MIXERCONTROL)); + switch (mxc.dwControlType) + { + case MIXERCONTROL_CONTROLTYPE.VOLUME: + rtn.volumeCtl = mxc.dwControlID; + rtn.minVolume = mxc.Bounds.lMinimum; + rtn.maxVolume = mxc.Bounds.lMaximum; + break; + case MIXERCONTROL_CONTROLTYPE.MUTE: + rtn.muteCtl = mxc.dwControlID; + break; + } + } + + Marshal.FreeHGlobal(mlc.pamxctrl); + + return rtn; + } + static VOLUME GetVolume(MixerInfo mi) + { + MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); + mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); + mcd.dwControlID = mi.volumeCtl; + mcd.cMultipleItems = 0; + mcd.cChannels = 2; + mcd.cbDetails = (uint)Marshal.SizeOf(typeof(VOLUME)); + mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails); + + mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); + + VOLUME rtn = (VOLUME)Marshal.PtrToStructure(mcd.paDetails, typeof(VOLUME)); + + Marshal.FreeHGlobal(mcd.paDetails); + + return rtn; + } + public static bool IsMuted(MixerInfo mi) + { + MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); + mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); + mcd.dwControlID = mi.muteCtl; + mcd.cMultipleItems = 0; + mcd.cChannels = 1; + mcd.cbDetails = 4; + mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails); + + mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); + + int rtn = Marshal.ReadInt32(mcd.paDetails); + + Marshal.FreeHGlobal(mcd.paDetails); + + return rtn != 0; + } + + static void MuteIt(MixerInfo mi, bool left, bool right) + { + VOLUME volume = GetVolume(mi); + if (!left && !right) // mute off + { + volume.left = 65530; + volume.right = 65530; + } + else if (left) //mute left channel + { + volume.left = 0; + volume.right = 65530; + } + else if (right) // mute right channel + { + volume.left = 65530; + volume.right = 0; + } + + SetVolume(mi, volume); + } + + static void SetVolume(MixerInfo mi, VOLUME volume) + { + MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); + mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); + mcd.dwControlID = mi.volumeCtl; + mcd.cMultipleItems = 0; + mcd.cChannels = 2; + mcd.cbDetails = (uint)Marshal.SizeOf(typeof(VOLUME)); + mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails); + + Marshal.StructureToPtr(volume, mcd.paDetails, false); + + mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); + + Marshal.FreeHGlobal(mcd.paDetails); + } + + #endregion private methods + + #region public methods + + /// + /// Mutes the left hand channel and transfers audio fully to the right + /// + public void MuteLeftChannel() + { + MixerInfo mi = GetMixerControls(); + MuteIt(mi, false, true); + } + + /// + /// Mutes the right hand channel and transfers audio fully to the left + /// + public void MuteRightChannel() + { + MixerInfo mi = GetMixerControls(); + MuteIt(mi, true, false); + } + + public void MuteOff() + { + MixerInfo mi = GetMixerControls(); + MuteIt(mi, false, false); + } + + #endregion public methods + } +} \ No newline at end of file diff --git a/Source/MyDb/SysFuns/SuperForm.cs b/Source/MyDb/SysFuns/SuperForm.cs new file mode 100644 index 0000000..2c96805 --- /dev/null +++ b/Source/MyDb/SysFuns/SuperForm.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 窗体操作类 + /// + public class SuperForm + { + private Form form; + private IntPtr handle = IntPtr.Zero; + /// + /// 构造函数 + /// + /// + public SuperForm(Form _form) + { + form = _form; + handle = form.Handle; + wndProcDelegate = new WndProcDelegate(WndProc); + oldWndFunc = SetWindowLong(handle, MyDb.RyWin32.GWL_WNDPROC, wndProcDelegate); + } + /// + /// 析构 + /// + ~SuperForm() + { + MyDb.RyWin32.SetWindowLong(handle, MyDb.RyWin32.GWL_WNDPROC, oldWndFunc); + } + private bool isMouseDown = false; + private Point FormLocation; //form的location + private Point mouseOffset; //鼠标的按下位置 + const int HTLEFT = 10; + const int HTRIGHT = 11; + const int HTTOP = 12; + const int HTTOPLEFT = 13; + const int HTTOPRIGHT = 14; + const int HTBOTTOM = 15; + const int HTBOTTOMLEFT = 0x10; + const int HTBOTTOMRIGHT = 17; + private readonly IntPtr oldWndFunc; + private delegate IntPtr WndProcDelegate(IntPtr hwnd, int Msg, IntPtr wParam, IntPtr lParam); + private readonly WndProcDelegate wndProcDelegate; + [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, WndProcDelegate wndProcDelegate); + /// + /// 设置让窗体支持移动 + /// + public void SetFormMove(Control ctl) + { + ctl.MouseMove += new MouseEventHandler((object o, MouseEventArgs e) => + { + try + { + int _x = 0; + int _y = 0; + if (isMouseDown) + { + Point pt = Control.MousePosition; + _x = mouseOffset.X - pt.X; + _y = mouseOffset.Y - pt.Y; + + form.Location = new Point(FormLocation.X - _x, FormLocation.Y - _y); + } + } + catch (Exception) { } + }); + ctl.MouseDown+=new MouseEventHandler((object o, MouseEventArgs e) => + { + try + { + if (e.Button == MouseButtons.Left) + { + isMouseDown = true; + FormLocation = form.Location; + mouseOffset = Control.MousePosition; + } + } + catch (Exception) { } + }); + ctl.MouseUp+=new MouseEventHandler((object o, MouseEventArgs e) => + { + isMouseDown = false; + }); + + } + /// + /// 是否允许可调节大小 + /// + public bool Resizable { get; set; } + /// + /// 可调节窗体大小的宽度 + /// + public int ResizeBorderWidth { get; set; } = 5; + /// + /// + /// + /// + protected virtual void WndProc(ref Message m) + { + m.Result = MyDb.RyWin32.CallWindowProc(oldWndFunc, m.HWnd, m.Msg, m.WParam, m.LParam); + switch (m.Msg) + { + case 0x0084: + //base.WndProc(ref m); + if (!Resizable) { return; } + Point vPoint = new Point((int)m.LParam & 0xFFFF, + (int)m.LParam >> 16 & 0xFFFF); + vPoint =form.PointToClient(vPoint); + if (vPoint.X <= ResizeBorderWidth) + if (vPoint.Y <= ResizeBorderWidth) + m.Result = (IntPtr)HTTOPLEFT; + else if (vPoint.Y >= form.ClientSize.Height - ResizeBorderWidth) + m.Result = (IntPtr)HTBOTTOMLEFT; + else m.Result = (IntPtr)HTLEFT; + else if (vPoint.X >= form.ClientSize.Width - ResizeBorderWidth) + if (vPoint.Y <= ResizeBorderWidth) + m.Result = (IntPtr)HTTOPRIGHT; + else if (vPoint.Y >= form.ClientSize.Height - ResizeBorderWidth) + m.Result = (IntPtr)HTBOTTOMRIGHT; + else m.Result = (IntPtr)HTRIGHT; + else if (vPoint.Y <= ResizeBorderWidth) + m.Result = (IntPtr)HTTOP; + else if (vPoint.Y >= form.ClientSize.Height - ResizeBorderWidth) + m.Result = (IntPtr)HTBOTTOM; + break; + case 0x0201://鼠标左键按下的消息 + //m.Msg = 0x00A1;//更改消息为非客户区按下鼠标 + //m.LParam = IntPtr.Zero;//默认值 + //m.WParam = new IntPtr(2);//鼠标放在标题栏内 + + //以下做了一些修正,确保放大缩小按钮区域可以正常使用 + Point point = Control.MousePosition; + point = form.PointToClient(point); + if (point.X < form.Width - 100 && point.Y < 30) + { + m.Msg = 0x00A1;//更改消息为非客户区按下鼠标 + m.LParam = IntPtr.Zero;//默认值 + m.WParam = new IntPtr(2);//鼠标放在标题栏内 + } + //base.WndProc(ref m); + break; + default: + //base.WndProc(ref m); + break; + } + } + private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam) + { + System.Windows.Forms.Message m = System.Windows.Forms.Message.Create(hWnd, msg, wParam, lParam); + WndProc(ref m); + return m.Result; + } + } +} diff --git a/Source/MyDb/SysFuns/WinHotReg.cs b/Source/MyDb/SysFuns/WinHotReg.cs new file mode 100644 index 0000000..8550968 --- /dev/null +++ b/Source/MyDb/SysFuns/WinHotReg.cs @@ -0,0 +1,229 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace SysFuns +{ + /// + /// 功能键 + /// + [Flags()] + public enum KeyModifiers + { + /// + /// 无 + /// + None = 0, + /// + /// Alt键 + /// + Alt = 1, + /// + /// Ctrl键 + /// + Ctrl = 2, + /// + /// Shift键 + /// + Shift = 4, + /// + /// Win键 + /// + WindowsKey = 8 + } + /// + /// 热键类 + /// + public class WinHotReg : System.Windows.Forms.IMessageFilter + { + //如果函数执行成功,返回值不为0。 + //如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。 + [DllImport("user32.dll", SetLastError = true)] + private static extern bool RegisterHotKey( + IntPtr hWnd, //要定义热键的窗口的句柄 + int id, //定义热键ID(不能与其它ID重复) + KeyModifiers fsModifiers, //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效 + Keys vk //定义热键的内容 + ); + + [DllImport("user32.dll", SetLastError = true)] + private static extern bool UnregisterHotKey( + IntPtr hWnd, //要取消热键的窗口的句柄 + int id //要取消热键的ID + ); + + readonly IntPtr handle; + /// + /// 热键类 + /// + /// + public WinHotReg(IntPtr _handle) + { + handle = _handle; + System.Windows.Forms.Application.AddMessageFilter(this); + } + /// + /// 热键注销 + /// + ~WinHotReg() + { + UnHotKey(); + System.Windows.Forms.Application.RemoveMessageFilter(this); + } + /// + /// 热键是否有效 + /// + public bool Enabled { get; set; } = true; + /// + /// 释放热键 + /// + public void Free() + { + UnHotKey(); + System.Windows.Forms.Application.RemoveMessageFilter(this); + } + List list_hotkey = new List(); + /// + /// 注册热键 + /// + /// + /// + /// + /// + public bool RegHotKey(int id, KeyModifiers fsModifiers, Keys vk) + { + bool result = RegisterHotKey(handle, id, fsModifiers, vk); + if (result) + { + list_hotkey.Add(new HotKeyType(id, fsModifiers, vk)); + } + return result; + } + /// + /// 注册热键 + /// + /// + /// + /// + /// + public bool RegHotKey(int id, int fsModifiers, Keys vk) + { + if (!Enum.IsDefined(typeof(KeyModifiers), fsModifiers)) + { + return false; + } + bool result = RegisterHotKey(handle, id, (KeyModifiers)fsModifiers, vk); + if (result) + { + list_hotkey.Add(new HotKeyType(id, (KeyModifiers)fsModifiers, vk)); + } + return result; + } + /// + /// 删除热键 + /// + /// + /// + public bool UnHotKey(int id) + { + bool result = UnregisterHotKey(handle, id); + if (result) + { + for (int i = list_hotkey.Count - 1; i >= 0; i--) + { + HotKeyType item = (HotKeyType)list_hotkey[i]; + if (item.id == id) + { + list_hotkey.RemoveAt(i); + break; + } + } + } + return result; + } + /// + /// 删除所有热键 + /// + public void UnHotKey() + { + for (int i = list_hotkey.Count - 1; i >= 0; i--) + { + HotKeyType item = (HotKeyType)list_hotkey[i]; + bool result = UnregisterHotKey(handle, item.id); + if (result) + { + list_hotkey.RemoveAt(i); + } + } + } + /// + /// 热键事件 + /// + /// + public delegate void HotkeyEventHandler(int HotKeyID); + /// + /// 当使用热键时发生的事件 + /// + public event HotkeyEventHandler OnHotkey; + /// + /// 热键消息过滤 + /// + /// + /// + public bool PreFilterMessage(ref System.Windows.Forms.Message m) + { + if (m.Msg == 0x312) + { + if (OnHotkey != null) + { + if (!Enabled) { return true; } + for (int i = list_hotkey.Count - 1; i >= 0; i--) + { + HotKeyType item = (HotKeyType)list_hotkey[i]; + if ((UInt32)m.WParam == item.id) + { + OnHotkey((int)m.WParam); + return true; + } + //OnHotkey((int)m.WParam); + } + //OnHotkey((int)m.WParam); + } + } + return false; + } + } + /// + /// 热键类型 + /// + public class HotKeyType + { + /// + /// 热键id + /// + public int id; + /// + /// 功能键 + /// + public KeyModifiers fsModifiers; + /// + /// 普通键 + /// + public Keys vk; + /// + /// 热键类型 + /// + /// + /// + /// + public HotKeyType(int id, KeyModifiers fsModifiers, Keys vk) + { + this.id = id; + this.fsModifiers = fsModifiers; + this.vk = vk; + } + } +} diff --git a/Source/MyDb/bin/x86/Debug/MyDb.dll b/Source/MyDb/bin/x86/Debug/MyDb.dll new file mode 100644 index 0000000..0fab45f Binary files /dev/null and b/Source/MyDb/bin/x86/Debug/MyDb.dll differ diff --git a/Source/MyDb/bin/x86/Release/MyDb.dll b/Source/MyDb/bin/x86/Release/MyDb.dll new file mode 100644 index 0000000..16f2c92 Binary files /dev/null and b/Source/MyDb/bin/x86/Release/MyDb.dll differ diff --git a/Source/MyDb_MSSQL/MyDb_MSSQLV35.csproj b/Source/MyDb_MSSQL/MyDb_MSSQLV35.csproj new file mode 100644 index 0000000..fd8182d --- /dev/null +++ b/Source/MyDb_MSSQL/MyDb_MSSQLV35.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + {631290D3-7CB8-4B62-833E-361C20A5F2E0} + Library + Properties + MyDb_MSSQL + MyDb_MSSQL + v3.5 + 512 + + + + true + full + false + ..\输出dll\.NET3.5\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\输出dll\.NET3.5\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV35 + + + + + \ No newline at end of file diff --git a/Source/MyDb_MSSQL/MyDb_MSSQLV4.csproj b/Source/MyDb_MSSQL/MyDb_MSSQLV4.csproj new file mode 100644 index 0000000..2a94f8d --- /dev/null +++ b/Source/MyDb_MSSQL/MyDb_MSSQLV4.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + {631290D3-7CB8-4B62-833E-361C20A5F2E0} + Library + Properties + MyDb_MSSQL + MyDb_MSSQL + v4.0 + 512 + + + + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\..\Bin\Release\CommonControls\.NET4\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV4 + + + + + \ No newline at end of file diff --git a/Source/MyDb_MSSQL/Properties/AssemblyInfo.cs b/Source/MyDb_MSSQL/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8dcd215 --- /dev/null +++ b/Source/MyDb_MSSQL/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("MyDb_MSSQL")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MyDb_MSSQL")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +//将 ComVisible 设置为 false 将使此程序集中的类型 +//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("631290d3-7cb8-4b62-833e-361c20a5f2e0")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.2.1712.1800")] +[assembly: AssemblyFileVersion("2.2.1712.1800")] diff --git a/Source/MyDb_MSSQL/SqlDataProvider.cs b/Source/MyDb_MSSQL/SqlDataProvider.cs new file mode 100644 index 0000000..692bb5c --- /dev/null +++ b/Source/MyDb_MSSQL/SqlDataProvider.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using DataParameter = System.Data.SqlClient.SqlParameter; +using DataCommand = System.Data.SqlClient.SqlCommand; +using DataAdapter = System.Data.SqlClient.SqlDataAdapter; +namespace ryCommonDb +{ + public class SqlDataProvider:IDbInterface + { + ryCommonDb.MSSQLDb myDb = new MSSQLDb(); + public int ConnDb(string sql) + { + myDb.fv_ConnStr = sql; + return myDb.ConnDb(); + } + public int CloseDb() + { + myDb.CloseDb(); + return 1; + } + public int GetCount(string tableName, string wheresql) + { + string m_where = ""; + if (wheresql != "") + { + m_where = " where " + wheresql; + } + string m_order = "(order by id)"; + string sql= "select count(*) from (select *,(ROW_NUMBER() OVER" + m_order + ") as myrow from " + tableName + m_where + ") as t"; + return Convert.ToInt32(myDb.ExecuteSQL(sql,(DataParameter[])GetParameter(), "0")[0]); + } + public int ChangePwd(string newPwd) + { + return -1000; + } + private List list_param = new List(); + public void AddParameter(string name,object value) + { + list_param.Add(new SQLIitem(name, value)); + } + public void ClearParameter(object name, object value) + { + list_param.Clear(); + } + public object[] GetParameter() + { + DataParameter[] defPar = new DataParameter[list_param.Count]; + for (int i = 0; i < list_param.Count; i++) + { + SQLIitem item = (SQLIitem)list_param[i]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + return defPar; + } + public object[] GetParameter(RyQuickSQL mySQL) + { + DataParameter[] defPar = new DataParameter[mySQL.List.Count + mySQL.List_param.Count]; + for (int i = 0; i < mySQL.List.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List[i]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + for (int i = mySQL.List.Count; i < mySQL.List.Count + mySQL.List_param.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List_param[i - mySQL.List.Count]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + return defPar; + } + public string GetPageSQL(string tableName, string wheresql, string orderSQL) + { + return GetPageSQL("*", tableName, wheresql, orderSQL); + } + public string GetPageSQL(string field, string tableName, string wheresql, string orderSQL) + { + string m_where = ""; + if (wheresql != "") + { + m_where = " where " + wheresql; + } + string m_order = "(order by id)"; + if (orderSQL != "") + { + m_order = "(" + orderSQL + ")"; + } + return "select "+ field + " from (select *,(ROW_NUMBER() OVER" + m_order + ")as myrow from " + tableName + m_where + ") as t where t.myrow between {recordnum1} and {pageendnum1}"; + } + public string GetPageSQL2(string tableName, string wheresql, string orderSQL) + { + return ""; + } + public string GetPageSQL2(string field, string tableName, string wheresql, string orderSQL) + { + return ""; + } + public bool ContainsData(string sql, object[] Parameter) + { + System.Data.DataSet ds = ReadData(sql, Parameter); + if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) + { + return true; + } + return false; + } + public System.Data.DataSet ReadData(string sql, object[] Parameter) + { + try + { + DataCommand cmd = myDb.SQL_cn.CreateCommand(); + cmd.Parameters.Clear(); + if (Parameter != null) + cmd.Parameters.AddRange(Parameter); + cmd.CommandText = sql; + DataAdapter ad = new DataAdapter(cmd); + System.Data.DataSet ds = new System.Data.DataSet(); + ad.Fill(ds); + ad.Dispose(); + cmd.Parameters.Clear(); + cmd.Dispose(); + return ds; + } + catch { return new System.Data.DataSet(); } + } + public System.Data.DataSet ReadData(string sql, RyQuickSQL mySQL) + { + return ReadData(sql,GetParameter(mySQL)); + } + public System.Data.DataSet ReadData(string sql) + { + object[] Parameter = null; + return ReadData(sql, Parameter); + } + public System.Data.DataSet ReadData(string tableName, string id) + { + object[] Parameter = null; + return ReadData("select * from " + tableName + " where id=" + id, Parameter); + } + public int ExecuteNonQuery(string sql, object[] Parameter) + { + DataCommand cmd = myDb.SQL_cn.CreateCommand(); + cmd.Parameters.Clear(); + if(Parameter!=null) + cmd.Parameters.AddRange(Parameter); + cmd.CommandText = sql; + int i= cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + cmd.Dispose(); + return i; + } + public int ExecuteNonQuery(string sql, RyQuickSQL mySQL) + { + return ExecuteNonQuery(sql,GetParameter(mySQL)); + } + public int ExecuteNonQuery(string sql) + { + object[] pram = null; + return ExecuteNonQuery(sql, pram); + } + public int DelById(string tableName, string id) + { + object[] param = null; + return ExecuteNonQuery("delete from " + tableName + " where id=" + id, param); + } + public int CreateDb(RyQuickSQL mySQL) + { + string tmpSQL = "CREATE TABLE " + mySQL.TableName + " ([ID] INTEGER PRIMARY KEY,"; + for (int i = 0; i < mySQL.List.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List[i]; + if (item.value is string) + { + if (item.len == 0) + { + tmpSQL += "[" + item.Field + "] [nvarchar](max),"; + } + else + { tmpSQL += "[" + item.Field + "] [nvarchar]("+ item.len + "),"; } + } + else if (item.value is int || item.value is Int64) + { + tmpSQL += "[" + item.Field + "] [int] 0,"; + } + else if (item.value is double || item.value is float) + { + tmpSQL += "[" + item.Field + "] [float] 0,"; + } + else if (item.value is DateTime) + { + tmpSQL += "[" + item.Field + "] [DATETIME],"; + } + } + object[] param = null; + return ExecuteNonQuery(tmpSQL.Substring(0, tmpSQL.Length - 1) + ")", param); + } + SqlTransaction tr; + public void BeginTransaction() + { + tr = myDb.SQL_cn.BeginTransaction(); + } + public void Commit() + { + tr.Commit(); + } + public void Free() + { + list_param.Clear(); + myDb.CloseDb(); + } + } +} diff --git a/Source/MyDb_MSSQL/clsMSSQLDb.cs b/Source/MyDb_MSSQL/clsMSSQLDb.cs new file mode 100644 index 0000000..8371038 --- /dev/null +++ b/Source/MyDb_MSSQL/clsMSSQLDb.cs @@ -0,0 +1,502 @@ +//--------------------------日期:2014-2-22 +//--------------------------版本:1.0.0.0 +//--------------------------作者:itrycn +using System; +using System.Collections.Generic; +using System.Text; +using System.Data; +using System.Data.SqlClient; +using System.ComponentModel; +namespace ryCommonDb +{ + public class MSSQLDb : IDisposable + { + public delegate void ErrorHandler(object sender, string errorStr,string errorId); + [Description("发生错误时发生")] + public event ErrorHandler OnError; + public SqlConnection SQL_cn; + public string fv_ConnStr = ""; + public MSSQLDb() + { + } + /// + /// 连接数据库 + /// + /// 数据库连接字符串 + /// + public MSSQLDb(string ConnStr) + { + fv_ConnStr = ConnStr; + } + /// + /// 连接数据库 + /// + /// 数据源 + /// 数据库名称 + /// 用户id + /// 用户密码 + public MSSQLDb(string DataSource, string DbName, string uId, string pwd) + { + if (uId == "") + { + fv_ConnStr = "Data Source=" + DataSource + ";database=" + DbName + ";Integrated Security=True;Pooling=False"; + } + else + { + fv_ConnStr = "Data Source=" + DataSource + ";database=" + DbName + ";uid=" + uId + ";pwd=" + pwd; + } + } + ~MSSQLDb() + { + CloseDb(); + } + /// + /// 连接数据库 + /// + /// + public int ConnDb() + { + try + { + SQL_cn = new SqlConnection() + { + ConnectionString = fv_ConnStr, + }; + SQL_cn.Open(); + return 1; + } + catch(Exception ex) + { + OnError?.Invoke(this,ex.Message,"errorconn"); + return -1; + } + } + /// + /// 关闭数据库 + /// + /// + public void CloseDb() + { + try + { + if (SQL_cn != null && SQL_cn.State != ConnectionState.Closed) + { + SQL_cn.Close(); + } + } + catch + { + OnError?.Invoke(this, "关闭数据库出错", "errorclose"); + } + } + /// + /// 运行SQL命令 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ExecuteNonQuery(string SQLText, SqlParameter[] commandParameters) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + foreach (SqlParameter parm in commandParameters) + { cm.Parameters.Add(parm); } + } + cm.Connection = SQL_cn; + int i = cm.ExecuteNonQuery(); + cm.Parameters.Clear(); + cm.Dispose(); + return i; + } + #endregion + } + catch (Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + /// + /// 运行SQL命令 + /// + /// SQL语句 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ExecuteNonQuery(string SQLText) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + cm.Connection = SQL_cn; + int i = cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this,ex.Message,"errrorconn"); + return -1; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, SqlParameter[] commandParameters) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + } + SqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return null; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// SQL命令参数 + /// 数组第一个默认的值 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, SqlParameter[] commandParameters, string DefFristValue) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + } + SqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + if (resultStr == null) + { + resultStr = new string[1]; + resultStr[0] = DefFristValue; + } + cm.Parameters.Clear(); + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch(Exception ex) + { + string[] resultStr = null; + resultStr = new string[1]; + resultStr[0] = DefFristValue; + OnError?.Invoke(this, ex.Message, "errorconn"); + return resultStr; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return null; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// 数组第一个默认的值 + /// 运行失败,则返回DefFristValue,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, string DefFristValue) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + if (resultStr == null) + { + resultStr = new string[1]; + resultStr[0] = DefFristValue; + } + return resultStr; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + string[] resultStr = null; + resultStr = new string[1]; + resultStr[0] = DefFristValue; + return resultStr; + } + } + /// + /// 清空指定表的所有数据 + /// + /// 表名 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ClearTableData(string TableName) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "delete from " + TableName; + cm.Connection = SQL_cn; + int i = cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + /// + /// 判断指定值是否存在 + /// + /// 表名 + /// 指定值所属字段 + /// 指定值 + /// 当前id,如果是新增记录,请填写-1 + /// + public bool IsExistValue(string TableName, string valueField, string value, int curId) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "select * from " + TableName + " where " + valueField + "=@tvalue"; + cm.Parameters.AddWithValue("@tvalue", DbType.String); + cm.Parameters["@tvalue"].Value = value; + SqlDataReader reader = cm.ExecuteReader(); + bool result = false; + while (reader.Read()) + { + if (curId < 0) + { + result = true; + } + else + { + if (reader["id"].ToString() == curId.ToString()) + { + result = false; + } + else + { + result = true; + } + } + break; + } + + reader.Close(); + cm.Dispose(); + return result; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return false; + } + } + /// + /// 判断SQL语句是否有结果返回 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回-1;存在结果,返回1;不存在结果,返回0 + public int ExecuteReadResult(string SQLText, SqlParameter[] commandParameters) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + //foreach (SQLiteParameter parm in commandParameters) + //{ cm.Parameters.Add(parm); } + } + SqlDataReader reader = cm.ExecuteReader(); + int i = 0; + while (reader.Read()) + { + i = 1; + break; + } + reader.Close(); + cm.Parameters.Clear(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + /// + /// 判断SQL语句是否有结果返回 + /// + /// SQL语句 + /// 运行失败,则返回-1;存在结果,返回1;不存在结果,返回0 + public int ExecuteReadResult(string SQLText) + { + try + { + #region 数据库 + { + SqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SqlDataReader reader = cm.ExecuteReader(); + int i = 0; + while (reader.Read()) + { + i = 1; + break; + } + reader.Close(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + private bool disposed = false; + public virtual void Dispose() + { + if (!this.disposed) + { + try + { + CloseDb(); + // release scarce resource here + } + finally + { + this.disposed = true; + GC.SuppressFinalize(this); + } + } + } + } +} diff --git a/Source/MyDb_MySQL/.vs/MyDb_MySQLV4/v15/.suo b/Source/MyDb_MySQL/.vs/MyDb_MySQLV4/v15/.suo new file mode 100644 index 0000000..3582927 Binary files /dev/null and b/Source/MyDb_MySQL/.vs/MyDb_MySQLV4/v15/.suo differ diff --git a/Source/MyDb_MySQL/MyDb_MySQLV35.csproj b/Source/MyDb_MySQL/MyDb_MySQLV35.csproj new file mode 100644 index 0000000..c74fa44 --- /dev/null +++ b/Source/MyDb_MySQL/MyDb_MySQLV35.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + {631290D3-7CB8-4B62-833E-361C20A5F2E0} + Library + Properties + MyDb_MySQL + MyDb_MySQL + v3.5 + 512 + + + + true + full + false + ..\输出dll\.NET3.5\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\输出dll\.NET3.5\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV35 + + + + + \ No newline at end of file diff --git a/Source/MyDb_MySQL/MyDb_MySQLV4.csproj b/Source/MyDb_MySQL/MyDb_MySQLV4.csproj new file mode 100644 index 0000000..a7d2a55 --- /dev/null +++ b/Source/MyDb_MySQL/MyDb_MySQLV4.csproj @@ -0,0 +1,64 @@ + + + + + Debug + AnyCPU + {DE092C43-1AB5-4229-8EC8-35C9936C4331} + Library + Properties + MyDb_MySQL + MyDb_MySQL + v4.0 + 512 + + + + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + none + true + ..\..\Bin\Release\CommonControls\.NET4\ + TRACE + prompt + 4 + + + + ..\..\Bin\Release\CommonControls\.NET4\MySql.Data.dll + + + + + + + + + + + + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV4 + + + + + \ No newline at end of file diff --git a/Source/MyDb_MySQL/Properties/AssemblyInfo.cs b/Source/MyDb_MySQL/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8dcd215 --- /dev/null +++ b/Source/MyDb_MySQL/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("MyDb_MSSQL")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MyDb_MSSQL")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +//将 ComVisible 设置为 false 将使此程序集中的类型 +//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("631290d3-7cb8-4b62-833e-361c20a5f2e0")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.2.1712.1800")] +[assembly: AssemblyFileVersion("2.2.1712.1800")] diff --git a/Source/MyDb_MySQL/clsMySQLDb.cs b/Source/MyDb_MySQL/clsMySQLDb.cs new file mode 100644 index 0000000..17e5b8f --- /dev/null +++ b/Source/MyDb_MySQL/clsMySQLDb.cs @@ -0,0 +1,501 @@ +//--------------------------日期:2014-2-22 +//--------------------------版本:1.0.0.0 +//--------------------------作者:itrycn +using System; +using System.Collections.Generic; +using System.Text; +using System.Data; +using SQLClient = MySql.Data.MySqlClient; +using System.ComponentModel; +namespace ryCommonDb +{ + public class ClsMySQLDb : IDisposable + { + public delegate void ErrorHandler(object sender, string errorStr,string errorId); + [Description("发生错误时发生")] + public event ErrorHandler OnError; + public SQLClient.MySqlConnection SQL_cn; + public string fv_ConnStr = ""; + public ClsMySQLDb() + { + } + /// + /// 连接数据库 + /// + /// 数据库连接字符串 + /// + public ClsMySQLDb(string ConnStr) + { + fv_ConnStr = ConnStr; + } + /// + /// 连接数据库 + /// + /// 数据源 + /// 数据库名称 + /// 用户id + /// 用户密码 + public ClsMySQLDb(string DataSource, string DbName, string uId, string pwd) + { + if (uId == "") + { + fv_ConnStr = "Data Source=" + DataSource + ";database=" + DbName + ";Integrated Security=True;Pooling=False"; + } + else + { + fv_ConnStr = "Data Source=" + DataSource + ";database=" + DbName + ";uid=" + uId + ";pwd=" + pwd; + } + } + ~ClsMySQLDb() + { + CloseDb(); + } + /// + /// 连接数据库 + /// + /// + public int ConnDb() + { + try + { + SQL_cn = new SQLClient.MySqlConnection + { + ConnectionString = fv_ConnStr + }; + SQL_cn.Open(); + return 1; + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + /// + /// 关闭数据库 + /// + /// + public void CloseDb() + { + try + { + if (SQL_cn != null && SQL_cn.State != ConnectionState.Closed) + { + SQL_cn.Close(); + } + } + catch + { + OnError?.Invoke(this, "关闭数据库出错", "errorclose"); + } + } + /// + /// 运行SQL命令 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ExecuteNonQuery(string SQLText, SQLClient.MySqlParameter[] commandParameters) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + foreach (SQLClient.MySqlParameter parm in commandParameters) + { cm.Parameters.Add(parm); } + } + cm.Connection = SQL_cn; + int i = cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch (Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + /// + /// 运行SQL命令 + /// + /// SQL语句 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ExecuteNonQuery(string SQLText) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + cm.Connection = SQL_cn; + int i = cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errrorconn"); + return -1; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, SQLClient.MySqlParameter[] commandParameters) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + } + SQLClient.MySqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return null; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// SQL命令参数 + /// 数组第一个默认的值 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, SQLClient.MySqlParameter[] commandParameters, string DefFristValue) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + } + SQLClient.MySqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + if (resultStr == null) + { + resultStr = new string[1]; + resultStr[0] = DefFristValue; + } + cm.Parameters.Clear(); + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch(Exception ex) + { + string[] resultStr = null; + resultStr = new string[1]; + resultStr[0] = DefFristValue; + OnError?.Invoke(this, ex.Message, "errorconn"); + return resultStr; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SQLClient.MySqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return null; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// 数组第一个默认的值 + /// 运行失败,则返回DefFristValue,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, string DefFristValue) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SQLClient.MySqlDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + if (resultStr == null) + { + resultStr = new string[1]; + resultStr[0] = DefFristValue; + } + return resultStr; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + string[] resultStr = null; + resultStr = new string[1]; + resultStr[0] = DefFristValue; + return resultStr; + } + } + /// + /// 清空指定表的所有数据 + /// + /// 表名 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ClearTableData(string TableName) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "delete from " + TableName; + cm.Connection = SQL_cn; + int i = cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + /// + /// 判断指定值是否存在 + /// + /// 表名 + /// 指定值所属字段 + /// 指定值 + /// 当前id,如果是新增记录,请填写-1 + /// + public bool IsExistValue(string TableName, string valueField, string value, int curId) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "select * from " + TableName + " where " + valueField + "=@tvalue"; + cm.Parameters.AddWithValue("@tvalue", DbType.String); + cm.Parameters["@tvalue"].Value = value; + SQLClient.MySqlDataReader reader = cm.ExecuteReader(); + bool result = false; + while (reader.Read()) + { + if (curId < 0) + { + result = true; + } + else + { + if (reader["id"].ToString() == curId.ToString()) + { + result = false; + } + else + { + result = true; + } + } + break; + } + + reader.Close(); + cm.Dispose(); + return result; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return false; + } + } + /// + /// 判断SQL语句是否有结果返回 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回-1;存在结果,返回1;不存在结果,返回0 + public int ExecuteReadResult(string SQLText, SQLClient.MySqlParameter[] commandParameters) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + //foreach (SQLiteParameter parm in commandParameters) + //{ cm.Parameters.Add(parm); } + } + SQLClient.MySqlDataReader reader = cm.ExecuteReader(); + int i = 0; + while (reader.Read()) + { + i = 1; + break; + } + reader.Close(); + cm.Parameters.Clear(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + /// + /// 判断SQL语句是否有结果返回 + /// + /// SQL语句 + /// 运行失败,则返回-1;存在结果,返回1;不存在结果,返回0 + public int ExecuteReadResult(string SQLText) + { + try + { + #region 数据库 + { + SQLClient.MySqlCommand cm = SQL_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SQLClient.MySqlDataReader reader = cm.ExecuteReader(); + int i = 0; + while (reader.Read()) + { + i = 1; + break; + } + reader.Close(); + cm.Dispose(); + return i; + } + #endregion + } + catch(Exception ex) + { + OnError?.Invoke(this, ex.Message, "errorconn"); + return -1; + } + } + private bool disposed = false; + public virtual void Dispose() + { + if (!this.disposed) + { + try + { + CloseDb(); + // release scarce resource here + } + finally + { + this.disposed = true; + GC.SuppressFinalize(this); + } + } + } + } +} diff --git a/Source/MyDb_MySQL/mySqlDataProvider.cs b/Source/MyDb_MySQL/mySqlDataProvider.cs new file mode 100644 index 0000000..fd8a8c1 --- /dev/null +++ b/Source/MyDb_MySQL/mySqlDataProvider.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using DataParameter =MySql.Data.MySqlClient.MySqlParameter; +using DataCommand = MySql.Data.MySqlClient.MySqlCommand; +using DataAdapter = MySql.Data.MySqlClient.MySqlDataAdapter; +using ryCommonDb; + +namespace ryCommonDb +{ + public class MySqlDataProvider:IDbInterface + { + ClsMySQLDb myDb = new ClsMySQLDb(); + public int ConnDb(string sql) + { + myDb.fv_ConnStr = sql; + return myDb.ConnDb(); + } + public int CloseDb() + { + myDb.CloseDb(); + return 1; + } + public int GetCount(string tableName, string wheresql) + { + string m_where = ""; + if (wheresql != "") + { + m_where = " where " + wheresql; + } + string m_order = "(order by id)"; + string sql= "select count(*) from (select *,(ROW_NUMBER() OVER" + m_order + ") as myrow from " + tableName + m_where + ") as t"; + return Convert.ToInt32(myDb.ExecuteSQL(sql,(DataParameter[])GetParameter(), "0")[0]); + } + public int ChangePwd(string newPwd) + { + return -1000; + } + private List list_param = new List(); + public void AddParameter(string name,object value) + { + list_param.Add(new SQLIitem(name, value)); + } + public void ClearParameter(object name, object value) + { + list_param.Clear(); + } + public object[] GetParameter() + { + DataParameter[] defPar = new DataParameter[list_param.Count]; + for (int i = 0; i < list_param.Count; i++) + { + SQLIitem item = (SQLIitem)list_param[i]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + return defPar; + } + public object[] GetParameter(RyQuickSQL mySQL) + { + DataParameter[] defPar = new DataParameter[mySQL.List.Count + mySQL.List_param.Count]; + for (int i = 0; i < mySQL.List.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List[i]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + for (int i = mySQL.List.Count; i < mySQL.List.Count + mySQL.List_param.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List_param[i - mySQL.List.Count]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + return defPar; + } + public string GetPageSQL(string tableName, string wheresql, string orderSQL) + { + return GetPageSQL("*", tableName, wheresql, orderSQL); + } + public string GetPageSQL(string field, string tableName, string wheresql, string orderSQL) + { + string m_where = ""; + if (wheresql != "") + { + m_where = " where " + wheresql; + } + string m_order = ""; + if (orderSQL != "") + { + m_order = " " + orderSQL; + } + return "select " + field + " from " + tableName + m_where + m_order + " limit {recordnum},{pagesize}"; + } + public string GetPageSQL2(string tableName, string wheresql, string orderSQL) + { + return ""; + } + public string GetPageSQL2(string field, string tableName, string wheresql, string orderSQL) + { + return ""; + } + public bool ContainsData(string sql, object[] Parameter) + { + System.Data.DataSet ds = ReadData(sql, Parameter); + if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) + { + return true; + } + return false; + } + public System.Data.DataSet ReadData(string sql, object[] Parameter) + { + DataCommand cmd = myDb.SQL_cn.CreateCommand(); + cmd.Parameters.Clear(); + if (Parameter != null) + cmd.Parameters.AddRange(Parameter); + cmd.CommandText = sql; + DataAdapter ad = new DataAdapter(cmd); + System.Data.DataSet ds=new System.Data.DataSet(); + ad.Fill(ds); + ad.Dispose(); + cmd.Parameters.Clear(); + cmd.Dispose(); + return ds; + } + public System.Data.DataSet ReadData(string sql, RyQuickSQL mySQL) + { + return ReadData(sql,GetParameter(mySQL)); + } + public System.Data.DataSet ReadData(string sql) + { + object[] Parameter = null; + return ReadData(sql, Parameter); + } + public System.Data.DataSet ReadData(string tableName, string id) + { + object[] Parameter = null; + return ReadData("select * from " + tableName + " where id=" + id, Parameter); + } + public int ExecuteNonQuery(string sql, object[] Parameter) + { + DataCommand cmd = myDb.SQL_cn.CreateCommand(); + cmd.Parameters.Clear(); + if(Parameter!=null) + cmd.Parameters.AddRange(Parameter); + cmd.CommandText = sql; + int i= cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + cmd.Dispose(); + return i; + } + public int ExecuteNonQuery(string sql, RyQuickSQL mySQL) + { + return ExecuteNonQuery(sql, GetParameter(mySQL)); + } + public int ExecuteNonQuery(string sql) + { + object[] pram = null; + return ExecuteNonQuery(sql, pram); + } + public int DelById(string tableName, string id) + { + object[] param = null; + return ExecuteNonQuery("delete from " + tableName + " where id=" + id, param); + } + public int CreateDb(RyQuickSQL mySQL) + { + string tmpSQL = "CREATE TABLE " + mySQL.TableName + " ([ID] INTEGER PRIMARY KEY,"; + for (int i = 0; i < mySQL.List.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List[i]; + if (item.value is string) + { + if (item.len == 0) + { + tmpSQL += "[" + item.Field + "] [nvarchar](max),"; + } + else + { tmpSQL += "[" + item.Field + "] [nvarchar]("+ item.len + "),"; } + } + else if (item.value is int || item.value is Int64) + { + tmpSQL += "[" + item.Field + "] [int] 0,"; + } + else if (item.value is double || item.value is float) + { + tmpSQL += "[" + item.Field + "] [float] 0,"; + } + else if (item.value is DateTime) + { + tmpSQL += "[" + item.Field + "] [DATETIME],"; + } + } + object[] param = null; + return ExecuteNonQuery(tmpSQL.Substring(0, tmpSQL.Length - 1) + ")", param); + } + MySql.Data.MySqlClient.MySqlTransaction tr; + public void BeginTransaction() + { + tr = myDb.SQL_cn.BeginTransaction(); + } + public void Commit() + { + tr.Commit(); + } + public void Free() + { + list_param.Clear(); + myDb.CloseDb(); + } + } +} diff --git a/Source/MyDb_SQLite/MyDb_SQLiteV35.csproj b/Source/MyDb_SQLite/MyDb_SQLiteV35.csproj new file mode 100644 index 0000000..0e05137 --- /dev/null +++ b/Source/MyDb_SQLite/MyDb_SQLiteV35.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {6B969CE8-D723-4B2C-A8FD-FAD2FB28FF01} + Library + Properties + MyDb_SQLite + MyDb_SQLite + v3.5 + 512 + + + + true + full + false + ..\输出dll\.NET3.5\ + DEBUG;TRACE + prompt + 4 + x86 + + + none + true + ..\输出dll\.NET3.5\Release\ + TRACE + prompt + 4 + x86 + Auto + + + + + + ..\..\..\..\程序开发源码\QO流程管理\Bin\Debug\System.Data.SQLite.DLL + + + + + + + + + + + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV35 + + + + + \ No newline at end of file diff --git a/Source/MyDb_SQLite/MyDb_SQLiteV4.csproj b/Source/MyDb_SQLite/MyDb_SQLiteV4.csproj new file mode 100644 index 0000000..eb92d34 --- /dev/null +++ b/Source/MyDb_SQLite/MyDb_SQLiteV4.csproj @@ -0,0 +1,72 @@ + + + + + Debug + AnyCPU + {6B969CE8-D723-4B2C-A8FD-FAD2FB28FF01} + Library + Properties + MyDb_SQLite + MyDb_SQLite + v4.0 + 512 + + + + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4\ + DEBUG;TRACE + prompt + 4 + x86 + + + none + true + ..\..\Bin\Release\CommonControls\.NET4\ + TRACE + prompt + 4 + x86 + Auto + + + + + + False + D:\Program Files (x86)\System.Data.SQLite\.NET 4.0\bin\System.Data.SQLite.dll + + + + + + + + + + + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV4 + + + + + + + + + \ No newline at end of file diff --git a/Source/MyDb_SQLite/Properties/AssemblyInfo.cs b/Source/MyDb_SQLite/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..74ff908 --- /dev/null +++ b/Source/MyDb_SQLite/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("MyDb_SQLite")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MyDb_SQLite")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +//将 ComVisible 设置为 false 将使此程序集中的类型 +//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("6b969ce8-d723-4b2c-a8fd-fad2fb28ff01")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.1.1909.1202")] +[assembly: AssemblyFileVersion("2.1.1909.1202")] \ No newline at end of file diff --git a/Source/MyDb_SQLite/SQLiteDataProvider.cs b/Source/MyDb_SQLite/SQLiteDataProvider.cs new file mode 100644 index 0000000..47f4682 --- /dev/null +++ b/Source/MyDb_SQLite/SQLiteDataProvider.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections.Generic; +using System.Data.SQLite; +using System.Linq; +using System.Text; +using DataParameter = System.Data.SQLite.SQLiteParameter; +using DataCommand = System.Data.SQLite.SQLiteCommand; +using DataAdapter = System.Data.SQLite.SQLiteDataAdapter; +using System.Windows.Forms; + +namespace ryCommonDb +{ + public class SQLiteDataProvider : IDbInterface + { + ryCommonDb.ClsDb myDb = new ryCommonDb.ClsDb(); + public int ConnDb(string sql) + { + string[] item = sql.Split('|'); + if (item.Length == 1) + { + return myDb.ConnDb(sql.Replace("",Application.StartupPath),""); + } + else + { return myDb.ConnDb(item[0].Replace("", Application.StartupPath), item[1]); } + } + public int CloseDb() + { + myDb.CloseDb(); + return 1; + } + public int GetCount(string tableName, string wheresql) + { + string m_where = ""; + if (wheresql != "") + { + m_where = " where " + wheresql; + } + string sql= "select count(*) from "+ tableName + m_where; + return Convert.ToInt32(myDb.ExecuteSQL(sql,(DataParameter[])GetParameter(), "0")[0]); + } + public int ChangePwd(string newPwd) + { + myDb.ChangePwd(newPwd); + return 1; + } + private List list_param = new List(); + public void AddParameter(string name,object value) + { + list_param.Add(new SQLIitem(name, value)); + } + public void ClearParameter(object name, object value) + { + list_param.Clear(); + } + public object[] GetParameter() + { + DataParameter[] defPar = new DataParameter[list_param.Count]; + for (int i = 0; i < list_param.Count; i++) + { + SQLIitem item = (SQLIitem)list_param[i]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + return defPar; + } + public object[] GetParameter(RyQuickSQL mySQL) + { + DataParameter[] defPar = new DataParameter[mySQL.List.Count + mySQL.List_param.Count]; + for (int i = 0; i < mySQL.List.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List[i]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + for (int i = mySQL.List.Count; i < mySQL.List.Count + mySQL.List_param.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List_param[i - mySQL.List.Count]; + defPar[i] = new DataParameter("@" + item.Field.TrimStart('@').TrimStart('[').TrimEnd(']'), item.value); + } + return defPar; + } + public string GetPageSQL(string tableName, string wheresql, string orderSQL) + { + return GetPageSQL("*", tableName, wheresql, orderSQL); + } + public string GetPageSQL2(string tableName, string wheresql, string orderSQL) + { + return ""; + } + public string GetPageSQL(string field,string tableName, string wheresql, string orderSQL) + { + string m_where = ""; + if (wheresql != "") + { + m_where = " where " + wheresql; + } + string m_order = ""; + if (orderSQL != "") + { + m_order = " " + orderSQL; + } + return "select "+ field + " from " + tableName + m_where + m_order + " limit {pagesize} offset {recordnum}"; + } + public string GetPageSQL2(string field,string tableName, string wheresql, string orderSQL) + { + return ""; + } + public bool ContainsData(string sql, object[] Parameter) + { + System.Data.DataSet ds=ReadData(sql, Parameter); + if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) + { + return true; + } + return false; + } + public System.Data.DataSet ReadData(string sql, object[] Parameter) + { + DataCommand cmd = myDb.SQLite_cn.CreateCommand(); + cmd.Parameters.Clear(); + if (Parameter != null) + cmd.Parameters.AddRange(Parameter); + cmd.CommandText = sql; + DataAdapter ad = new DataAdapter(cmd); + System.Data.DataSet ds=new System.Data.DataSet(); + ad.Fill(ds); + ad.Dispose(); + cmd.Dispose(); + return ds; + } + public System.Data.DataSet ReadData(string sql, RyQuickSQL mySQL) + { + return ReadData(sql, GetParameter(mySQL)); + } + public System.Data.DataSet ReadData(string sql) + { + object[] Parameter = null; + return ReadData(sql, Parameter); + } + public System.Data.DataSet ReadData(string tableName, string id) + { + object[] Parameter = null; + return ReadData("select * from " + tableName + " where id=" + id, Parameter); + } + public int ExecuteNonQuery(string sql, object[] Parameter) + { + DataCommand cmd = myDb.SQLite_cn.CreateCommand(); + cmd.Parameters.Clear(); + if(Parameter!=null) + cmd.Parameters.AddRange(Parameter); + cmd.CommandText = sql; + int i= cmd.ExecuteNonQuery(); + cmd.Dispose(); + return i; + } + public int ExecuteNonQuery(string sql, RyQuickSQL mySQL) + { + return ExecuteNonQuery(sql, GetParameter(mySQL)); + } + public int ExecuteNonQuery(string sql) + { + object[] pram = null; + return ExecuteNonQuery(sql, pram); + } + SQLiteTransaction tr; + public void BeginTransaction() + { + tr= myDb.SQLite_cn.BeginTransaction(); + } + public void Commit() + { + tr.Commit(); + } + public int DelById(string tableName, string id) + { + object[] param = null; + return ExecuteNonQuery("delete from " + tableName + " where id=" + id, param); + } + public int CreateDb(RyQuickSQL mySQL) + { + bool table_exist = true; + DataCommand cmd = myDb.SQLite_cn.CreateCommand(); + cmd.Parameters.Clear(); + cmd.CommandText = "SELECT COUNT(*) FROM sqlite_master where type='table' and name='" + mySQL.TableName + "'"; + if (0 == Convert.ToInt32(cmd.ExecuteScalar())) + { + table_exist = false; + } + else + { + table_exist = true; + } + cmd.Dispose(); + if (table_exist) + { + System.Data.DataSet ds = ReadData("select * from " + mySQL.TableName + " limit 1"); + for (int i = 0; i < mySQL.List.Count; i++) + { + #region 循环表字段,如果不存在就创建 + SQLIitem item = (SQLIitem)mySQL.List[i]; + if (ds.Tables[0].Columns.Contains(item.Field)) + { continue; } + string Field = ""; + if (item.value is string) + { + Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] TEXT COLLATE NOCASE"; + } + else if (item.value is int || item.value is Int64) + { + Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] INTEGER DEFAULT 0"; + } + else if (item.value is double || item.value is float) + { + Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] FLOAT DEFAULT 0"; + } + else if (item.value is DateTime) + { + Field = "[" + item.Field.TrimStart('[').TrimEnd(']') + "] DATETIME"; + } + try + { + object[] param = null; + ExecuteNonQuery("ALTER TABLE " + mySQL.TableName + " ADD COLUMN " + Field, param); + } + catch (Exception) { } + #endregion + } + return 1; + } + else + { + #region 创建表 + string tmpSQL = "CREATE TABLE " + mySQL.TableName + " ([ID] INTEGER PRIMARY KEY,"; + for (int i = 0; i < mySQL.List.Count; i++) + { + SQLIitem item = (SQLIitem)mySQL.List[i]; + if (item.value is string) + { + tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] TEXT COLLATE NOCASE,"; + } + else if (item.value is int || item.value is Int64) + { + tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] INTEGER DEFAULT 0,"; + } + else if (item.value is double || item.value is float) + { + tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] FLOAT DEFAULT 0,"; + } + else if (item.value is DateTime) + { + tmpSQL += "[" + item.Field.TrimStart('[').TrimEnd(']') + "] DATETIME,"; + } + } + object[] param = null; + return ExecuteNonQuery(tmpSQL.Substring(0, tmpSQL.Length - 1) + ")", param); + #endregion + } + } + public void Free() + { + list_param.Clear(); + myDb.CloseDb(); + } + } +} diff --git a/Source/MyDb_SQLite/clsDb.cs b/Source/MyDb_SQLite/clsDb.cs new file mode 100644 index 0000000..e57b4ef --- /dev/null +++ b/Source/MyDb_SQLite/clsDb.cs @@ -0,0 +1,708 @@ +//--------------------------日期:2014-2-22 +//--------------------------版本:2.0.2.0 +//--------------------------作者:itrycn +using System; +using System.Data; +using System.Data.SQLite; +//数据库操作类 +namespace ryCommonDb +{ + public class ClsDb + { + public ClsDb() + { + } + ~ClsDb() + { + CloseDb(); + } + /// + /// + /// + /// 数据库路径 + /// 数据库密码 + /// + public ClsDb(string DbFilePath, string PassWord) + { + DbPath = DbFilePath; + DbPassWord = PassWord; + } + /// + /// + /// + /// 数据库路径 + /// + public ClsDb(string DbFilePath) + { + DbPath = DbFilePath; + } + public SQLiteConnection SQLite_cn; + public string DbPath = ""; + public string DbPassWord = ""; + /// + /// 连接数据库 + /// + /// + public int ConnDb() + { + try + { + string folderPath = System.IO.Path.GetDirectoryName(DbPath); + if (!System.IO.Directory.Exists(folderPath)) + { + System.IO.Directory.CreateDirectory(folderPath); + } + string connstr = string.Format("Data Source={0}", DbPath); + SQLite_cn = new SQLiteConnection(connstr); + SQLite_cn.SetPassword(DbPassWord); + SQLite_cn.Open(); + return 1; + } + catch { return -1; } + } + /// + /// 设置路径和密码 + /// + /// + public int SetPathPwd(string Path, string PassWord) + { + DbPath = Path; + DbPassWord = PassWord; + return 1; + } + /// + /// 连接数据库 + /// + /// + public int ConnDb(string Path, string PassWord) + { + try + { + DbPath = Path; + string folderPath = System.IO.Path.GetDirectoryName(DbPath); + if (!System.IO.Directory.Exists(folderPath)) + { + System.IO.Directory.CreateDirectory(folderPath); + } + DbPassWord = PassWord; + string connstr = string.Format("Data Source={0}", DbPath); + SQLite_cn = new SQLiteConnection(connstr); + SQLite_cn.SetPassword(DbPassWord); + SQLite_cn.Open(); + DataTable schemaTable = SQLite_cn.GetSchema("TABLES"); + return SQLite_cn.State==ConnectionState.Open?1:0; + } + catch { return -1; } + } + public void ChangePwd(string newPwd) + { + SQLite_cn.ChangePassword(newPwd); + } + /// + /// 连接或创建数据库,如果数据库不存在,就创建,否则连接 + /// + /// + public int ConnOrCreateDb() + { + try + { + string folderPath = System.IO.Path.GetDirectoryName(DbPath); + if (System.IO.File.Exists(DbPath) == false) + { + if (System.IO.Directory.Exists(folderPath) == false) + { + System.IO.Directory.CreateDirectory(folderPath); + } + if (System.IO.Directory.Exists(folderPath) == false) + { + return -1; + } + else + { + CreateDbByExample(); + return 1; + } + } + else + { + ConnDb(); + return 1; + } + } + catch { return -2; } + } + /// + /// 连接或创建数据库,如果数据库不存在,就创建,否则连接 + /// + /// + public int ConnOrCreateDb(string Path,string PassWord) + { + try + { + DbPath = Path; + DbPassWord = PassWord; + string folderPath = System.IO.Path.GetDirectoryName(DbPath); + if (System.IO.File.Exists(DbPath) == false) + { + if (System.IO.Directory.Exists(folderPath) == false) + { + System.IO.Directory.CreateDirectory(folderPath); + } + if (System.IO.Directory.Exists(folderPath) == false) + { + return -1; + } + else + { + CreateDbByExample(); + return 1; + } + } + else + { + ConnDb(); + return 1; + } + } + catch { return -2; } + } + /// + /// 关闭数据库 + /// + /// + public void CloseDb() + { + try + { + if (SQLite_cn!=null && SQLite_cn.State != ConnectionState.Closed) + { + SQLite_cn.Close(); + } + } + catch { } + } + /// + /// 运行SQL命令 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ExecuteNonQuery(string SQLText, SQLiteParameter[] commandParameters) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + foreach (SQLiteParameter parm in commandParameters) + { cm.Parameters.Add(parm); } + } + cm.Connection = SQLite_cn; + int i=cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch + { + return -1; + } + } + /// + /// 运行SQL命令 + /// + /// SQL语句 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ExecuteNonQuery(string SQLText) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + cm.Connection = SQLite_cn; + int i = cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch + { + return -1; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, SQLiteParameter[] commandParameters) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + } + SQLiteDataReader reader = cm.ExecuteReader(); + string[] resultStr=null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch + { + return null; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// SQL命令参数 + /// 数组第一个默认的值 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText, SQLiteParameter[] commandParameters, string DefFristValue) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + } + SQLiteDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + if (resultStr == null) + { + resultStr = new string[1]; + resultStr[0] = DefFristValue; + } + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch + { + string[] resultStr = null; + resultStr = new string[1]; + resultStr[0] = DefFristValue; + return resultStr; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// 运行失败,则返回null,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SQLiteDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + return resultStr; + } + #endregion + } + catch + { + return null; + } + } + /// + /// 运行SQL命令,并返回结果 + /// + /// SQL语句 + /// 数组第一个默认的值 + /// 运行失败,则返回DefFristValue,否则返回以数组显示的字符串 + public string[] ExecuteSQL(string SQLText,string DefFristValue) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SQLiteDataReader reader = cm.ExecuteReader(); + string[] resultStr = null; + while (reader.Read()) + { + resultStr = new string[reader.FieldCount]; + for (int i = 0; i < reader.FieldCount; i++) + { + resultStr[i] = reader[i].ToString(); + } + break; + } + reader.Close(); + cm.Dispose(); + if (resultStr == null) + { + resultStr = new string[1]; + resultStr[0] = DefFristValue; + } + return resultStr; + } + #endregion + } + catch + { + string[] resultStr = null; + resultStr = new string[1]; + resultStr[0] = DefFristValue; + return resultStr; + } + } + /// + /// 清空指定表的所有数据 + /// + /// 表名 + /// 运行失败,则返回-1,否则返回影响的行数 + [Obsolete("不建议使用,请使用ClearTableData属性", false)] + public int DeleteTable(string TableName) + { + return ClearTableData(TableName); + } + /// + /// 清空指定表的所有数据 + /// + /// 表名 + /// 运行失败,则返回-1,否则返回影响的行数 + public int ClearTableData(string TableName) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "delete from " + TableName; + cm.Connection = SQLite_cn; + int i = cm.ExecuteNonQuery(); + cm.Dispose(); + return i; + } + #endregion + } + catch + { + return -1; + } + } + /// + /// 判断指定值是否存在 + /// + /// 表名 + /// 指定值所属字段 + /// 指定值 + /// 当前id,如果是新增记录,请填写-1 + /// + public bool IsExistValue(string TableName,string valueField,string value,int curId) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "select * from " + TableName + " where " + valueField + "=@tvalue"; + cm.Parameters.Add("@tvalue", DbType.String); + cm.Parameters["@tvalue"].Value = value; + SQLiteDataReader reader = cm.ExecuteReader(); + bool result = false; + while (reader.Read()) + { + if (curId < 0) + { + result = true; + } + else + { + if (reader["id"].ToString() == curId.ToString()) + { + result = false; + } + else + { + result=true; + } + } + break; + } + + reader.Close(); + cm.Dispose(); + return result; + } + #endregion + } + catch + { + return false; + } + } + /// + /// 判断SQL语句是否有结果返回 + /// + /// SQL语句 + /// SQL命令参数 + /// 运行失败,则返回-1;存在结果,返回1;不存在结果,返回0 + public int ExecuteReadResult(string SQLText, SQLiteParameter[] commandParameters) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + if (commandParameters.Length > 0) + { + cm.Parameters.AddRange(commandParameters); + //foreach (SQLiteParameter parm in commandParameters) + //{ cm.Parameters.Add(parm); } + } + SQLiteDataReader reader = cm.ExecuteReader(); + int i = 0; + while (reader.Read()) + { + i = 1; + break; + } + reader.Close(); + cm.Dispose(); + return i; + } + #endregion + } + catch + { + return -1; + } + } + /// + /// 判断SQL语句是否有结果返回 + /// + /// SQL语句 + /// 运行失败,则返回-1;存在结果,返回1;不存在结果,返回0 + public int ExecuteReadResult(string SQLText) + { + try + { + #region 数据库 + { + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = SQLText; + SQLiteDataReader reader = cm.ExecuteReader(); + int i = 0; + while (reader.Read()) + { + i = 1; + break; + } + reader.Close(); + cm.Dispose(); + return i; + } + #endregion + } + catch + { + return -1; + } + } + /// + /// 创建数据库 + /// + /// SQL语句 + /// + public void CreateDb(string SQLText) + { + if (SQLite_cn == null) + { + ConnDb(); + } + if (SQLite_cn.State != ConnectionState.Open) //如果数据库未打开,则先打开数据库 + { + ConnDb(); + } + SQLiteCommand cmd = SQLite_cn.CreateCommand(); + cmd.CommandText = SQLText; + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + /// + /// 根据内置例子创建数据库 + /// + /// + public void CreateDbByExample() + { + if (SQLite_cn == null) + { + ConnDb(); + } + if (SQLite_cn.State != ConnectionState.Open) //如果数据库未打开,则先打开数据库 + { + ConnDb(); + } + SQLiteCommand cmd = SQLite_cn.CreateCommand(); + string tmpStr = "([ID] INTEGER PRIMARY KEY,[Name] TEXT COLLATE NOCASE,[sValue1] TEXT COLLATE NOCASE,[sValue2] TEXT COLLATE NOCASE,[TD1] TEXT COLLATE NOCASE, [TD2] TEXT COLLATE NOCASE, [TD3] TEXT COLLATE NOCASE, [TD4] TEXT COLLATE NOCASE, [TD5] TEXT COLLATE NOCASE, [IntData1] INTEGER DEFAULT 0, [IntData2] INTEGER DEFAULT 0, [IntData3] INTEGER DEFAULT 0, [floatData1] FLOAT DEFAULT 0, [floatData2] FLOAT DEFAULT 0, [floatData3] FLOAT DEFAULT 0, [floatData4] FLOAT DEFAULT 0, [floatData5] FLOAT, [date1] DATETIME, [date2] DATETIME, [date3] DATETIME, [date4] DATETIME, [date5] DATETIME);"; + for (int i = 1; i < 16; i++) + { + cmd.CommandText = "CREATE TABLE MainTable"+i.ToString()+" " + tmpStr; + cmd.ExecuteNonQuery(); + } + cmd.Dispose(); + } + /// + /// 保存信息,如果Name不存在,系统会自动创建 + /// + /// 返回1,表示成功,0表示失败 + public int SetSysNameValue(string Name, string Value, string TableName) + { + try + { + #region 添加记录到数据库 + //try + { + int haveRecord = 0; + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "update [" + TableName + "] set sValue1=@sValue1,date2=@date2 where Name=@Name"; + cm.Parameters.Add("@Name", DbType.String); + cm.Parameters["@Name"].Value = Name; + cm.Parameters.Add("@sValue1", DbType.String); + cm.Parameters["@sValue1"].Value = Value; + cm.Parameters.Add("@date2", DbType.DateTime); + cm.Parameters["@date2"].Value = DateTime.Now; + cm.Connection = SQLite_cn; + haveRecord=cm.ExecuteNonQuery(); + cm.Parameters.Clear(); + if (haveRecord == 0) + { + cm.CommandText = "insert into [" + TableName + "] ([Name],[sValue1],[date1],[date2]) values(@Name,@sValue1,@date1,@date1)"; + cm.Parameters.Add("@Name", DbType.String); + cm.Parameters["@Name"].Value = Name; + cm.Parameters.Add("@sValue1", DbType.String); + cm.Parameters["@sValue1"].Value = Value; + cm.Parameters.Add("@date1", DbType.DateTime); + cm.Parameters["@date1"].Value = DateTime.Now; + cm.Connection = SQLite_cn; + cm.ExecuteNonQuery(); + cm.Dispose(); + } + } + //catch { } + #endregion + return 1; + } + catch + { + return 0; + } + } + /// + /// 获取信息 + /// + /// + public string GetValueByName(string Name,string TableName,string defValue) + { + try + { + #region 从数据库获取记录 + //try + { + string haveRecord = defValue; + SQLiteCommand cm = SQLite_cn.CreateCommand(); + cm.Parameters.Clear(); + cm.CommandText = "select * from " + TableName + " where Name=@Name"; + cm.Parameters.Add("@Name", DbType.String); + cm.Parameters["@Name"].Value = Name; + cm.Connection = SQLite_cn; + SQLiteDataReader reader = cm.ExecuteReader(); + while (reader.Read()) + { + haveRecord = reader["sValue1"].ToString(); + break; + } + reader.Close(); + cm.Dispose(); + return haveRecord; + } + //catch { } + #endregion + } + catch + { + return defValue; + } + } + /// + /// 获取信息 + /// + /// + public string GetValueByName(string Name, string TableName) + { + return GetValueByName(Name, TableName,""); + } + } +} diff --git a/Source/RyPrint/Mod/FrameControl.cs b/Source/RyPrint/Mod/FrameControl.cs new file mode 100644 index 0000000..9014d4b --- /dev/null +++ b/Source/RyPrint/Mod/FrameControl.cs @@ -0,0 +1,421 @@ +/****************************************************************** + * 创 建 人: SamWang + * 创建时间: 2012-5-10 17:00 + * 描 述: + * 在控件外部加上边框,用于拖拉,以改变内部控件的大小 + * 原 理: + * 版 本: V1.0 + * 环 境: VS2010 +******************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace DragControl +{ + class FrameControl : UserControl + { + #region Constructors + /// + /// 构造函数 + /// + public FrameControl(Control ctrl) + { + baseControl = ctrl; + AddEvents(); + CreateBounds(); + } + #endregion + + #region Fields + const int Band = 6; //调整大小的响应边框 + private int MinWidth = 20; //最小宽度 + private int MinHeight = 20;//最小高度 + Size square = new Size(Band, Band);//小矩形大小 + Control baseControl; //基础控件,即被包围的控件 + Rectangle[] smallRects = new Rectangle[8];//边框中的八个小圆圈 + Rectangle[] sideRects = new Rectangle[4];//四条边框,用来做响应区域 + Point[] linePoints = new Point[5];//四条边,用于画虚线 + Graphics g; //画图板 + Rectangle ControlRect; //控件包含边框的区域 + private Point pPoint; //上个鼠标坐标 + private Point cPoint; //当前鼠标坐标 + private MousePosOnCtrl mpoc; + #endregion + + #region Properties + /// + /// 鼠标在控件中位置 + /// + enum MousePosOnCtrl + { + NONE = 0, + TOP = 1, + RIGHT = 2, + BOTTOM = 3, + LEFT = 4, + TOPLEFT = 5, + TOPRIGHT = 6, + BOTTOMLEFT = 7, + BOTTOMRIGHT = 8, + } + #endregion + + #region Methods + /// + /// 加载事件 + /// + private void AddEvents() + { + this.Name = "FrameControl" + baseControl.Name; + this.MouseDown += new MouseEventHandler(FrameControl_MouseDown); + this.MouseMove += new MouseEventHandler(FrameControl_MouseMove); + this.MouseUp += new MouseEventHandler(FrameControl_MouseUp); + } + + #region 创建边框 + /// + /// 建立控件可视区域 + /// + private void CreateBounds() + { + //创建边界 + int X = baseControl.Bounds.X - square.Width - 1; + int Y = baseControl.Bounds.Y - square.Height - 1; + int Height = baseControl.Bounds.Height + (square.Height * 2) + 2; + int Width = baseControl.Bounds.Width + (square.Width * 2) + 2; + this.Bounds = new Rectangle(X, Y, Width, Height); + this.BringToFront(); + SetRectangles(); + //设置可视区域 + this.Region = new Region(BuildFrame()); + g = this.CreateGraphics(); + } + + /// + /// 设置定义8个小矩形的范围 + /// + void SetRectangles() + { + //左上 + smallRects[0] = new Rectangle(new Point(0, 0), square); + //右上 + smallRects[1] = new Rectangle(new Point(this.Width - square.Width - 1, 0), square); + //左下 + smallRects[2] = new Rectangle(new Point(0, this.Height - square.Height - 1), square); + //右下 + smallRects[3] = new Rectangle(new Point(this.Width - square.Width - 1, this.Height - square.Height - 1), square); + //上中 + smallRects[4] = new Rectangle(new Point(this.Width / 2 - 1, 0), square); + //下中 + smallRects[5] = new Rectangle(new Point(this.Width / 2 - 1, this.Height - square.Height - 1), square); + //左中 + smallRects[6] = new Rectangle(new Point(0, this.Height / 2 - 1), square); + //右中 + smallRects[7] = new Rectangle(new Point(square.Width + baseControl.Width + 1, this.Height / 2 - 1), square); + + //四条边线 + //左上 + linePoints[0] = new Point(square.Width / 2, square.Height / 2); + //右上 + linePoints[1] = new Point(this.Width - square.Width / 2 - 1, square.Height / 2); + //右下 + linePoints[2] = new Point(this.Width - square.Width / 2 - 1, this.Height - square.Height / 2); + //左下 + linePoints[3] = new Point(square.Width / 2, this.Height - square.Height / 2 - 1); + //左上 + linePoints[4] = new Point(square.Width / 2, square.Height / 2); + + //整个包括周围边框的范围 + ControlRect = new Rectangle(new Point(0, 0), this.Bounds.Size); + } + + /// + /// 设置边框控件可视区域 + /// + /// + private GraphicsPath BuildFrame() + { + GraphicsPath path = new GraphicsPath(); + //上边框 + sideRects[0] = new Rectangle(0, 0, this.Width - square.Width - 1, square.Height + 1); + //左边框 + sideRects[1] = new Rectangle(0, square.Height + 1, square.Width + 1, this.Height - square.Height - 1); + //下边框 + sideRects[2] = new Rectangle(square.Width + 1, this.Height - square.Height - 1, this.Width - square.Width - 1, square.Height + 1); + //右边框 + sideRects[3] = new Rectangle(this.Width - square.Width - 1, 0, square.Width + 1, this.Height - square.Height - 1); + + path.AddRectangle(sideRects[0]); + path.AddRectangle(sideRects[1]); + path.AddRectangle(sideRects[2]); + path.AddRectangle(sideRects[3]); + return path; + } + #endregion + + /// + /// 绘图 + /// + public void Draw() + { + this.BringToFront(); + //g.FillRectangles(Brushes.LightGray, sideRects); //填充四条边框的内部 + Pen pen = new Pen(Color.Black) + { + DashStyle = DashStyle.Dot//设置为虚线,用虚线画四边,模拟微软效果 + }; + g.DrawLines(pen, linePoints);//绘制四条边线 + g.FillRectangles(Brushes.White, smallRects); //填充8个小矩形的内部 + foreach (Rectangle smallRect in smallRects) + { + g.DrawEllipse(Pens.Black, smallRect); //绘制8个小椭圆 + } + //g.DrawRectangles(Pens.Black, smallRects); //绘制8个小矩形的黑色边线 + } + + /// + /// 设置光标状态 + /// + public bool SetCursorShape(int x, int y) + { + Point point = new Point(x, y); + if (!ControlRect.Contains(point)) + { + Cursor.Current = Cursors.Arrow; + return false; + } + else if (smallRects[0].Contains(point)) + { + Cursor.Current = Cursors.SizeNWSE; + mpoc = MousePosOnCtrl.TOPLEFT; + } + else if (smallRects[1].Contains(point)) + { + Cursor.Current = Cursors.SizeNESW; + mpoc = MousePosOnCtrl.TOPRIGHT; + } + else if (smallRects[2].Contains(point)) + { + Cursor.Current = Cursors.SizeNESW; + mpoc = MousePosOnCtrl.BOTTOMLEFT; + } + else if (smallRects[3].Contains(point)) + { + Cursor.Current = Cursors.SizeNWSE; + mpoc = MousePosOnCtrl.BOTTOMRIGHT; + } + else if (sideRects[0].Contains(point)) + { + Cursor.Current = Cursors.SizeNS; + mpoc = MousePosOnCtrl.TOP; + } + else if (sideRects[1].Contains(point)) + { + Cursor.Current = Cursors.SizeWE; + mpoc = MousePosOnCtrl.LEFT; + } + else if (sideRects[2].Contains(point)) + { + Cursor.Current = Cursors.SizeNS; + mpoc = MousePosOnCtrl.BOTTOM; + } + else if (sideRects[3].Contains(point)) + { + Cursor.Current = Cursors.SizeWE; + mpoc = MousePosOnCtrl.RIGHT; + } + else + { + Cursor.Current = Cursors.Arrow; + } + return true; + } + + /// + /// 控件移动 + /// + private void ControlMove() + { + cPoint = Cursor.Position; + int x = cPoint.X - pPoint.X; + int y = cPoint.Y - pPoint.Y; + switch (this.mpoc) + { + case MousePosOnCtrl.TOP: + if (baseControl.Height - y > MinHeight) + { + baseControl.Top += y; + baseControl.Height -= y; + } + else + { + baseControl.Top -= MinHeight - baseControl.Height; + baseControl.Height = MinHeight; + } + break; + case MousePosOnCtrl.BOTTOM: + if (baseControl.Height + y > MinHeight) + { + baseControl.Height += y; + } + else + { + baseControl.Height = MinHeight; + } + break; + case MousePosOnCtrl.LEFT: + if (baseControl.Width - x > MinWidth) + { + baseControl.Left += x; + baseControl.Width -= x; + } + else + { + baseControl.Left -= MinWidth - baseControl.Width; + baseControl.Width = MinWidth; + } + + break; + case MousePosOnCtrl.RIGHT: + if (baseControl.Width + x > MinWidth) + { + baseControl.Width += x; + } + else + { + baseControl.Width = MinWidth; + } + break; + case MousePosOnCtrl.TOPLEFT: + if (baseControl.Height - y > MinHeight) + { + baseControl.Top += y; + baseControl.Height -= y; + } + else + { + baseControl.Top -= MinHeight - baseControl.Height; + baseControl.Height = MinHeight; + } + if (baseControl.Width - x > MinWidth) + { + baseControl.Left += x; + baseControl.Width -= x; + } + else + { + baseControl.Left -= MinWidth - baseControl.Width; + baseControl.Width = MinWidth; + } + break; + case MousePosOnCtrl.TOPRIGHT: + if (baseControl.Height - y > MinHeight) + { + baseControl.Top += y; + baseControl.Height -= y; + } + else + { + baseControl.Top -= MinHeight - baseControl.Height; + baseControl.Height = MinHeight; + } + if (baseControl.Width + x > MinWidth) + { + baseControl.Width += x; + } + else + { + baseControl.Width = MinWidth; + } + break; + case MousePosOnCtrl.BOTTOMLEFT: + if (baseControl.Height + y > MinHeight) + { + baseControl.Height += y; + } + else + { + baseControl.Height = MinHeight; + } + if (baseControl.Width - x > MinWidth) + { + baseControl.Left += x; + baseControl.Width -= x; + } + else + { + baseControl.Left -= MinWidth - baseControl.Width; + baseControl.Width = MinWidth; + } + break; + case MousePosOnCtrl.BOTTOMRIGHT: + if (baseControl.Height + y > MinHeight) + { + baseControl.Height += y; + } + else + { + baseControl.Height = MinHeight; + } + if (baseControl.Width + x > MinWidth) + { + baseControl.Width += x; + } + else + { + baseControl.Width = MinWidth; + } + break; + + } + this.Size = baseControl.Size; + pPoint = Cursor.Position; + } + + #endregion + + #region Events + /// + /// 鼠标按下事件:记录当前鼠标相对窗体的坐标 + /// + void FrameControl_MouseDown(object sender, MouseEventArgs e) + { + pPoint = Cursor.Position; + SetCursorShape(e.X, e.Y); //更新鼠标指针样式 + } + + /// + /// 鼠标移动事件:让控件跟着鼠标移动 + /// + void FrameControl_MouseMove(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + this.Visible = false; + MoveControl.DrawDragBound(baseControl); + ControlMove(); + } + else + { + this.Visible = true; + SetCursorShape(e.X, e.Y); //更新鼠标指针样式 + } + } + + /// + /// 鼠标弹起事件:让自定义的边框出现 + /// + void FrameControl_MouseUp(object sender, MouseEventArgs e) + { + this.baseControl.Refresh(); //刷掉黑色边框 + this.Visible = true; + CreateBounds(); + Draw(); + } + #endregion + } +} diff --git a/Source/RyPrint/Mod/MoveControl.cs b/Source/RyPrint/Mod/MoveControl.cs new file mode 100644 index 0000000..ba6d0be --- /dev/null +++ b/Source/RyPrint/Mod/MoveControl.cs @@ -0,0 +1,203 @@ +/****************************************************************** + * 创 建 人: SamWang + * 创建时间: 2012-5-10 16:06 + * 描 述: + * 移动控件但不改变大小 + * 原 理: + * 版 本: V1.0 + * 环 境: VS2010 +******************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; + +namespace DragControl +{ + public class MoveControl + { + #region Constructors + public MoveControl(Control ctrl) + { + currentControl = ctrl; + AddEvents(); + } + #endregion + + #region Fields + private Control currentControl; //传入的控件 + private Point pPoint; //上个鼠标坐标 + private Point cPoint; //当前鼠标坐标 + FrameControl fc;//边框控件 + #endregion + + #region Properties + + #endregion + + #region Methods + /// + /// 挂载事件 + /// + private void AddEvents() + { + currentControl.MouseClick += new MouseEventHandler(MouseClick); + currentControl.MouseDown += new MouseEventHandler(MouseDown); + currentControl.MouseMove += new MouseEventHandler(MouseMove); + currentControl.MouseUp += new MouseEventHandler(MouseUp); + currentControl.KeyDown += CurrentControl_KeyDown; + //currentControl.KeyUp += CurrentControl_KeyUp; + } + + private void CurrentControl_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Up) + { + foreach (Control ct in this.currentControl.Parent.Controls) + { + if (ct is FrameControl) + { + ct.Top--; + } + } + } + else if (e.KeyCode == Keys.Down) + { + foreach (Control ct in this.currentControl.Parent.Controls) + { + if (ct is FrameControl) + { + ct.Top++; + } + } + } + else if (e.KeyCode == Keys.Left) + { + foreach (Control ct in this.currentControl.Parent.Controls) + { + if (ct is FrameControl) + { + ct.Left--; + } + } + } + else if (e.KeyCode == Keys.Right) + { + foreach (Control ct in this.currentControl.Parent.Controls) + { + if (ct is FrameControl) + { + ct.Left++; + } + } + } + } + + private void CurrentControl_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Delete) + { + if (this.currentControl.Parent != null) + { + this.currentControl.Parent.Refresh();//刷新父容器,清除掉其他控件的边框 + foreach (Control ct in this.currentControl.Parent.Controls) + { + if (ct is FrameControl) + { + this.currentControl.Parent.Controls.Remove(ct); + } + } + } + if (fc != null) { fc.Dispose(); } + } + } + + public void CurrentControl_Disposed(object sender, EventArgs e) + { + + } + + /// + /// 绘制拖拉时的黑色边框 + /// + public static void DrawDragBound(Control ctrl) + { + ctrl.Refresh(); + Graphics g = ctrl.CreateGraphics(); + int width = ctrl.Width; + int height = ctrl.Height; + Point[] ps = new Point[5]{new Point(0,0),new Point(width -1,0), + new Point(width -1,height -1),new Point(0,height-1),new Point(0,0)}; + g.DrawLines(new Pen(Color.Black), ps); + } + + #endregion + + #region Events + /// + /// 鼠标单击事件:用来显示边框 + /// + /// + /// + protected void MouseClick(object sender, MouseEventArgs e) + { + this.currentControl.Parent.Refresh();//刷新父容器,清除掉其他控件的边框 + this.currentControl.BringToFront(); + foreach (Control ct in this.currentControl.Parent.Controls) + { + if (ct is FrameControl) + { + this.currentControl.Parent.Controls.Remove(ct); + } + } + if (fc != null) { fc.Dispose(); } + fc = new FrameControl(this.currentControl); + this.currentControl.Parent.Controls.Add(fc); + fc.Visible = true; + fc.Draw(); + } + + /// + /// 鼠标按下事件:记录当前鼠标相对窗体的坐标 + /// + void MouseDown(object sender, MouseEventArgs e) + { + pPoint = Cursor.Position; + } + + /// + /// 鼠标移动事件:让控件跟着鼠标移动 + /// + void MouseMove(object sender, MouseEventArgs e) + { + Cursor.Current = Cursors.SizeAll; //当鼠标处于控件内部时,显示光标样式为SizeAll + //当鼠标左键按下时才触发 + if (e.Button == MouseButtons.Left) + { + MoveControl.DrawDragBound(this.currentControl); + if(fc != null ) fc.Visible = false; //先隐藏 + cPoint = Cursor.Position;//获得当前鼠标位置 + int x = cPoint.X - pPoint.X; + int y = cPoint.Y - pPoint.Y; + currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y + y); + if (fc != null) fc.Location = currentControl.Location; + pPoint = cPoint; + } + } + + /// + /// 鼠标弹起事件:让自定义的边框出现 + /// + void MouseUp(object sender, MouseEventArgs e) + { + this.currentControl.Refresh(); + if (fc != null) + { + fc.Visible = true; + fc.Draw(); + } + } + #endregion + } +} diff --git a/Source/RyPrint/Mod/PrintModEdit.Designer.cs b/Source/RyPrint/Mod/PrintModEdit.Designer.cs new file mode 100644 index 0000000..14b9304 --- /dev/null +++ b/Source/RyPrint/Mod/PrintModEdit.Designer.cs @@ -0,0 +1,248 @@ +namespace RyPrint.Mod +{ + partial class PrintModEdit + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.PnlTop = new System.Windows.Forms.Panel(); + this.BtnAddLabel = new System.Windows.Forms.Button(); + this.btnBrowser = new System.Windows.Forms.Button(); + this.txtPicPath = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.numHeight = new System.Windows.Forms.NumericUpDown(); + this.label6 = new System.Windows.Forms.Label(); + this.numWidth = new System.Windows.Forms.NumericUpDown(); + this.label4 = new System.Windows.Forms.Label(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.添加自定义ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.添加数据库字段ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.PnlPic = new System.Windows.Forms.Panel(); + this.picPreview = new System.Windows.Forms.PictureBox(); + this.PnlTop.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numHeight)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numWidth)).BeginInit(); + this.contextMenuStrip1.SuspendLayout(); + this.PnlPic.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picPreview)).BeginInit(); + this.SuspendLayout(); + // + // propertyGrid1 + // + this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Left; + this.propertyGrid1.LineColor = System.Drawing.SystemColors.ControlDark; + this.propertyGrid1.Location = new System.Drawing.Point(0, 28); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.Size = new System.Drawing.Size(244, 680); + this.propertyGrid1.TabIndex = 1; + this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.PropertyGrid1_PropertyValueChanged); + // + // PnlTop + // + this.PnlTop.Controls.Add(this.BtnAddLabel); + this.PnlTop.Controls.Add(this.btnBrowser); + this.PnlTop.Controls.Add(this.txtPicPath); + this.PnlTop.Controls.Add(this.label3); + this.PnlTop.Controls.Add(this.numHeight); + this.PnlTop.Controls.Add(this.label6); + this.PnlTop.Controls.Add(this.numWidth); + this.PnlTop.Controls.Add(this.label4); + this.PnlTop.Dock = System.Windows.Forms.DockStyle.Top; + this.PnlTop.Location = new System.Drawing.Point(0, 0); + this.PnlTop.Name = "PnlTop"; + this.PnlTop.Size = new System.Drawing.Size(1287, 28); + this.PnlTop.TabIndex = 2; + // + // BtnAddLabel + // + this.BtnAddLabel.Location = new System.Drawing.Point(717, 2); + this.BtnAddLabel.Name = "BtnAddLabel"; + this.BtnAddLabel.Size = new System.Drawing.Size(68, 23); + this.BtnAddLabel.TabIndex = 37; + this.BtnAddLabel.Text = "添加"; + this.BtnAddLabel.UseVisualStyleBackColor = true; + this.BtnAddLabel.Click += new System.EventHandler(this.BtnAddLabel_Click); + // + // btnBrowser + // + this.btnBrowser.Location = new System.Drawing.Point(662, 2); + this.btnBrowser.Name = "btnBrowser"; + this.btnBrowser.Size = new System.Drawing.Size(36, 23); + this.btnBrowser.TabIndex = 36; + this.btnBrowser.Text = "..."; + this.btnBrowser.UseVisualStyleBackColor = true; + this.btnBrowser.Click += new System.EventHandler(this.BtnBrowser_Click); + // + // txtPicPath + // + this.txtPicPath.Location = new System.Drawing.Point(384, 3); + this.txtPicPath.Name = "txtPicPath"; + this.txtPicPath.Size = new System.Drawing.Size(272, 21); + this.txtPicPath.TabIndex = 35; + this.txtPicPath.TextChanged += new System.EventHandler(this.txtPicPath_TextChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(301, 8); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(77, 12); + this.label3.TabIndex = 34; + this.label3.Text = "背景参考图片"; + // + // numHeight + // + this.numHeight.DecimalPlaces = 3; + this.numHeight.Location = new System.Drawing.Point(214, 3); + this.numHeight.Maximum = new decimal(new int[] { + 100000, + 0, + 0, + 0}); + this.numHeight.Name = "numHeight"; + this.numHeight.Size = new System.Drawing.Size(81, 21); + this.numHeight.TabIndex = 33; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(155, 8); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(53, 12); + this.label6.TabIndex = 32; + this.label6.Text = "宽(毫米)"; + // + // numWidth + // + this.numWidth.DecimalPlaces = 3; + this.numWidth.Location = new System.Drawing.Point(68, 3); + this.numWidth.Maximum = new decimal(new int[] { + 100000, + 0, + 0, + 0}); + this.numWidth.Name = "numWidth"; + this.numWidth.Size = new System.Drawing.Size(81, 21); + this.numWidth.TabIndex = 25; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(9, 8); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(53, 12); + this.label4.TabIndex = 24; + this.label4.Text = "长(毫米)"; + // + // openFileDialog1 + // + this.openFileDialog1.Filter = "图片|*.jpg;*.png;*.gif;*.bmp"; + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.添加自定义ToolStripMenuItem, + this.添加数据库字段ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(149, 48); + // + // 添加自定义ToolStripMenuItem + // + this.添加自定义ToolStripMenuItem.Name = "添加自定义ToolStripMenuItem"; + this.添加自定义ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.添加自定义ToolStripMenuItem.Text = "添加自定义"; + this.添加自定义ToolStripMenuItem.Click += new System.EventHandler(this.添加自定义ToolStripMenuItem_Click); + // + // 添加数据库字段ToolStripMenuItem + // + this.添加数据库字段ToolStripMenuItem.Name = "添加数据库字段ToolStripMenuItem"; + this.添加数据库字段ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.添加数据库字段ToolStripMenuItem.Text = "添加数据字段"; + this.添加数据库字段ToolStripMenuItem.Click += new System.EventHandler(this.添加数据库字段ToolStripMenuItem_Click); + // + // PnlPic + // + this.PnlPic.AutoScroll = true; + this.PnlPic.Controls.Add(this.picPreview); + this.PnlPic.Dock = System.Windows.Forms.DockStyle.Fill; + this.PnlPic.Location = new System.Drawing.Point(244, 28); + this.PnlPic.Name = "PnlPic"; + this.PnlPic.Size = new System.Drawing.Size(1043, 680); + this.PnlPic.TabIndex = 19; + // + // picPreview + // + this.picPreview.Location = new System.Drawing.Point(6, 6); + this.picPreview.Name = "picPreview"; + this.picPreview.Size = new System.Drawing.Size(749, 385); + this.picPreview.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.picPreview.TabIndex = 18; + this.picPreview.TabStop = false; + // + // PrintModEdit + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.Control; + this.Controls.Add(this.PnlPic); + this.Controls.Add(this.propertyGrid1); + this.Controls.Add(this.PnlTop); + this.Name = "PrintModEdit"; + this.Size = new System.Drawing.Size(1287, 708); + this.PnlTop.ResumeLayout(false); + this.PnlTop.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numHeight)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numWidth)).EndInit(); + this.contextMenuStrip1.ResumeLayout(false); + this.PnlPic.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.picPreview)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.Panel PnlTop; + private System.Windows.Forms.NumericUpDown numHeight; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.NumericUpDown numWidth; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Button btnBrowser; + private System.Windows.Forms.TextBox txtPicPath; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.Button BtnAddLabel; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 添加自定义ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 添加数据库字段ToolStripMenuItem; + private System.Windows.Forms.Panel PnlPic; + private System.Windows.Forms.PictureBox picPreview; + } +} diff --git a/Source/RyPrint/Mod/PrintModEdit.cs b/Source/RyPrint/Mod/PrintModEdit.cs new file mode 100644 index 0000000..619b3b3 --- /dev/null +++ b/Source/RyPrint/Mod/PrintModEdit.cs @@ -0,0 +1,397 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using ryPrint.Mod; +using ryPrint; + +namespace RyPrint.Mod +{ + public partial class PrintModEdit : UserControl + { + public PrintModEdit() + { + InitializeComponent(); + } + public bool IsDataChanged = false; + #region 添加控件函数 + public myLabel AddControl(string name, ClsProperty.En_Type _type) + { + if (GetControl(name) != null) + { + MessageBox.Show("该项已经存在", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Information); + return null; + } + else + { + return AddControl(name, Enum.GetName(typeof(ClsProperty.En_Type), _type), _type, "", ""); + } + } + public myLabel AddControl(string name, string title, ClsProperty.En_Type sType, string format, string value) + { + return AddControl(name, title, sType, format, value, ""); + } + public myLabel AddControl(string name, string title, ClsProperty.En_Type sType, string format, string value, string DataSource) + { + IsDataChanged = true; + myLabel ct = new myLabel() + { + Size = new Size(100, 25), + BackColor = Color.Transparent, + Text = title, + Name = name, + Parent = picPreview, + Cursor = Cursors.Arrow, + Font = new Font("黑体", 10, FontStyle.Regular) + }; + //ct.MouseDown += new MouseEventHandler(ct_MouseDown); + ct.KeyUp += Ct_KeyUp; + ct.KeyDown += new KeyEventHandler(Ct_KeyDown); + //ct.MouseMove += new MouseEventHandler(ct_MouseMove); + //ct.MouseUp += new MouseEventHandler(ct_MouseUp); + ct.SizeChanged += new EventHandler(Ct_SizeChanged); + ct.Click += new EventHandler(Ct_Click); + //ct.sType = sType; + //ct.title = title; + //ct.format = format; + //ct.value = value; + ct.Property.DataSource = DataSource; + ct.Property.Type = sType; + ct.Property.Title = title; + ct.Property.CustomFormat = format; + ct.Property.Value = value; + ct.Property.FontSize = ct.Font.Size; + ct.Property.Size = new SizeF(RySet.Pixeltomm(ct.Size.Width), RySet.Pixeltomm(ct.Size.Height)); + ct.Property.Postion = new PointF(RySet.Pixeltomm(ct.Location.X), RySet.Pixeltomm(ct.Location.Y)); + new DragControl.MoveControl(ct); + picPreview.Controls.Add(ct); + return ct; + } + private void Ct_KeyUp(object sender, KeyEventArgs e) + { + //if (e.KeyCode == Keys.Up) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Top--; + //} + //else if (e.KeyCode == Keys.Down) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Top++; + //} + //else if (e.KeyCode == Keys.Left) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Left--; + //} + //else if (e.KeyCode == Keys.Right) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Left++; + //} + } + + void Ct_SizeChanged(object sender, EventArgs e) + { + IsDataChanged = true; + myLabel ct = (myLabel)sender; + LoadProperty(ct); + } + + void Ct_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Delete) + { + IsDataChanged = true; + myLabel ct = (myLabel)sender; + picPreview.Controls.Remove(ct); + propertyGrid1.SelectedObject = null; + } + } + private myLabel GetControl(string name) + { + foreach (Control ct in picPreview.Controls) + { + if (ct.Name == name) + { + if (ct is myLabel) + { + return (myLabel)ct; + } + else + { + return null; + } + } + } + return null; + } + #endregion + + private void LoadProperty(myLabel ct) + { + propertyGrid1.SelectedObject = ct.Property; + } + private void Ct_Click(object sender, EventArgs e) + { + myLabel ct = (myLabel)sender; + LoadProperty(ct); + } + #region 控件拖放 + //private Point position; + + private void PicPreview_DragEnter(object sender, DragEventArgs e) + { + //当Button被拖拽到WinForm上时候,鼠标效果出现 + if ((e.Data.GetDataPresent(typeof(TextBox))) || (e.Data.GetDataPresent(typeof(myLabel)))) + { + e.Effect = DragDropEffects.Move; + } + } + #endregion + /// + /// 重设控件位置 + /// + /// + public string ResetLocationControl() + { + ryCommon.Storage tStor = new ryCommon.Storage(); + foreach (Control ct1 in picPreview.Controls) + { + switch(ct1) + { + case myLabel ct: + ct.Size = new Size(RySet.MMtopixel(ct.Property.Size.Width), RySet.MMtopixel(ct.Property.Size.Height)); + ct.Location = new Point(RySet.MMtopixel(ct.Property.Postion.X), RySet.MMtopixel(ct.Property.Postion.Y)); + break; + } + } + return tStor.GetXMLText(); + } + /// + /// 获取或设置配置信息 + /// + public string Config + { + get {return SaveControl(); } + set { LoadControl(value); } + } + /// + /// 保存布局配置信息到字符串 + /// + /// + public string SaveControl() + { + ryCommon.Storage tStor = new ryCommon.Storage(); + foreach (Control ct1 in picPreview.Controls) + { + switch (ct1) + { + case myLabel ct: + tStor.AddNode2("Name", ct.Name); + tStor.SetAttrValue("Title", ct.Property.Title); + tStor.SetAttrValue("Width", RySet.Pixeltomm(ct.Size.Width)); + tStor.SetAttrValue("Height", RySet.Pixeltomm(ct.Size.Height)); + tStor.SetAttrValue("FontSize", ct.Font.Size); + tStor.SetAttrValue("Left", RySet.Pixeltomm(ct.Location.X)); + tStor.SetAttrValue("Top", RySet.Pixeltomm(ct.Location.Y)); + //tStor.SetAttrValue("Left", ct.Location.X>picExpress.Image.Width?0:ct.Location.X); + //tStor.SetAttrValue("Top", ct.Location.Y>picExpress.Image.Height?0:ct.Location.Y); + tStor.SetAttrValue("Multiline", ct.Property.Multiline); + tStor.SetAttrValue("align", ct.AlignStr); + tStor.SetAttrValue("format", ct.Property.CustomFormat); + tStor.SetAttrValue("value", ct.Property.Value); + tStor.SetAttrValue("sType", (int)ct.Property.Type); + tStor.SetAttrValue("LineSpace", ct.Property.LineSpace); + tStor.SetAttrValue("PageCount", ct.Property.PageCount); + tStor.SetAttrValue("DataSource", ct.Property.DataSource); + tStor.SetAttrValue("NoPrint", ct.Property.NoPrint); + break; + } + } + ryCommon.Storage tStor_set = new ryCommon.Storage(); + tStor_set.SelectNode2("id", "set"); + tStor_set.SetAttrValue("Width",numWidth.Value); + tStor_set.SetAttrValue("Height", numHeight.Value); + tStor_set.SetAttrValue("PreviewPicPath",txtPicPath.Text); + tStor_set.SelectNode2("id", "print_xml"); + tStor_set.SetAttrValue("Value", tStor.GetXMLText()); + return tStor_set.GetXMLText(); + } + /// + /// 保存配置到文件 + /// + /// 要保存的路径 + public void SaveToFile(string path) + { + if(!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(path))) + { + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); + } + System.IO.File.WriteAllText(path, SaveControl(), Encoding.UTF8); + } + /// + /// 从xml文本中加载配置 + /// + /// + public void LoadControl(string xml) + { + ryCommon.Storage tStor_set = new ryCommon.Storage(xml); + tStor_set.SelectNode2("id", "set"); + numWidth.Value = tStor_set.GetAttrValue("Width",0); + numHeight.Value = tStor_set.GetAttrValue("Height", 0); + txtPicPath.Text = tStor_set.GetAttrValue("PreviewPicPath", ""); + tStor_set.SelectNode2("id","print_xml"); + ryCommon.Storage tStor = new ryCommon.Storage(tStor_set.GetAttrValue("Value")); + System.Xml.XmlNodeList list = tStor.GetList(); + for (int i = 0; i < list.Count; i++) + { + tStor.SelectNode3(list[i]); + myLabel ct = new myLabel() + { + Font = new Font("黑体", tStor.GetAttrValueByInt("FontSize", 10), FontStyle.Regular), + Size = new Size(RySet.MMtopixel(tStor.GetAttrValue("Width", 50f)), RySet.MMtopixel(tStor.GetAttrValue("Height", 10f))) + }; + ct.Property.Multiline = tStor.GetAttrValueByBool("Multiline", false); + if (ct.Size.Height == 0) { ct.Height = 21; } + if (ct.Size.Width == 0) { ct.Width = 100; } + ct.Property.Size = new SizeF((float)tStor.GetAttrValue("Width", 50f), (float)tStor.GetAttrValue("Height", 10f)); + ct.Location = new Point(RySet.MMtopixel(tStor.GetAttrValue("Left", 0f)), RySet.MMtopixel(tStor.GetAttrValue("Top", 0f))); + ct.Property.Postion = new PointF((float)tStor.GetAttrValue("Left", 0f), (float)tStor.GetAttrValue("Top", 0f)); + if (ct.Location.Y < 0) { ct.Top = 0; } + if (ct.Location.X < 0) { ct.Left = 0; } + //ct.Size = new Size(tStor.GetAttrValue("Width", 50), tStor.GetAttrValue("Height", 10)); + //if (ct.Size.Height == 0) { ct.Height = 21; } + //if (ct.Size.Width == 0) { ct.Width = 100; } + //ct.Property.Size = new SizeF((float)pixelTomm_Width(tStor.GetAttrValue("Width", 50)), (float)pixelTomm_Height(tStor.GetAttrValue("Height", 10))); + ////ct.Location = new Point((int)pixelTomm_Width(tStor.GetAttrValue("Left", 0)), (int)pixelTomm_Height(tStor.GetAttrValue("Top", 0))); + //ct.Property.Postion = new PointF((float)pixelTomm_Width(tStor.GetAttrValue("Left", 0)), (float)pixelTomm_Height(tStor.GetAttrValue("Top", 0))); + //ct.Size = new Size(tStor.GetAttrValue("Width", 50),tStor.GetAttrValue("Height", 10)); + //ct.Location = new Point(tStor.GetAttrValue("Left", 0),tStor.GetAttrValue("Top", 0)); + // + ClsProperty.En_Type _type = ClsProperty.En_Type.自定义; + try + { + _type = (ClsProperty.En_Type)tStor.GetAttrValue("sType", 0); + } + catch { } + ct.Property.Type = _type; + ct.Property.Title = tStor.GetAttrValue("Title"); + ct.Property.LineSpace = tStor.GetAttrValue("LineSpace", 0d); + ct.Property.PageCount = tStor.GetAttrValue("PageCount", 0); + ct.Name = tStor.GetAttrValue("Name"); + ct.Parent = picPreview; + //ct.ReadOnly = true; + ct.BackColor = Color.Transparent; + ct.Cursor = Cursors.Arrow; + ct.SetAlign(tStor.GetAttrValue("align")); + ct.Property.Value = tStor.GetAttrValue("value"); + ct.Property.CustomFormat = tStor.GetAttrValue("format"); + ct.Property.DataSource = tStor.GetAttrValue("DataSource"); + ct.Property.NoPrint = tStor.GetAttrValue("NoPrint", false); + ct.Property.Type = _type; + ct.Refresh(); + //ct.MouseDown += new MouseEventHandler(ct_MouseDown); + //ct.MouseMove += new MouseEventHandler(ct_MouseMove); + //ct.MouseUp += new MouseEventHandler(ct_MouseUp); + new DragControl.MoveControl(ct); + ct.Click += new EventHandler(Ct_Click); + ct.KeyUp += Ct_KeyUp; + ct.KeyDown += new KeyEventHandler(Ct_KeyDown); + ct.SizeChanged += new EventHandler(Ct_SizeChanged); + picPreview.Controls.Add(ct); + } + } + /// + /// 从文件中加载配置。 + /// + /// + /// + public int LoadFromFile(string path) + { + if(System.IO.File.Exists(path)) + { + LoadControl(System.IO.File.ReadAllText(path, ryCommon.TxtFileEncoder.GetEncoding(path))); + return 1; + } + return 0; + } + private void PropertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + IsDataChanged = true; + ClsProperty item = (ClsProperty)propertyGrid1.SelectedObject; + myLabel ct = GetControl(item.Name); + if (ct != null) + { + ct.Property = item; + ct.Refresh(); + } + } + + private void BtnBrowser_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == DialogResult.OK) + { + txtPicPath.Text = openFileDialog1.FileName.Replace(Application.StartupPath, ""); + } + } + private void txtPicPath_TextChanged(object sender, EventArgs e) + { + string picPath = RySet.GetTruePath(txtPicPath.Text); + if (System.IO.File.Exists(picPath)) + { + Image image = Image.FromFile(picPath); + picPreview.Image = image; + numWidth.Value = Convert.ToDecimal(RySet.InchesTomm(image.Width / Convert.ToDecimal(image.HorizontalResolution))); + numHeight.Value = Convert.ToDecimal(RySet.InchesTomm(image.Height / Convert.ToDecimal(image.VerticalResolution))); + picPreview.Width = RySet.MMtopixel((float)numWidth.Value); + picPreview.Height = RySet.MMtopixel((float)numHeight.Value); + ResetLocationControl(); + //picExpress. + } + else { picPreview.Image = null; } + } + /// + /// 获取新的控件名 + /// + /// + private string GetNewName() + { + int i = 1; + while (true) + { + if (GetControl("custom" + i.ToString()) == null) + { + return "custom" + i.ToString(); + } + i++; + } + } + private void 添加自定义ToolStripMenuItem_Click(object sender, EventArgs e) + { + string name = GetNewName(); + AddControl(name, "自定义" + name.Replace("custom", ""), ClsProperty.En_Type.自定义, "", ""); + } + + private void 添加数据库字段ToolStripMenuItem_Click(object sender, EventArgs e) + { + string name = GetNewName(); + AddControl(name, "数据字段" + name.Replace("custom", ""), ClsProperty.En_Type.数据字段, "", ""); + } + + private void BtnAddLabel_Click(object sender, EventArgs e) + { + Button ct = (Button)sender; + Point p = new Point(0, ct.Height); + contextMenuStrip1.Show(ct, p); + } + } +} diff --git a/Source/RyPrint/Mod/PrintModEdit.resx b/Source/RyPrint/Mod/PrintModEdit.resx new file mode 100644 index 0000000..ae05f8f --- /dev/null +++ b/Source/RyPrint/Mod/PrintModEdit.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 165, 17 + + \ No newline at end of file diff --git a/Source/RyPrint/Mod/SmartAnalyAddr.cs b/Source/RyPrint/Mod/SmartAnalyAddr.cs new file mode 100644 index 0000000..afa0f9f --- /dev/null +++ b/Source/RyPrint/Mod/SmartAnalyAddr.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ryPrint.Mod +{ + /// + /// 智能分析地址 + /// + public class SmartAnalyAddr + { + public static string GetStr(string input, string point1, string point2, int iPos1, out int endPos, string defValue) + { + int iIndex = iPos1; + endPos = -1; + if (iPos1 < 0) { return defValue; } + if (point1 != "") + { iIndex = input.IndexOf(point1, iPos1); } + if (iIndex == -1) { return defValue; } + int iIndex2 = 0; + if (point2 == "") { iIndex2 = input.Length; } + else { iIndex2 = input.IndexOf(point2, iIndex + point1.Length); } + string tmpStr = input; + if (iIndex < iIndex2 && iIndex >= 0) + { + tmpStr = input.Substring(iIndex + point1.Length, iIndex2 - iIndex - point1.Length); + endPos = iIndex2 + point2.Length; + } + else + { + return defValue; + } + return tmpStr; + } + public static AddrType AnalyAddr(string addr) + { + AddrType result = new AddrType(); + int iPos = 0; + int validPos = 0; + result.Province = GetStr(addr, "", "省", 0, out iPos, "").Trim(); + if (iPos >= 0) { validPos = iPos; } + result.City = GetStr(addr, "", "市", validPos, out iPos, "").Trim(); if (iPos >= 0) { validPos = iPos; } + result.County = GetStr(addr, "", "县", validPos, out iPos, "").Trim(); if (iPos >= 0) { validPos = iPos; } + if (result.County != "") { result.County += "县"; } + if (result.County=="") + { + result.County = GetStr(addr, "", "市", validPos, out iPos, "").Trim(); if (iPos >= 0) { validPos = iPos; } + if (result.County != "") { result.County += "市"; } + } + if (result.County == "") + { + result.County = GetStr(addr, "", "区", validPos, out iPos, "").Trim(); if (iPos >= 0) { validPos = iPos; } + if (result.County != "") { result.County += "区"; } + } + if(result.County=="") + { + if (addr.IndexOf("瑞安市") > 0) { result.City = "温州"; result.County = "瑞安市"; } + } + result.AddrDetail = addr.Substring(validPos); + return result; + } + public static Tb_AddrType AnalyTaobaoAddr(string addr) + { + Tb_AddrType result = new Tb_AddrType(); + int iPos = 0; + int validPos = 0; + result.Province = GetStr(addr, "", " ", 0, out iPos, ""); + if (iPos >= 0) { validPos = iPos; } + result.City = GetStr(addr, "", " ", validPos, out iPos, ""); if (iPos >= 0) { validPos = iPos; } + result.County = GetStr(addr, "", " ", validPos, out iPos, ""); if (iPos >= 0) { validPos = iPos; } + int r_k = addr.LastIndexOf(")"); + int l_k = addr.LastIndexOf("("); + if (r_k > l_k) + { + result.PCode = addr.Substring(l_k + 1, r_k - l_k-1); + result.Addr = addr.Substring(0, l_k).Trim(','); + } + else + { result.Addr = addr.Trim(','); } + if (l_k > validPos) + { + result.AddrDetail = addr.Substring(validPos, l_k- validPos).Trim(','); + } + else + { result.AddrDetail = addr.Substring(validPos).Trim(','); } + return result; + } + } + public class AddrType + { + /// + /// 省份 + /// + public string Province { get; set; } = ""; + /// + /// 所在市 + /// + public string City { get; set; } = ""; + /// + /// 所在县区 + /// + public string County { get; set; } = ""; + /// + /// 详细地址 + /// + public string AddrDetail { get; set; } = ""; + } + public class Tb_AddrType + { + /// + /// 省份 + /// + public string Province { get; set; } = ""; + /// + /// 所在市 + /// + public string City { get; set; } = ""; + /// + /// 所在县区 + /// + public string County { get; set; } = ""; + /// + /// 详细地址 + /// + public string AddrDetail { get; set; } = ""; + /// + /// + /// + public string Addr { get; set; } = ""; + /// + /// 邮编 + /// + public string PCode { get; set; } = ""; + } +} diff --git a/Source/RyPrint/Mod/clsProperty.cs b/Source/RyPrint/Mod/clsProperty.cs new file mode 100644 index 0000000..782047f --- /dev/null +++ b/Source/RyPrint/Mod/clsProperty.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace ryPrint +{ + [DefaultPropertyAttribute("Name")] + public class ClsProperty + { + private string _Name = ""; + [ReadOnlyAttribute(true),DescriptionAttribute("显示的控件ID")] + public string Name + { + get { return _Name; } + set { _Name = value; } + } + private string _Title = "自定义"; + [CategoryAttribute("内容"), DescriptionAttribute("显示的名称,只在类型为自定义时生效")] + public string Title + { + get { + if (Type == ClsProperty.En_Type.自定义 || Type == ClsProperty.En_Type.数据字段) + { + return _Title; + } + else + { + return Enum.GetName(typeof(ClsProperty.En_Type), Type); + } + } + set { _Title = value; } + } + public enum En_Type + { + 自定义 = 0, + 数据字段=12 + } + private En_Type _Type = En_Type.自定义; + [CategoryAttribute("内容"), DescriptionAttribute("当前控件的类型,当为数据类型时,将对数据进行分行打印")] + public En_Type Type + { + get { return _Type; } + set { _Type = value; } + } + private string _CustomFormat= ""; + [CategoryAttribute("内容"), DescriptionAttribute("显示的内容格式,只在类型为自定义时生效,支持时间格式化")] + public string CustomFormat + { + get { return _CustomFormat; } + set { _CustomFormat = value; } + } + private string _Value = ""; + [CategoryAttribute("内容"), DescriptionAttribute("显示的内容,只在类型为自定义或数据字段,且内容格式为空时生效。当为数据类型时,该值表示数据集合的列名,通常等于表的列名")] + public string Value + { + get { return _Value; } + set { _Value = value; } + } + private double _LineSpace = 2; + [CategoryAttribute("内容"), DescriptionAttribute("行距(单位为毫米),只在类型为数据字段时才有效,表示每项数据之间隔开的行距")] + public double LineSpace + { + get { return _LineSpace; } + set { _LineSpace = value; } + } + private int _PageCount = 0; + [CategoryAttribute("内容"), DescriptionAttribute("每页显示的数量,只在类型为数据字段时才有效,为0则表示打印所有数据。")] + public int PageCount + { + get { return _PageCount; } + set { _PageCount = value; } + } + private string _DataSource =""; + [CategoryAttribute("内容"), DescriptionAttribute("数据源;为空则表示默认数据源.")] + public string DataSource + { + get { return _DataSource; } + set { _DataSource = value; } + } + private PointF _postion =new PointF(0,0); + /// + /// 当前控件所属的位置,单位是毫米 + /// + [CategoryAttribute("基本属性"), DescriptionAttribute("当前控件所属的位置,单位是毫米")] + public PointF Postion + { + get { return _postion; } + set { _postion = value; } + } + /// + /// 当前控件所属的位置,单位是毫米 + /// + [CategoryAttribute("基本属性"), DescriptionAttribute("当前控件所属的距顶部位置,单位是毫米")] + public float Top + { + get { return _postion.Y; } + set { _postion.Y = value; } + } + /// + /// 当前控件所属的位置,单位是毫米 + /// + [CategoryAttribute("基本属性"), DescriptionAttribute("当前控件所属的距左边位置,单位是毫米")] + public float Left + { + get { return _postion.X; } + set { _postion.X = value; } + } + [CategoryAttribute("基本属性"), DescriptionAttribute("当前字符串显示方式")] + public HorizontalAlignment Align + { + get; + set; + } = HorizontalAlignment.Left; + private bool _multiline =false; + [CategoryAttribute("基本属性"), DescriptionAttribute("是否允许多行选择")] + public bool Multiline + { + get { return _multiline; } + set { _multiline = value; } + } + private bool _NoPrint = false; + [CategoryAttribute("基本属性"), DescriptionAttribute("只在预览中打印")] + public bool NoPrint + { + get { return _NoPrint; } + set { _NoPrint = value; } + } + private float _fontsize = 10; + [CategoryAttribute("基本属性"), DescriptionAttribute("当前控件字体大小")] + public float FontSize + { + get { return _fontsize; } + set { _fontsize = value; } + } + private SizeF _Size = new SizeF(); + [CategoryAttribute("基本属性"), DescriptionAttribute("控件大小,单位是毫米")] + public SizeF Size + { + get { return _Size; } + set { _Size = value; } + } + } +} diff --git a/Source/RyPrint/Mod/frmAddMod.Designer.cs b/Source/RyPrint/Mod/frmAddMod.Designer.cs new file mode 100644 index 0000000..629d253 --- /dev/null +++ b/Source/RyPrint/Mod/frmAddMod.Designer.cs @@ -0,0 +1,753 @@ +namespace ryPrint.Mod +{ + partial class frmAddMod + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmAddMod)); + this.label1 = new System.Windows.Forms.Label(); + this.txtName = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.txtDes = new System.Windows.Forms.TextBox(); + this.picExpress = new System.Windows.Forms.PictureBox(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.btnAddControl = new System.Windows.Forms.Button(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.寄件人姓名ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人电话ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人地址ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人地址类型ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.省份ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人市地址ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人所在县区ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人详细地址ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人邮编ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.寄件人单位ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.收件人姓名ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人电话ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人地址ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人地址类型ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人省份ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人所在市ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人所在县区ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人详细地址ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人邮编ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.收件人单位ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); + this.自定义ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.label3 = new System.Windows.Forms.Label(); + this.txtPicPath = new System.Windows.Forms.TextBox(); + this.btnUpdate = new System.Windows.Forms.Button(); + this.label4 = new System.Windows.Forms.Label(); + this.numWidth = new System.Windows.Forms.NumericUpDown(); + this.btnAddShop = new System.Windows.Forms.Button(); + this.contextMenuStrip2 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.货品名称ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.货品单位ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.货品规格ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.货品数量ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.货品价格ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.货品总价格ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.订单单号ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.发货备注ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.订单优惠前价格ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.优惠减免ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.订单优惠后价格ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.客户姓名ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.客户电话ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.客户公司ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.客户地址ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.btnBrowser = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.label5 = new System.Windows.Forms.Label(); + this.cbbType = new System.Windows.Forms.ComboBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.numHeight = new System.Windows.Forms.NumericUpDown(); + this.label6 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.picExpress)).BeginInit(); + this.contextMenuStrip1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numWidth)).BeginInit(); + this.contextMenuStrip2.SuspendLayout(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numHeight)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(10, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(29, 12); + this.label1.TabIndex = 0; + this.label1.Text = "名称"; + // + // txtName + // + this.txtName.Location = new System.Drawing.Point(12, 26); + this.txtName.Name = "txtName"; + this.txtName.Size = new System.Drawing.Size(243, 21); + this.txtName.TabIndex = 1; + this.txtName.TextChanged += new System.EventHandler(this.txtName_TextChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 50); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(29, 12); + this.label2.TabIndex = 2; + this.label2.Text = "备注"; + // + // txtDes + // + this.txtDes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtDes.Location = new System.Drawing.Point(12, 65); + this.txtDes.Name = "txtDes"; + this.txtDes.Size = new System.Drawing.Size(1117, 21); + this.txtDes.TabIndex = 3; + this.txtDes.TextChanged += new System.EventHandler(this.txtDes_TextChanged); + // + // picExpress + // + this.picExpress.Location = new System.Drawing.Point(3, 3); + this.picExpress.Name = "picExpress"; + this.picExpress.Size = new System.Drawing.Size(887, 521); + this.picExpress.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.picExpress.TabIndex = 4; + this.picExpress.TabStop = false; + this.picExpress.Click += new System.EventHandler(this.picExpress_Click); + this.picExpress.DragEnter += new System.Windows.Forms.DragEventHandler(this.picEXpress_DragEnter); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.Location = new System.Drawing.Point(1061, 622); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(68, 23); + this.btnCancel.TabIndex = 6; + this.btnCancel.Text = "取消"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point(987, 622); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(68, 23); + this.btnOK.TabIndex = 5; + this.btnOK.Text = "确定"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // propertyGrid1 + // + this.propertyGrid1.Location = new System.Drawing.Point(12, 140); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.Size = new System.Drawing.Size(224, 473); + this.propertyGrid1.TabIndex = 15; + this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged); + this.propertyGrid1.Click += new System.EventHandler(this.propertyGrid1_Click); + // + // btnAddControl + // + this.btnAddControl.ContextMenuStrip = this.contextMenuStrip1; + this.btnAddControl.Location = new System.Drawing.Point(13, 95); + this.btnAddControl.Name = "btnAddControl"; + this.btnAddControl.Size = new System.Drawing.Size(95, 32); + this.btnAddControl.TabIndex = 17; + this.btnAddControl.Text = "添加快递信息"; + this.btnAddControl.UseVisualStyleBackColor = true; + this.btnAddControl.Click += new System.EventHandler(this.btnAddControl_Click); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.寄件人姓名ToolStripMenuItem, + this.寄件人电话ToolStripMenuItem, + this.寄件人地址ToolStripMenuItem, + this.寄件人地址类型ToolStripMenuItem, + this.寄件人邮编ToolStripMenuItem, + this.寄件人单位ToolStripMenuItem, + this.toolStripMenuItem1, + this.收件人姓名ToolStripMenuItem, + this.收件人电话ToolStripMenuItem, + this.收件人地址ToolStripMenuItem, + this.收件人地址类型ToolStripMenuItem, + this.收件人邮编ToolStripMenuItem, + this.收件人单位ToolStripMenuItem, + this.toolStripMenuItem2, + this.自定义ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(161, 302); + // + // 寄件人姓名ToolStripMenuItem + // + this.寄件人姓名ToolStripMenuItem.Name = "寄件人姓名ToolStripMenuItem"; + this.寄件人姓名ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人姓名ToolStripMenuItem.Text = "寄件人姓名"; + this.寄件人姓名ToolStripMenuItem.Click += new System.EventHandler(this.寄件人姓名ToolStripMenuItem_Click); + // + // 寄件人电话ToolStripMenuItem + // + this.寄件人电话ToolStripMenuItem.Name = "寄件人电话ToolStripMenuItem"; + this.寄件人电话ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人电话ToolStripMenuItem.Text = "寄件人电话"; + this.寄件人电话ToolStripMenuItem.Click += new System.EventHandler(this.寄件人电话ToolStripMenuItem_Click); + // + // 寄件人地址ToolStripMenuItem + // + this.寄件人地址ToolStripMenuItem.Name = "寄件人地址ToolStripMenuItem"; + this.寄件人地址ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人地址ToolStripMenuItem.Text = "寄件人地址"; + this.寄件人地址ToolStripMenuItem.Click += new System.EventHandler(this.寄件人地址ToolStripMenuItem_Click); + // + // 寄件人地址类型ToolStripMenuItem + // + this.寄件人地址类型ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.省份ToolStripMenuItem, + this.寄件人市地址ToolStripMenuItem, + this.寄件人所在县区ToolStripMenuItem, + this.寄件人详细地址ToolStripMenuItem}); + this.寄件人地址类型ToolStripMenuItem.Name = "寄件人地址类型ToolStripMenuItem"; + this.寄件人地址类型ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人地址类型ToolStripMenuItem.Text = "寄件人地址类型"; + // + // 省份ToolStripMenuItem + // + this.省份ToolStripMenuItem.Name = "省份ToolStripMenuItem"; + this.省份ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.省份ToolStripMenuItem.Text = "寄件人省份"; + this.省份ToolStripMenuItem.Click += new System.EventHandler(this.省份ToolStripMenuItem_Click); + // + // 寄件人市地址ToolStripMenuItem + // + this.寄件人市地址ToolStripMenuItem.Name = "寄件人市地址ToolStripMenuItem"; + this.寄件人市地址ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人市地址ToolStripMenuItem.Text = "寄件人所在市"; + this.寄件人市地址ToolStripMenuItem.Click += new System.EventHandler(this.寄件人市地址ToolStripMenuItem_Click); + // + // 寄件人所在县区ToolStripMenuItem + // + this.寄件人所在县区ToolStripMenuItem.Name = "寄件人所在县区ToolStripMenuItem"; + this.寄件人所在县区ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人所在县区ToolStripMenuItem.Text = "寄件人所在县区"; + this.寄件人所在县区ToolStripMenuItem.Click += new System.EventHandler(this.寄件人所在县区ToolStripMenuItem_Click); + // + // 寄件人详细地址ToolStripMenuItem + // + this.寄件人详细地址ToolStripMenuItem.Name = "寄件人详细地址ToolStripMenuItem"; + this.寄件人详细地址ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人详细地址ToolStripMenuItem.Text = "寄件人详细地址"; + this.寄件人详细地址ToolStripMenuItem.Click += new System.EventHandler(this.寄件人详细地址ToolStripMenuItem_Click); + // + // 寄件人邮编ToolStripMenuItem + // + this.寄件人邮编ToolStripMenuItem.Name = "寄件人邮编ToolStripMenuItem"; + this.寄件人邮编ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人邮编ToolStripMenuItem.Text = "寄件人邮编"; + this.寄件人邮编ToolStripMenuItem.Click += new System.EventHandler(this.寄件人邮编ToolStripMenuItem_Click); + // + // 寄件人单位ToolStripMenuItem + // + this.寄件人单位ToolStripMenuItem.Name = "寄件人单位ToolStripMenuItem"; + this.寄件人单位ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.寄件人单位ToolStripMenuItem.Text = "寄件人公司"; + this.寄件人单位ToolStripMenuItem.Click += new System.EventHandler(this.寄件人单位ToolStripMenuItem_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(157, 6); + // + // 收件人姓名ToolStripMenuItem + // + this.收件人姓名ToolStripMenuItem.Name = "收件人姓名ToolStripMenuItem"; + this.收件人姓名ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人姓名ToolStripMenuItem.Text = "收件人姓名"; + this.收件人姓名ToolStripMenuItem.Click += new System.EventHandler(this.收件人姓名ToolStripMenuItem_Click); + // + // 收件人电话ToolStripMenuItem + // + this.收件人电话ToolStripMenuItem.Name = "收件人电话ToolStripMenuItem"; + this.收件人电话ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人电话ToolStripMenuItem.Text = "收件人电话"; + this.收件人电话ToolStripMenuItem.Click += new System.EventHandler(this.收件人电话ToolStripMenuItem_Click); + // + // 收件人地址ToolStripMenuItem + // + this.收件人地址ToolStripMenuItem.Name = "收件人地址ToolStripMenuItem"; + this.收件人地址ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人地址ToolStripMenuItem.Text = "收件人地址"; + this.收件人地址ToolStripMenuItem.Click += new System.EventHandler(this.收件人地址ToolStripMenuItem_Click); + // + // 收件人地址类型ToolStripMenuItem + // + this.收件人地址类型ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.收件人省份ToolStripMenuItem, + this.收件人所在市ToolStripMenuItem, + this.收件人所在县区ToolStripMenuItem, + this.收件人详细地址ToolStripMenuItem}); + this.收件人地址类型ToolStripMenuItem.Name = "收件人地址类型ToolStripMenuItem"; + this.收件人地址类型ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人地址类型ToolStripMenuItem.Text = "收件人地址类型"; + // + // 收件人省份ToolStripMenuItem + // + this.收件人省份ToolStripMenuItem.Name = "收件人省份ToolStripMenuItem"; + this.收件人省份ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人省份ToolStripMenuItem.Text = "收件人省份"; + this.收件人省份ToolStripMenuItem.Click += new System.EventHandler(this.收件人省份ToolStripMenuItem_Click); + // + // 收件人所在市ToolStripMenuItem + // + this.收件人所在市ToolStripMenuItem.Name = "收件人所在市ToolStripMenuItem"; + this.收件人所在市ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人所在市ToolStripMenuItem.Text = "收件人所在市"; + this.收件人所在市ToolStripMenuItem.Click += new System.EventHandler(this.收件人所在市ToolStripMenuItem_Click); + // + // 收件人所在县区ToolStripMenuItem + // + this.收件人所在县区ToolStripMenuItem.Name = "收件人所在县区ToolStripMenuItem"; + this.收件人所在县区ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人所在县区ToolStripMenuItem.Text = "收件人所在县区"; + this.收件人所在县区ToolStripMenuItem.Click += new System.EventHandler(this.收件人所在县区ToolStripMenuItem_Click); + // + // 收件人详细地址ToolStripMenuItem + // + this.收件人详细地址ToolStripMenuItem.Name = "收件人详细地址ToolStripMenuItem"; + this.收件人详细地址ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人详细地址ToolStripMenuItem.Text = "收件人详细地址"; + this.收件人详细地址ToolStripMenuItem.Click += new System.EventHandler(this.收件人详细地址ToolStripMenuItem_Click); + // + // 收件人邮编ToolStripMenuItem + // + this.收件人邮编ToolStripMenuItem.Name = "收件人邮编ToolStripMenuItem"; + this.收件人邮编ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人邮编ToolStripMenuItem.Text = "收件人邮编"; + this.收件人邮编ToolStripMenuItem.Click += new System.EventHandler(this.收件人邮编ToolStripMenuItem_Click); + // + // 收件人单位ToolStripMenuItem + // + this.收件人单位ToolStripMenuItem.Name = "收件人单位ToolStripMenuItem"; + this.收件人单位ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.收件人单位ToolStripMenuItem.Text = "收件人公司"; + this.收件人单位ToolStripMenuItem.Click += new System.EventHandler(this.收件人单位ToolStripMenuItem_Click); + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(157, 6); + // + // 自定义ToolStripMenuItem + // + this.自定义ToolStripMenuItem.Name = "自定义ToolStripMenuItem"; + this.自定义ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.自定义ToolStripMenuItem.Text = "自定义"; + this.自定义ToolStripMenuItem.Click += new System.EventHandler(this.自定义ToolStripMenuItem_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(270, 9); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(77, 12); + this.label3.TabIndex = 19; + this.label3.Text = "背景参考图片"; + // + // txtPicPath + // + this.txtPicPath.Location = new System.Drawing.Point(272, 26); + this.txtPicPath.Name = "txtPicPath"; + this.txtPicPath.Size = new System.Drawing.Size(272, 21); + this.txtPicPath.TabIndex = 20; + this.txtPicPath.TextChanged += new System.EventHandler(this.txtPicPath_TextChanged); + // + // btnUpdate + // + this.btnUpdate.Location = new System.Drawing.Point(592, 24); + this.btnUpdate.Name = "btnUpdate"; + this.btnUpdate.Size = new System.Drawing.Size(51, 23); + this.btnUpdate.TabIndex = 21; + this.btnUpdate.Text = "刷新"; + this.btnUpdate.UseVisualStyleBackColor = true; + this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(647, 9); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(53, 12); + this.label4.TabIndex = 22; + this.label4.Text = "长(毫米)"; + // + // numWidth + // + this.numWidth.DecimalPlaces = 3; + this.numWidth.Location = new System.Drawing.Point(649, 24); + this.numWidth.Maximum = new decimal(new int[] { + 100000, + 0, + 0, + 0}); + this.numWidth.Name = "numWidth"; + this.numWidth.Size = new System.Drawing.Size(81, 21); + this.numWidth.TabIndex = 23; + // + // btnAddShop + // + this.btnAddShop.ContextMenuStrip = this.contextMenuStrip1; + this.btnAddShop.Location = new System.Drawing.Point(114, 95); + this.btnAddShop.Name = "btnAddShop"; + this.btnAddShop.Size = new System.Drawing.Size(95, 32); + this.btnAddShop.TabIndex = 25; + this.btnAddShop.Text = "添加货品信息"; + this.btnAddShop.UseVisualStyleBackColor = true; + this.btnAddShop.Click += new System.EventHandler(this.btnAddShop_Click); + // + // contextMenuStrip2 + // + this.contextMenuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.货品名称ToolStripMenuItem, + this.货品单位ToolStripMenuItem, + this.货品规格ToolStripMenuItem, + this.货品数量ToolStripMenuItem, + this.货品价格ToolStripMenuItem, + this.货品总价格ToolStripMenuItem, + this.toolStripMenuItem3, + this.订单单号ToolStripMenuItem, + this.发货备注ToolStripMenuItem, + this.订单优惠前价格ToolStripMenuItem, + this.优惠减免ToolStripMenuItem, + this.订单优惠后价格ToolStripMenuItem, + this.客户姓名ToolStripMenuItem, + this.客户电话ToolStripMenuItem, + this.客户公司ToolStripMenuItem, + this.客户地址ToolStripMenuItem}); + this.contextMenuStrip2.Name = "contextMenuStrip2"; + this.contextMenuStrip2.Size = new System.Drawing.Size(161, 340); + // + // 货品名称ToolStripMenuItem + // + this.货品名称ToolStripMenuItem.Name = "货品名称ToolStripMenuItem"; + this.货品名称ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.货品名称ToolStripMenuItem.Text = "货品名称"; + this.货品名称ToolStripMenuItem.Click += new System.EventHandler(this.货品名称ToolStripMenuItem_Click); + // + // 货品单位ToolStripMenuItem + // + this.货品单位ToolStripMenuItem.Name = "货品单位ToolStripMenuItem"; + this.货品单位ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.货品单位ToolStripMenuItem.Text = "货品单位"; + this.货品单位ToolStripMenuItem.Click += new System.EventHandler(this.货品单位ToolStripMenuItem_Click); + // + // 货品规格ToolStripMenuItem + // + this.货品规格ToolStripMenuItem.Name = "货品规格ToolStripMenuItem"; + this.货品规格ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.货品规格ToolStripMenuItem.Text = "货品规格"; + this.货品规格ToolStripMenuItem.Click += new System.EventHandler(this.货品规格ToolStripMenuItem_Click); + // + // 货品数量ToolStripMenuItem + // + this.货品数量ToolStripMenuItem.Name = "货品数量ToolStripMenuItem"; + this.货品数量ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.货品数量ToolStripMenuItem.Text = "货品数量"; + this.货品数量ToolStripMenuItem.Click += new System.EventHandler(this.货品数量ToolStripMenuItem_Click); + // + // 货品价格ToolStripMenuItem + // + this.货品价格ToolStripMenuItem.Name = "货品价格ToolStripMenuItem"; + this.货品价格ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.货品价格ToolStripMenuItem.Text = "货品价格"; + this.货品价格ToolStripMenuItem.Click += new System.EventHandler(this.货品价格ToolStripMenuItem_Click); + // + // 货品总价格ToolStripMenuItem + // + this.货品总价格ToolStripMenuItem.Name = "货品总价格ToolStripMenuItem"; + this.货品总价格ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.货品总价格ToolStripMenuItem.Text = "货品总价"; + this.货品总价格ToolStripMenuItem.Click += new System.EventHandler(this.货品总价格ToolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(157, 6); + // + // 订单单号ToolStripMenuItem + // + this.订单单号ToolStripMenuItem.Name = "订单单号ToolStripMenuItem"; + this.订单单号ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.订单单号ToolStripMenuItem.Text = "订单单号"; + this.订单单号ToolStripMenuItem.Click += new System.EventHandler(this.订单单号ToolStripMenuItem_Click); + // + // 发货备注ToolStripMenuItem + // + this.发货备注ToolStripMenuItem.Name = "发货备注ToolStripMenuItem"; + this.发货备注ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.发货备注ToolStripMenuItem.Text = "发货备注"; + this.发货备注ToolStripMenuItem.Click += new System.EventHandler(this.发货备注ToolStripMenuItem_Click); + // + // 订单优惠前价格ToolStripMenuItem + // + this.订单优惠前价格ToolStripMenuItem.Name = "订单优惠前价格ToolStripMenuItem"; + this.订单优惠前价格ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.订单优惠前价格ToolStripMenuItem.Text = "订单优惠前价格"; + this.订单优惠前价格ToolStripMenuItem.Click += new System.EventHandler(this.订单优惠前价格ToolStripMenuItem_Click); + // + // 优惠减免ToolStripMenuItem + // + this.优惠减免ToolStripMenuItem.Name = "优惠减免ToolStripMenuItem"; + this.优惠减免ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.优惠减免ToolStripMenuItem.Text = "优惠减免"; + this.优惠减免ToolStripMenuItem.Click += new System.EventHandler(this.优惠减免ToolStripMenuItem_Click); + // + // 订单优惠后价格ToolStripMenuItem + // + this.订单优惠后价格ToolStripMenuItem.Name = "订单优惠后价格ToolStripMenuItem"; + this.订单优惠后价格ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.订单优惠后价格ToolStripMenuItem.Text = "订单优惠后价格"; + this.订单优惠后价格ToolStripMenuItem.Click += new System.EventHandler(this.订单优惠后价格ToolStripMenuItem_Click); + // + // 客户姓名ToolStripMenuItem + // + this.客户姓名ToolStripMenuItem.Name = "客户姓名ToolStripMenuItem"; + this.客户姓名ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.客户姓名ToolStripMenuItem.Text = "客户姓名"; + this.客户姓名ToolStripMenuItem.Click += new System.EventHandler(this.客户姓名ToolStripMenuItem_Click); + // + // 客户电话ToolStripMenuItem + // + this.客户电话ToolStripMenuItem.Name = "客户电话ToolStripMenuItem"; + this.客户电话ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.客户电话ToolStripMenuItem.Text = "客户电话"; + this.客户电话ToolStripMenuItem.Click += new System.EventHandler(this.客户电话ToolStripMenuItem_Click); + // + // 客户公司ToolStripMenuItem + // + this.客户公司ToolStripMenuItem.Name = "客户公司ToolStripMenuItem"; + this.客户公司ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.客户公司ToolStripMenuItem.Text = "客户公司"; + this.客户公司ToolStripMenuItem.Click += new System.EventHandler(this.客户公司ToolStripMenuItem_Click); + // + // 客户地址ToolStripMenuItem + // + this.客户地址ToolStripMenuItem.Name = "客户地址ToolStripMenuItem"; + this.客户地址ToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.客户地址ToolStripMenuItem.Text = "客户地址"; + this.客户地址ToolStripMenuItem.Click += new System.EventHandler(this.客户地址ToolStripMenuItem_Click); + // + // btnBrowser + // + this.btnBrowser.Location = new System.Drawing.Point(550, 24); + this.btnBrowser.Name = "btnBrowser"; + this.btnBrowser.Size = new System.Drawing.Size(36, 23); + this.btnBrowser.TabIndex = 27; + this.btnBrowser.Text = "..."; + this.toolTip1.SetToolTip(this.btnBrowser, "选择背景图"); + this.btnBrowser.UseVisualStyleBackColor = true; + this.btnBrowser.Click += new System.EventHandler(this.btnBrowser_Click); + // + // openFileDialog1 + // + this.openFileDialog1.Filter = "图片|*.jpg;*.png;*.gif;*.bmp"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(821, 9); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(53, 12); + this.label5.TabIndex = 28; + this.label5.Text = "单据类型"; + // + // cbbType + // + this.cbbType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbbType.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.cbbType.FormattingEnabled = true; + this.cbbType.Items.AddRange(new object[] { + "快递单", + "发货单"}); + this.cbbType.Location = new System.Drawing.Point(823, 23); + this.cbbType.Name = "cbbType"; + this.cbbType.Size = new System.Drawing.Size(121, 22); + this.cbbType.TabIndex = 29; + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.AutoScroll = true; + this.panel1.Controls.Add(this.picExpress); + this.panel1.Location = new System.Drawing.Point(242, 92); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(887, 521); + this.panel1.TabIndex = 30; + // + // numHeight + // + this.numHeight.DecimalPlaces = 3; + this.numHeight.Location = new System.Drawing.Point(736, 24); + this.numHeight.Maximum = new decimal(new int[] { + 100000, + 0, + 0, + 0}); + this.numHeight.Name = "numHeight"; + this.numHeight.Size = new System.Drawing.Size(81, 21); + this.numHeight.TabIndex = 32; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(734, 9); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(53, 12); + this.label6.TabIndex = 31; + this.label6.Text = "宽(毫米)"; + // + // frmAddMod + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScroll = true; + this.ClientSize = new System.Drawing.Size(1141, 654); + this.Controls.Add(this.numHeight); + this.Controls.Add(this.label6); + this.Controls.Add(this.cbbType); + this.Controls.Add(this.label5); + this.Controls.Add(this.btnBrowser); + this.Controls.Add(this.btnAddShop); + this.Controls.Add(this.numWidth); + this.Controls.Add(this.label4); + this.Controls.Add(this.btnUpdate); + this.Controls.Add(this.txtPicPath); + this.Controls.Add(this.label3); + this.Controls.Add(this.btnAddControl); + this.Controls.Add(this.propertyGrid1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.txtDes); + this.Controls.Add(this.label2); + this.Controls.Add(this.txtName); + this.Controls.Add(this.label1); + this.Controls.Add(this.panel1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "frmAddMod"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "添加模板"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmAddMod_FormClosing); + this.Load += new System.EventHandler(this.frmAddMod_Load); + ((System.ComponentModel.ISupportInitialize)(this.picExpress)).EndInit(); + this.contextMenuStrip1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.numWidth)).EndInit(); + this.contextMenuStrip2.ResumeLayout(false); + this.panel1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.numHeight)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtName; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtDes; + private System.Windows.Forms.PictureBox picExpress; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.Button btnAddControl; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 寄件人姓名ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 寄件人电话ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 寄件人地址ToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem 收件人姓名ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人电话ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人地址ToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem 自定义ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 寄件人邮编ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人邮编ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 寄件人单位ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人单位ToolStripMenuItem; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtPicPath; + private System.Windows.Forms.Button btnUpdate; + private System.Windows.Forms.ToolStripMenuItem 寄件人地址类型ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 省份ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 寄件人市地址ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 寄件人所在县区ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 寄件人详细地址ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人地址类型ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人省份ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人所在市ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人所在县区ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 收件人详细地址ToolStripMenuItem; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.NumericUpDown numWidth; + private System.Windows.Forms.Button btnAddShop; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip2; + private System.Windows.Forms.ToolStripMenuItem 货品名称ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 货品单位ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 货品规格ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 货品数量ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 货品价格ToolStripMenuItem; + private System.Windows.Forms.Button btnBrowser; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.ComboBox cbbType; + private System.Windows.Forms.ToolStripMenuItem 货品总价格ToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem 订单单号ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 发货备注ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 订单优惠前价格ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 优惠减免ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 订单优惠后价格ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 客户姓名ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 客户电话ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 客户公司ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 客户地址ToolStripMenuItem; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.NumericUpDown numHeight; + private System.Windows.Forms.Label label6; + } +} \ No newline at end of file diff --git a/Source/RyPrint/Mod/frmAddMod.cs b/Source/RyPrint/Mod/frmAddMod.cs new file mode 100644 index 0000000..2ed9378 --- /dev/null +++ b/Source/RyPrint/Mod/frmAddMod.cs @@ -0,0 +1,729 @@ +//#define isSysEidt +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Data.SQLite; +using ryCommon; + +namespace ryPrint.Mod +{ + public partial class frmAddMod : Form + { + public frmAddMod() + { + InitializeComponent(); + cbbType.SelectedIndex = 0; + } + bool isDataChanged = false; + #region 添加控件函数 + private myLabel AddControl(string name, string title, ClsProperty.En_Type sType, string format, string value) + { + return AddControl(name, title, sType, format, value,""); + } + private myLabel AddControl(string name, string title, ClsProperty.En_Type sType, string format, string value,string DataSource) + { + isDataChanged = true; + myLabel ct = new myLabel(); + ct.Size = new Size(100, 25); + ct.BackColor = Color.Transparent; + ct.Text = title; + ct.Name = name; + ct.Parent = picExpress; + //ct.ReadOnly = true; + ct.BackColor = Color.Transparent; + ct.Cursor = Cursors.Arrow; + ct.Font = new Font("黑体",10,FontStyle.Regular); + //ct.MouseDown += new MouseEventHandler(ct_MouseDown); + ct.KeyUp += Ct_KeyUp; + ct.KeyDown += new KeyEventHandler(ct_KeyDown); + //ct.MouseMove += new MouseEventHandler(ct_MouseMove); + //ct.MouseUp += new MouseEventHandler(ct_MouseUp); + ct.SizeChanged += new EventHandler(ct_SizeChanged); + ct.Click += new EventHandler(ct_Click); + //ct.sType = sType; + //ct.title = title; + //ct.format = format; + //ct.value = value; + ct.Property.DataSource = DataSource; + ct.Property.Type = sType; + ct.Property.Title = title; + ct.Property.CustomFormat = format; + ct.Property.Value = value; + ct.Property.FontSize = ct.Font.Size; + ct.Property.Size = new SizeF(rySet.pixeltomm(ct.Size.Width), rySet.pixeltomm(ct.Size.Height)); + ct.Property.Postion = new PointF(rySet.pixeltomm(ct.Location.X), rySet.pixeltomm(ct.Location.Y)); + new DragControl.MoveControl(ct); + picExpress.Controls.Add(ct); + return ct; + } + private void Ct_KeyUp(object sender, KeyEventArgs e) + { + //if (e.KeyCode == Keys.Up) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Top--; + //} + //else if (e.KeyCode == Keys.Down) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Top++; + //} + //else if (e.KeyCode == Keys.Left) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Left--; + //} + //else if (e.KeyCode == Keys.Right) + //{ + // isDataChanged = true; + // myLabel ct = (myLabel)sender; + // ct.Left++; + //} + } + + void ct_SizeChanged(object sender, EventArgs e) + { + isDataChanged = true; + myLabel ct = (myLabel)sender; + LoadProperty(ct); + } + + void ct_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Delete) + { + isDataChanged = true; + myLabel ct = (myLabel)sender; + picExpress.Controls.Remove(ct); + propertyGrid1.SelectedObject = null; + } + } + private void AddControl(string name, ClsProperty.En_Type _type) + { + if (GetControl(name) != null) + { + MessageBox.Show("该项已经存在", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + AddControl(name, Enum.GetName(typeof(ClsProperty.En_Type), _type), _type, "", ""); + } + } + private myLabel GetControl(string name) + { + foreach (Control ct in picExpress.Controls) + { + if (ct.Name == name) + { + if (ct is myLabel) + { + return (myLabel)ct; + } + else + { + return null; + } + } + } + return null; + } + #endregion + private void LoadProperty(myLabel ct) + { + propertyGrid1.SelectedObject = ct.Property; + } + void ct_Click(object sender, EventArgs e) + { + myLabel ct = (myLabel)sender; + LoadProperty(ct); + } + #region 控件拖放 + private Point position; + private bool capture = false; + private void ct_MouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e) + { + //左键的话,标志位为true(表示拖拽开始) + if ((e.Button == System.Windows.Forms.MouseButtons.Left)) + { + position = new Point(e.X, e.Y); + capture = true; + } + } + private void ct_MouseMove(System.Object sender, System.Windows.Forms.MouseEventArgs e) + { + if (capture) + { + if (sender is TextBox) + { + TextBox ct = (TextBox)sender; + ct.Location = new Point(e.X + ct.Left - position.X, e.Y + ct.Top - position.Y); + // this.Label1.Location = new Point(this.Label1.Left, this.label1.Top); + } + else if (sender is myLabel) + { + myLabel ct = (myLabel)sender; + ct.Location = new Point(e.X + ct.Left - position.X, e.Y + ct.Top - position.Y); + // this.label1.Location = new Point(this.label1.Left, this.label1.Top); + } + } + } + private void ct_MouseUp(System.Object sender, System.Windows.Forms.MouseEventArgs e) + { + capture = false; + } + + private void picEXpress_DragEnter(object sender, DragEventArgs e) + { + //当Button被拖拽到WinForm上时候,鼠标效果出现 + if ((e.Data.GetDataPresent(typeof(TextBox))) || (e.Data.GetDataPresent(typeof(myLabel)))) + { + e.Effect = DragDropEffects.Move; + } + } + #endregion + private string ResetLocationControl() + { + ryCommon.clsStorage tStor = new ryCommon.clsStorage(); + foreach (Control ct1 in picExpress.Controls) + { + if (ct1 is myLabel) + { + myLabel ct = (myLabel)ct1; + ct.Size = new Size(rySet.mmtopixel(ct.Property.Size.Width), rySet.mmtopixel(ct.Property.Size.Height)); + ct.Location = new Point(rySet.mmtopixel(ct.Property.Postion.X), rySet.mmtopixel(ct.Property.Postion.Y)); + } + } + return tStor.GetXMLText(); + } + private decimal pixelTomm_Width(int pixel) + { + return pixel * numWidth.Value / picExpress.Width; + } + private decimal pixelTomm_Height(int pixel) + { + return pixel * numHeight.Value / picExpress.Height; + } + private string SaveControl() + { + ryCommon.clsStorage tStor = new ryCommon.clsStorage(); + foreach (Control ct1 in picExpress.Controls) + { + if (ct1 is myLabel) + { + myLabel ct =(myLabel)ct1; + tStor.AddNode2("Name",ct.Name); + tStor.SetAttrValue("Title", ct.Property.Title); + tStor.SetAttrValue("Width", rySet.pixeltomm(ct.Size.Width)); + tStor.SetAttrValue("Height", rySet.pixeltomm(ct.Size.Height)); + tStor.SetAttrValue("FontSize", ct.Font.Size); + tStor.SetAttrValue("Left", rySet.pixeltomm(ct.Location.X)); + tStor.SetAttrValue("Top", rySet.pixeltomm(ct.Location.Y)); + //tStor.SetAttrValue("Left", ct.Location.X>picExpress.Image.Width?0:ct.Location.X); + //tStor.SetAttrValue("Top", ct.Location.Y>picExpress.Image.Height?0:ct.Location.Y); + tStor.SetAttrValue("Multiline", ct.Property.Multiline); + tStor.SetAttrValue("align", ct.AlignStr); + tStor.SetAttrValue("format", ct.Property.CustomFormat); + tStor.SetAttrValue("value", ct.Property.Value); + tStor.SetAttrValue("sType", (int)ct.Property.Type); + tStor.SetAttrValue("LineSpace", ct.Property.LineSpace); + tStor.SetAttrValue("DataSource", ct.Property.DataSource); + tStor.SetAttrValue("NoPrint", ct.Property.NoPrint); + } + } + return tStor.GetXMLText(); + } + private void LoadControl(string xml) + { + ryCommon.clsStorage tStor = new ryCommon.clsStorage(xml); + System.Xml.XmlNodeList list = tStor.GetList(); + for (int i = 0; i < list.Count; i++) + { + tStor.SelectNode3(list[i]); + myLabel ct = new myLabel(); + ct.Font = new Font("黑体", tStor.GetAttrValueByInt("FontSize", 10), FontStyle.Regular); + ct.Property.Multiline = tStor.GetAttrValueByBool("Multiline", false); + ct.Size = new Size(rySet.mmtopixel(tStor.GetAttrValue("Width", 50f)), rySet.mmtopixel(tStor.GetAttrValue("Height", 10f))); + if (ct.Size.Height == 0) { ct.Height = 21; } + if (ct.Size.Width == 0) { ct.Width = 100; } + ct.Property.Size= new SizeF((float)tStor.GetAttrValue("Width", 50f), (float)tStor.GetAttrValue("Height", 10f)); + ct.Location = new Point(rySet.mmtopixel(tStor.GetAttrValue("Left", 0f)), rySet.mmtopixel(tStor.GetAttrValue("Top", 0f))); + ct.Property.Postion = new PointF((float)tStor.GetAttrValue("Left", 0f),(float)tStor.GetAttrValue("Top", 0f)); + if (ct.Location.Y < 0) { ct.Top = 0; } + if (ct.Location.X < 0) { ct.Left = 0; } + //ct.Size = new Size(tStor.GetAttrValue("Width", 50), tStor.GetAttrValue("Height", 10)); + //if (ct.Size.Height == 0) { ct.Height = 21; } + //if (ct.Size.Width == 0) { ct.Width = 100; } + //ct.Property.Size = new SizeF((float)pixelTomm_Width(tStor.GetAttrValue("Width", 50)), (float)pixelTomm_Height(tStor.GetAttrValue("Height", 10))); + ////ct.Location = new Point((int)pixelTomm_Width(tStor.GetAttrValue("Left", 0)), (int)pixelTomm_Height(tStor.GetAttrValue("Top", 0))); + //ct.Property.Postion = new PointF((float)pixelTomm_Width(tStor.GetAttrValue("Left", 0)), (float)pixelTomm_Height(tStor.GetAttrValue("Top", 0))); + //ct.Size = new Size(tStor.GetAttrValue("Width", 50),tStor.GetAttrValue("Height", 10)); + //ct.Location = new Point(tStor.GetAttrValue("Left", 0),tStor.GetAttrValue("Top", 0)); + // + Mod.ClsProperty.en_Type _type = Mod.ClsProperty.en_Type.自定义; + try + { + _type = (Mod.ClsProperty.en_Type)tStor.GetAttrValueByInt("sType", 0); + } + catch { } + ct.Property.Type = _type; + ct.Property.Title = tStor.GetAttrValue("Title"); + ct.Property.LineSpace = tStor.GetAttrValue("LineSpace",0); + ct.Name = tStor.GetAttrValue("Name"); + ct.Parent = picExpress; + //ct.ReadOnly = true; + ct.BackColor = Color.Transparent; + ct.Cursor = Cursors.Arrow; + ct.SetAlign(tStor.GetAttrValue("align")); + ct.Property.Value = tStor.GetAttrValue("value"); + ct.Property.CustomFormat = tStor.GetAttrValue("format"); + ct.Property.DataSource = tStor.GetAttrValue("DataSource"); + ct.Property.NoPrint = tStor.GetAttrValue("NoPrint",false); + ct.Property.Type = _type; + ct.Refresh(); + //ct.MouseDown += new MouseEventHandler(ct_MouseDown); + //ct.MouseMove += new MouseEventHandler(ct_MouseMove); + //ct.MouseUp += new MouseEventHandler(ct_MouseUp); + new DragControl.MoveControl(ct); + ct.Click += new EventHandler(ct_Click); + ct.KeyUp += Ct_KeyUp; + ct.KeyDown += new KeyEventHandler(ct_KeyDown); + ct.SizeChanged+=new EventHandler(ct_SizeChanged); + picExpress.Controls.Add(ct); + } + } + private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + isDataChanged = true; + ClsProperty item = (ClsProperty)propertyGrid1.SelectedObject; + myLabel ct = GetControl(item.Name); + if (ct != null) + { + ct.Property = item; + ct.Refresh(); + } + } + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + } + public int isAdd = 1; + public string selectId = "-1"; + private void btnOK_Click(object sender, EventArgs e) + { + if (txtName.Text == "") + { + MessageBox.Show("请输入名称", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + isDataChanged = false; + ryQuickSQL mySQL = new ryQuickSQL(Table.s_Express.TableName); + mySQL.AddField(Table.s_Express.Name, txtName.Text); + mySQL.AddField(Table.s_Express.PicPath, txtPicPath.Text); + mySQL.AddField(Table.s_Express.Width, numWidth.Value); + mySQL.AddField(Table.s_Express.Height,numHeight.Value); + mySQL.AddField(Table.s_Express.SysId,0); + mySQL.AddField(Table.s_Express.billType, cbbType.SelectedIndex); + mySQL.AddField(Table.s_Express.ModXML, SaveControl()); + mySQL.AddField(Table.s_Express.Des, txtDes.Text); + if (isAdd >= 1) + { + mySQL.AddField(Table.s_Express.AddTime, DateTime.Now); + } + #if isSysEidt + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.SysDbPath, clsPram.DbPwd); + #else + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.UserExpressDbPath, clsPram.DbPwd); + #endif + myDb.ConnOrCreateDb(); + if (isAdd >= 1) + { + myDb.ExecuteNonQuery(mySQL.GetInsertSQL(), mySQL.GetSQLiteParameter()); + } + else + { + myDb.ExecuteNonQuery(mySQL.GetUpdateSQL() + " where id=" + selectId, mySQL.GetSQLiteParameter()); + } + this.DialogResult = DialogResult.OK; + } + private void frmAddMod_Load(object sender, EventArgs e) + { + #if isSysEidt + Text += "(调试模式)"; +#endif + } + public void GetDataInfoById(string id) + { + #region 数据库 + try + { + #if isSysEidt + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.SysDbPath, clsPram.DbPwd); + #else + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.UserExpressDbPath, clsPram.DbPwd); + #endif + myDb.ConnOrCreateDb(); + SQLiteCommand cmd = myDb.SQLite_cn.CreateCommand(); + cmd.CommandText = "select * from " +Table.s_Express.TableName + " where id=@id"; + cmd.Parameters.Add("@id", DbType.Int32); //id + cmd.Parameters["@id"].Value = id; + SQLiteDataReader reader = cmd.ExecuteReader(); + while (reader.Read()) + { + try + { + txtName.Text = reader[Table.s_Express.Name].ToString(); + txtDes.Text = reader[Table.s_Express.Des].ToString(); + txtPicPath.Text = reader[Table.s_Express.PicPath].ToString(); + numWidth.Value=Convert.ToDecimal(reader[Table.s_Express.Width]); + numHeight.Value = Convert.ToDecimal(reader[Table.s_Express.Height]); + try + { + cbbType.SelectedIndex = Convert.ToInt32(reader[Table.s_Express.billType]); + } + catch { cbbType.SelectedIndex = 0; } + #if isSysEidt + string picPath = clsPram.GetTruePath(reader[Table.s_Express.PicPath].ToString(), 1); + #else + string picPath = clsPram.GetTruePath(reader[Table.s_Express.PicPath].ToString(), Convert.ToInt32(reader[Table.s_Express.SysId])); + #endif + if (System.IO.File.Exists(picPath)) + { + Image image = Image.FromFile(picPath); + picExpress.Width =rySet.mmtopixel(Convert.ToDouble(reader[Table.s_Express.Width])); + picExpress.Height = rySet.mmtopixel(Convert.ToDouble(reader[Table.s_Express.Height])); + picExpress.Image = image; + //numWidth.Value = Convert.ToDecimal(rySet.InchesTomm(picExpress.Width / Convert.ToDecimal(picExpress.Image.HorizontalResolution))); + // numHeight.Value = Convert.ToDecimal(rySet.InchesTomm(picExpress.Height / Convert.ToDecimal(picExpress.Image.VerticalResolution))); + } + LoadControl(reader[Table.s_Express.ModXML].ToString()); + } + catch { } + break; + } + reader.Close(); + cmd.Dispose(); + } + catch { } + #endregion + isDataChanged = false; + } + #region 添加控件菜单 + private void 寄件人姓名ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人姓名); + } + + private void 寄件人电话ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人电话); + } + + private void 寄件人地址ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人地址); + } + + private void 收件人姓名ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人姓名); + } + + private void 收件人电话ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人电话); + } + + private void 收件人地址ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人地址); + } + private void 寄件人邮编ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人邮编); + } + + private void 收件人邮编ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人邮编); + } + + private void 寄件人单位ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人公司); + } + + private void 收件人单位ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人公司); + } + /// + /// 获取新的控件名 + /// + /// + private string GetNewName() + { + int i = 1; + while (true) + { + if (GetControl("custom" + i.ToString()) == null) + { + return "custom" + i.ToString(); + } + i++; + } + } + /// + /// 获取新的控件名 + /// + /// + private string GetNewName2() + { + int i = 1; + while (true) + { + if (GetControl("lbl" + i.ToString()) == null) + { + return "lbl" + i.ToString(); + } + i++; + } + } + private void 自定义ToolStripMenuItem_Click(object sender, EventArgs e) + { + string name = GetNewName(); + AddControl(name, "自定义" + name.Replace("custom", ""), ClsProperty.En_Type.自定义, "", ""); + } + + private void btnAddControl_Click(object sender, EventArgs e) + { + Button ct = (Button)sender; + Point p = new Point(0, ct.Height); + contextMenuStrip1.Show(ct, p); + } + #endregion + + private void btnUpdate_Click(object sender, EventArgs e) + { + #if isSysEidt + string picPath = clsPram.GetTruePath(txtPicPath.Text,1); + #else + string picPath = clsPram.GetTruePath(txtPicPath.Text,0); + #endif + if (System.IO.File.Exists(picPath)) + { + Image image = Image.FromFile(picPath); + picExpress.Image = image; + numWidth.Value=Convert.ToDecimal(rySet.InchesTomm(image.Width/ Convert.ToDecimal(image.HorizontalResolution))); + numHeight.Value = Convert.ToDecimal(rySet.InchesTomm(image.Height / Convert.ToDecimal(image.VerticalResolution))); + picExpress.Width =rySet.mmtopixel((float)numWidth.Value); + picExpress.Height = rySet.mmtopixel((float)numHeight.Value); + ResetLocationControl(); + //picExpress. + } + else { picExpress.Image = null; } + } + + private void txtName_TextChanged(object sender, EventArgs e) + { + isDataChanged = true; + } + + private void txtPicPath_TextChanged(object sender, EventArgs e) + { + isDataChanged = true; + #if isSysEidt + string picPath = clsPram.GetTruePath(txtPicPath.Text, 1); + #else + string picPath = clsPram.GetTruePath(txtPicPath.Text,0); + #endif + if (System.IO.File.Exists(picPath)) + { + Image image = Image.FromFile(picPath); + picExpress.Image = image; + } + else { picExpress.Image = null; } + } + + private void txtDes_TextChanged(object sender, EventArgs e) + { + isDataChanged = true; + } + + private void frmAddMod_FormClosing(object sender, FormClosingEventArgs e) + { + if (isDataChanged && DialogResult != DialogResult.OK) + { + if (MessageBox.Show("数据已经被修改,确定要不保存退出吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) + { + e.Cancel = true; + return; + } + } + } + + private void picExpress_Click(object sender, EventArgs e) + { + + } + + private void 省份ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人省份); + } + + private void 寄件人市地址ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人所在市); + } + + private void 寄件人所在县区ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人县区); + } + + private void 寄件人详细地址ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.寄件人详细地址); + } + + private void 收件人省份ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人省份); + } + + private void 收件人所在市ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人所在市); + } + + private void 收件人所在县区ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人县区); + } + + private void 收件人详细地址ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddControl(GetNewName2(), ClsProperty.En_Type.收件人详细地址); + } + + private void propertyGrid1_Click(object sender, EventArgs e) + { + + } + + private void btnCalcDpi_Click(object sender, EventArgs e) + { + frmCalcDpi frm = new frmCalcDpi(); + frm.Icon = Icon; + frm.kd_Width = picExpress.Image.Width; + if(frm.ShowDialog()==DialogResult.OK) + { + numWidth.Value = frm.dpiValue; + } + } + + private void btnAddShop_Click(object sender, EventArgs e) + { + Button ct = (Button)sender; + Point p = new Point(0, ct.Height); + contextMenuStrip2.Show(ct, p); + } + + private void 货品名称ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl("货品名称"); + } + + private void 货品单位ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl("货品单位"); + } + + private void 货品规格ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl("货品规格"); + } + + private void 货品数量ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl("货品数量"); + } + private void AddDataControl(string name) + { + AddControl(GetNewName2(), name, ClsProperty.En_Type.数据字段, "", name); + } + private void AddDataControl2(string name) + { + AddControl(GetNewName2(), name, ClsProperty.En_Type.数据字段, "", name,"info"); + } + private void 货品价格ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl("货品单价"); + } + + private void btnBrowser_Click(object sender, EventArgs e) + { + if(openFileDialog1.ShowDialog()==DialogResult.OK) + { + txtPicPath.Text = openFileDialog1.FileName.Replace(Application.StartupPath + "\\Db\\Pics","").Replace(Application.StartupPath, ""); + } + } + + private void 货品总价格ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl("货品总价"); + } + + private void 订单单号ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("单号"); + } + + private void 发货备注ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("发货备注"); + } + + private void 订单优惠前价格ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("订单优惠前价格"); + } + + private void 优惠减免ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("优惠减免"); + } + + private void 订单优惠后价格ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("订单优惠后价格"); + } + + private void 客户姓名ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("客户姓名"); + } + + private void 客户电话ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("客户电话"); + } + + private void 客户公司ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("客户公司"); + } + + private void 客户地址ToolStripMenuItem_Click(object sender, EventArgs e) + { + AddDataControl2("客户地址"); + } + } +} diff --git a/Source/RyPrint/Mod/frmAddMod.resx b/Source/RyPrint/Mod/frmAddMod.resx new file mode 100644 index 0000000..a52409b --- /dev/null +++ b/Source/RyPrint/Mod/frmAddMod.resx @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 171, 17 + + + 484, 17 + + + 336, 17 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABILAAASCwAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wDmuEEA5rhBAOa4QQDmuEEA5rhBAOS1PgDksz0A47I7AOOwOgDirzsA4a86A+Gu + OS7irjhc4q82gOKvNJPirzST4q41geKtOF/hrDkx4a06BeGtOwDhrToA4a46AOKvPADisD0A5LJAAOSy + QADkskAA5LJAAOSyQAD///8A////AOa4QQDmuEEA5rhBAOa4QQDmuEEA5LU+AOSzPQDjsjsA47A7BeKw + OVfisTSw47It6uOyJ//jsiP/47Ih/+OyIf/jsiP/47In/+OxLezisDO04a45XeGtOwnhrjoA4q88AOKw + PQDkskAA5LJAAOSyQADkskAA5LJAAP///wD///8A5rhBAOa4QQDmuEEA5rhBAOa4QQDktT4A5LM9AOOz + O03kszPR5LQn/+SzHf/jsRf/47AS/+KvEP/irw7/4q0J/+KtCP/irQr/4q4O/+OvE//jsSH/47Iz2OGv + OlXhrz0A4rA9AOSyQADkskAA5LJAAOSyQADkskAA////AP///wDmuEEA5rhBAOa4QQDmuEEA5rhBAOS1 + PwfltTqg5bYs/+S0Hv/jsRX/468P/+KuDP/irQr/4q0I/+GrA//muC3/57w6/+i9Pv/pv0T/6sJN/+e8 + N//kshj/5LQq/+OyOavisD4M5LJAAOSyQADkskAA5LJAAOSyQAD///8A////AOa4QQDmuEEA5rhBAOa4 + QQDmuEIS5bg6wua3Kf/ksxr/47AS/+OvDv/irgz/464M/+OuDP/hqgD/68RV//jnzf/458z/+OfN//jo + zv/67Nz/8NKB/+OvDv/ltB//5bUn/+S0OMrkskAZ5LJAAOSyQADkskAA5LJAAP///wD///8A57lCAOe5 + QgDnuUIA57lDB+e6Pb/muCr/5bQb/+SxFP/jsBD/47AP/+OwD//jsBD/4q0H/+i8N//458r/9+bJ//fl + xv/35cb/+OfL//Xht//lshb/8daP/+/Odf/ksBH/5rcp/+W2O8vks0IM5LNBAOSzQQDks0EA////AP// + /wDovEUA6LxFAOi8RgDovEOe57ow/+a1H//lsxf/5LEU/+SxE//ksRP/5LET/+SwD//mtR//9+K5//no + zv/45sj/+ObI//jmyP/56dL/6b8//+zFVP/66tX/6b04/+SxEf/mtR//57kv/+a3Qa3ktUQA5LVDAOS1 + QwD///8A////AOm+SQDpvkkA6b9JROm9Ov/nuCf/5rUc/+WzGf/lsxj/5bMY/+WzGP/ltBj/5LAO//HV + if/569b/+OfK//jozP/56tT/+uvZ//HUhv/nuSz/+erS/+/Nb//ksAz/5bMZ/+a1HP/nuCb/6Ls4/+e4 + RlLmt0YA5rdGAP///wD///8A68JNAOvCTgTrwUbQ6bwx/+e3I//mtR7/5rUc/+a1HP/mtRz/5rUd/+az + FP/rxE3/+evV//jpzf/46c//9+XA//HTgv/03aP/6Lsv//bjuf/14K3/5rMW/+a1G//mtRz/5rUe/+e3 + Iv/pvC//6bxE3ee6SgnoukkA////AP///wDrxFEA7MRRTevBQP/puyz/6Lgk/+i3If/otyH/6Lch/+i3 + If/otyD/57Ye//bhr//57Nf/+erP//rt2v/z147/5rIO/+e1Gf/rwUH/9uK0/+vBP//ntRv/6Lci/+i3 + If/otyL/6Lgk/+m7LP/qvz7/6bxNXOm8TQD///8A////AO3HVgLtxlGo68A8/+q7LP/puSf/6bkm/+m5 + Jv/puSb/6bkm/+i3Hf/tyVn/+u7c//nr0//569P/+u3Z/+3GUP/otx//6bkm/+m4I//ouCH/6bgj/+m5 + J//puSb/6bkm/+m5Jv/puSf/6bss/+vAO//rwE236r5RBv///wD///8A78pbJO7HUOXrwTv/6r0v/+q8 + K//qvCv/6rwr/+q8K//qvCv/6rom//birv/67t3/+uzV//ru3P/35Lb/6roo/+q8K//qvCv/6rwr/+q7 + K//qvCv/6rwr/+q8K//qvCv/6rwr/+q8K//qvS//7MA6/+zDTO/rwlUx////AP///wDvy1xS7sdP/uzB + PP/rvzL/674w/+u+MP/rvjD/674w/+u8K//ux1D/++/d//ru2f/67tn/+/Hj//LUff/quyb/674x/+u+ + MP/rvjD/674w/+u+MP/rvjD/674w/+u+MP/rvjD/674w/+u+Mv/swTv/7cVN/+3FWGH///8A////AO/L + XnrvyFD/7cM//+zAN//swDb/7MA2/+zANv/swDb/670r//TZi//78+f/+u/c//rw3f/679n/7sZJ/+y/ + Mv/swDb/7MA2/+zANv/swDb/7MA2/+zANv/swDb/7MA2/+zANv/swDb/7MA3/+3CPv/ux0//7shbhP// + /wD///8A8MthkfDJU//vxEP/7sI8/+7CO//uwjv/7sI7/+7CO//twTf/+Oi9//vy5f/78d///PPn//fk + sf/twDP/7sI7/+7CO//uwjv/7sI7/+7CO//uwjv/7sI7/+7CO//uwjv/7sI7/+7CO//uwjz/78RD//DJ + Uv/wy1+U////AP///wDxzGSQ8ctY//DHSP/vxUH/78VA/+/FQP/vxUD/78Q9//DJUP/78d3/+/Pk//vy + 4//89ev/89Ny/+7COP/vxUD/78VA/+/FQP/vxUD/78VA/+/FQP/vxUD/78VA/+/FQP/vxUD/78VA/+/F + QP/wxkf/8cxX//HOZJT///8A////APHNZ3fyzV7/8cpO//DHR//wx0b/8MdG//DHRv/wxT//89Nx//z2 + 7f/89Ob//PXq//rv1P/xx0j/8MZE//DHRv/wx0b/8MdG//DHRv/wx0b/8MdG//DHRv/wx0b/8MdG//DH + Rv/wx0b/8MdH//HJTf/yzl3/89Bqgv///wD///8A8s1qT/PPZP3zzFb/8slN//LJS//yyUv/8slL//HG + Qv/335j//fjz//z16f/9+PP/+OKj//HGQf/yyUv/8slL//LJS//yyUv/8slL//LJS//yyUv/8slL//LJ + S//yyUv/8slL//LJS//yyU3/88xV//TQZf/003Fe////AP///wDyzWwi89Bq4/TPXf/zzFP/88tQ//PL + UP/zy1D/8slH//nns//9+fX//fft//337f/002v/88pL//PLUP/zy1D/88tQ//PLUP/zy1D/88tQ//PL + UP/zy1D/88tQ//PLUP/zy1D/88tQ//PMU//0zlz/9dRu7fbWdy7///8A////APPNbgH0z26l9dJm//TP + Wv/0zVb/9M1V//TNVf/0y07/++zF//369v/9+fL//fbm//XTaf/0zE//9M1U//TNVP/0zVX/9M1V//TN + Vf/0zVX/9M1V//TNVf/0zVX/9M1V//TNVf/0zVb/9M9a//XSZv/21naz9tZ6BP///wD///8A881vAPPO + cEf202//9tJj//XQXP/1z1r/9c9a//XOVf/78M///fv4//358v/9+vb//Pjt//fZff/20V7/9dFf//XP + Wv/1z1r/9c9a//XPWv/1z1r/9c9a//XPWv/1z1r/9c9a//XQXP/20mL/9tZw//bWelb21nsA////AP// + /wDzzXAA881wAvXRc8n31W3/9tNk//bSYP/20l//9tFb//zy1f/+/Pv//vv1//769f/+/f//+N6L//rn + rf/77MH/9tBY//bSX//20l//9tJf//bSX//20l//9tJf//bSX//20WD/9tNj//fWbf/313rX9tZ8BvbW + fAD///8A////APTOcgD0znIA9M5zPPfWdv/41m7/+NRm//jTZP/40l3//PLV//7////+/Pj//vz4//79 + /P/52n3//O7G//zvyP/40Vz/+NNk//jTZP/402T/+NNk//jTZP/402T/+NNk//jUZv/41m3/+Nl4//fW + fUr21n0A9tZ9AP///wD///8A9M5zAPTOcwD0zXMA9dF1kvnYeP/52HD/+NZq//jUZP/63ob//vns//7/ + ///+/fv//v35//nZdv/99Nj//O2+//jTX//41Wj/+NVo//jVaP/41Wj/+NVo//jVaP/41mr/+dhw//nZ + ef/3136i99Z9APfWfQD31n0A////AP///wD0znMA9M5zAPTOcwD0zXMD9tJ4t/rae//52nT/+dhv//nV + Zf/623v//vfj////////+/P/+dl1//746f/867f/+dVj//nXbP/512z/+dds//nXbP/5123/+dhv//nZ + c//623z/+Nh/w/bWfQj21n0A9tZ9APbWfQD///8A////APTOcwD0znMA9M5zAPTOcwD1znMN99N5tvrb + fv/73Hn/+tp1//rXbP/72nX//vTW///78f/62nf///76//3pr//61mj/+thw//rYcP/62HH/+tlx//ra + dP/723n/+tx///nYgL731n4S9tZ9APbWfQD21n0A9tZ9AP///wD///8A9M5zAPTOcwD0znMA9M5zAPXO + cwD1znQC9tJ5kvrZgP/73H//+9x7//vadP/723f//OKR//vbd//845f/+91+//vacv/72nX/+9t1//vb + d//73Hv/+91///rcgv/414Cd99V9BvfWfgD21n0A9tZ9APbWfQD21n0A////AP///wD0znMA9M5zAPTO + cwD0znMA9c5zAPXPdAD1znUA9tB3QPjVfcT624L//N6D//zef//83Hr//N19//zbd//83Hv//N19//ze + fv/83oH//N6D//vdhP/52IHL99R+SPfUfQD31X0A99Z+APbWfQD21n0A9tZ9APbWfQD///8A////APTO + cwD0znMA9M5zAPTOcwD1znMA9c90APXPdQD2z3YA9s52APbQeEn41Hyi+diA3/vbg/373IT/+92E//vd + hP/73YT/+9uE/vrZg+L51oCm99R9T/fTfQL31H0A99R9APfVfQD31n4A9tZ9APbWfQD21n0A9tZ9AP// + /wD///8A9M5zAPTOcwD0znMA9M5zAPXOcwD1z3QA9c91APbPdgD2z3cA9s93APbOdgD2z3ci99F5TvfS + e3X303yO99N9j/fTfHf30nxQ99J7JffRewD303wA99N9APfUfQD31H0A99V9APfWfgD21n0A9tZ9APbW + fQD21n0A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A///////gB///gAH//wAA//wAAD/4AAAf8AAAD/AAAA/gAAAHwAAAA8AA + AAOAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/AA + AA/4AAAf/AAAP/8AAP//wAH///AP//////8= + + + \ No newline at end of file diff --git a/Source/RyPrint/Mod/frmModView.Designer.cs b/Source/RyPrint/Mod/frmModView.Designer.cs new file mode 100644 index 0000000..e0dab9a --- /dev/null +++ b/Source/RyPrint/Mod/frmModView.Designer.cs @@ -0,0 +1,209 @@ +namespace ryPrint.Mod +{ + partial class frmModView + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmModView)); + this.btnSearch = new System.Windows.Forms.Button(); + this.txtSearch = new System.Windows.Forms.TextBox(); + this.listView1 = new System.Windows.Forms.ListView(); + this.colExpressName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.colExpressDes = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.colBillType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.添加快递模板ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.修改快递模板ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.删除快递模板ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.复制快递模板ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ctlMyPage1 = new MyPage.ctlMyPage(); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // btnSearch + // + this.btnSearch.Location = new System.Drawing.Point(360, 7); + this.btnSearch.Name = "btnSearch"; + this.btnSearch.Size = new System.Drawing.Size(75, 23); + this.btnSearch.TabIndex = 11; + this.btnSearch.Text = "搜索"; + this.btnSearch.UseVisualStyleBackColor = true; + this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click); + // + // txtSearch + // + this.txtSearch.Location = new System.Drawing.Point(6, 9); + this.txtSearch.Name = "txtSearch"; + this.txtSearch.Size = new System.Drawing.Size(348, 21); + this.txtSearch.TabIndex = 10; + this.txtSearch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtSearch_KeyDown); + // + // listView1 + // + this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.colExpressName, + this.colExpressDes, + this.columnHeader3, + this.colBillType}); + this.listView1.ContextMenuStrip = this.contextMenuStrip1; + this.listView1.FullRowSelect = true; + this.listView1.Location = new System.Drawing.Point(6, 39); + this.listView1.Name = "listView1"; + this.listView1.ShowItemToolTips = true; + this.listView1.Size = new System.Drawing.Size(643, 362); + this.listView1.TabIndex = 8; + this.listView1.UseCompatibleStateImageBehavior = false; + this.listView1.View = System.Windows.Forms.View.Details; + // + // colExpressName + // + this.colExpressName.Text = "名称"; + this.colExpressName.Width = 150; + // + // colExpressDes + // + this.colExpressDes.Text = "备注"; + this.colExpressDes.Width = 300; + // + // columnHeader3 + // + this.columnHeader3.Text = "模板类型"; + this.columnHeader3.Width = 80; + // + // colBillType + // + this.colBillType.Text = "单据类型"; + this.colBillType.Width = 80; + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.添加快递模板ToolStripMenuItem, + this.修改快递模板ToolStripMenuItem, + this.删除快递模板ToolStripMenuItem, + this.toolStripMenuItem1, + this.复制快递模板ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(153, 120); + // + // 添加快递模板ToolStripMenuItem + // + this.添加快递模板ToolStripMenuItem.Name = "添加快递模板ToolStripMenuItem"; + this.添加快递模板ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.添加快递模板ToolStripMenuItem.Text = "添加模板"; + this.添加快递模板ToolStripMenuItem.Click += new System.EventHandler(this.添加快递模板ToolStripMenuItem_Click); + // + // 修改快递模板ToolStripMenuItem + // + this.修改快递模板ToolStripMenuItem.Name = "修改快递模板ToolStripMenuItem"; + this.修改快递模板ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.修改快递模板ToolStripMenuItem.Text = "修改模板"; + this.修改快递模板ToolStripMenuItem.Click += new System.EventHandler(this.修改快递模板ToolStripMenuItem_Click); + // + // 删除快递模板ToolStripMenuItem + // + this.删除快递模板ToolStripMenuItem.Name = "删除快递模板ToolStripMenuItem"; + this.删除快递模板ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.删除快递模板ToolStripMenuItem.Text = "删除模板"; + this.删除快递模板ToolStripMenuItem.Click += new System.EventHandler(this.删除快递模板ToolStripMenuItem_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(149, 6); + // + // 复制快递模板ToolStripMenuItem + // + this.复制快递模板ToolStripMenuItem.Name = "复制快递模板ToolStripMenuItem"; + this.复制快递模板ToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.复制快递模板ToolStripMenuItem.Text = "复制模板"; + this.复制快递模板ToolStripMenuItem.Click += new System.EventHandler(this.复制快递模板ToolStripMenuItem_Click); + // + // ctlMyPage1 + // + this.ctlMyPage1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.ctlMyPage1.Location = new System.Drawing.Point(6, 407); + this.ctlMyPage1.Name = "ctlMyPage1"; + this.ctlMyPage1.PageSize = 50; + this.ctlMyPage1.RecordCount = 0; + this.ctlMyPage1.Size = new System.Drawing.Size(506, 26); + this.ctlMyPage1.SQLText = ""; + this.ctlMyPage1.SQLText2 = ""; + this.ctlMyPage1.T_FirstCaption = "首页"; + this.ctlMyPage1.T_LastCaption = "末页"; + this.ctlMyPage1.T_NextCaption = "下一页"; + this.ctlMyPage1.T_Parameters = null; + this.ctlMyPage1.T_PreCaption = "上一页"; + this.ctlMyPage1.T_SkipCaption = "跳到"; + this.ctlMyPage1.T_TipCaption = "{pageindex}/{pagecount} 页,共 {recordcount} 条记录,每页 {pagesize} 条"; + this.ctlMyPage1.TabIndex = 9; + this.ctlMyPage1.OnPageChange += new System.EventHandler(this.ctlMyPage1_OnPageChange); + // + // frmModView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(661, 438); + this.Controls.Add(this.btnSearch); + this.Controls.Add(this.txtSearch); + this.Controls.Add(this.ctlMyPage1); + this.Controls.Add(this.listView1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "frmModView"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "单据模板"; + this.Load += new System.EventHandler(this.frmModView_Load); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnSearch; + private System.Windows.Forms.TextBox txtSearch; + private MyPage.ctlMyPage ctlMyPage1; + private System.Windows.Forms.ListView listView1; + private System.Windows.Forms.ColumnHeader colExpressName; + private System.Windows.Forms.ColumnHeader colExpressDes; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 添加快递模板ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 修改快递模板ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 删除快递模板ToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem 复制快递模板ToolStripMenuItem; + private System.Windows.Forms.ColumnHeader columnHeader3; + private System.Windows.Forms.ColumnHeader colBillType; + } +} \ No newline at end of file diff --git a/Source/RyPrint/Mod/frmModView.cs b/Source/RyPrint/Mod/frmModView.cs new file mode 100644 index 0000000..8c84550 --- /dev/null +++ b/Source/RyPrint/Mod/frmModView.cs @@ -0,0 +1,247 @@ +//#define isSysEidt +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Data.SQLite; +namespace ryPrint.Mod +{ + public partial class frmModView : Form + { + public frmModView() + { + InitializeComponent(); + } + string m_SearchText = ""; + string m_SQLWhereText = ""; + private void btnSearch_Click(object sender, EventArgs e) + { + listView1.Items.Clear(); + #if isSysEidt + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.SysDbPath, clsPram.DbPwd); + #else + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.UserExpressDbPath, clsPram.DbPwd); + #endif + myDb.ConnOrCreateDb(); + SQLiteCommand cmd = myDb.SQLite_cn.CreateCommand(); + m_SearchText = txtSearch.Text; + m_SearchText = m_SearchText.Replace(":", " ").Replace(":", " "); + ryCommon.clsLiteDb cLite = new ryCommon.clsLiteDb(); + m_SQLWhereText = cLite.GetSearchSQL(Table.s_Express.Name, m_SearchText); + m_SQLWhereText += " order by " + Table.s_Express.AddTime + " desc"; + cmd.CommandText = "select count(*) from " + Table.s_Express.TableName + " where " + m_SQLWhereText; + ctlMyPage1.T_Parameters = cLite.GetParameters(); + cmd.Parameters.AddRange(ctlMyPage1.T_Parameters); + SQLiteDataReader reader = cmd.ExecuteReader(); + while (reader.Read()) + { + ctlMyPage1.RecordCount = Convert.ToInt32(reader[0].ToString()); + break; + } + reader.Close(); + ctlMyPage1.SQLText = "select * from " + Table.s_Express.TableName + " where " + m_SQLWhereText + " limit {pagesize} offset {recordnum}"; + ctlMyPage1.SQLText2 = "select * from " + Table.s_Express.TableName + " where " + m_SQLWhereText + " limit {pagesize} offset {recordnum}"; + cmd.Dispose(); + ctlMyPage1.GotoPageIndex(1); + } + public bool isChanged = false; + private void txtSearch_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + btnSearch.PerformClick(); + } + } + + private void ctlMyPage1_OnPageChange(object sender, EventArgs e) + { + listView1.Items.Clear(); + #if isSysEidt + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.SysDbPath, clsPram.DbPwd); + #else + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.UserExpressDbPath, clsPram.DbPwd); + #endif + myDb.ConnOrCreateDb(); + SQLiteCommand cmd = myDb.SQLite_cn.CreateCommand(); + cmd.CommandText = ctlMyPage1.GetSQLText; + cmd.Parameters.AddRange(ctlMyPage1.T_Parameters); + listView1.Columns[0].Text = "名称(正在读取)"; + SQLiteDataReader reader = cmd.ExecuteReader(); + while (reader.Read()) + { + ListViewItem item; + item = listView1.Items.Add(reader[Table.s_Express.Name].ToString()); + item.Tag = reader["id"].ToString(); + item.SubItems.Add(reader[Table.s_Express.Des].ToString()); + item.SubItems.Add(reader[Table.s_Express.SysId].ToString()=="0"?"用户模板":"系统模板"); + item.ForeColor = reader[Table.s_Express.SysId].ToString() == "0" ? Color.Black : Color.Blue; + switch(reader[Table.s_Express.billType].ToString()) + { + case "0": + item.SubItems.Add("快递单"); + break; + case "1": + item.SubItems.Add("发货单"); + break; + default: + item.SubItems.Add("未知"); + break; + } + } + reader.Close(); + listView1.Columns[0].Text = "名称(" + listView1.Items.Count.ToString() + ")"; + cmd.Dispose(); + } + + private void 添加快递模板ToolStripMenuItem_Click(object sender, EventArgs e) + { + frmAddMod frm = new frmAddMod(); + frm.isAdd = 1; + if (frm.ShowDialog() == DialogResult.OK) + { + isChanged = true; + btnSearch.PerformClick(); + } + } + + private void 修改快递模板ToolStripMenuItem_Click(object sender, EventArgs e) + { + if (listView1.SelectedItems.Count == 0) { return; } + #if isSysEidt + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.SysDbPath, clsPram.DbPwd); + myDb.ConnOrCreateDb(); + #else + #region 数据库 + string sysId = "0"; + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.UserExpressDbPath, clsPram.DbPwd); + myDb.ConnOrCreateDb(); + SQLiteCommand cmd2 = myDb.SQLite_cn.CreateCommand(); + cmd2.CommandText = "select * from " + Table.s_Express.TableName + " where id=@id"; + cmd2.Parameters.Add("@id", DbType.Int32); //id + cmd2.Parameters["@id"].Value = listView1.SelectedItems[0].Tag.ToString(); + SQLiteDataReader reader2 = cmd2.ExecuteReader(); + while (reader2.Read()) + { + sysId = reader2[Table.s_Express.SysId].ToString(); + break; + } + reader2.Close(); + cmd2.Dispose(); + if (sysId != "0") + { + MessageBox.Show("该模板是系统模板,您不能修改。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + #endregion + #endif + frmAddMod frm = new frmAddMod(); + frm.Text = "修改模板"; + frm.isAdd = 0; + frm.selectId = listView1.SelectedItems[0].Tag.ToString(); + frm.GetDataInfoById(frm.selectId); + if (frm.ShowDialog() == DialogResult.OK) + { + isChanged = true; + try + { + SQLiteCommand cmd = myDb.SQLite_cn.CreateCommand(); + cmd.CommandText = "select * from " + Table.s_Express.TableName + " where id=@id"; + cmd.Parameters.Add("@id", DbType.Int32); //id + cmd.Parameters["@id"].Value = frm.selectId; + SQLiteDataReader reader = cmd.ExecuteReader(); + while (reader.Read()) + { + listView1.SelectedItems[0].SubItems[colExpressName.Index].Text= reader[Table.s_Express.Name].ToString(); + listView1.SelectedItems[0].SubItems[colExpressDes.Index].Text = reader[Table.s_Express.Des].ToString(); + string billtype = "未知"; + switch (reader[Table.s_Express.billType].ToString()) + { + case "0": + billtype="快递单"; + break; + case "1": + billtype="发货单"; + break; + default: + billtype="未知"; + break; + } + listView1.SelectedItems[0].SubItems[colBillType.Index].Text = billtype; + break; + } + reader.Close(); + cmd.Dispose(); + } + catch { } + } + } + + private void 删除快递模板ToolStripMenuItem_Click(object sender, EventArgs e) + { + if (listView1.SelectedItems.Count == 0) { return; } + #region 数据库 + string sysId = "0"; + try + { + ryCommon.clsDb myDb2 = new ryCommon.clsDb(clsPram.UserExpressDbPath, clsPram.DbPwd); + myDb2.ConnOrCreateDb(); + SQLiteCommand cmd = myDb2.SQLite_cn.CreateCommand(); + cmd.CommandText = "select * from " + Table.s_Express.TableName + " where id=@id"; + cmd.Parameters.Add("@id", DbType.Int32); //id + cmd.Parameters["@id"].Value = listView1.SelectedItems[0].Tag.ToString(); + SQLiteDataReader reader = cmd.ExecuteReader(); + while (reader.Read()) + { + sysId = reader[Table.s_Express.SysId].ToString(); + break; + } + reader.Close(); + cmd.Dispose(); + } + catch { } + if (sysId != "0") + { + MessageBox.Show("该模板是系统模板,您不能删除。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + #endregion + if (MessageBox.Show("确定要删除该模板吗?一旦删除将不可恢复。", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) + { + return; + } + if (listView1.SelectedItems.Count == 0) { return; } + ryCommon.clsDb myDb = new ryCommon.clsDb(clsPram.UserExpressDbPath, clsPram.DbPwd); + myDb.ConnOrCreateDb(); + myDb.ExecuteNonQuery("delete from " + Table.s_Express.TableName + " where id=" + listView1.SelectedItems[0].Tag.ToString()); + listView1.SelectedItems[0].Remove(); + listView1.Columns[0].Text = "名称(" + listView1.Items.Count.ToString() + ")"; + isChanged = true; + } + + private void frmModView_Load(object sender, EventArgs e) + { + #if isSysEidt + Text += "(调试模式)"; + #endif + btnSearch.PerformClick(); + } + + private void 复制快递模板ToolStripMenuItem_Click(object sender, EventArgs e) + { + if (listView1.SelectedItems.Count == 0) { return; } + frmAddMod frm = new frmAddMod(); + frm.Text = "复制并添加模板"; + frm.isAdd = 1; + frm.selectId = listView1.SelectedItems[0].Tag.ToString(); + frm.GetDataInfoById(frm.selectId); + if (frm.ShowDialog() == DialogResult.OK) + { + isChanged = true; + btnSearch.PerformClick(); + } + } + } +} diff --git a/Source/RyPrint/Mod/frmModView.resx b/Source/RyPrint/Mod/frmModView.resx new file mode 100644 index 0000000..2e81e2f --- /dev/null +++ b/Source/RyPrint/Mod/frmModView.resx @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABILAAASCwAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wDmuEEA5rhBAOa4QQDmuEEA5rhBAOS1PgDksz0A47I7AOOwOgDirzsA4a86A+Gu + OS7irjhc4q82gOKvNJPirzST4q41geKtOF/hrDkx4a06BeGtOwDhrToA4a46AOKvPADisD0A5LJAAOSy + QADkskAA5LJAAOSyQAD///8A////AOa4QQDmuEEA5rhBAOa4QQDmuEEA5LU+AOSzPQDjsjsA47A7BeKw + OVfisTSw47It6uOyJ//jsiP/47Ih/+OyIf/jsiP/47In/+OxLezisDO04a45XeGtOwnhrjoA4q88AOKw + PQDkskAA5LJAAOSyQADkskAA5LJAAP///wD///8A5rhBAOa4QQDmuEEA5rhBAOa4QQDktT4A5LM9AOOz + O03kszPR5LQn/+SzHf/jsRf/47AS/+KvEP/irw7/4q0J/+KtCP/irQr/4q4O/+OvE//jsSH/47Iz2OGv + OlXhrz0A4rA9AOSyQADkskAA5LJAAOSyQADkskAA////AP///wDmuEEA5rhBAOa4QQDmuEEA5rhBAOS1 + PwfltTqg5bYs/+S0Hv/jsRX/468P/+KuDP/irQr/4q0I/+GrA//muC3/57w6/+i9Pv/pv0T/6sJN/+e8 + N//kshj/5LQq/+OyOavisD4M5LJAAOSyQADkskAA5LJAAOSyQAD///8A////AOa4QQDmuEEA5rhBAOa4 + QQDmuEIS5bg6wua3Kf/ksxr/47AS/+OvDv/irgz/464M/+OuDP/hqgD/68RV//jnzf/458z/+OfN//jo + zv/67Nz/8NKB/+OvDv/ltB//5bUn/+S0OMrkskAZ5LJAAOSyQADkskAA5LJAAP///wD///8A57lCAOe5 + QgDnuUIA57lDB+e6Pb/muCr/5bQb/+SxFP/jsBD/47AP/+OwD//jsBD/4q0H/+i8N//458r/9+bJ//fl + xv/35cb/+OfL//Xht//lshb/8daP/+/Odf/ksBH/5rcp/+W2O8vks0IM5LNBAOSzQQDks0EA////AP// + /wDovEUA6LxFAOi8RgDovEOe57ow/+a1H//lsxf/5LEU/+SxE//ksRP/5LET/+SwD//mtR//9+K5//no + zv/45sj/+ObI//jmyP/56dL/6b8//+zFVP/66tX/6b04/+SxEf/mtR//57kv/+a3Qa3ktUQA5LVDAOS1 + QwD///8A////AOm+SQDpvkkA6b9JROm9Ov/nuCf/5rUc/+WzGf/lsxj/5bMY/+WzGP/ltBj/5LAO//HV + if/569b/+OfK//jozP/56tT/+uvZ//HUhv/nuSz/+erS/+/Nb//ksAz/5bMZ/+a1HP/nuCb/6Ls4/+e4 + RlLmt0YA5rdGAP///wD///8A68JNAOvCTgTrwUbQ6bwx/+e3I//mtR7/5rUc/+a1HP/mtRz/5rUd/+az + FP/rxE3/+evV//jpzf/46c//9+XA//HTgv/03aP/6Lsv//bjuf/14K3/5rMW/+a1G//mtRz/5rUe/+e3 + Iv/pvC//6bxE3ee6SgnoukkA////AP///wDrxFEA7MRRTevBQP/puyz/6Lgk/+i3If/otyH/6Lch/+i3 + If/otyD/57Ye//bhr//57Nf/+erP//rt2v/z147/5rIO/+e1Gf/rwUH/9uK0/+vBP//ntRv/6Lci/+i3 + If/otyL/6Lgk/+m7LP/qvz7/6bxNXOm8TQD///8A////AO3HVgLtxlGo68A8/+q7LP/puSf/6bkm/+m5 + Jv/puSb/6bkm/+i3Hf/tyVn/+u7c//nr0//569P/+u3Z/+3GUP/otx//6bkm/+m4I//ouCH/6bgj/+m5 + J//puSb/6bkm/+m5Jv/puSf/6bss/+vAO//rwE236r5RBv///wD///8A78pbJO7HUOXrwTv/6r0v/+q8 + K//qvCv/6rwr/+q8K//qvCv/6rom//birv/67t3/+uzV//ru3P/35Lb/6roo/+q8K//qvCv/6rwr/+q7 + K//qvCv/6rwr/+q8K//qvCv/6rwr/+q8K//qvS//7MA6/+zDTO/rwlUx////AP///wDvy1xS7sdP/uzB + PP/rvzL/674w/+u+MP/rvjD/674w/+u8K//ux1D/++/d//ru2f/67tn/+/Hj//LUff/quyb/674x/+u+ + MP/rvjD/674w/+u+MP/rvjD/674w/+u+MP/rvjD/674w/+u+Mv/swTv/7cVN/+3FWGH///8A////AO/L + XnrvyFD/7cM//+zAN//swDb/7MA2/+zANv/swDb/670r//TZi//78+f/+u/c//rw3f/679n/7sZJ/+y/ + Mv/swDb/7MA2/+zANv/swDb/7MA2/+zANv/swDb/7MA2/+zANv/swDb/7MA3/+3CPv/ux0//7shbhP// + /wD///8A8MthkfDJU//vxEP/7sI8/+7CO//uwjv/7sI7/+7CO//twTf/+Oi9//vy5f/78d///PPn//fk + sf/twDP/7sI7/+7CO//uwjv/7sI7/+7CO//uwjv/7sI7/+7CO//uwjv/7sI7/+7CO//uwjz/78RD//DJ + Uv/wy1+U////AP///wDxzGSQ8ctY//DHSP/vxUH/78VA/+/FQP/vxUD/78Q9//DJUP/78d3/+/Pk//vy + 4//89ev/89Ny/+7COP/vxUD/78VA/+/FQP/vxUD/78VA/+/FQP/vxUD/78VA/+/FQP/vxUD/78VA/+/F + QP/wxkf/8cxX//HOZJT///8A////APHNZ3fyzV7/8cpO//DHR//wx0b/8MdG//DHRv/wxT//89Nx//z2 + 7f/89Ob//PXq//rv1P/xx0j/8MZE//DHRv/wx0b/8MdG//DHRv/wx0b/8MdG//DHRv/wx0b/8MdG//DH + Rv/wx0b/8MdH//HJTf/yzl3/89Bqgv///wD///8A8s1qT/PPZP3zzFb/8slN//LJS//yyUv/8slL//HG + Qv/335j//fjz//z16f/9+PP/+OKj//HGQf/yyUv/8slL//LJS//yyUv/8slL//LJS//yyUv/8slL//LJ + S//yyUv/8slL//LJS//yyU3/88xV//TQZf/003Fe////AP///wDyzWwi89Bq4/TPXf/zzFP/88tQ//PL + UP/zy1D/8slH//nns//9+fX//fft//337f/002v/88pL//PLUP/zy1D/88tQ//PLUP/zy1D/88tQ//PL + UP/zy1D/88tQ//PLUP/zy1D/88tQ//PMU//0zlz/9dRu7fbWdy7///8A////APPNbgH0z26l9dJm//TP + Wv/0zVb/9M1V//TNVf/0y07/++zF//369v/9+fL//fbm//XTaf/0zE//9M1U//TNVP/0zVX/9M1V//TN + Vf/0zVX/9M1V//TNVf/0zVX/9M1V//TNVf/0zVb/9M9a//XSZv/21naz9tZ6BP///wD///8A881vAPPO + cEf202//9tJj//XQXP/1z1r/9c9a//XOVf/78M///fv4//358v/9+vb//Pjt//fZff/20V7/9dFf//XP + Wv/1z1r/9c9a//XPWv/1z1r/9c9a//XPWv/1z1r/9c9a//XQXP/20mL/9tZw//bWelb21nsA////AP// + /wDzzXAA881wAvXRc8n31W3/9tNk//bSYP/20l//9tFb//zy1f/+/Pv//vv1//769f/+/f//+N6L//rn + rf/77MH/9tBY//bSX//20l//9tJf//bSX//20l//9tJf//bSX//20WD/9tNj//fWbf/313rX9tZ8BvbW + fAD///8A////APTOcgD0znIA9M5zPPfWdv/41m7/+NRm//jTZP/40l3//PLV//7////+/Pj//vz4//79 + /P/52n3//O7G//zvyP/40Vz/+NNk//jTZP/402T/+NNk//jTZP/402T/+NNk//jUZv/41m3/+Nl4//fW + fUr21n0A9tZ9AP///wD///8A9M5zAPTOcwD0zXMA9dF1kvnYeP/52HD/+NZq//jUZP/63ob//vns//7/ + ///+/fv//v35//nZdv/99Nj//O2+//jTX//41Wj/+NVo//jVaP/41Wj/+NVo//jVaP/41mr/+dhw//nZ + ef/3136i99Z9APfWfQD31n0A////AP///wD0znMA9M5zAPTOcwD0zXMD9tJ4t/rae//52nT/+dhv//nV + Zf/623v//vfj////////+/P/+dl1//746f/867f/+dVj//nXbP/512z/+dds//nXbP/5123/+dhv//nZ + c//623z/+Nh/w/bWfQj21n0A9tZ9APbWfQD///8A////APTOcwD0znMA9M5zAPTOcwD1znMN99N5tvrb + fv/73Hn/+tp1//rXbP/72nX//vTW///78f/62nf///76//3pr//61mj/+thw//rYcP/62HH/+tlx//ra + dP/723n/+tx///nYgL731n4S9tZ9APbWfQD21n0A9tZ9AP///wD///8A9M5zAPTOcwD0znMA9M5zAPXO + cwD1znQC9tJ5kvrZgP/73H//+9x7//vadP/723f//OKR//vbd//845f/+91+//vacv/72nX/+9t1//vb + d//73Hv/+91///rcgv/414Cd99V9BvfWfgD21n0A9tZ9APbWfQD21n0A////AP///wD0znMA9M5zAPTO + cwD0znMA9c5zAPXPdAD1znUA9tB3QPjVfcT624L//N6D//zef//83Hr//N19//zbd//83Hv//N19//ze + fv/83oH//N6D//vdhP/52IHL99R+SPfUfQD31X0A99Z+APbWfQD21n0A9tZ9APbWfQD///8A////APTO + cwD0znMA9M5zAPTOcwD1znMA9c90APXPdQD2z3YA9s52APbQeEn41Hyi+diA3/vbg/373IT/+92E//vd + hP/73YT/+9uE/vrZg+L51oCm99R9T/fTfQL31H0A99R9APfVfQD31n4A9tZ9APbWfQD21n0A9tZ9AP// + /wD///8A9M5zAPTOcwD0znMA9M5zAPXOcwD1z3QA9c91APbPdgD2z3cA9s93APbOdgD2z3ci99F5TvfS + e3X303yO99N9j/fTfHf30nxQ99J7JffRewD303wA99N9APfUfQD31H0A99V9APfWfgD21n0A9tZ9APbW + fQD21n0A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A///////gB///gAH//wAA//wAAD/4AAAf8AAAD/AAAA/gAAAHwAAAA8AA + AAOAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/AA + AA/4AAAf/AAAP/8AAP//wAH///AP//////8= + + + \ No newline at end of file diff --git a/Source/RyPrint/Mod/myLabel.Designer.cs b/Source/RyPrint/Mod/myLabel.Designer.cs new file mode 100644 index 0000000..b75fe3d --- /dev/null +++ b/Source/RyPrint/Mod/myLabel.Designer.cs @@ -0,0 +1,50 @@ +namespace ryPrint.Mod +{ + partial class myLabel + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // myLabel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Font = new System.Drawing.Font("黑体", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.Name = "myLabel"; + this.Size = new System.Drawing.Size(182, 70); + this.Load += new System.EventHandler(this.myLabel_Load); + this.Paint += new System.Windows.Forms.PaintEventHandler(this.myLabel_Paint); + this.Resize += new System.EventHandler(this.myLabel_Resize); + this.ResumeLayout(false); + + } + + #endregion + } +} diff --git a/Source/RyPrint/Mod/myLabel.cs b/Source/RyPrint/Mod/myLabel.cs new file mode 100644 index 0000000..3dc12a1 --- /dev/null +++ b/Source/RyPrint/Mod/myLabel.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace ryPrint.Mod +{ + public partial class myLabel : UserControl + { + public myLabel() + { + InitializeComponent(); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + this.DoubleBuffered = true; + this.BorderStyle = BorderStyle.FixedSingle; + + } + public void SetAlign(string align) + { + switch (align) + { + case "Left": + Property.Align = HorizontalAlignment.Left; + break; + case "Right": + Property.Align = HorizontalAlignment.Right; + break; + case "Center": + Property.Align = HorizontalAlignment.Center; + break; + default: + Property.Align = HorizontalAlignment.Left; + break; + } + } + public string AlignStr + { + get + { + switch (Property.Align) + { + case HorizontalAlignment.Left: + return "Left"; + case HorizontalAlignment.Right: + return "Right"; + case HorizontalAlignment.Center: + return "Center"; + default: + return "Left"; + + } + } + } + private ClsProperty _Property=new ClsProperty(); + public ClsProperty Property + { + get + { + _Property.Size = new SizeF(RySet.Pixeltomm(this.Size.Width), RySet.Pixeltomm(this.Size.Height)); + _Property.Postion = new PointF(RySet.Pixeltomm(this.Location.X), RySet.Pixeltomm(this.Location.Y)); + _Property.FontSize = this.Font.Size; + return _Property; + } + + set + { + _Property = value; + this.Font = new Font(this.Font.FontFamily, _Property.FontSize); + //this.Size=_Property.Size; + //this.Location = _Property.Postion; + Refresh(); + } + } + private void myLabel_Load(object sender, EventArgs e) + { + + } + + private void myLabel_Paint(object sender, PaintEventArgs e) + { + StringFormat sf = new StringFormat(); + e.Graphics.PageUnit = GraphicsUnit.Pixel; + if (Property.Multiline) + { + Brush fontBrush = SystemBrushes.ControlText; + //sf.Alignment = StringAlignment.Center; + //sf.LineAlignment = StringAlignment.Center; + RectangleF rect = new RectangleF(new PointF(0, 0), this.Size); + e.Graphics.DrawString(Property.Title, this.Font, fontBrush, rect, sf); + } + else + { + switch (Property.Align) + { + case HorizontalAlignment.Left: + sf.Alignment = StringAlignment.Near; + break; + case HorizontalAlignment.Right: + sf.Alignment = StringAlignment.Far; + break; + case HorizontalAlignment.Center: + sf.Alignment = StringAlignment.Center; + break; + } + //sf.LineAlignment = sf.Alignment; + this.Height = (int)e.Graphics.MeasureString(Property.Title, this.Font).Height; + if (sf.Alignment == StringAlignment.Center || sf.Alignment == StringAlignment.Far) + { + RectangleF rect = new RectangleF(new PointF(0, 0), new Size(Width,Height)); + sf.LineAlignment = sf.Alignment; + e.Graphics.DrawString(Property.Title, this.Font, Brushes.Black, rect, sf); + } + else + { + e.Graphics.DrawString(Property.Title, this.Font, Brushes.Black, new PointF(0, 0)); + } + } + } + + private void myLabel_Resize(object sender, EventArgs e) + { + } + } +} diff --git a/Source/RyPrint/Mod/myLabel.resx b/Source/RyPrint/Mod/myLabel.resx new file mode 100644 index 0000000..7080a7d --- /dev/null +++ b/Source/RyPrint/Mod/myLabel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/Source/RyPrint/Mod/rySet.cs b/Source/RyPrint/Mod/rySet.cs new file mode 100644 index 0000000..780d8c6 --- /dev/null +++ b/Source/RyPrint/Mod/rySet.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace ryPrint.Mod +{ + public class RySet + { + /// + /// 毫米转像素 + /// + /// + /// + public static int MMtopixel(double mm) + { + return Convert.ToInt32(mm * 5); + } + /// + /// 像素转毫米 + /// + /// + /// + public static float Pixeltomm(int pixel) + { + return pixel / 5f; + } + /// + /// 毫米转英寸 + /// + /// + public static float MMToInches(double mm) + { + return (float)(0.0393701 * mm); + } + /// + /// 英寸转毫米 + /// + /// + public static float InchesTomm(decimal Inches) + { + return (float)(Inches/0.0393701m); + } + public static string GetTruePath(string path) + { + return path.Replace("", Application.StartupPath); + } + } +} diff --git a/Source/RyPrint/Properties/AssemblyInfo.cs b/Source/RyPrint/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..0263aed --- /dev/null +++ b/Source/RyPrint/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("RyPrint")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("睿元网络工作室")] +[assembly: AssemblyProduct("睿元打印控件")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("b6784652-825a-482c-8a21-08e2539af2bf")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.1909.1202")] +[assembly: AssemblyFileVersion("1.0.1909.1202")] \ No newline at end of file diff --git a/Source/RyPrint/Properties/soft_info.txt b/Source/RyPrint/Properties/soft_info.txt new file mode 100644 index 0000000..c42075c --- /dev/null +++ b/Source/RyPrint/Properties/soft_info.txt @@ -0,0 +1,2 @@ +//ʱ +compile_time=0 diff --git a/Source/RyPrint/RyPrint.csproj b/Source/RyPrint/RyPrint.csproj new file mode 100644 index 0000000..949310b --- /dev/null +++ b/Source/RyPrint/RyPrint.csproj @@ -0,0 +1,99 @@ + + + + + Debug + AnyCPU + {B6784652-825A-482C-8A21-08E2539AF2BF} + Library + Properties + RyPrint + RyPrint + v4.0 + 512 + + + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + pdbonly + true + ..\..\Bin\Release\CommonControls\.NET4\ + TRACE + prompt + 4 + + + + + true + + + + + + + + + + + + + + + Form + + + frmPrintPreview.cs + + + + UserControl + + + UserControl + + + PrintModEdit.cs + + + + UserControl + + + myLabel.cs + + + + + + + + frmPrintPreview.cs + + + PrintModEdit.cs + + + myLabel.cs + + + + + {9df20d86-a56e-4cf6-a3d8-f30421297b1b} + MyDbV4 + + + + + + + + \ No newline at end of file diff --git a/Source/RyPrint/RyPrint.csproj.user b/Source/RyPrint/RyPrint.csproj.user new file mode 100644 index 0000000..944ec00 --- /dev/null +++ b/Source/RyPrint/RyPrint.csproj.user @@ -0,0 +1,6 @@ + + + + ShowAllFiles + + \ No newline at end of file diff --git a/Source/RyPrint/SmartPrint.cs b/Source/RyPrint/SmartPrint.cs new file mode 100644 index 0000000..4f31d3b --- /dev/null +++ b/Source/RyPrint/SmartPrint.cs @@ -0,0 +1,376 @@ +using ryPrint; +using ryPrint.Mod; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Printing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace RyPrint +{ + /// + /// 如果涉及到分页打印,切勿在PrintPage事件中多次实例化 + /// + public class SmartPrint + { + private Hashtable dt_list = new Hashtable(); + /// + /// 设置获取加载的模板 + /// + public string Mod_Xml { get; set; } = ""; + private PrintDocument _Print_Doc = null; + public SmartPrint(string mod_xml,PrintDocument Print_Doc) + { + Mod_Xml = mod_xml; + Print_Doc.BeginPrint += Print_Doc_BeginPrint; + Print_Doc.PrintPage += Print_Doc_PrintPage; + _Print_Doc = Print_Doc; + } + + + public SmartPrint(PrintDocument Print_Doc) + { + Print_Doc.BeginPrint += Print_Doc_BeginPrint; + Print_Doc.PrintPage += Print_Doc_PrintPage; + _Print_Doc = Print_Doc; + } + public SmartPrint() + { + } + /// + /// 显示打印预览窗口 + /// + public void ShowPreviewForm() + { + if (!_Print_Doc.PrinterSettings.IsValid) + { MessageBox.Show("当前打印机无效。请确认是否已安装打印机。","提示",MessageBoxButtons.OK,MessageBoxIcon.Information); return; } + IsPreview = true; + frmPrintPreview frm = new frmPrintPreview(); + frm._SmartPrint = this; + frm.PrintDoc = _Print_Doc; + frm.ShowDialog(); + } + private void Print_Doc_PrintPage(object sender, PrintPageEventArgs e) + { + Print(Mod_Xml, e, IsPreview); + } + + private void Print_Doc_BeginPrint(object sender, PrintEventArgs e) + { + StartPrint(); + } + + /// + /// 左边距 + /// + public int MarginLeft { get; set; } = 0; + /// + /// 顶部边距 + /// + public int MarginTop { get; set; } = 0; + /// + /// 单位是否是英寸,如果false,则是毫米,默认false。 + /// + public bool IsInch { get; set; } = false; + /// + /// 是否是预览 + /// + public bool IsPreview { get; set; } = false; + public string FontName { get; set; } = "黑体"; + private int _curPageIndex = 0; + /// + /// 获取或设置当前打印的是第几页,从0开始计数 + /// + public int curPageIndex + { + get { return _curPageIndex; } + set + { + if (value < 0) { _curPageIndex=0; } + else { _curPageIndex= value; } + } + } + private int _MaxPage = -1; + /// + /// 获取或设置当前最多打印到第几页,从0开始计数,-1表示打印到结束 + /// + public int MaxPage + { + get { return _MaxPage; } + set + { + if (value < 0) { _MaxPage = -1; } + else { _MaxPage = value; } + } + } + /// + /// 设置纸张名称 + /// + public string PaperName { get; set; } = "打印内容"; + /// + /// 是否横向打印 + /// + public bool Landscape { get; set; } = true; + /// + /// 是否打印多页,如果设为true,有多页文本,则打印多页,没有则打印一页。 + /// + public bool PrintMorePages { get; set; } = true; + public delegate void DataSetHandler(string DataSource,out DataTable ds); + [Description("获取数据表时激发")] + public event DataSetHandler OnDataSet; + public void StartPrint() + { + //curPageIndex = 0; + dt_list.Clear(); + ryCommon.Storage tStor_set = new ryCommon.Storage(Mod_Xml); + tStor_set.SelectNode2("id", "set"); + double mmWidth = tStor_set.GetAttrValue("Width", 0d); + double mmHeight = tStor_set.GetAttrValue("Height", 0d); + PaperSize sPSize = new PaperSize(PaperName, (int)RySet.MMToInches(mmHeight * 100), (int)RySet.MMToInches(mmWidth * 100));//267为英寸转厘米为8厘米 //PaperSize sPSize = new PaperSize("快递单", (int)pixelsToInches(image.Width * 100), (int)pixelsToInches(image.Height * 100)); + if (!Landscape) + { + sPSize = new PaperSize(PaperName, (int)RySet.MMToInches(mmWidth * 100), (int)RySet.MMToInches(mmHeight * 100));//267为英寸转厘米为8厘米 + } + _Print_Doc.DefaultPageSettings.PaperSize = sPSize; + } + public void Print() + { + curPageIndex = 0; + MaxPage = -1; + IsPreview = false; + _Print_Doc.PrinterSettings.FromPage = 0; + _Print_Doc.Print(); + } + /// + /// 打印 + /// + /// 打印模板 + /// 打印参数 + /// 是否是预览 + public void Print(string mod_xml, PrintPageEventArgs e,bool isPreview) + { + try + { + e.Graphics.PageUnit = IsInch ? GraphicsUnit.Inch : GraphicsUnit.Millimeter; + #region 根据模板打印 + ryCommon.Storage tStor_set = new ryCommon.Storage(mod_xml); + tStor_set.SelectNode2("id", "set"); + double mmWidth = tStor_set.GetAttrValue("Width", 0d); + double mmHeight = tStor_set.GetAttrValue("Height", 0d); + if (IsInch) + { + mmWidth = RySet.MMToInches(mmWidth); + mmHeight = RySet.MMToInches(mmHeight); + } + string picPath = RySet.GetTruePath(tStor_set.GetAttrValue("PreviewPicPath", "")); + tStor_set.SelectNode2("id", "print_xml"); + ryCommon.Storage tStor = new ryCommon.Storage(tStor_set.GetAttrValue("Value")); + System.Xml.XmlNodeList list = tStor.GetList(); + if (System.IO.File.Exists(picPath)) + { + Image image = Image.FromFile(picPath); + if (isPreview) + { + + Bitmap pic = (Bitmap)image; + //pic.SetResolution(dpiValue, dpiValue); + e.Graphics.DrawImage(pic, 0, 0, (float)mmWidth, (float)mmHeight); + } + } + for (int i = 0; i < list.Count; i++) + { + tStor.SelectNode3(list[i]); + Font _Font = new Font(FontName, tStor.GetAttrValueByInt("FontSize", 10), FontStyle.Regular); + bool Multiline = tStor.GetAttrValueByBool("Multiline", false); + SizeF size = new SizeF((float)(tStor.GetAttrValue("Width", 100f)), (float)(tStor.GetAttrValue("Height", 21f))); + PointF location = new PointF((float)(tStor.GetAttrValue("Left", 0f) + MarginLeft), (float)(tStor.GetAttrValue("Top", 0f) + MarginTop)); + if (IsInch) + { + size = new SizeF(RySet.MMToInches(size.Width), RySet.MMToInches(size.Height)); + location = new PointF(RySet.MMToInches(location.X), RySet.MMToInches(location.Y)); + } + string title = tStor.GetAttrValue("Title"); + ClsProperty.En_Type _type = ClsProperty.En_Type.自定义; + try + { + _type = (ClsProperty.En_Type)tStor.GetAttrValueByInt("sType", 0); + } + catch { } + List value_list = new List(); + #region 转换值 + switch (_type) + { + case ClsProperty.En_Type.自定义: + string format = tStor.GetAttrValue("format"); + if (format == "") + { + if (tStor.GetAttrValue("value") == "") + { value_list.Add(title); } + else + { + value_list.Add(tStor.GetAttrValue("value")); + } + } + else + { + value_list.Add(DateTime.Now.ToString(format)); + } + break; + case ClsProperty.En_Type.数据字段: + string datasource = tStor.GetAttrValue("DataSource"); + if (datasource != "") + { + DataTable dt = new DataTable(); + HashItem item = new HashItem(); + if (!dt_list.ContainsKey(datasource)) + { + OnDataSet?.Invoke(datasource, out dt); + item.dt = dt; + dt_list.Add(datasource, item); + } + else + { + item = (HashItem)dt_list[datasource]; + if (item.dt!= null) + dt = item.dt; + } + if (!dt.Columns.Contains(tStor.GetAttrValue("value"))) { item.ReadEnd = true; continue; } + int PageCount = tStor.GetAttrValue("PageCount", 0); + int startRow = curPageIndex* PageCount; + int endRow = dt.Rows.Count; + if(PageCount>0) + { + if((curPageIndex+1) * PageCount>= dt.Rows.Count) + { + endRow = dt.Rows.Count; + item.ReadEnd = true; + } + else + { + endRow = (curPageIndex + 1) *PageCount; + } + } + else + { + item.ReadEnd = true; + } + dt_list[datasource] = item; + for (int m = startRow; m < endRow; m++) + { + value_list.Add(dt.Rows[m][tStor.GetAttrValue("value")].ToString()); + } + } + break; + } + #endregion + float total_top = location.Y; + #region 打印内容 + for (int k = 0; k < value_list.Count; k++) + { + location.Y = total_top; + string value = value_list[k]; + float rowHeight = e.Graphics.MeasureString(value + "有", _Font).Height; + if (value != "") + { + StringFormat sf = new StringFormat(); + Brush fontBrush = Brushes.Black; + if (tStor.GetAttrValue("NoPrint", false)) + { + if (isPreview) + { + fontBrush = Brushes.Blue; + } + else + { continue; } + } + if (Multiline) + { + //sf.Alignment = StringAlignment.Center; + //sf.LineAlignment = StringAlignment.Center; + RectangleF rect = new RectangleF(location, size); + rowHeight = rect.Height; + e.Graphics.DrawString(value, _Font, fontBrush, rect, sf); + } + else + { + #region 单行打印 + switch (tStor.GetAttrValue("align")) + { + case "Left": + sf.Alignment = StringAlignment.Near; + break; + case "Right": + sf.Alignment = StringAlignment.Far; + break; + case "Center": + sf.Alignment = StringAlignment.Center; + break; + } + //sf.LineAlignment = sf.Alignment; + if (sf.Alignment == StringAlignment.Center) + { + SizeF _size = e.Graphics.MeasureString(value, _Font); + if (size.Width < _size.Width) { size.Width = _size.Width; } + size.Height = _size.Height; + RectangleF rect = new RectangleF(location, size); + sf.LineAlignment = sf.Alignment; + e.Graphics.DrawString(value, _Font, fontBrush, rect, sf); + } + else + { + e.Graphics.DrawString(value, _Font, fontBrush, location, sf); + } + #endregion + } + } + if (IsInch) + { total_top += rowHeight + RySet.MMToInches(tStor.GetAttrValue("LineSpace", 0)); } + else + { + total_top += rowHeight + tStor.GetAttrValue("LineSpace", 0); + } + } + #endregion + } + #endregion + } + catch { } + #region 判断记录是否已经打印完 + bool PageEnd = true; + foreach (DictionaryEntry de in dt_list) + { + HashItem _item = (HashItem)de.Value; + if (!_item.ReadEnd) + { + PageEnd = false; + break; + } + } + if (PageEnd) { e.HasMorePages = false; }///如果已经是尾页,则不继续打印 + else + { + if(MaxPage>0) + { + if(curPageIndex>= MaxPage) + { + e.HasMorePages = false; + return; + } + } + e.HasMorePages = true; + curPageIndex++; + } + #endregion + } + } + class HashItem + { + public DataTable dt=new DataTable(); + public bool ReadEnd = false; + } +} diff --git a/Source/RyPrint/document_print_preview_3_32px_539642_easyicon.net.ico b/Source/RyPrint/document_print_preview_3_32px_539642_easyicon.net.ico new file mode 100644 index 0000000..855a4a3 Binary files /dev/null and b/Source/RyPrint/document_print_preview_3_32px_539642_easyicon.net.ico differ diff --git a/Source/RyPrint/frmPrintPreview.Designer.cs b/Source/RyPrint/frmPrintPreview.Designer.cs new file mode 100644 index 0000000..827d625 --- /dev/null +++ b/Source/RyPrint/frmPrintPreview.Designer.cs @@ -0,0 +1,165 @@ +namespace RyPrint +{ + partial class frmPrintPreview + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmPrintPreview)); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.BtnPrint = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.BtnSetting = new System.Windows.Forms.ToolStripButton(); + this.BtnPrev = new System.Windows.Forms.ToolStripButton(); + this.BtnNext = new System.Windows.Forms.ToolStripButton(); + this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); + this.printPreviewControl1 = new System.Windows.Forms.PrintPreviewControl(); + this.printDialog1 = new System.Windows.Forms.PrintDialog(); + this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.BtnPrint, + this.toolStripSeparator1, + this.BtnSetting, + this.BtnPrev, + this.BtnNext, + this.toolStripLabel1}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(856, 25); + this.toolStrip1.TabIndex = 3; + this.toolStrip1.Text = "toolStrip1"; + // + // BtnPrint + // + this.BtnPrint.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.BtnPrint.Image = ((System.Drawing.Image)(resources.GetObject("BtnPrint.Image"))); + this.BtnPrint.ImageTransparentColor = System.Drawing.Color.Magenta; + this.BtnPrint.Name = "BtnPrint"; + this.BtnPrint.Size = new System.Drawing.Size(23, 22); + this.BtnPrint.Text = "打印"; + this.BtnPrint.ToolTipText = "打印"; + this.BtnPrint.Click += new System.EventHandler(this.BtnPrint_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // BtnSetting + // + this.BtnSetting.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.BtnSetting.Image = ((System.Drawing.Image)(resources.GetObject("BtnSetting.Image"))); + this.BtnSetting.ImageTransparentColor = System.Drawing.Color.Magenta; + this.BtnSetting.Name = "BtnSetting"; + this.BtnSetting.Size = new System.Drawing.Size(23, 22); + this.BtnSetting.Text = "打印设置"; + this.BtnSetting.ToolTipText = "打印设置"; + this.BtnSetting.Visible = false; + this.BtnSetting.Click += new System.EventHandler(this.BtnSetting_Click); + // + // BtnPrev + // + this.BtnPrev.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.BtnPrev.Image = ((System.Drawing.Image)(resources.GetObject("BtnPrev.Image"))); + this.BtnPrev.ImageTransparentColor = System.Drawing.Color.Magenta; + this.BtnPrev.Name = "BtnPrev"; + this.BtnPrev.Size = new System.Drawing.Size(23, 22); + this.BtnPrev.Text = "上一页"; + this.BtnPrev.Click += new System.EventHandler(this.BtnPrev_Click); + // + // BtnNext + // + this.BtnNext.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.BtnNext.Image = ((System.Drawing.Image)(resources.GetObject("BtnNext.Image"))); + this.BtnNext.ImageTransparentColor = System.Drawing.Color.Magenta; + this.BtnNext.Name = "BtnNext"; + this.BtnNext.Size = new System.Drawing.Size(23, 22); + this.BtnNext.Text = "下一页"; + this.BtnNext.Click += new System.EventHandler(this.BtnNext_Click); + // + // toolStripLabel1 + // + this.toolStripLabel1.ForeColor = System.Drawing.Color.Blue; + this.toolStripLabel1.Name = "toolStripLabel1"; + this.toolStripLabel1.Size = new System.Drawing.Size(167, 22); + this.toolStripLabel1.Text = "注意:蓝色表示只在预览中显示"; + // + // printPreviewControl1 + // + this.printPreviewControl1.AutoZoom = false; + this.printPreviewControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.printPreviewControl1.Location = new System.Drawing.Point(0, 25); + this.printPreviewControl1.Name = "printPreviewControl1"; + this.printPreviewControl1.Size = new System.Drawing.Size(856, 483); + this.printPreviewControl1.TabIndex = 4; + this.printPreviewControl1.Zoom = 1D; + // + // printDialog1 + // + this.printDialog1.AllowSelection = true; + this.printDialog1.AllowSomePages = true; + this.printDialog1.ShowHelp = true; + this.printDialog1.UseEXDialog = true; + // + // frmPrintPreview + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(856, 508); + this.Controls.Add(this.printPreviewControl1); + this.Controls.Add(this.toolStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "frmPrintPreview"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "预览"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.frmPrintPreview_FormClosed); + this.Load += new System.EventHandler(this.frmPrintPreview_Load); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton BtnPrint; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.PrintPreviewControl printPreviewControl1; + private System.Windows.Forms.PrintDialog printDialog1; + private System.Windows.Forms.PageSetupDialog pageSetupDialog1; + private System.Windows.Forms.ToolStripButton BtnSetting; + private System.Windows.Forms.ToolStripLabel toolStripLabel1; + private System.Windows.Forms.ToolStripButton BtnPrev; + private System.Windows.Forms.ToolStripButton BtnNext; + } +} \ No newline at end of file diff --git a/Source/RyPrint/frmPrintPreview.cs b/Source/RyPrint/frmPrintPreview.cs new file mode 100644 index 0000000..5935f3f --- /dev/null +++ b/Source/RyPrint/frmPrintPreview.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Drawing.Printing; + +namespace RyPrint +{ + public partial class frmPrintPreview : Form + { + public frmPrintPreview() + { + InitializeComponent(); + } + private PrintDocument m_PrintDoc; + [Description("打印文档")] + public PrintDocument PrintDoc + { + get { return m_PrintDoc; } + set { m_PrintDoc = value; } + } + private int m_TotalPageCount; + [Description("总页数")] + public int TotalPageCount + { + get { return m_TotalPageCount; } + set { m_TotalPageCount = value; } + } + public SmartPrint _SmartPrint = null; + private void frmPrintPreview_Load(object sender, EventArgs e) + { + try + { + m_PrintDoc.PrinterSettings.FromPage = 0; + m_PrintDoc.EndPrint += Print_Doc_EndPrint; + //PaperSize sPSize = new PaperSize("发货清单纸", Convert.ToInt32(clsPram.PageWidth * (decimal)33.375), Convert.ToInt32(clsPram.PageHeight * (decimal)33.375));//267为英寸转厘米为8厘米 + //printDocument1.DefaultPageSettings.PaperSize = sPSize; + printPreviewControl1.Document = m_PrintDoc; + printDialog1.Document = m_PrintDoc; + pageSetupDialog1.Document = m_PrintDoc; + printPreviewControl1.Zoom = 1; + this.Text = "打印预览"; + } + catch + { + MessageBox.Show("没有安装打印机。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + public void Print_Doc_EndPrint(object sender, PrintEventArgs e) + { + TotalPageCount = _SmartPrint.curPageIndex + 1; + this.Text = "打印预览(共" + (_SmartPrint.curPageIndex+1) + "页,当前第"+ (printPreviewControl1.StartPage+1) + "页)"; + } + private void BtnPrint_Click(object sender, EventArgs e) + { + printPreviewControl1.Document.PrinterSettings.FromPage = 0; + printDialog1.AllowSomePages = true; + DialogResult dr = printDialog1.ShowDialog(); + if (dr == DialogResult.OK) + { + _SmartPrint.IsPreview = false; + if (printDialog1.PrinterSettings.PrintRange == PrintRange.SomePages) + { + _SmartPrint.curPageIndex = printDialog1.PrinterSettings.FromPage; + _SmartPrint.MaxPage = printDialog1.PrinterSettings.ToPage; + } + else + { + _SmartPrint.curPageIndex = 0; + _SmartPrint.MaxPage = -1; + } + printPreviewControl1.Document.Print(); + } + } + + private void BtnSetting_Click(object sender, EventArgs e) + { + //frmSettingPrint frm = new frmSettingPrint(); + //frm.ShowDialog(); + //if (frm.DialogResult == DialogResult.Yes) + //{ + //clsPram.LoadPrintSetting(Application.StartupPath + "\\Db\\PrintSetting.dat"); + printPreviewControl1.Document.DefaultPageSettings.Landscape = true; //横向打印 + //PaperSize sPSize = new PaperSize("发货清单纸", Convert.ToInt32(clsPram.PageWidth * (decimal)33.375), Convert.ToInt32(clsPram.PageHeight * (decimal)33.375));//267为英寸转厘米为8厘米 + //printPreviewControl1.Document.DefaultPageSettings.PaperSize = sPSize; //PaperSize sPSize = new PaperSize("快递单", (int)pixelsToInches(image.Width * 100), (int)pixelsToInches(image.Height * 100)); + printPreviewControl1.InvalidatePreview(); + //} + } + + private void BtnPrev_Click(object sender, EventArgs e) + { + if (printPreviewControl1.StartPage > 0) + { + printPreviewControl1.StartPage -= 1; + } + this.Text = "打印预览(共" + (_SmartPrint.curPageIndex + 1) + "页,当前第" + (printPreviewControl1.StartPage + 1) + "页)"; + } + + private void BtnNext_Click(object sender, EventArgs e) + { + if (printPreviewControl1.StartPage < TotalPageCount - 1) + { + printPreviewControl1.StartPage += 1; + } + this.Text = "打印预览(共" + (_SmartPrint.curPageIndex + 1) + "页,当前第" + (printPreviewControl1.StartPage + 1) + "页)"; + } + + private void frmPrintPreview_FormClosed(object sender, FormClosedEventArgs e) + { + m_PrintDoc.EndPrint -= Print_Doc_EndPrint; + } + } +} diff --git a/Source/RyPrint/frmPrintPreview.resx b/Source/RyPrint/frmPrintPreview.resx new file mode 100644 index 0000000..e1aa580 --- /dev/null +++ b/Source/RyPrint/frmPrintPreview.resx @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + + + 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 + q4QbdxCg0/0JJiaBR4yFeEsAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAPoSURBVEhLtZR7TJV1GMfPXCsQCpxpR0ItLJ2sy8JcoVKL + zXXZ1DQJHYVAWZll5RJWLbQ/rKbOaFyc2jSmEQWOKC0lJG5CgCCBUCkitwMnOBzOgfcczv3T8x4Qa5ob + C57t2e99zx+f7/f5Pr/3aMZT9yY3ot1UzejrxNd9OUYmVSTsxyFerbV4RYK31E68iDpBjsE9JnLbhjMT + KxJ+fJAuF/zQ55gcEXWCXXoPjVbI19uuisTdQGTh0X6CD/QSlKEf6bQeZqX2oE3pZtZn3Wg/16Hd08Xt + uztYkNbFux1uEi+5KDZ7KDK6WPyzcmORuw4ZONrtILfXSbZeusdJlt5BVo9dfrdzRGcns8vOl502Ui/b + eeuik4TzDmLqbWxvtnJK4hoTuV5cYdkG5ZwFLtrgvIzeJN0o7w0K1A1BzSBUmqFK+vs+N/ECj//NTlSN + jRVVw14Rted9a7q+SEhGu7Kj00V6L+zu9rBT5ya5w0Nym0Rx2c3WFgdvXHCyqdlJfIOd9edsRNcM82y1 + leWlVq/7iHLlv0XmprUqSZLrHj181OnhA3lOanXzTovTC36l2UFcvYDP2lhbPcyqGitPn7HyRImFx04r + qN+GCr4i8sjBdq+If2z5iMicnS1KYquLj3Ue3hPXSZecvC3gzb8LvNFBrGQdLXGsFvjKimGWl1l4vEgh + vGCIsOND3J9nJiR3gGmH+8dElh4YEfFOMntHi/Lmn04+bPOwVRaogjcKOE5yXl9rY41EsUIiebJcXP+i + sKRAYdEJAeebmZ9rYs7XRrRHjAQe6kOzq4NQEb8i4r1ZQdsvKC832dnW4uY1iUPNObbOxvNnJY5fJQ4B + R0ocERLHwz8N8cB3ZhYcMxHyzQBBcsWnHzbgf1DgKb1oMnpZetLE3Yn1+L84GlHg+81KTP0wr//hIrbW + PhqHlWcqZIkCjxBHj0ocD50YJPSYmXnZAwR/1c+MzH4CvjDgs0/An7QzRYTUc8aGYsn/H0sO2NagRIvb + hCYH6+rsrJJlPiVZR5ZZWVZsYdFJReIY5J68QeYK/A4Bq3H4CnhKqh7Np+3ckikTCHxmXMm113T6ljqW + 5Q8QWWhhibhcnG/iwRwTodlG5mcaCBHYnft7mSlf+bT0Hvz293Fz+l9o9uoE3satWcar8LiKf8PVCoyv + xD+mHL91pdLF+EWVMDWqiKnPncZ3baGchfisKcB3dQE+MWVo9olb+dtQ4UGyD/VU4QEJldfCx1s3vSCL + 2ytwEZidJ84FHvhSFZrokv8P95ZMo0nRsfDUiPOJhaslsPBSxQsPmHC4WipQdb5xMuBqCVS7WZY5KXC1 + VPC44BrN38lmcVzWivqPAAAAAElFTkSuQmCC + + + + 127, 17 + + + 252, 17 + + + 78 + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAANJJAADSSQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAHAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA + AAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAA + AAcAAAAFAAAAAgAAAAAAAAAAAAAAAQAAAAcAAAATAAAAHAAAACQAAAAnAAAAKAAAACgAAAAoAAAAKAAA + ACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAA + ACgAAAAnAAAAJQAAAB4AAAAVAAAACQAAAAEAAAAHAAAAFwQEBCtCQ0N5VldXsFhZWbNZWluzW1xcs1xd + XrNdX1+zXl9gs11fX7NdXl+zXF5es1xdXbNbXV2zW1xcs1pcXLNaW1uzWVtbs1laWrNYWVqzWFlZs1dY + WbNXWFizVldYs1ZXV7NUVVWwP0BAdwICAi0AAAAaAAAACgAAAAsAAAAaOTk5XGVnZ+97fn//gIOE/4SH + iP+Ii4z/jI+Q/4+TlP+RlZb/kJSV/46Sk/+NkZH/i4+Q/4qNjv+IjI3/h4qL/4WJif+Eh4j/goaG/4GE + hf9/goP/foGC/3x/gP97fn7/eXx9/3d5ev9jZGTsNjY2XAAAAB4AAAAOAAAABCUlJR95eXnBra6u/7O0 + tf+ys7T/sbOz/7Gysv+wsbH/r7Gx/6+wsP+ur6//ra6v/6ytrv+rra3/qqys/6qrq/+pqqr/qKmq/6eo + qf+mqKj/paen/6Wmpv+kpaX/o6Sl/6KjpP+hoqP/oKKj/5ucnf9zc3PCJCQkIgAAAAZtbW0AT09PIJeY + mOLc3t7/2tzc/9jb2//X2dn/1tjY/9XW1//T1dX/0tTU/9DS0//P0dH/ztDQ/8zOz//Lzc7/yszM/8jK + y//Hycr/xsjI/8TGx//Dxcb/wsTF/8HCw/+/wcL/vsDB/7y+v/+7vb7/vb6//4yNjeJRUFAhe3t7AGZm + ZgBVVVUempub4Nvd3f/X2dn/1tjY/9XX1//T1dX/0tTU/9HT0//P0dL/ztDQ/83Pz//Lzc7/yszM/8nL + y//Hycr/xsjI/8XHx//Dxcb/w8XG/72/v/+ztbb/u72+/72/wP+7vb7/ury9/7i6u/+9v8D/kJGR4FlZ + WR5mZmYAZ2dnAFVUVB6cnJzg3N7e/9fZ2f/X2dn/1tjY/9TW1//T1dX/0tTU/9DS0//P0dH/ztDQ/8zO + z//Lzc3/yszM/8jKy//Hycn/xsjI/8XHyP+vsbH/hYaG/4yMjP+LjIz/tLW2/72/wP+6vL3/uLq7/7/B + wv+TlJTgWFhXHmdnZwBnZ2cAVFRUHp6enuDd39//1tjY/8jJyv/CxMT/wcPD/8DBwv+/wMD/vb+//7y+ + vv+7vb3/ury8/7m7u/+4ubr/t7i5/7a3uP+3uLn/o6Wl/3p6ev+wsLD/4eHh/7CwsP+LjIz/rq+w/7K0 + tf+4urv/wcPE/5aWl+BXV1ceZ2dnAGdnZwBUU1Men6Cg4N/h4f+xsrL/n5+g/6qqq/+pqqr/qamq/6ip + qf+oqan/qKmp/6ipqf+oqKn/qKip/6ioqf+oqKn/p6io/319ff9zc3P/oqKi/7Ozs//Y2Nj/t7e3/4WG + hv+nqKj/lJWV/6mrrP/Exsf/mZmZ4FZWVh5nZ2cAZ2dnAFNTUx6hoaHg3d7e/6ipqv/T1NX/uLm6/+Xm + 5//29/j/9vf4//b3+P/3+Pn/9/j5//b3+P/19vf/9vf4//P09f+0tLX/g4OD/6enp/+np6f/oKCg/5ub + m/+MjIz/3d7e//j5+v/Ky8z/nZ6f/8fIyf+cnJzgVVVVHmdnZwBnZ2cAUlJSHqOjo+Df4OD/xsjI/+Dh + 4v/DxMX/3t/g//Hy8//h4eL/0tPU/83Ozv/R0tL/3d7f/+7v8P/t7u//pqen/4aGhv+qqqr/paWl/5+f + n/+Li4v/hYaG/9bX2P/z9PX/8vP1/93e3/+tr6//yMnK/5+fn+BUVFQeZ2dnAGdnZwBSUlIfpaWl4ejp + 6f/i4+P/7e7v/+vs7f/S09P/tre3/7u8vP/Jysv/z9DR/8nKyv+1tbb/qqur/5ycnf+Pj4//ra2t/6Oj + o/+dnZ3/hoaG/4+PkP/Z2tv/6+zt/+nq6v/p6ur/3t/g/8nKy//V19f/oqKi4VNTUx9nZ2cAZ2dnAE9P + Txibm5vZ+Pj4//z8/P/5+fn/zMzM/7u7vP/h4OD/5t3V/9rGtv/Vvar/2se3/+fe1v/d3Nz/srKz/8LC + wv+jo6P/m5ub/4ODg/+fn5//7e3t//j4+P/39/f/9/f3//X19f/z9PT/9PT0//Pz8/+ZmZnYUFBQGGdn + ZwBnZ2cAKyoqA3h4eJLS09P//f39/8/Pz//Dw8P/6OPe/8iojv+ug2D/q4Vl/6yKbP+phGX/roRh/8mp + kf/t5+P/5ubn/7CwsP98fHz/fn5+/7e3t/+9vb3/vLy8/7y8vP+7u7v/29vb/+vr6//w8PD/yMjI/3V1 + dYoaGhoCZ2dnAGdnZwBlZWUAWVlZIpOTk9PW1tb/vLy9/+fh3P+9lnb/tI5t/7igiv+2o5L/tKSU/7Wk + lP+2oY7/so5v/72XeP/q5eH/qaqq/4iIiP+mpqb/pqam/6Wlpf+mpqb/p6en/56env/Kysr/7u7u/9ra + 2v+Hh4fJWFhYG2RkZABnZ2cAZ2dnAFNSUgB1dXUAa2trUpOTk+va2dn/x6eN/72Vcv/Hr5j/v6qX/7qp + mf+4q57/uaue/7uqm/++qZb/tY9v/8ipkP/W1tb/l5eX/7CwsP+ysrL/tLS0/729vf/Dw8P/tra2/5ub + m+ulpaXhi4yMzGZmZkJqamoAaGhoAGdnZwAAAAAAZ2dnAIODgwBxcXEQqamqzdzSy/+yhF77zrOZ/tjE + sf/UxLT/z8G1/8m9sv/Gua3/x7en/8i0of/Irpb/t4xo/9zUzf+sra3/ubm5/8bGxv/Hx8f/0dHR/9jY + 2P/FxcX9gICAbUhISBtTU1MUdnd3AF9fXwBnZ2cAAAAAAAAAAAAAAAAAioqKAH9/fyS3uLnl0Lys/7WH + X+zey7n97N7R/+rf1P/p39b/5t3U/97Sxv/Zx7b/2MKu/9e/p//Bl3P/0L6v/76/wP/Hx8f/4+Pj/+Pj + 4//r6+v/7+/v/8/Pz/2Li4tXgICAAGdnZwBnZ2cAZ2dnAAAAAAAAAAAAAAAAAAAAAACKiooAgYGBK7i5 + uurKsp7+vI9o5ebWxv3y5dn/8+je//Tr4f/16+P/9Ong/+3czf/lzbf/48mw/8qgff/Nt6T/xMXG/9fX + 1//+/v7//Pz8//z8/P/9/f3/0dHR/YuLi1mMjIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIqK + igB8fHwetLW238+7q/+5jGXs59jJ/fPo3f/z6d//8ung//Ho3//w5dv/7N/S/9/GsP/avKH/wpVw/9TC + s//Cw8T/3Nzc//v7+//5+fn/+fn5//r6+v/R0dH9i4uLWYyMjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAioqKAGVlZQmoqam42dDJ/7SGYPzhzrz+9evi//Ts5P/07OT/8ung//Dl2//t4NT/4su2/9Sz + lP+7jmj/4dnT/7e4uP/c3Nz/6urq/+rq6v/y8vL/9vb2/9DQ0P2Li4tZjIyMAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACKiooAoKCgAJOUlGnT09P+xqaN/8umhv/z6d//9/Dq//Xu6P/z6eH/8OTZ/+3f + 0v/izLj/wpdx/8mrk//c3Nz/tra2/9/f3//g4OD/4uLi/+3t7f/y8vL/0NDQ/YuLi1mMjIwAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIqKigCIiIgAeXl5FbCwsMHh3Nj/wJh4/86qjP/t39L/9Ovj//Lo + 3//t4dT/4sy4/8SbeP+/mHn/5uHd/7e4uP/Kysr/29vb/9ra2v/c3Nz/6Ojo/+3t7f/Pz8/9i4uLWYyM + jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIuLiwCRkZEAiYmJN7u8vNji3Nj/yKmQ/72S + bv/GoH//yqaH/8Scef+8j2r/yauS/+Tg3P++vr//urq6/9bW1v/W1tb/1dXV/9fX1//j4+P/6enp/87O + zv2Li4tZjIyMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAioqKAHV1dQCVlZUAi4uLabKz + s//Y2Nj/39bP/9XCs//Ruqf/1sO0/9/X0f/X19f/s7S0/7u7u//T09P/09PT/9PT0//T09P/1NTU/9/f + 3//m5ub/zs7O/YuLi1mMjIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAioqKAI2N + jQCNjY1bycnJ/s3Nzf/FxcX/y8zN/83Oz//Jysv/wcHC/8LCwv/S0tL/3Nzc/9vb2//b29v/29vb/9vb + 2//c3Nz/4+Pj/+rq6v/Pz8/+ioqKWoyMjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAi4uLAImJiUa4uLjx0tLS/s3Nzf3Gxsb9w8PD/cXFxf3Ly8v90dHR/dHR0f3Q0ND90NDQ/dDQ + 0P3Q0ND90NDQ/dDQ0P3Q0ND90dHR/rW1tfCIiIhEioqKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACIiIgAh4eHCImJiUWMjIxajY2NWo6OjlqOjo5ajo6OWo2NjVqMjIxajIyMWoyM + jFqMjIxajIyMWoyMjFqMjIxajIyMWoyMjFqMjIxaiYmJRIeHhweJiYkAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAImJiQCIiIgAi4uLAI6OjgCOjo4Ajo6OAI6OjgCOjo4Ajo6OAI6O + jgCOjo4Ajo6OAI6OjgCOjo4Ajo6OAI6OjgCOjo4Ajo6OAI6OjgCLi4sAiIiIAImJiQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAcAAAAPAAAAfwAAAH8AAAB/AAAAfwAAAH+AA + AB/gAAAf8AAAH/gAAB/4AAAf+AAAH/////8= + + + \ No newline at end of file diff --git a/Source/RyWeb/HttpHelper.cs b/Source/RyWeb/HttpHelper.cs new file mode 100644 index 0000000..c0cb9b8 --- /dev/null +++ b/Source/RyWeb/HttpHelper.cs @@ -0,0 +1,877 @@ +/// +/// 类说明:HttpHelper类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理 +/// 重要提示:请不要自行修改本类,如果因为你自己修改后将无法升级到新版本。如果确实有什么问题请到官方网站提建议, +/// 我们一定会及时修改 +/// 编码日期:2011-09-20 +/// 编 码 人:苏飞 +/// 联系方式:361983679 +/// 官方网址:http://www.sufeinet.com/thread-3-1-1.html +/// 修改日期:2017-01-16 +/// 版 本 号:1.8 +/// +using System; +using System.Collections.Generic; +using System.Text; +using System.Net; +using System.IO; +using System.Text.RegularExpressions; +using System.IO.Compression; +using System.Security.Cryptography.X509Certificates; +using System.Net.Security; +using System.Linq; +using System.Net.Cache; + +namespace DotNet4.Utilities +{ + /// + /// Http连接操作帮助类 + /// + public class HttpHelper + { + #region 预定义方变量 + //默认的编码 + private Encoding encoding = Encoding.Default; + //Post数据编码 + private Encoding postencoding = Encoding.Default; + //HttpWebRequest对象用来发起请求 + private HttpWebRequest request = null; + //获取影响流的数据对象 + private HttpWebResponse response = null; + //设置本地的出口ip和端口 + private IPEndPoint _IPEndPoint = null; + #endregion + + #region Public + public string GetSmallCookie(string strcookie) + { + string result; + if (string.IsNullOrWhiteSpace(strcookie)) + { + result = string.Empty; + } + else + { + List list = new List(); + string[] array = strcookie.ToString().Split(new string[] + { + ",", + ";" + }, StringSplitOptions.RemoveEmptyEntries); + string[] array2 = array; + for (int i = 0; i < array2.Length; i++) + { + string text = array2[i]; + string text2 = text.ToLower().Trim().Replace("\r\n", string.Empty).Replace("\n", string.Empty); + if (!string.IsNullOrWhiteSpace(text2)) + { + if (text2.Contains("=")) + { + if (!text2.Contains("path=")) + { + if (!text2.Contains("expires=")) + { + if (!text2.Contains("domain=")) + { + if (!list.Contains(text)) + { + list.Add(string.Format("{0};", text)); + } + } + } + } + } + } + } + result = string.Join(";", list); + } + return result; + } + /// + /// 根据相传入的数据,得到相应页面数据 + /// + /// 参数类对象 + /// 返回HttpResult类型 + public HttpResult GetHtml(HttpItem item) + { + //返回参数 + HttpResult result = new HttpResult(); + try + { + //准备参数 + SetRequest(item); + } + catch (Exception ex) + { + //配置参数时出错 + return new HttpResult() { Cookie = string.Empty, Header = null, Html = ex.Message, StatusDescription = "配置参数时出错:" + ex.Message }; + } + try + { + //请求数据 + using (response = (HttpWebResponse)request.GetResponse()) + { + GetData(item, result); + } + } + catch (WebException ex) + { + if (ex.Response != null) + { + using (response = (HttpWebResponse)ex.Response) + { + GetData(item, result); + } + } + else + { + result.Html = ex.Message; + } + } + catch (Exception ex) + { + result.Html = ex.Message; + } + if (item.IsToLower) result.Html = result.Html.ToLower(); + return result; + } + #endregion + + #region GetData + + /// + /// 获取数据的并解析的方法 + /// + /// + /// + private void GetData(HttpItem item, HttpResult result) + { + if (response == null) + { + return; + } + #region base + //获取StatusCode + result.StatusCode = response.StatusCode; + //获取StatusDescription + result.StatusDescription = response.StatusDescription; + //获取Headers + result.Header = response.Headers; + //获取最后访问的URl + result.ResponseUri = response.ResponseUri.ToString(); + //获取CookieCollection + if (response.Cookies != null) result.CookieCollection = response.Cookies; + //获取set-cookie + if (response.Headers["set-cookie"] != null) result.Cookie = response.Headers["set-cookie"]; + #endregion + + #region byte + //处理网页Byte + byte[] ResponseByte = GetByte(); + #endregion + + #region Html + if (ResponseByte != null && ResponseByte.Length > 0) + { + //设置编码 + SetEncoding(item, result, ResponseByte); + //得到返回的HTML + result.Html = encoding.GetString(ResponseByte); + } + else + { + //没有返回任何Html代码 + result.Html = string.Empty; + } + #endregion + } + /// + /// 设置编码 + /// + /// HttpItem + /// HttpResult + /// byte[] + private void SetEncoding(HttpItem item, HttpResult result, byte[] ResponseByte) + { + //是否返回Byte类型数据 + if (item.ResultType == ResultType.Byte) result.ResultByte = ResponseByte; + //从这里开始我们要无视编码了 + if (encoding == null) + { + string c = string.Empty; + var charset= result.Header["Content-Type"]; + if (charset != null) + { + int pos = charset.IndexOf("charset=", StringComparison.OrdinalIgnoreCase); + if(pos>0) + { + c = charset.Substring(pos + "charset=".Length); + } + //System.IO.File.AppendAllText(@"G:\程序开发源码\QO流程管理\Bin\Debug\1122.txt", charset+" "+ c); + } + if(c== string.Empty) + { + Match meta = Regex.Match(Encoding.Default.GetString(ResponseByte), " 0) + { + c = meta.Groups[1].Value.ToLower().Trim(); + } + } + if (c == string.Empty) + { + if(item.URL.ToLower().Replace("https://","").IndexOf("http://api.dataoke.com/index.php")==0) + { + c = "gb2312"; + } + } + if (c.Length > 2) + { + try + { + encoding = Encoding.GetEncoding(c.Replace("\"", string.Empty).Replace("'", "").Replace(";", "").Replace("iso-8859-1", "gbk").Trim()); + } + catch + { + if (string.IsNullOrEmpty(response.CharacterSet)) + { + encoding = Encoding.UTF8; + } + else + { + encoding = Encoding.GetEncoding(response.CharacterSet); + } + } + } + else + { + if (string.IsNullOrEmpty(response.CharacterSet)) + { + encoding = Encoding.UTF8; + } + else + { + encoding = Encoding.GetEncoding(response.CharacterSet); + } + } + } + } + /// + /// 提取网页Byte + /// + /// + private byte[] GetByte() + { + byte[] ResponseByte = null; + using (MemoryStream _stream = new MemoryStream()) + { + //GZIIP处理 + if (response.ContentEncoding != null && response.ContentEncoding.Equals("gzip", StringComparison.InvariantCultureIgnoreCase)) + { + //开始读取流并设置编码方式 + new GZipStream(response.GetResponseStream(), CompressionMode.Decompress).CopyTo(_stream, 10240); + } + else + { + //开始读取流并设置编码方式 + response.GetResponseStream().CopyTo(_stream, 10240); + } + //获取Byte + ResponseByte = _stream.ToArray(); + } + return ResponseByte; + } + + + #endregion + + #region SetRequest + + /// + /// 为请求准备参数 + /// + ///参数列表 + private void SetRequest(HttpItem item) + { + + // 验证证书 + SetCer(item); + if (item.IPEndPoint != null) + { + _IPEndPoint = item.IPEndPoint; + //设置本地的出口ip和端口 + request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback); + } + //设置Header参数 + if (item.Header != null && item.Header.Count > 0) foreach (string key in item.Header.AllKeys) + { + request.Headers.Add(key, item.Header[key]); + } + // 设置代理 + SetProxy(item); + if (item.ProtocolVersion != null) request.ProtocolVersion = item.ProtocolVersion; + request.ServicePoint.Expect100Continue = item.Expect100Continue; + //请求方式Get或者Post + request.Method = item.Method; + request.Timeout = item.Timeout; + request.KeepAlive = item.KeepAlive; + request.ReadWriteTimeout = item.ReadWriteTimeout; + if (!string.IsNullOrWhiteSpace(item.Host)) + { + request.Host = item.Host; + } + if (item.IfModifiedSince != null) request.IfModifiedSince = Convert.ToDateTime(item.IfModifiedSince); + //Accept + request.Accept = item.Accept; + //ContentType返回类型 + request.ContentType = item.ContentType; + //UserAgent客户端的访问类型,包括浏览器版本和操作系统信息 + request.UserAgent = item.UserAgent; + // 编码 + encoding = item.Encoding; + //设置安全凭证 + request.Credentials = item.ICredentials; + //设置Cookie + SetCookie(item); + //来源地址 + request.Referer = item.Referer; + //是否执行跳转功能 + request.AllowAutoRedirect = item.Allowautoredirect; + if (item.MaximumAutomaticRedirections > 0) + { + request.MaximumAutomaticRedirections = item.MaximumAutomaticRedirections; + } + //设置Post数据 + SetPostData(item); + //设置最大连接 + if (item.Connectionlimit > 0) request.ServicePoint.ConnectionLimit = item.Connectionlimit; + } + /// + /// 设置证书 + /// + /// + private void SetCer(HttpItem item) + { + if (!string.IsNullOrWhiteSpace(item.CerPath)) + { + //这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。 + ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); + //初始化对像,并设置请求的URL地址 + request = (HttpWebRequest)WebRequest.Create(item.URL); + SetCerList(item); + //将证书添加到请求里 + request.ClientCertificates.Add(new X509Certificate(item.CerPath)); + } + else + { + //初始化对像,并设置请求的URL地址 + request = (HttpWebRequest)WebRequest.Create(item.URL); + SetCerList(item); + } + } + /// + /// 设置多个证书 + /// + /// + private void SetCerList(HttpItem item) + { + if (item.ClentCertificates != null && item.ClentCertificates.Count > 0) + { + foreach (X509Certificate c in item.ClentCertificates) + { + request.ClientCertificates.Add(c); + } + } + } + /// + /// 设置Cookie + /// + /// Http参数 + private void SetCookie(HttpItem item) + { + if (!string.IsNullOrEmpty(item.Cookie)) request.Headers[HttpRequestHeader.Cookie] = item.Cookie; + //设置CookieCollection + if (item.ResultCookieType == ResultCookieType.CookieCollection) + { + request.CookieContainer = new CookieContainer(); + if (item.CookieCollection != null && item.CookieCollection.Count > 0) + request.CookieContainer.Add(item.CookieCollection); + } + } + /// + /// 设置Post数据 + /// + /// Http参数 + private void SetPostData(HttpItem item) + { + //验证在得到结果时是否有传入数据 + if (!request.Method.Trim().ToLower().Contains("get")) + { + if (item.PostEncoding != null) + { + postencoding = item.PostEncoding; + } + byte[] buffer = null; + //写入Byte类型 + if (item.PostDataType == PostDataType.Byte && item.PostdataByte != null && item.PostdataByte.Length > 0) + { + //验证在得到结果时是否有传入数据 + buffer = item.PostdataByte; + }//写入文件 + else if (item.PostDataType == PostDataType.FilePath && !string.IsNullOrWhiteSpace(item.Postdata)) + { + StreamReader r = new StreamReader(item.Postdata, postencoding); + buffer = postencoding.GetBytes(r.ReadToEnd()); + r.Close(); + } //写入字符串 + else if (!string.IsNullOrWhiteSpace(item.Postdata)) + { + buffer = postencoding.GetBytes(item.Postdata); + } + if (buffer != null) + { + request.ContentLength = buffer.Length; + request.GetRequestStream().Write(buffer, 0, buffer.Length); + } + else + { + request.ContentLength = 0; + } + } + } + /// + /// 设置代理 + /// + /// 参数对象 + private void SetProxy(HttpItem item) + { + bool isIeProxy = false; + if (!string.IsNullOrWhiteSpace(item.ProxyIp)) + { + isIeProxy = item.ProxyIp.ToLower().Contains("ieproxy"); + } + if (!string.IsNullOrWhiteSpace(item.ProxyIp) && !isIeProxy) + { + //设置代理服务器 + if (item.ProxyIp.Contains(":")) + { + string[] plist = item.ProxyIp.Split(':'); + WebProxy myProxy = new WebProxy(plist[0].Trim(), Convert.ToInt32(plist[1].Trim())) + { + //建议连接 + Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd) + }; + //给当前请求对象 + request.Proxy = myProxy; + } + else + { + WebProxy myProxy = new WebProxy(item.ProxyIp, false) + { + //建议连接 + Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd) + }; + //给当前请求对象 + request.Proxy = myProxy; + } + } + else if (isIeProxy) + { + //设置为IE代理 + } + else + { + request.Proxy = item.WebProxy; + } + } + + + #endregion + + #region private main + /// + /// 回调验证证书问题 + /// + /// 流对象 + /// 证书 + /// X509Chain + /// SslPolicyErrors + /// bool + private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; } + + /// + /// 通过设置这个属性,可以在发出连接的时候绑定客户端发出连接所使用的IP地址。 + /// + /// + /// + /// + /// + private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount) + { + return _IPEndPoint;//端口号 + } + #endregion + } + + #region public calss + /// + /// Http请求参考类 + /// + public class HttpItem + { + /// + /// 请求URL必须填写 + /// + public string URL { get; set; } + string _Method = "GET"; + /// + /// 请求方式默认为GET方式,当为POST方式时必须设置Postdata的值 + /// + public string Method + { + get { return _Method; } + set { _Method = value; } + } + int _Timeout = 100000; + /// + /// 默认请求超时时间 + /// + public int Timeout + { + get { return _Timeout; } + set { _Timeout = value; } + } + int _ReadWriteTimeout = 30000; + /// + /// 默认写入Post数据超时间 + /// + public int ReadWriteTimeout + { + get { return _ReadWriteTimeout; } + set { _ReadWriteTimeout = value; } + } + /// + /// 设置Host的标头信息 + /// + public string Host { get; set; } + Boolean _KeepAlive = true; + /// + /// 获取或设置一个值,该值指示是否与 Internet 资源建立持久性连接默认为true。 + /// + public Boolean KeepAlive + { + get { return _KeepAlive; } + set { _KeepAlive = value; } + } + string _Accept = "text/html, application/xhtml+xml, */*"; + /// + /// 请求标头值 默认为text/html, application/xhtml+xml, */* + /// + public string Accept + { + get { return _Accept; } + set { _Accept = value; } + } + string _ContentType = "text/html"; + /// + /// 请求返回类型默认 text/html + /// + public string ContentType + { + get { return _ContentType; } + set { _ContentType = value; } + } + string _UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"; + /// + /// 客户端访问信息默认Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) + /// + public string UserAgent + { + get { return _UserAgent; } + set { _UserAgent = value; } + } + /// + /// 返回数据编码默认为NUll,可以自动识别,一般为utf-8,gbk,gb2312 + /// + public Encoding Encoding { get; set; } + private PostDataType _PostDataType = PostDataType.String; + /// + /// Post的数据类型 + /// + public PostDataType PostDataType + { + get { return _PostDataType; } + set { _PostDataType = value; } + } + /// + /// Post请求时要发送的字符串Post数据 + /// + public string Postdata { get; set; } + /// + /// Post请求时要发送的Byte类型的Post数据 + /// + public byte[] PostdataByte { get; set; } + /// + /// Cookie对象集合 + /// + public CookieCollection CookieCollection { get; set; } + /// + /// 请求时的Cookie + /// + public string Cookie { get; set; } + /// + /// 来源地址,上次访问地址 + /// + public string Referer { get; set; } + /// + /// 证书绝对路径 + /// + public string CerPath { get; set; } + /// + /// 设置代理对象,不想使用IE默认配置就设置为Null,而且不要设置ProxyIp + /// + public WebProxy WebProxy { get; set; } + private Boolean isToLower = false; + /// + /// 是否设置为全文小写,默认为不转化 + /// + public Boolean IsToLower + { + get { return isToLower; } + set { isToLower = value; } + } + private Boolean allowautoredirect = false; + /// + /// 支持跳转页面,查询结果将是跳转后的页面,默认是不跳转 + /// + public Boolean Allowautoredirect + { + get { return allowautoredirect; } + set { allowautoredirect = value; } + } + private int connectionlimit = 1024; + /// + /// 最大连接数 + /// + public int Connectionlimit + { + get { return connectionlimit; } + set { connectionlimit = value; } + } + /// + /// 代理Proxy 服务器用户名 + /// + public string ProxyUserName { get; set; } + /// + /// 代理 服务器密码 + /// + public string ProxyPwd { get; set; } + /// + /// 代理 服务IP,如果要使用IE代理就设置为ieproxy + /// + public string ProxyIp { get; set; } + private ResultType resulttype = ResultType.String; + /// + /// 设置返回类型String和Byte + /// + public ResultType ResultType + { + get { return resulttype; } + set { resulttype = value; } + } + private WebHeaderCollection header = new WebHeaderCollection(); + /// + /// header对象 + /// + public WebHeaderCollection Header + { + get { return header; } + set { header = value; } + } + /// + // 获取或设置用于请求的 HTTP 版本。返回结果:用于请求的 HTTP 版本。默认为 System.Net.HttpVersion.Version11。 + /// + public Version ProtocolVersion { get; set; } + private Boolean _expect100continue = false; + /// + /// 获取或设置一个 System.Boolean 值,该值确定是否使用 100-Continue 行为。如果 POST 请求需要 100-Continue 响应,则为 true;否则为 false。默认值为 true。 + /// + public Boolean Expect100Continue + { + get { return _expect100continue; } + set { _expect100continue = value; } + } + /// + /// 设置509证书集合 + /// + public X509CertificateCollection ClentCertificates { get; set; } + /// + /// 设置或获取Post参数编码,默认的为Default编码 + /// + public Encoding PostEncoding { get; set; } + private ResultCookieType _ResultCookieType = ResultCookieType.String; + /// + /// Cookie返回类型,默认的是只返回字符串类型 + /// + public ResultCookieType ResultCookieType + { + get { return _ResultCookieType; } + set { _ResultCookieType = value; } + } + private ICredentials _ICredentials = CredentialCache.DefaultCredentials; + /// + /// 获取或设置请求的身份验证信息。 + /// + public ICredentials ICredentials + { + get { return _ICredentials; } + set { _ICredentials = value; } + } + /// + /// 设置请求将跟随的重定向的最大数目 + /// + public int MaximumAutomaticRedirections { get; set; } + private DateTime? _IfModifiedSince = null; + /// + /// 获取和设置IfModifiedSince,默认为当前日期和时间 + /// + public DateTime? IfModifiedSince + { + get { return _IfModifiedSince; } + set { _IfModifiedSince = value; } + } + #region ip-port + private IPEndPoint _IPEndPoint = null; + /// + /// 设置本地的出口ip和端口 + /// ] + /// + ///item.IPEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.1"),80); + /// + public IPEndPoint IPEndPoint + { + get { return _IPEndPoint; } + set { _IPEndPoint = value; } + } + #endregion + } + /// + /// Http返回参数类 + /// + public class HttpResult + { + /// + /// Http请求返回的Cookie + /// + public string Cookie { get; set; } + /// + /// Cookie对象集合 + /// + public CookieCollection CookieCollection { get; set; } + private string _html = string.Empty; + /// + /// 返回的String类型数据 只有ResultType.String时才返回数据,其它情况为空 + /// + public string Html + { + get { return _html; } + set { _html = value; } + } + /// + /// 返回的Byte数组 只有ResultType.Byte时才返回数据,其它情况为空 + /// + public byte[] ResultByte { get; set; } + /// + /// header对象 + /// + public WebHeaderCollection Header { get; set; } + /// + /// 返回状态说明 + /// + public string StatusDescription { get; set; } + /// + /// 返回状态码,默认为OK + /// + public HttpStatusCode StatusCode { get; set; } + /// + /// 最后访问的URl + /// + public string ResponseUri { get; set; } + /// + /// 获取重定向的URl + /// + public string RedirectUrl + { + get + { + try + { + if (Header != null && Header.Count > 0) + { + if (Header.AllKeys.Any(k => k.ToLower().Contains("location"))) + { + string baseurl = Header["location"].ToString().Trim(); + string locationurl = baseurl.ToLower(); + if (!string.IsNullOrWhiteSpace(locationurl)) + { + bool b = locationurl.StartsWith("http://") || locationurl.StartsWith("https://"); + if (!b) + { + baseurl = new Uri(new Uri(ResponseUri), baseurl).AbsoluteUri; + } + } + return baseurl; + } + } + } + catch { } + return string.Empty; + } + } + } + /// + /// 返回类型 + /// + public enum ResultType + { + /// + /// 表示只返回字符串 只有Html有数据 + /// + String, + /// + /// 表示返回字符串和字节流 ResultByte和Html都有数据返回 + /// + Byte + } + /// + /// Post的数据格式默认为string + /// + public enum PostDataType + { + /// + /// 字符串类型,这时编码Encoding可不设置 + /// + String, + /// + /// Byte类型,需要设置PostdataByte参数的值编码Encoding可设置为空 + /// + Byte, + /// + /// 传文件,Postdata必须设置为文件的绝对路径,必须设置Encoding的值 + /// + FilePath + } + /// + /// Cookie返回类型 + /// + public enum ResultCookieType + { + /// + /// 只返回字符串类型的Cookie + /// + String, + /// + /// CookieCollection格式的Cookie集合同时也返回String类型的cookie + /// + CookieCollection + } + #endregion +} \ No newline at end of file diff --git a/Source/RyWeb/LiveUpdate_EventArgs.cs b/Source/RyWeb/LiveUpdate_EventArgs.cs new file mode 100644 index 0000000..271e0fc --- /dev/null +++ b/Source/RyWeb/LiveUpdate_EventArgs.cs @@ -0,0 +1,65 @@ +using System; + +namespace LiveUpdate +{ + public struct UpdateInfo + { + public string UpdateType;//更新类型 + public string UpdateDes_Url;//更新描述Url + public string UpdateDes;//更新描述 + public string UpdateVer;//版本 + public string UpdateDate;//更新日期 + public string UpdateUrl;//更新地址 + public string sxSettingXML;//升级程序要使用的设置xml + } + public struct UpdateErrorInfo + { + public string ErrorStr;//错误字符串 + public int ErrorId;//错误id + } + public sealed class LiveUpdateEventArgs : EventArgs + { + private long _CurrentFileSize; + private string _CurrentFileName; + private string _CurrentUrl; + private double _CurrProgress; + private bool _IsCompleted; + private string _CurrentStatus; + public LiveUpdateEventArgs() + { + _CurrentFileSize = 0; + _CurrentUrl = ""; + _IsCompleted = false; + } + public long CurrentFileSize + { + get { return _CurrentFileSize; } + set { _CurrentFileSize = value; } + } + public string CurrentFileName + { + get { return _CurrentFileName; } + set { _CurrentFileName = value; } + } + public string CurrentUrl + { + get { return _CurrentUrl; } + set { _CurrentUrl = value; } + } + public double CurrProgress + { + get { return _CurrProgress; } + set { _CurrProgress = value; } + } + public bool IsCompleted + { + get { return _IsCompleted; } + set { _IsCompleted = value; } + } + public string CurrentStatus + { + get { return _CurrentStatus; } + set { _CurrentStatus = value; } + } + } +} diff --git a/Source/RyWeb/Properties/AssemblyInfo.cs b/Source/RyWeb/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..962c177 --- /dev/null +++ b/Source/RyWeb/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("RyWeb")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RyWeb")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("e64caa45-23b4-4417-b353-192beb675825")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.2011.1601")] +[assembly: AssemblyFileVersion("1.0.2011.1601")] \ No newline at end of file diff --git a/Source/RyWeb/QuickWeb.cs b/Source/RyWeb/QuickWeb.cs new file mode 100644 index 0000000..fd4ecfe --- /dev/null +++ b/Source/RyWeb/QuickWeb.cs @@ -0,0 +1,263 @@ +using DotNet4.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RyWeb +{ + public class QuickWeb + { + /// + /// 以post方式获取网页源码 + /// + /// + /// + /// + /// + public HttpResult Post(string url, string post, string cookie) + { + return Post(url, post, "application/x-www-form-urlencoded", cookie); + } + /// + /// 以post方式提交json内容 + /// + /// + /// + /// + /// + public HttpResult PostJson(string url, string post, string cookie) + { + return Post(url, post, "application/json", cookie); + } + /// + /// 以post方式提交json内容 + /// + /// + /// + /// + public HttpResult PostJson(string url, string post) + { + return Post(url, post, "application/json", ""); + } + /// + /// 以post方式获取网页源码 + /// + /// + /// + /// + /// + /// + public HttpResult Post(string url, string post,string ContentType, string cookie) + { + try + { + HttpHelper t = new HttpHelper(); + HttpItem m = new HttpItem() + { + URL = url, + Postdata = post, + ContentType = ContentType, + Method = "POST", + Timeout = Timeout, + ReadWriteTimeout = Timeout, + UserAgent = UserAgent + }; + if (cookie.Length > 0) + { + m.Cookie = cookie; + } + HttpResult r = t.GetHtml(m); + return r; + } + catch + { + HttpResult r = new HttpResult(); + return r; + } + } + /// + /// 以post方式获取网页源码 + /// + /// + /// + /// + public HttpResult Post(string url, string post) + { + return Post(url, post, cookie); + } + /// + /// 获取网址对应的文件大小 + /// + /// + /// + public long GetSize(string url) + { + try + { + HttpHelper t = new HttpHelper(); + HttpItem m = new HttpItem() + { + URL = url, + Method = "HEAD", + Allowautoredirect = true, + Cookie = cookie, + Timeout = Timeout, + ReadWriteTimeout = Timeout, + UserAgent=UserAgent + }; + HttpResult r = t.GetHtml(m); + if (r.StatusCode == System.Net.HttpStatusCode.OK) + { + return Convert.ToInt64(r.Header["Content-Length"]); + } + else if (r.StatusCode == System.Net.HttpStatusCode.MethodNotAllowed) + { + System.Net.ServicePointManager.DefaultConnectionLimit = 512; + System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url); + System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse(); + long totalBytes = response.ContentLength; + return totalBytes; + } + else + return 0; + } + catch + { + return 0; + } + } + public string UserAgent + { + get; set; + } = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"; + /// + /// 获取网页源码 + /// + /// + /// + /// + public HttpResult Get(string url, string cookie) + { + try + { + HttpHelper t = new HttpHelper(); + HttpItem m = new HttpItem() + { + URL = url, + ContentType= "application/x-www-form-urlencoded" + }; + if (cookie.Length>0) + { + m.Cookie = cookie; + } + m.UserAgent = UserAgent; + m.Allowautoredirect = true; + m.Timeout = Timeout; + m.ReadWriteTimeout = Timeout; + HttpResult r = t.GetHtml(m); + return r; + } + catch + { + HttpResult r = new HttpResult() + { + Html = "" + }; + return r; + } + } + /// + /// 获取网页源码 + /// + /// + /// + /// + public HttpResult Get(string url,Encoding encoding, string cookie) + { + try + { + HttpHelper t = new HttpHelper(); + HttpItem m = new HttpItem() + { + URL = url + }; + if (cookie != "") + { + m.Cookie = cookie; + } + m.UserAgent = UserAgent; + m.Encoding = encoding; + m.Allowautoredirect = true; + m.Timeout = Timeout; + m.ReadWriteTimeout = Timeout; + HttpResult r = t.GetHtml(m); + return r; + } + catch + { + HttpResult r = new HttpResult() + { + Html = "" + }; + return r; + } + } + /// + /// 获取网页源码 + /// + /// + /// + public HttpResult Get(string url) + { + return Get(url, cookie); + } + public string Cookie + { + get { return cookie; } + } + public int Timeout { get; set; } = 10000; + public string UrlEncode(string str, Encoding encode) + { + StringBuilder sb = new StringBuilder(); + byte[] byStr = encode.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str) + for (int i = 0; i < byStr.Length; i++) + { + var item = Convert.ToString(byStr[i], 16); + if (item.Length == 1) { item = "0" + item; } + sb.Append(@"%" + item); + } + return (sb.ToString()); + } + private string cookie = ""; + /// + /// 将相对网址转换成绝对网址 + /// + /// 相对网址 + /// 当前页面地址 + /// 转换后的绝对网址 + public string ConvertUrl(string rel_url, string cur_pageUrl) + { + if (rel_url == "") + { + return cur_pageUrl; + } + try + { + string _rel_url = rel_url; + if (_rel_url.IndexOf("//")==0) + { + int iPos = cur_pageUrl.IndexOf(":"); + if (iPos > 0) + { + _rel_url = cur_pageUrl.Substring(0,iPos)+ ":" + _rel_url; + } + } + Uri baseUri = new Uri(cur_pageUrl); // + Uri absoluteUri = new Uri(baseUri, _rel_url);//相对绝对路径都在这里转 这里的urlx ="../test.html" + return absoluteUri.AbsoluteUri.Replace("&", "&");// + } + catch { return rel_url; } + } + } +} diff --git a/Source/RyWeb/RyWeb.csproj b/Source/RyWeb/RyWeb.csproj new file mode 100644 index 0000000..7e1095f --- /dev/null +++ b/Source/RyWeb/RyWeb.csproj @@ -0,0 +1,49 @@ + + + + + Debug + AnyCPU + {E64CAA45-23B4-4417-B353-192BEB675825} + Library + Properties + RyWeb + RyWeb + v4.0 + 512 + + + true + full + false + ..\..\Bin\Debug\CommonControls\.NET4\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\Bin\Release\CommonControls\.NET4\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/RyWeb/RyWeb.csproj.user b/Source/RyWeb/RyWeb.csproj.user new file mode 100644 index 0000000..9b86104 --- /dev/null +++ b/Source/RyWeb/RyWeb.csproj.user @@ -0,0 +1,6 @@ + + + + ShowAllFiles + + \ No newline at end of file diff --git a/Source/RyWeb/WebDecode.cs b/Source/RyWeb/WebDecode.cs new file mode 100644 index 0000000..fcf2887 --- /dev/null +++ b/Source/RyWeb/WebDecode.cs @@ -0,0 +1,437 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RyWeb +{ + public class UrlDecoder + { + // Fields + private int _bufferSize; + private byte[] _byteBuffer; + private char[] _charBuffer; + private Encoding _encoding; + private int _numBytes; + private int _numChars; + internal UrlDecoder(int bufferSize, Encoding encoding) + { + this._bufferSize = bufferSize; + this._encoding = encoding; + this._charBuffer = new char[bufferSize]; + } + internal void AddByte(byte b) + { + if (this._byteBuffer == null) + { + this._byteBuffer = new byte[this._bufferSize]; + } + this._byteBuffer[this._numBytes++] = b; + } + internal void AddChar(char ch) + { + if (this._numBytes > 0) + { + this.FlushBytes(); + } + this._charBuffer[this._numChars++] = ch; + } + internal string GetString() + { + if (this._numBytes > 0) + { + this.FlushBytes(); + } + if (this._numChars > 0) + { + return new string(this._charBuffer, 0, this._numChars); + } + return string.Empty; + } + private void FlushBytes() + { + if (this._numBytes > 0) + { + this._numChars += this._encoding.GetChars(this._byteBuffer, 0, this._numBytes, this._charBuffer, this._numChars); + this._numBytes = 0; + } + } + } + public class WebDecode + { + private static int HexToInt(char h) + { + if ((h >= '0') && (h <= '9')) + { + return (h - '0'); + } + if ((h >= 'a') && (h <= 'f')) + { + return ((h - 'a') + 10); + } + if ((h >= 'A') && (h <= 'F')) + { + return ((h - 'A') + 10); + } + return -1; + } + private static string UrlDecodeStringFromStringInternal(string s, Encoding e) + { + int length = s.Length; + UrlDecoder decoder = new UrlDecoder(length, e); + for (int i = 0; i < length; i++) + { + char ch = s[i]; + if (ch == '+') + { + ch = ' '; + } + else if ((ch == '%') && (i < (length - 2))) + { + if ((s[i + 1] == 'u') && (i < (length - 5))) + { + int num3 = HexToInt(s[i + 2]); + int num4 = HexToInt(s[i + 3]); + int num5 = HexToInt(s[i + 4]); + int num6 = HexToInt(s[i + 5]); + if (((num3 < 0) || (num4 < 0)) || ((num5 < 0) || (num6 < 0))) + { + goto Label_0106; + } + ch = (char)((((num3 << 12) | (num4 << 8)) | (num5 << 4)) | num6); + i += 5; + decoder.AddChar(ch); + continue; + } + int num7 = HexToInt(s[i + 1]); + int num8 = HexToInt(s[i + 2]); + if ((num7 >= 0) && (num8 >= 0)) + { + byte b = (byte)((num7 << 4) | num8); + i += 2; + decoder.AddByte(b); + continue; + } + } + Label_0106: + if ((ch & 0xff80) == 0) + { + decoder.AddByte((byte)ch); + } + else + { + decoder.AddChar(ch); + } + } + return decoder.GetString(); + } + /// + /// url解密 + /// + /// + /// + /// + public static string UrlDecode(string str, Encoding e) + { + if (str == null) + { + return null; + } + return UrlDecodeStringFromStringInternal(str, e); + } + /// + /// url解密,按UTF8方式解密 + /// + /// + /// + public static string UrlDecode(string s) + { + Encoding e = Encoding.UTF8; + return UrlDecode(s, e); + } + /// + /// Url加密 + /// + /// + /// + /// + public static string UrlEncode(string str, Encoding encode) + { + StringBuilder sb = new StringBuilder(); + byte[] byStr = encode.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str) + for (int i = 0; i < byStr.Length; i++) + { + sb.Append(@"%" + Convert.ToString(byStr[i], 16)); + } + return (sb.ToString().Replace(" ", "+")); + } + /// + /// Url加密,按UTF8方式加密 + /// + /// + /// + public static string UrlEncode(string str) + { + return UrlEncodeNonAscii(str,Encoding.UTF8).Replace(" ", "+"); + } + private static int HexDigit(char c) + { + if ((c >= '0') && (c <= '9')) + { + return (c - '0'); + } + if ((c >= 'A') && (c <= 'F')) + { + return (('\n' + c) - 0x41); + } + if ((c >= 'a') && (c <= 'f')) + { + return (('\n' + c) - 0x61); + } + return -1; + } + /// + /// 解密 + /// + /// + /// + public static string Unescape(object @string) + { + string str = Convert.ToString(@string); + int length = str.Length; + StringBuilder builder = new StringBuilder(length); + int num6 = -1; + while (++num6 < length) + { + char ch = str[num6]; + if (ch == '%') + { + int num2; + int num3; + int num4; + int num5; + if (((((num6 + 5) < length) && (str[num6 + 1] == 'u')) && (((num2 = HexDigit(str[num6 + 2])) != -1) && ((num3 = HexDigit(str[num6 + 3])) != -1))) && (((num4 = HexDigit(str[num6 + 4])) != -1) && ((num5 = HexDigit(str[num6 + 5])) != -1))) + { + ch = (char)((((num2 << 12) + (num3 << 8)) + (num4 << 4)) + num5); + num6 += 5; + } + else if ((((num6 + 2) < length) && ((num2 = HexDigit(str[num6 + 1])) != -1)) && ((num3 = HexDigit(str[num6 + 2])) != -1)) + { + ch = (char)((num2 << 4) + num3); + num6 += 2; + } + } + builder.Append(ch); + } + return builder.ToString(); + } + /// + /// 加密 + /// + /// + /// + public static string Escape(object @string) + { + string str = Convert.ToString(@string); + string str2 = "0123456789ABCDEF"; + int length = str.Length; + StringBuilder builder = new StringBuilder(length * 2); + int num3 = -1; + while (++num3 < length) + { + char ch = str[num3]; + int num2 = ch; + if ((((0x41 > num2) || (num2 > 90)) && ((0x61 > num2) || (num2 > 0x7a))) && ((0x30 > num2) || (num2 > 0x39))) + { + switch (ch) + { + case '@': + case '*': + case '_': + case '+': + case '-': + case '.': + case '/': + goto Label_0125; + } + builder.Append('%'); + if (num2 < 0x100) + { + builder.Append(str2[num2 / 0x10]); + ch = str2[num2 % 0x10]; + } + else + { + builder.Append('u'); + builder.Append(str2[(num2 >> 12) % 0x10]); + builder.Append(str2[(num2 >> 8) % 0x10]); + builder.Append(str2[(num2 >> 4) % 0x10]); + ch = str2[num2 % 0x10]; + } + } + Label_0125: + builder.Append(ch); + } + return builder.ToString(); + } + private static bool ValidateUrlEncodingParameters(byte[] bytes, int offset, int count) + { + if ((bytes == null) && (count == 0)) + { + return false; + } + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if ((offset < 0) || (offset > bytes.Length)) + { + throw new ArgumentOutOfRangeException("offset"); + } + if ((count < 0) || ((offset + count) > bytes.Length)) + { + throw new ArgumentOutOfRangeException("count"); + } + return true; + } + private static bool IsNonAsciiByte(byte b) + { + if (b < 0x7f) + { + return (b < 0x20); + } + return true; + } + public static byte[] UrlEncodeNonAscii(byte[] bytes, int offset, int count, bool alwaysCreateNewReturnValue) + { + if (!ValidateUrlEncodingParameters(bytes, offset, count)) + { + return null; + } + int num = 0; + for (int i = 0; i < count; i++) + { + if (IsNonAsciiByte(bytes[offset + i])) + { + num++; + } + } + if (!alwaysCreateNewReturnValue && (num == 0)) + { + return bytes; + } + byte[] buffer = new byte[count + (num * 2)]; + int num3 = 0; + for (int j = 0; j < count; j++) + { + byte b = bytes[offset + j]; + if (IsNonAsciiByte(b)) + { + buffer[num3++] = 0x25; + buffer[num3++] = (byte)IntToHex((b >> 4) & 15); + buffer[num3++] = (byte)IntToHex(b & 15); + } + else + { + buffer[num3++] = b; + } + } + return buffer; + } + public static string UrlEncodeNonAscii(string str, Encoding e) + { + if (string.IsNullOrEmpty(str)) + { + return str; + } + if (e == null) + { + e = Encoding.UTF8; + } + byte[] bytes = e.GetBytes(str); + byte[] buffer2 = UrlEncodeNonAscii(bytes, 0, bytes.Length, false); + return Encoding.ASCII.GetString(buffer2); + } + /// + /// url加密,Unicode + /// + /// + /// + /// + public static string UrlEncodeUnicode(string value, bool ignoreAscii) + { + if (value == null) + { + return null; + } + int length = value.Length; + StringBuilder builder = new StringBuilder(length); + for (int i = 0; i < length; i++) + { + char ch = value[i]; + if ((ch & 0xff80) == 0) + { + if (ignoreAscii || IsUrlSafeChar(ch)) + { + builder.Append(ch); + } + else if (ch == ' ') + { + builder.Append('+'); + } + else + { + builder.Append('%'); + builder.Append(IntToHex((ch >> 4) & '\x000f')); + builder.Append(IntToHex(ch & '\x000f')); + } + } + else + { + builder.Append("%u"); + builder.Append(IntToHex((ch >> 12) & '\x000f')); + builder.Append(IntToHex((ch >> 8) & '\x000f')); + builder.Append(IntToHex((ch >> 4) & '\x000f')); + builder.Append(IntToHex(ch & '\x000f')); + } + } + return builder.ToString(); + } + public static bool IsUrlSafeChar(char ch) + { + if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) || ((ch >= '0') && (ch <= '9'))) + { + return true; + } + switch (ch) + { + case '(': + case ')': + case '*': + case '-': + case '.': + case '_': + case '!': + return true; + } + return false; + } + public static char IntToHex(int n) + { + if (n <= 9) + { + return (char)(n + 0x30); + } + return (char)((n - 10) + 0x61); + } + /// + /// Html解码,将html里未转义成功的重新转义。 + /// + /// + /// + public static string ConvertHtmlInner(string str) + { + return System.Web.HttpUtility.HtmlDecode(str); + } + } +} diff --git a/Source/ryControls/Controls/ButtonEX.cs b/Source/ryControls/Controls/ButtonEX.cs new file mode 100644 index 0000000..55c905c --- /dev/null +++ b/Source/ryControls/Controls/ButtonEX.cs @@ -0,0 +1,765 @@ +using ryControls.Skin; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace ryControls +{ + /// + /// 控件的状态。 + /// + public enum ControlState + { + /// + /// 正常 + /// + Normal, + /// + /// 鼠标经过 + /// + Hover, + /// + /// 鼠标按下 + /// + Pressed, + } + /// + /// 鼠标的当前位置 + /// + public enum ButtonMousePosition + { + /// + /// + /// + None, + /// + /// + /// + Button, + /// + /// + /// + Splitebutton, + } + /// + /// 美化按钮 + /// + public class ButtonEx : Button + { + private Color _baseColor = Color.FromArgb(12, 125, 182);//基颜色 + private Color _foreColor = Color.White;//字体颜色 + private ControlState _controlState;//控件状态 + private int _imageWidth = 16; + private RoundStyle _roundStyle = RoundStyle.All;//圆角 + private int _radius = 8; //圆角半径 + /// + /// 普通按钮矩形位置 + /// + internal Rectangle ButtonRect + { + get + { + if (ShowSpliteButton) + { + return new Rectangle(0, 0, ClientRectangle.Width - SpliteButtonWidth, ClientRectangle.Height); + } + else + { + return new Rectangle(0,0,Width,Height); + } + } + } + /// + ///美化按钮 + /// + public ButtonEx() : base() + { + ForeColor = Color.White; + this.SetStyle( + ControlStyles.UserPaint | //控件自行绘制,而不使用操作系统的绘制 + ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,减少闪烁。 + ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。 + ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。 + ControlStyles.SupportsTransparentBackColor, true);//支持透明背景颜色 + } + private int _spliteButtonWidth = 18; + /// + /// 分割按钮的宽度 + /// + [DefaultValue(18)] + [Description("分割按钮的宽度")] + public int SpliteButtonWidth + { + get { return _spliteButtonWidth; } + set + { + if (_spliteButtonWidth != value) + { + _spliteButtonWidth = value; + base.Invalidate(); + } + } + } + private bool _showSpliteButton = false; + /// + /// 是否启用分割按钮 + /// + [DefaultValue(false)] + [Description("是否启用分割按钮")] + public bool ShowSpliteButton + { + get { return _showSpliteButton; } + set + { + if (_showSpliteButton != value) + { + _showSpliteButton = value; + base.Invalidate(); + } + } + } + private bool _UseDefSkin = true; + /// + ///优先使用默认皮肤 + /// + [Description("优先使用默认皮肤")] + [DefaultValue(typeof(bool), "true")] + public bool UseDefSkin + { + get + { + return _UseDefSkin; + } + set + { + _UseDefSkin = value; + base.Invalidate(); + } + } + /// + ///按钮基础背景色 + /// + [Description("按钮基础背景色")] + [DefaultValue(typeof(Color), "12, 125, 182")] + public Color BaseColor + { + get + { + if(SkinCommon.UseDefSkin && UseDefSkin) + { + return SkinCommon.ButtonSkin.BackColor; + } + return _baseColor; + } + set + { + _baseColor = value; + base.Invalidate(); + } + } + /// + ///按钮字体颜色 + /// + [Description("按钮字体颜色")] + [DefaultValue(typeof(Color), "255, 255, 255")] + public new Color ForeColor + { + get + { + if (SkinCommon.UseDefSkin && UseDefSkin) + { + return SkinCommon.ButtonSkin.ForeColor; + } + return _foreColor; + } + set + { + _foreColor = value; + base.Invalidate(); + } + } + /// + ///图片宽度,默认值为18px,最小12px + /// + [Description("图片宽度,默认值为18px,最小12px")] + [DefaultValue(16)]//默认值为18px,最小12px + public int ImageWidth + { + get { return _imageWidth; } + set + { + if (value != _imageWidth) + { + + _imageWidth = value < 12 ? 12 : value; + base.Invalidate(); + } + } + } + /// + ///圆角的位置,默认全部都是圆角 + /// + [Description("圆角的位置,默认全部都是圆角")] + [DefaultValue(typeof(RoundStyle), "1")]//默认全部都是圆角 + public RoundStyle RoundStyle + { + get { return _roundStyle; } + set + { + if (_roundStyle != value) + { + _roundStyle = value; + base.Invalidate(); + } + } + } + /// + ///设置圆角半径 + /// + [Description("圆角半径")] + [DefaultValue(8)]//设置圆角半径,默认值为8,最小值为4px + public int Radius + { + get { return _radius; } + set + { + if (_radius != value) + { + _radius = value < 4 ? 4 : value; + base.Invalidate(); + } + } + } + private bool _ColorGradient = false; + /// + /// 背景色是否渐变 + /// + [DefaultValue(false)] + [Description("背景色是否渐变")] + public bool ColorGradient + { + get { return _ColorGradient; } + set + { + if (value != _ColorGradient) + { + + _ColorGradient = value; + base.Invalidate(); + } + } + } + private int _imageHeight = 16; + /// + /// 图片高度 + /// + [DefaultValue(16)] + [Description("图片高度")] + public int ImageHeight + { + get { return _imageHeight; } + set + { + if (value != _imageHeight) + { + + _imageHeight = value < 12 ? 12 : value; + base.Invalidate(); + } + } + } + private int _imageTextSpace = 2; + /// + /// 图片与文字之间的间距 + /// + [DefaultValue(2)] + [Description("图片与文字之间的间距")] + public int ImageTextSpace + { + get { return _imageTextSpace; } + set + { + if (_imageTextSpace != value) + { + _imageTextSpace = value < 0 ? 0 : value; + base.Invalidate(); + } + } + } + private bool _pressOffset = true; + /// + /// 当鼠标按下时图片和文字是否产生偏移 + /// + [DefaultValue(true)] + [Description("当鼠标按下时图片和文字是否产生偏移")] + public bool PressOffset + { + get { return _pressOffset; } + set + { + _pressOffset = value; + } + } + internal ControlState ControlState //控件的状态 + { + get { return _controlState; } + set + { + if (_controlState != value) + { + _controlState = value; + base.Invalidate(); + } + } + } + /// + /// 鼠标进入时 + /// + /// + protected override void OnMouseEnter(EventArgs e)//鼠标进入时 + { + base.OnMouseEnter(e); + ControlState = ControlState.Hover;//正常 + } + /// + /// 鼠标离开 + /// + /// + protected override void OnMouseLeave(EventArgs e)//鼠标离开 + { + base.OnMouseLeave(e); + ControlState = ControlState.Normal;//正常 + } + /// + /// 鼠标按下 + /// + /// + protected override void OnMouseDown(MouseEventArgs e)//鼠标按下 + { + base.OnMouseDown(e); + if (e.Button == MouseButtons.Left && e.Clicks == 1)//鼠标左键且点击次数为1 + { + ControlState = ControlState.Pressed;//按下的状态 + } + } + /// + /// 鼠标弹起 + /// + /// + protected override void OnMouseUp(MouseEventArgs e)//鼠标弹起 + { + base.OnMouseUp(e); + if (e.Button == MouseButtons.Left && e.Clicks == 1) + { + if (ClientRectangle.Contains(e.Location))//控件区域包含鼠标的位置 + { + ControlState = ControlState.Hover; + } + else + { + ControlState = ControlState.Normal; + } + } + } + private ButtonMousePosition _mousePosition; + + /// + /// 鼠标当前所在位置 + /// + internal ButtonMousePosition CurrentMousePosition + { + get { return _mousePosition; } + set + { + if (_mousePosition != value) + { + _mousePosition = value; + base.Invalidate(); + } + } + } + + /// + /// 获取图像以及文字的位置 + /// + /// + /// + /// + private void CalculateRect( + out Rectangle imageRect, out Rectangle textRect, Graphics g) + { + imageRect = Rectangle.Empty; + textRect = Rectangle.Empty; + SizeF textSize = g.MeasureString(Text, Font); + if (Image == null) + { + switch (TextAlign) + { + case ContentAlignment.BottomCenter: + textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.BottomLeft: + textRect = new Rectangle(2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.BottomRight: + textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.MiddleCenter: + textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.MiddleLeft: + textRect = new Rectangle(2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.MiddleRight: + textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.TopCenter: + textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.TopLeft: + textRect = new Rectangle(2, 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.TopRight: + textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, 2, (int)textSize.Width, (int)textSize.Height); + break; + } + if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button) + { + textRect.X += 1; + textRect.Y += 1; + } + if (RightToLeft == RightToLeft.Yes) + { + textRect.X = ButtonRect.Width - textRect.Right; + } + return; + } + if (this.Text == "") + { + switch (ImageAlign) + { + case ContentAlignment.BottomCenter: + imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, Height - ImageHeight - 3, ImageWidth, ImageHeight); + break; + case ContentAlignment.BottomLeft: + imageRect = new Rectangle(2, Height - ImageHeight - 3, ImageWidth, ImageHeight); + break; + case ContentAlignment.BottomRight: + imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, Height - ImageHeight - 3, ImageWidth, ImageHeight); + break; + case ContentAlignment.MiddleCenter: + imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.MiddleLeft: + imageRect = new Rectangle(2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.MiddleRight: + imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, (Height - ImageHeight) / 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.TopCenter: + imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.TopLeft: + imageRect = new Rectangle(2, 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.TopRight: + imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, 2, ImageWidth, ImageHeight); + break; + } + if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button) + { + imageRect.X += 1; + imageRect.Y += 1; + } + if (RightToLeft == RightToLeft.Yes) + { + imageRect.X = ButtonRect.Width - imageRect.Right; + } + return; + } + switch (TextImageRelation) + { + case TextImageRelation.Overlay: + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2, + (Height - ImageHeight) / 2, + ImageWidth, + ImageHeight); + textRect = new Rectangle( + imageRect.Right + ImageTextSpace, + (Height - (int)textSize.Height) / 2, + (int)textSize.Width, + (int)textSize.Height); + break; + case TextImageRelation.ImageAboveText: + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth) / 2, + (Height - ImageHeight - (int)textSize.Height - ImageTextSpace) / 2, + ImageWidth, + ImageHeight); + textRect = new Rectangle( + (ButtonRect.Width - (int)textSize.Width) / 2, + imageRect.Bottom + ImageTextSpace, + (int)textSize.Width, + (int)textSize.Height); + break; + case TextImageRelation.ImageBeforeText: + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2, + (Height - ImageHeight) / 2, + ImageWidth, + ImageHeight); + textRect = new Rectangle( + imageRect.Right + ImageTextSpace, + (Height - (int)textSize.Height) / 2, + (int)textSize.Width, + (int)textSize.Height); + break; + case TextImageRelation.TextAboveImage: + textRect = new Rectangle( + (ButtonRect.Width - (int)textSize.Width) / 2, + (Height - (int)textSize.Height - ImageHeight - ImageTextSpace) / 2, + (int)textSize.Width, + (int)textSize.Height); + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth) / 2, + textRect.Bottom + ImageTextSpace, + ImageWidth, + ImageHeight); + break; + case TextImageRelation.TextBeforeImage: + textRect = new Rectangle( + (ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2, + (Height - (int)textSize.Height) / 2, + (int)textSize.Width, + (int)textSize.Height); + imageRect = new Rectangle( + textRect.Right + ImageTextSpace, + (Height - ImageHeight) / 2, + ImageWidth, + ImageHeight); + break; + } + if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button) + { + imageRect.X += 1; + imageRect.Y += 1; + textRect.X += 1; + textRect.Y += 1; + } + + if (RightToLeft == RightToLeft.Yes) + { + imageRect.X = ButtonRect.Width - imageRect.Right; + textRect.X = ButtonRect.Width - textRect.Right; + } + } + /// + /// + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + base.OnPaintBackground(e); + + Graphics g = e.Graphics; + //Rectangle imageRect;//图像区域 + //Rectangle textRect;//文字区域 + + this.CalculateRect(out Rectangle imageRect, out Rectangle textRect, g); + + g.SmoothingMode = SmoothingMode.AntiAlias; + + Color baseColor; + Color borderColor; + Color innerBorderColor = this.BaseColor;//Color.FromArgb(200, 255, 255, 255); ; + + if (Enabled) + { + switch (ControlState) + { + case ControlState.Hover: + baseColor = GetColor(BaseColor, 0, -35, -24, -30); + borderColor = BaseColor; + break; + case ControlState.Pressed: + baseColor = GetColor(BaseColor, 0, -35, -24, -9); + borderColor = BaseColor; + break; + default: + baseColor = BaseColor; + borderColor = BaseColor; + break; + } + } + else + { + baseColor = SystemColors.ControlDark; + borderColor = SystemColors.ControlDark; + } + + this.RenderBackgroundInternal( + g, + ClientRectangle, + baseColor, + borderColor, + innerBorderColor, + RoundStyle, + Radius, + 0.35f, + false, + true, + LinearGradientMode.Vertical); + + if (Image != null) + { + g.InterpolationMode = InterpolationMode.HighQualityBilinear; + g.DrawImage(Image, imageRect, 0, 0, Image.Width, Image.Height, GraphicsUnit.Pixel); + } + TextRenderer.DrawText(g, Text, Font, textRect, ForeColor, GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes)); + } + + + private Color GetColor(Color colorBase, int a, int r, int g, int b) + { + int a0 = colorBase.A; + int r0 = colorBase.R; + int g0 = colorBase.G; + int b0 = colorBase.B; + if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); } + if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); } + if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); } + if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); } + + return Color.FromArgb(a, r, g, b); + } + + + internal void RenderBackgroundInternal( + Graphics g, + Rectangle rect, + Color baseColor, + Color borderColor, + Color innerBorderColor, + RoundStyle style, + int roundWidth,//圆角半径 + float basePosition, + bool drawBorder, + bool drawGlass, + LinearGradientMode mode) + { + if (drawBorder)//是否画边框 + { + rect.Width--; + rect.Height--; + } + + using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode)) + { + Color[] colors = new Color[4]; + if (ColorGradient) + { + colors[0] = GetColor(baseColor, 0, 35, 24, 9); + colors[1] = GetColor(baseColor, 0, 0, 0, 0); + colors[2] = baseColor; + colors[3] = GetColor(baseColor, 0, 0, 0, 0); + } + else + { + colors[0] = baseColor; + colors[1] = baseColor; + colors[2] = baseColor; + colors[3] = baseColor; + } + ColorBlend blend = new ColorBlend() + { + Positions = new float[] { 0.0f, basePosition, basePosition, 1.0f }, + Colors = colors + }; + brush.InterpolationColors = blend; + if (style != RoundStyle.None) + { + using (GraphicsPath path = + Drawing.CreatePath(rect, roundWidth, style, false)) + { + g.FillPath(brush, path); + } + + if (baseColor.A > 80) + { + Rectangle rectTop = rect; + + if (mode == LinearGradientMode.Vertical) + { + // rectTop.Height = (int)(rectTop.Height * basePosition); + } + else + { + // rectTop.Width = (int)(rect.Width * basePosition); + } + using (GraphicsPath pathTop = Drawing.CreatePath( + rectTop, roundWidth, RoundStyle.Top, false)) + { + if (ColorGradient) + { + using (SolidBrush brushAlpha = + new SolidBrush(Color.FromArgb(80, 255, 255, 255))) + { + g.FillPath(brushAlpha, pathTop); + } + } + } + } + + } + } + } + internal static TextFormatFlags GetTextFormatFlags( + ContentAlignment alignment, + bool rightToleft) + { + TextFormatFlags flags = TextFormatFlags.WordBreak | + TextFormatFlags.SingleLine; + if (rightToleft) + { + flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right; + } + + switch (alignment) + { + case ContentAlignment.BottomCenter: + flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter; + break; + case ContentAlignment.BottomLeft: + flags |= TextFormatFlags.Bottom | TextFormatFlags.Left; + break; + case ContentAlignment.BottomRight: + flags |= TextFormatFlags.Bottom | TextFormatFlags.Right; + break; + case ContentAlignment.MiddleCenter: + flags |= TextFormatFlags.HorizontalCenter | + TextFormatFlags.VerticalCenter; + break; + case ContentAlignment.MiddleLeft: + flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left; + break; + case ContentAlignment.MiddleRight: + flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right; + break; + case ContentAlignment.TopCenter: + flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter; + break; + case ContentAlignment.TopLeft: + flags |= TextFormatFlags.Top | TextFormatFlags.Left; + break; + case ContentAlignment.TopRight: + flags |= TextFormatFlags.Top | TextFormatFlags.Right; + break; + } + return flags; + } + } +} diff --git a/Source/ryControls/Controls/ButtonImages/GlassButton.Designer.cs b/Source/ryControls/Controls/ButtonImages/GlassButton.Designer.cs new file mode 100644 index 0000000..18c9c0c --- /dev/null +++ b/Source/ryControls/Controls/ButtonImages/GlassButton.Designer.cs @@ -0,0 +1,37 @@ +namespace ButtonImages +{ + partial class GlassButton + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + //this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + } + + #endregion + } +} diff --git a/Source/ryControls/Controls/ButtonImages/GlassButton.cs b/Source/ryControls/Controls/ButtonImages/GlassButton.cs new file mode 100644 index 0000000..b80f29c --- /dev/null +++ b/Source/ryControls/Controls/ButtonImages/GlassButton.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using System.Drawing.Drawing2D; + +namespace ButtonImages +{ + #region 控件状态 + /// + /// 控件状态 + /// + public enum State + { + /// + /// 无 + /// + Normal = 0, + /// + /// 获得焦点 + /// + Focused = 1, + /// + /// 失去焦点 + /// + LostFocused = 2, + /// + /// 鼠标指针进入控件 + /// + MouseEnter = 3 + } + #endregion + /// + /// Toolbar控件 + /// + public partial class GlassButton : Control + { + #region//私有变量 + private int bmp_Left; + private const int bmp_Top = 6; + private const int bmp_Size = 48; + private bool _focused = false; + private State state = State.Normal; + /// + /// + /// + public Bitmap _BackImg = ImageObject.GetResBitmap(ryControls.SkinHelp.SkinFolder + "ButtonImages.Toolbar_Hover.png"); + + private Bitmap _bmp = null; + #endregion + + #region//构造函数 + /// + /// + /// + public GlassButton() + { + try + { + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + this.SetStyle(ControlStyles.StandardDoubleClick, false); + this.SetStyle(ControlStyles.Selectable, true); + ResizeRedraw = true; + BackColor = Color.Transparent; + ForeColor = Color.White;//初始文本颜色 + Size = new Size(80, 75);//初始大小 + Font = new Font("微软雅黑", 9, System.Drawing.FontStyle.Bold);//控件字体 + } + catch { } + } + #endregion + + #region//属性 + /// + /// 获取或设置控件显示的图片 + /// + [CategoryAttribute("扩展属性"), Description("获取或设置控件显示的图标")] + public Bitmap Bitmap + { + get { return _bmp; } + set + { + _bmp = value; + Invalidate(false); + } + } + + /// + /// 重写控件焦点属性 + /// + [CategoryAttribute("扩展属性"), Description("重写控件焦点属性")] + public new bool Focused + { + get { return _focused; } + set + { + _focused = value; + + if (_focused) + state = State.Focused; + else + state = State.LostFocused; + + Invalidate(false); + } + } + #endregion + + #region//重载事件 + /// + /// 自定义绘制 + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + Graphics g = e.Graphics; + g.SmoothingMode = SmoothingMode.HighQuality; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + + switch (state) + { + case State.Focused: + { + DrawSelected(g); + break; + } + case State.MouseEnter: + { + if (!Focused) + //g.DrawImage(Properties.Resources.enter, ClientRectangle); + ImageDrawRect.DrawRect(g, _BackImg, ClientRectangle, 1, 2); + else + DrawSelected(g); + break; + } + } + + DrawImage(g); + DrawText(g); + } + + /// + /// 焦点进入 + /// + /// + protected override void OnEnter(EventArgs e) + { + base.OnEnter(e); + Focused = true; + } + /// + /// 失去焦点 + /// + /// + protected override void OnLeave(EventArgs e) + { + base.OnLeave(e); + Focused = false; + } + + /// + /// 禁止调整大小 + /// + /// + protected override void OnResize(EventArgs e) + { + Width = 80; + Height = 75; + } + /// + /// + /// + /// + protected override void OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + state = State.MouseEnter; + Invalidate(false); + } + /// + /// + /// + /// + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + if (!Focused) + { + state = State.LostFocused; + Invalidate(false); + } + } + /// + /// 只响应单击鼠标左键事件 + /// + /// + protected override void OnClick(EventArgs e) + { + MouseEventArgs m = (MouseEventArgs)e; + if (m.Button == MouseButtons.Left) + { + base.OnClick(e); + Focus(); + } + } + #endregion + + #region//方法 + + #region//Draw + void DrawSelected(Graphics g) + { + ImageDrawRect.DrawRect(g, _BackImg, ClientRectangle, 2, 2); + } + + void DrawImage(Graphics g) + { + if (_bmp != null) + { + Bitmap bmp = ScaleZoom(_bmp); + bmp_Left = (Width - bmp.Width) / 2; + g.DrawImage(bmp, new Rectangle(bmp_Left, bmp_Top, bmp.Width, bmp.Height)); + } + } + + void DrawText(Graphics g) + { + SizeF size = g.MeasureString(Text, Font); + g.DrawString(Text, Font, new SolidBrush(ForeColor), (Width - size.Width) / 2, 55); + } + #endregion + + #region//按比例缩放图片 + /// + /// 按比例缩放图片 + /// + /// + /// + public Bitmap ScaleZoom(Bitmap bmp) + { + if (bmp != null) + { + double zoomScale; + if (bmp.Width > bmp_Size || bmp.Height > bmp_Size) + { + double imageScale = (double)bmp.Width / (double)bmp.Height; + double thisScale = 1; + + if (imageScale > thisScale) + { + zoomScale = (double)bmp_Size / (double)bmp.Width; + return BitMapZoom(bmp, bmp_Size, (int)(bmp.Height * zoomScale)); + } + else + { + zoomScale = (double)bmp_Size / (double)bmp.Height; + return BitMapZoom(bmp, (int)(bmp.Width * zoomScale), bmp_Size); + } + } + } + return bmp; + } + #endregion + + #region//缩放BitMap + /// + /// 图片缩放 + /// + /// 源图片 + /// 缩放图片的宽度 + /// 缩放图片的高度 + /// 缩放的图片 + public Bitmap BitMapZoom(Bitmap bmpSource, int bmpWidth, int bmpHeight) + { + Bitmap bmp, zoomBmp; + try + { + bmp = new Bitmap(bmpSource); + zoomBmp = new Bitmap(bmpWidth, bmpHeight); + Graphics gh = Graphics.FromImage(zoomBmp); + gh.InterpolationMode = InterpolationMode.HighQualityBicubic; + gh.DrawImage(bmp, new Rectangle(0, 0, bmpWidth, bmpHeight), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel); + + gh.Dispose(); + return zoomBmp; + } + catch + { } + finally + { + bmp = null; + zoomBmp = null; + GC.Collect(); + } + return null; + } + #endregion + + #endregion + } +} diff --git a/Source/ryControls/Controls/ButtonImages/ImageDrawRect.cs b/Source/ryControls/Controls/ButtonImages/ImageDrawRect.cs new file mode 100644 index 0000000..6dca39c --- /dev/null +++ b/Source/ryControls/Controls/ButtonImages/ImageDrawRect.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace ButtonImages +{ + class ImageDrawRect + { + /// + /// 绘图对像 + /// + /// 绘图对像 + /// 图片 + /// 绘置的图片大小、坐标 + /// 绘置的图片边界 + /// 当前状态 + /// 状态总数 + public static void DrawRect(Graphics g, Bitmap img, Rectangle r, Rectangle lr, int index, int Totalindex) + { + if (img == null) return; + Rectangle r1, r2; + int x = (index - 1) * img.Width / Totalindex; + int y = 0; + int x1 = r.Left; + int y1 = r.Top; + + if (r.Height > img.Height && r.Width <= img.Width / Totalindex) + { + r1 = new Rectangle(x, y, img.Width / Totalindex, lr.Top); + r2 = new Rectangle(x1, y1, r.Width, lr.Top); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + r1 = new Rectangle(x, y + lr.Top, img.Width / Totalindex, img.Height - lr.Top - lr.Bottom); + r2 = new Rectangle(x1, y1 + lr.Top, r.Width, r.Height - lr.Top - lr.Bottom); + if ((lr.Top + lr.Bottom) == 0) r1.Height = r1.Height - 1; + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + r1 = new Rectangle(x, y + img.Height - lr.Bottom, img.Width / Totalindex, lr.Bottom); + r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, r.Width, lr.Bottom); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + } + else + if (r.Height <= img.Height && r.Width > img.Width / Totalindex) + { + r1 = new Rectangle(x, y, lr.Left, img.Height); + r2 = new Rectangle(x1, y1, lr.Left, r.Height); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + r1 = new Rectangle(x + lr.Left, y, img.Width / Totalindex - lr.Left - lr.Right, img.Height); + r2 = new Rectangle(x1 + lr.Left, y1, r.Width - lr.Left - lr.Right, r.Height); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, img.Height); + r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, r.Height); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + } + else + if (r.Height <= img.Height && r.Width <= img.Width / Totalindex) { r1 = new Rectangle((index - 1) * img.Width / Totalindex, 0, img.Width / Totalindex, img.Height); g.DrawImage(img, new Rectangle(x1, y1, r.Width, r.Height), r1, GraphicsUnit.Pixel); } + else if (r.Height > img.Height && r.Width > img.Width / Totalindex) + { + //top-left + r1 = new Rectangle(x, y, lr.Left, lr.Top); + r2 = new Rectangle(x1, y1, lr.Left, lr.Top); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //top-bottom + r1 = new Rectangle(x, y + img.Height - lr.Bottom, lr.Left, lr.Bottom); + r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, lr.Left, lr.Bottom); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //left + r1 = new Rectangle(x, y + lr.Top, lr.Left, img.Height - lr.Top - lr.Bottom); + r2 = new Rectangle(x1, y1 + lr.Top, lr.Left, r.Height - lr.Top - lr.Bottom); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //top + r1 = new Rectangle(x + lr.Left, y, + img.Width / Totalindex - lr.Left - lr.Right, lr.Top); + r2 = new Rectangle(x1 + lr.Left, y1, + r.Width - lr.Left - lr.Right, lr.Top); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //right-top + r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, lr.Top); + r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, lr.Top); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //Right + r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + lr.Top, + lr.Right, img.Height - lr.Top - lr.Bottom); + r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + lr.Top, + lr.Right, r.Height - lr.Top - lr.Bottom); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //right-bottom + r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + img.Height - lr.Bottom, + lr.Right, lr.Bottom); + r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + r.Height - lr.Bottom, + lr.Right, lr.Bottom); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //bottom + r1 = new Rectangle(x + lr.Left, y + img.Height - lr.Bottom, + img.Width / Totalindex - lr.Left - lr.Right, lr.Bottom); + r2 = new Rectangle(x1 + lr.Left, y1 + r.Height - lr.Bottom, + r.Width - lr.Left - lr.Right, lr.Bottom); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + + //Center + r1 = new Rectangle(x + lr.Left, y + lr.Top, + img.Width / Totalindex - lr.Left - lr.Right, img.Height - lr.Top - lr.Bottom); + r2 = new Rectangle(x1 + lr.Left, y1 + lr.Top, + r.Width - lr.Left - lr.Right, r.Height - lr.Top - lr.Bottom); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + } + } + + /// + /// 绘图对像 + /// + /// 绘图对像 + /// 图片对像 + /// 绘置的图片大小、坐标 + /// 当前状态 + /// 状态总数 + public static void DrawRect(Graphics g, Bitmap img, Rectangle r, int index, int Totalindex) + { + if (img == null) return; + int width = img.Width / Totalindex; + int height = img.Height; + Rectangle r1, r2; + int x = (index - 1) * width; + int y = 0; + r1 = new Rectangle(x, y, width, height); + r2 = new Rectangle(r.Left, r.Top, r.Width, r.Height); + g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); + } + } +} diff --git a/Source/ryControls/Controls/ButtonImages/ImageObject.cs b/Source/ryControls/Controls/ButtonImages/ImageObject.cs new file mode 100644 index 0000000..d703586 --- /dev/null +++ b/Source/ryControls/Controls/ButtonImages/ImageObject.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; + +namespace ButtonImages +{ + /// + /// + /// + public class ImageObject + { + /// + /// 得到要绘置的图片对像 + /// + /// 图像在程序集中的地址 + /// + public static Bitmap GetResBitmap(string str) + { + Stream sm; + sm = FindStream("", str); + if (sm == null) return null; + return new Bitmap(sm); + } + /// + /// 得到要绘置的图片对像 + /// + /// 图像在程序集中的路径 + /// 图像在程序集中的地址 + /// + public static Bitmap GetResBitmap(string path, string str) + { + Stream sm; + sm = FindStream(path, str); + if (sm == null) return null; + return new Bitmap(sm); + } + /// + /// 获取资源图标 + /// + /// + /// + public static Icon GetResIcon(string str) + { + Stream sm; + sm = FindStream(Application.ExecutablePath, str); + if (sm == null) return null; + return new Icon(sm); + } + /// + /// 得到图程序集中的图片对像 + /// + /// 图像在程序集中的地址 + /// + private static Stream FindStream(string str) + { + Assembly assembly = Assembly.GetExecutingAssembly(); + string[] resNames = assembly.GetManifestResourceNames(); + foreach (string s in resNames) + { + if (s == str) + { + return assembly.GetManifestResourceStream(s); + } + } + return null; + } + /// + /// 得到图程序集中的图片对像 + /// + /// 图像在程序集中的路径 + /// 图像在程序集中的地址 + /// + private static Stream FindStream(string path, string str) + { + Assembly assembly = Assembly.GetExecutingAssembly(); + if (path != "" && File.Exists(path)) + { assembly = Assembly.LoadFile(path); } + string[] resNames = assembly.GetManifestResourceNames(); + foreach (string s in resNames) + { + if (s == str) + { + return assembly.GetManifestResourceStream(s); + } + } + return null; + } + } +} diff --git a/Source/ryControls/Controls/ButtonImages/Toolbar_Hover.png b/Source/ryControls/Controls/ButtonImages/Toolbar_Hover.png new file mode 100644 index 0000000..40a9af4 Binary files /dev/null and b/Source/ryControls/Controls/ButtonImages/Toolbar_Hover.png differ diff --git a/Source/ryControls/Controls/ColorLabel.cs b/Source/ryControls/Controls/ColorLabel.cs new file mode 100644 index 0000000..351ea30 --- /dev/null +++ b/Source/ryControls/Controls/ColorLabel.cs @@ -0,0 +1,265 @@ + +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Drawing; + +namespace Tom.Component +{ + /// + /// 颜色标签 + /// + public partial class ColorLabel : System.Windows.Forms.Label + { + int lineDistance = 5;//行间距 + Graphics gcs; + int iHeight = 0, height = 200; + string[] nrLine; + string[] nrLinePos; + int searchPos = 0; + int section = 1; + /// + /// 行间距 + /// + [Description("行间距")] + public int LineDistance + { + get { return lineDistance; } + set + { + lineDistance = value; + Changed(this.Font, this.Width, this.Text); + } + } + /// + /// 颜色标签 + /// + public ColorLabel() + : base() + { + //this.TextChanged += new EventHandler(LabelTx_TextChanged); + this.SizeChanged += new EventHandler(LabelTx_SizeChanged); + this.FontChanged += new EventHandler(LabelTx_FontChanged); + //this.Font = new Font(this.Font.FontFamily, this.Font.Size, GraphicsUnit.Pixel); + } + + void LabelTx_FontChanged(object sender, EventArgs e) + { + Changed(this.Font, this.Width, this.Text); + } + + void LabelTx_SizeChanged(object sender, EventArgs e) + { + Changed(this.Font, this.Width, this.Text); + + } + /// + /// 更新 + /// + public void UpdateInfo() + { + Changed(this.Font, this.Width, this.Text); + } + /// + /// 字体高度 + /// + public int FHeight + { + get { return this.Font.Height; } + } + /// + /// 控件高 + /// + protected new int Height + { + get { return height; } + set + { + height = value; + base.Height = value; + } + } + /// + /// 控件文本 + /// + public override string Text + { + get + { + return base.Text; + } + set + { + //is.Font.Size. + base.Text = value; + Changed(this.Font, this.Width, value); + } + } + /// + /// 获取过滤掉颜色的字 + /// + /// + /// + private string GetNoColorText(string value) + { + string t_str = ""; + string[] text = value.Split('|'); + for (int i = 0; i < text.Length; i++) + { + int iPos = text[i].IndexOf(":"); + string mtext = text[i]; + Color color = ForeColor; + if (iPos > 0) + { + string color_str = text[i].Substring(0, iPos); + try + { + color = ColorTranslator.FromHtml(color_str); + t_str += text[i].Substring(iPos + 1); + } + catch { } + } + } + return t_str; + } + private string[] nrColorLine; + /// + /// 改变字体 + /// + /// + /// + /// + protected void Changed(Font ft, int iWidth, string value) + { + iHeight = 0; + if (value != "") + { + if (gcs == null) + { + gcs = this.CreateGraphics(); + SizeF sf0 = gcs.MeasureString(new string('测', 20), ft); + searchPos = (int)(iWidth * 20 / sf0.Width); + } + nrLine = GetNoColorText(value).Replace("\r", "").Split("\n".ToCharArray()); + nrColorLine=value.Replace("\r", "").Split("\n".ToCharArray()); + section = nrLine.Length; + nrLinePos = new string[section]; + SizeF sf1, sf2; + string temps, tempt; + string drawstring; + int temPos, ipos; + for (int i = 0; i < section; i++) + { + ipos = 0; + temPos = searchPos; + if (searchPos >= nrLine[i].Length) + { + ipos += nrLine[i].Length; + nrLinePos[i] += "," + ipos.ToString(); + iHeight++; + continue; + } + drawstring = nrLine[i]; + nrLinePos[i] = ""; + while (drawstring.Length > searchPos) + { + bool isfind = false; + for (int j = searchPos; j < drawstring.Length; j++) + { + temps = drawstring.Substring(0, j); + tempt = drawstring.Substring(0, j + 1); + sf1 = gcs.MeasureString(temps, ft); + sf2 = gcs.MeasureString(tempt, ft); + if (sf1.Width < iWidth && sf2.Width > iWidth) + { + iHeight++; + ipos += j; + nrLinePos[i] += "," + ipos.ToString(); + isfind = true; + drawstring = drawstring.Substring(j); + break; + + } + + } + if (!isfind) + { + //drawstring = drawstring.Substring(searchPos); + //iHeight++; + break; + } + + + } + ipos += drawstring.Length; + nrLinePos[i] += "," + ipos.ToString(); + iHeight++; + + //tempLine = (int)(sf1.Width - 1) / this.Width + 1; + //iHeight += tempLine; + } + } + this.Height = iHeight * (ft.Height + lineDistance); + } + /// + /// + /// + /// + protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) + { + //base.OnPaint(e); + //if (isPaint) return; + //isPaint = true; + Graphics g = e.Graphics; + String drawString = this.Text; + Font drawFont = this.Font; + SolidBrush drawBrush = new SolidBrush(this.ForeColor); + SizeF textSize = g.MeasureString(this.Text, this.Font);//文本的矩形区域大小 + int lineCount = Convert.ToInt32(textSize.Width / this.Width) + 1;//计算行数 + int fHeight = this.Font.Height; + int htHeight = 0; + + + this.AutoSize = false; + float x = 0.0F; + //float y = 0.0F; + StringFormat drawFormat = new StringFormat(); + //int step = 1; + //bool isFirst = true; + //SizeF sf1, sf2; + //string subN, subN1; + lineCount = drawString.Length;//行数不超过总字符数目 + int i, idx, first; + string subStr, tmpStr = "", midStr = ""; + string[] idxs; + Color lastColor = ForeColor; + for (i = 0; i < section; i++) + { + first = 0; + subStr = nrLine[i]; + if (nrLinePos[i] != null) tmpStr = nrLinePos[i].TrimStart(','); + midStr = subStr.Substring(first); + if (tmpStr != "") + { + idxs = tmpStr.Split(','); + for (int j = 0; j < idxs.Length; j++) + { + idx = int.Parse(idxs[j]); + midStr = subStr.Substring(first, idx - first); + e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt32(htHeight), drawFormat); + htHeight += (fHeight + lineDistance); + first = idx; + } + //midStr = subStr.Substring(first); + } + + //e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat); + //htHeight += ( lineDistance);//fHeight + + + } + + } + } +} diff --git a/Source/ryControls/Controls/ContextMenuStripRichText.cs b/Source/ryControls/Controls/ContextMenuStripRichText.cs new file mode 100644 index 0000000..11f0ee3 --- /dev/null +++ b/Source/ryControls/Controls/ContextMenuStripRichText.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryControls.Controls +{ + public partial class ContextMenuStripRichText : ContextMenuStrip + { + /// + /// + /// + public ContextMenuStripRichText() + { + InitializeComponent(); + AddMenu("撤销", "undo").Click += Undo_Click; + AddMenu("重做", "redo").Click += Redo_Click; + AddSeparatorMenu(); + AddMenu("剪切", "cut").Click += Cut_Click; + AddMenu("复制", "copy").Click += Copy_Click; + AddMenu("粘贴", "paste").Click += Paste_Click; + AddMenu("删除", "del").Click += Del_Click; + AddMenu("全选", "selectall").Click += SelectAll_Click; + } + private void SelectAll_Click(object sender, EventArgs e) + { + if (!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + rich_txt.SelectAll(); + } + private void Undo_Click(object sender, EventArgs e) + { + if(!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + rich_txt.Undo(); + } + private void Redo_Click(object sender, EventArgs e) + { + if (!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + rich_txt.Redo(); + } + private void Cut_Click(object sender, EventArgs e) + { + if (!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + rich_txt.Cut(); + } + private void Copy_Click(object sender, EventArgs e) + { + if (!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + rich_txt.Copy(); + } + private void Paste_Click(object sender, EventArgs e) + { + if (!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + rich_txt.Paste(); + } + private void Del_Click(object sender, EventArgs e) + { + if (!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + rich_txt.SelectedText=""; + } + /// + /// 添加菜单分隔线 + /// + /// + public ToolStripSeparator AddSeparatorMenu() + { + ToolStripSeparator item = new ToolStripSeparator(); + base.Items.Add(item); + return item; + } + /// + /// 添加菜单 + /// + /// + /// + /// + public ToolStripMenuItem AddMenu(string name, string tag) + { + ToolStripMenuItem item = new ToolStripMenuItem(name) + { + Tag = tag + }; + base.Items.Add(item); + return item; + } + + private void ContextMenuStripRichText_Opening(object sender, CancelEventArgs e) + { + if (!(base.SourceControl is RichTextBox)) { return; } + var rich_txt = (RichTextBox)base.SourceControl; + for (int i = 0; i < base.Items.Count; i++) + { + var item = base.Items[i]; + if (item.Tag == null) { continue; } + switch(item.Tag.ToString()) + { + case "undo": + item.Enabled = rich_txt.CanUndo; + break; + case "redo": + item.Enabled = rich_txt.CanRedo; + break; + case "cut": + item.Enabled = (rich_txt.SelectedText != "" && !rich_txt.ReadOnly) ? true : false; + break; + case "copy": + item.Enabled = rich_txt.SelectedText != "" ? true : false; + break; + case "paste": + item.Enabled = rich_txt.CanPaste(DataFormats.GetFormat(DataFormats.Text)); + break; + case "del": + item.Enabled =(rich_txt.SelectedText != "" && !rich_txt.ReadOnly) ? true : false; + break; + case "selectall": + item.Enabled = rich_txt.SelectedText != rich_txt.Text ? true : false; + break; + } + } + } + } +} diff --git a/Source/ryControls/Controls/ContextMenuStripRichText.designer.cs b/Source/ryControls/Controls/ContextMenuStripRichText.designer.cs new file mode 100644 index 0000000..a00e621 --- /dev/null +++ b/Source/ryControls/Controls/ContextMenuStripRichText.designer.cs @@ -0,0 +1,45 @@ +namespace ryControls.Controls +{ + /// + /// + /// + partial class ContextMenuStripRichText + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // ContextMenuStripRichText + // + this.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStripRichText_Opening); + this.ResumeLayout(false); + + } + + #endregion + } +} diff --git a/Source/ryControls/Controls/ContextMenuStripRichText.resx b/Source/ryControls/Controls/ContextMenuStripRichText.resx new file mode 100644 index 0000000..e5858cc --- /dev/null +++ b/Source/ryControls/Controls/ContextMenuStripRichText.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + False + + \ No newline at end of file diff --git a/Source/ryControls/Controls/DoubleText.Designer.cs b/Source/ryControls/Controls/DoubleText.Designer.cs new file mode 100644 index 0000000..d9073b2 --- /dev/null +++ b/Source/ryControls/Controls/DoubleText.Designer.cs @@ -0,0 +1,97 @@ +namespace ryControls +{ + partial class DoubleText + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.txtInfo = new System.Windows.Forms.TextBox(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.btnSelected = new ryControls.ButtonEx(); + this.SuspendLayout(); + // + // txtInfo + // + this.txtInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtInfo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(236)))), ((int)(((byte)(239)))), ((int)(((byte)(244))))); + this.txtInfo.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.txtInfo.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.txtInfo.ForeColor = System.Drawing.Color.Black; + this.txtInfo.Location = new System.Drawing.Point(0, 0); + this.txtInfo.Name = "txtInfo"; + this.txtInfo.ReadOnly = true; + this.txtInfo.Size = new System.Drawing.Size(235, 16); + this.txtInfo.TabIndex = 0; + this.txtInfo.TabStop = false; + this.toolTip1.SetToolTip(this.txtInfo, "双击进行选择"); + this.txtInfo.DoubleClick += new System.EventHandler(this.TxtInfo_DoubleClick); + this.txtInfo.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TxtInfo_KeyDown); + // + // btnSelected + // + this.btnSelected.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.btnSelected.BaseColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(76)))), ((int)(((byte)(95))))); + this.btnSelected.Location = new System.Drawing.Point(241, 0); + this.btnSelected.Name = "btnSelected"; + this.btnSelected.Radius = 12; + this.btnSelected.RoundStyle = ryControls.RoundStyle.Right; + this.btnSelected.Size = new System.Drawing.Size(41, 23); + this.btnSelected.TabIndex = 2; + this.btnSelected.Text = "…"; + this.toolTip1.SetToolTip(this.btnSelected, "点击选择"); + this.btnSelected.UseVisualStyleBackColor = true; + this.btnSelected.Click += new System.EventHandler(this.BtnSelected_Click); + // + // DoubleText + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(236)))), ((int)(((byte)(239)))), ((int)(((byte)(244))))); + this.Controls.Add(this.btnSelected); + this.Controls.Add(this.txtInfo); + this.Name = "DoubleText"; + this.Size = new System.Drawing.Size(282, 31); + this.Load += new System.EventHandler(this.DoubleText_Load); + this.FontChanged += new System.EventHandler(this.DoubleText_FontChanged); + this.Paint += new System.Windows.Forms.PaintEventHandler(this.DoubleText_Paint); + this.Enter += new System.EventHandler(this.DoubleText_Enter); + this.Resize += new System.EventHandler(this.DoubleText_Resize); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtInfo; + private System.Windows.Forms.ToolTip toolTip1; + private ButtonEx btnSelected; + } +} diff --git a/Source/ryControls/Controls/DoubleText.cs b/Source/ryControls/Controls/DoubleText.cs new file mode 100644 index 0000000..3247efc --- /dev/null +++ b/Source/ryControls/Controls/DoubleText.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using ryControls; + +namespace ryControls +{ + /// + /// 选择文本框 + /// + [DefaultEvent("OnSelected")] + public partial class DoubleText : UserControl + { + /// + /// 选择文本框 + /// + public DoubleText() + { + InitializeComponent(); + txtInfo.Font = Font; + base.GotFocus += DoubleText_Enter; + } + private Color _baseColor = Color.FromArgb(12, 125, 182);//基颜色 + /// + ///按钮基础背景色 + /// + [Description("按钮基础背景色")] + [DefaultValue(typeof(Color), "12, 125, 182")] + public Color BaseColor + { + get { return _baseColor; } + set + { + _baseColor = value; + btnSelected.BaseColor = _baseColor; + } + } + private bool _UseDefSkin = true; + /// + ///优先使用默认皮肤 + /// + [Description("优先使用默认皮肤")] + [DefaultValue(typeof(bool), "true")] + public bool UseDefSkin + { + get + { + return _UseDefSkin; + } + set + { + _UseDefSkin = value; + btnSelected.UseDefSkin = _UseDefSkin; + base.Invalidate(); + } + } + /// + /// 选择的id + /// + public string selectId = ""; + /// + /// 选择的名称 + /// + public string SelectName + { + get { return txtInfo.Text; } + set { txtInfo.Text = value; toolTip1.SetToolTip(txtInfo, value); toolTip1.SetToolTip(this, value); } + } + /// + /// 选择的名称 + /// + public override string Text + { + get + { + return SelectName; + } + + set + { + SelectName = value; + } + } + /// + /// 字体 + /// + public override Font Font + { + get + { + return txtInfo.Font; + } + + set + { + txtInfo.Font = value; + } + } + /// + /// 重新设置大小 + /// + public void ResizeSize() + { + txtInfo.Location = new Point(3, 1); + txtInfo.Top = (Height - txtInfo.Height) / 2; + //Height = txtInfo.Height; + btnSelected.Height = Height; + btnSelected.Width = Height; + btnSelected.Location = new Point(Width- btnSelected.Width, 0); + txtInfo.Width = Width - btnSelected.Width-3; + } + /// + /// 在选择时激发 + /// + [Description("在选择时激发")] + public event EventHandler OnSelected; + private void DoubleText_Load(object sender, EventArgs e) + { + ResizeSize(); + } + + private void DoubleText_Resize(object sender, EventArgs e) + { + ResizeSize(); + } + /// + /// 点击选择 + /// + public void PerformClick() + { + btnSelected.PerformClick(); + } + private void BtnSelected_Click(object sender, EventArgs e) + { + OnSelected?.Invoke(this, new EventArgs()); + } + + private void TxtInfo_DoubleClick(object sender, EventArgs e) + { + OnSelected?.Invoke(this, new EventArgs()); + } + + private void DoubleText_FontChanged(object sender, EventArgs e) + { + txtInfo.Font = Font; + btnSelected.Font = Font; + ResizeSize(); + } + + private void DoubleText_Paint(object sender, PaintEventArgs e) + { + e.Graphics.DrawRectangle(new Pen(SkinHelp.DefalutBorderColor), new Rectangle(0, 0, this.Width - 1, this.Height - 1)); + } + + private void TxtInfo_KeyDown(object sender, KeyEventArgs e) + { + if(e.KeyCode==Keys.Enter) + { + OnSelected?.Invoke(this, new EventArgs()); + } + } + + private void DoubleText_Enter(object sender, EventArgs e) + { + txtInfo.Focus(); + txtInfo.Select(); + } + } +} diff --git a/Source/ryControls/Controls/DoubleText.resx b/Source/ryControls/Controls/DoubleText.resx new file mode 100644 index 0000000..df8339b --- /dev/null +++ b/Source/ryControls/Controls/DoubleText.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + \ No newline at end of file diff --git a/Source/ryControls/Controls/Drawing.cs b/Source/ryControls/Controls/Drawing.cs new file mode 100644 index 0000000..b9f0bf2 --- /dev/null +++ b/Source/ryControls/Controls/Drawing.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; + +namespace ryControls +{ + /// + /// 建立圆角路径的样式。 + /// + public enum RoundStyle + { + /// + /// 四个角都不是圆角。 + /// + None = 0, + /// + /// 四个角都为圆角。 + /// + All = 1, + /// + /// 左边两个角为圆角。 + /// + Left = 2, + /// + /// 右边两个角为圆角。 + /// + Right = 3, + /// + /// 上边两个角为圆角。 + /// + Top = 4, + /// + /// 下边两个角为圆角。 + /// + Bottom = 5, + /// + /// 左下角为圆角。 + /// + BottomLeft = 6, + /// + /// 右下角为圆角。 + /// + BottomRight = 7 + } + /// + /// 画图相关API + /// + public class Drawing + { + /// + /// 建立带有圆角样式的路径。 + /// + /// 用来建立路径的矩形。 + /// 圆角的大小。 + /// 圆角的样式。 + /// 是否把矩形长宽减 1,以便画出边框。 + /// 建立的路径。 + public static GraphicsPath CreatePath(Rectangle rect, int radius, RoundStyle style, bool correction) + { + GraphicsPath path = new GraphicsPath(); + int radiusCorrection = correction ? 1 : 0; + switch (style) + { + case RoundStyle.None: + path.AddRectangle(rect); + break; + case RoundStyle.All: + path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); + path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90); + path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90); + path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90); + break; + case RoundStyle.Left: + path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); + path.AddLine(rect.Right - radiusCorrection, rect.Y, rect.Right - radiusCorrection, rect.Bottom - radiusCorrection); + path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90); + break; + case RoundStyle.Right: + path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90); + path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90); + path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y); + break; + case RoundStyle.Top: + path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); + path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90); + path.AddLine(rect.Right - radiusCorrection, rect.Bottom - radiusCorrection, rect.X, rect.Bottom - radiusCorrection); + break; + case RoundStyle.Bottom: + path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90); + path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90); + path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y); + break; + case RoundStyle.BottomLeft: + path.AddArc( + rect.X, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 90, + 90); + path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y); + path.AddLine( + rect.Right - radiusCorrection, + rect.Y, + rect.Right - radiusCorrection, + rect.Bottom - radiusCorrection); + break; + case RoundStyle.BottomRight: + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 0, + 90); + path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y); + path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y); + break; + } + path.CloseFigure(); //这句很关键,缺少会没有左边线。 + return path; + } + } +} diff --git a/Source/ryControls/Controls/FormImages/borderbm.bmp b/Source/ryControls/Controls/FormImages/borderbm.bmp new file mode 100644 index 0000000..fdbb739 Binary files /dev/null and b/Source/ryControls/Controls/FormImages/borderbm.bmp differ diff --git a/Source/ryControls/Controls/FormImages/btn_close.png b/Source/ryControls/Controls/FormImages/btn_close.png new file mode 100644 index 0000000..0bfc3f2 Binary files /dev/null and b/Source/ryControls/Controls/FormImages/btn_close.png differ diff --git a/Source/ryControls/Controls/FormImages/btn_close_Hover.png b/Source/ryControls/Controls/FormImages/btn_close_Hover.png new file mode 100644 index 0000000..4087e3a Binary files /dev/null and b/Source/ryControls/Controls/FormImages/btn_close_Hover.png differ diff --git a/Source/ryControls/Controls/FormImages/btn_max.png b/Source/ryControls/Controls/FormImages/btn_max.png new file mode 100644 index 0000000..0dcbfe3 Binary files /dev/null and b/Source/ryControls/Controls/FormImages/btn_max.png differ diff --git a/Source/ryControls/Controls/FormImages/btn_max_Hover.png b/Source/ryControls/Controls/FormImages/btn_max_Hover.png new file mode 100644 index 0000000..e62a3bb Binary files /dev/null and b/Source/ryControls/Controls/FormImages/btn_max_Hover.png differ diff --git a/Source/ryControls/Controls/FormImages/btn_mini.png b/Source/ryControls/Controls/FormImages/btn_mini.png new file mode 100644 index 0000000..85fd4b9 Binary files /dev/null and b/Source/ryControls/Controls/FormImages/btn_mini.png differ diff --git a/Source/ryControls/Controls/FormImages/btn_mini_Hover.png b/Source/ryControls/Controls/FormImages/btn_mini_Hover.png new file mode 100644 index 0000000..daed723 Binary files /dev/null and b/Source/ryControls/Controls/FormImages/btn_mini_Hover.png differ diff --git a/Source/ryControls/Controls/Formbase.Designer.cs b/Source/ryControls/Controls/Formbase.Designer.cs new file mode 100644 index 0000000..ccf4752 --- /dev/null +++ b/Source/ryControls/Controls/Formbase.Designer.cs @@ -0,0 +1,262 @@ +namespace ryControls +{ + partial class Formbase + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.s_pnlWinTop = new System.Windows.Forms.Panel(); + this.s_pnlWinTitle = new System.Windows.Forms.Panel(); + this.s_lblText = new System.Windows.Forms.Label(); + this.s_pnMini = new System.Windows.Forms.Panel(); + this.s_btnmin = new System.Windows.Forms.Button(); + this.s_pnMax = new System.Windows.Forms.Panel(); + this.s_btnMax = new System.Windows.Forms.Button(); + this.s_pnClose = new System.Windows.Forms.Panel(); + this.s_btnClose = new System.Windows.Forms.Button(); + this.s_pnTopRight = new System.Windows.Forms.Panel(); + this.s_pnTopLeft = new System.Windows.Forms.Panel(); + this.s_pnlToolMenu = new System.Windows.Forms.Panel(); + this.s_pnlWinTop.SuspendLayout(); + this.s_pnlWinTitle.SuspendLayout(); + this.s_pnMini.SuspendLayout(); + this.s_pnMax.SuspendLayout(); + this.s_pnClose.SuspendLayout(); + this.s_pnlToolMenu.SuspendLayout(); + this.SuspendLayout(); + // + // s_pnlWinTop + // + this.s_pnlWinTop.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(86)))), ((int)(((byte)(177)))), ((int)(((byte)(252))))); + this.s_pnlWinTop.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.s_pnlWinTop.Controls.Add(this.s_pnlWinTitle); + this.s_pnlWinTop.Controls.Add(this.s_pnMini); + this.s_pnlWinTop.Controls.Add(this.s_pnMax); + this.s_pnlWinTop.Controls.Add(this.s_pnClose); + this.s_pnlWinTop.Controls.Add(this.s_pnTopRight); + this.s_pnlWinTop.Controls.Add(this.s_pnTopLeft); + this.s_pnlWinTop.Dock = System.Windows.Forms.DockStyle.Fill; + this.s_pnlWinTop.Location = new System.Drawing.Point(0, 0); + this.s_pnlWinTop.Name = "s_pnlWinTop"; + this.s_pnlWinTop.Size = new System.Drawing.Size(592, 34); + this.s_pnlWinTop.TabIndex = 0; + this.s_pnlWinTop.DoubleClick += new System.EventHandler(this.PnlWinTop_DoubleClick); + this.s_pnlWinTop.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseDown); + this.s_pnlWinTop.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseMove); + this.s_pnlWinTop.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseUp); + // + // s_pnlWinTitle + // + this.s_pnlWinTitle.BackColor = System.Drawing.Color.Transparent; + this.s_pnlWinTitle.Controls.Add(this.s_lblText); + this.s_pnlWinTitle.Dock = System.Windows.Forms.DockStyle.Fill; + this.s_pnlWinTitle.Location = new System.Drawing.Point(10, 0); + this.s_pnlWinTitle.Name = "s_pnlWinTitle"; + this.s_pnlWinTitle.Size = new System.Drawing.Size(478, 34); + this.s_pnlWinTitle.TabIndex = 6; + this.s_pnlWinTitle.DoubleClick += new System.EventHandler(this.PnlWinTop_DoubleClick); + this.s_pnlWinTitle.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseDown); + this.s_pnlWinTitle.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseMove); + this.s_pnlWinTitle.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseUp); + // + // s_lblText + // + this.s_lblText.AutoSize = true; + this.s_lblText.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.s_lblText.ForeColor = System.Drawing.Color.White; + this.s_lblText.Location = new System.Drawing.Point(1, 10); + this.s_lblText.Name = "s_lblText"; + this.s_lblText.Size = new System.Drawing.Size(38, 16); + this.s_lblText.TabIndex = 0; + this.s_lblText.Text = "标题1"; + this.s_lblText.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseDown); + this.s_lblText.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseMove); + this.s_lblText.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseUp); + // + // s_pnMini + // + this.s_pnMini.BackColor = System.Drawing.Color.Transparent; + this.s_pnMini.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.s_pnMini.Controls.Add(this.s_btnmin); + this.s_pnMini.Dock = System.Windows.Forms.DockStyle.Right; + this.s_pnMini.Location = new System.Drawing.Point(488, 0); + this.s_pnMini.Name = "s_pnMini"; + this.s_pnMini.Size = new System.Drawing.Size(32, 34); + this.s_pnMini.TabIndex = 4; + this.s_pnMini.Paint += new System.Windows.Forms.PaintEventHandler(this.PnMini_Paint); + // + // s_btnmin + // + this.s_btnmin.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.s_btnmin.FlatAppearance.BorderSize = 0; + this.s_btnmin.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; + this.s_btnmin.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; + this.s_btnmin.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.s_btnmin.Location = new System.Drawing.Point(3, 6); + this.s_btnmin.Name = "s_btnmin"; + this.s_btnmin.Size = new System.Drawing.Size(26, 24); + this.s_btnmin.TabIndex = 5; + this.s_btnmin.TabStop = false; + this.s_btnmin.UseVisualStyleBackColor = true; + this.s_btnmin.Click += new System.EventHandler(this.Btnmin_Click); + // + // s_pnMax + // + this.s_pnMax.BackColor = System.Drawing.Color.Transparent; + this.s_pnMax.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.s_pnMax.Controls.Add(this.s_btnMax); + this.s_pnMax.Dock = System.Windows.Forms.DockStyle.Right; + this.s_pnMax.Location = new System.Drawing.Point(520, 0); + this.s_pnMax.Name = "s_pnMax"; + this.s_pnMax.Size = new System.Drawing.Size(32, 34); + this.s_pnMax.TabIndex = 7; + // + // s_btnMax + // + this.s_btnMax.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.s_btnMax.FlatAppearance.BorderSize = 0; + this.s_btnMax.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; + this.s_btnMax.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; + this.s_btnMax.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.s_btnMax.Location = new System.Drawing.Point(3, 6); + this.s_btnMax.Name = "s_btnMax"; + this.s_btnMax.Size = new System.Drawing.Size(26, 24); + this.s_btnMax.TabIndex = 5; + this.s_btnMax.TabStop = false; + this.s_btnMax.UseVisualStyleBackColor = true; + this.s_btnMax.Click += new System.EventHandler(this.BtnMax_Click); + this.s_btnMax.MouseEnter += new System.EventHandler(this.BtnMax_MouseEnter); + this.s_btnMax.MouseLeave += new System.EventHandler(this.BtnMax_MouseLeave); + // + // s_pnClose + // + this.s_pnClose.BackColor = System.Drawing.Color.Transparent; + this.s_pnClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.s_pnClose.Controls.Add(this.s_btnClose); + this.s_pnClose.Dock = System.Windows.Forms.DockStyle.Right; + this.s_pnClose.Location = new System.Drawing.Point(552, 0); + this.s_pnClose.Name = "s_pnClose"; + this.s_pnClose.Size = new System.Drawing.Size(30, 34); + this.s_pnClose.TabIndex = 2; + // + // s_btnClose + // + this.s_btnClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.s_btnClose.FlatAppearance.BorderSize = 0; + this.s_btnClose.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; + this.s_btnClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; + this.s_btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.s_btnClose.Location = new System.Drawing.Point(3, 6); + this.s_btnClose.Name = "s_btnClose"; + this.s_btnClose.Size = new System.Drawing.Size(27, 24); + this.s_btnClose.TabIndex = 2; + this.s_btnClose.TabStop = false; + this.s_btnClose.UseVisualStyleBackColor = true; + this.s_btnClose.Click += new System.EventHandler(this.BtnClose_Click); + this.s_btnClose.MouseEnter += new System.EventHandler(this.BtnClose_MouseEnter); + this.s_btnClose.MouseLeave += new System.EventHandler(this.BtnClose_MouseLeave); + // + // s_pnTopRight + // + this.s_pnTopRight.BackColor = System.Drawing.Color.Transparent; + this.s_pnTopRight.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.s_pnTopRight.Dock = System.Windows.Forms.DockStyle.Right; + this.s_pnTopRight.Location = new System.Drawing.Point(582, 0); + this.s_pnTopRight.Name = "s_pnTopRight"; + this.s_pnTopRight.Size = new System.Drawing.Size(10, 34); + this.s_pnTopRight.TabIndex = 1; + // + // s_pnTopLeft + // + this.s_pnTopLeft.BackColor = System.Drawing.Color.Transparent; + this.s_pnTopLeft.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.s_pnTopLeft.Dock = System.Windows.Forms.DockStyle.Left; + this.s_pnTopLeft.Location = new System.Drawing.Point(0, 0); + this.s_pnTopLeft.Name = "s_pnTopLeft"; + this.s_pnTopLeft.Size = new System.Drawing.Size(10, 34); + this.s_pnTopLeft.TabIndex = 0; + // + // s_pnlToolMenu + // + this.s_pnlToolMenu.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.s_pnlToolMenu.Controls.Add(this.s_pnlWinTop); + this.s_pnlToolMenu.Dock = System.Windows.Forms.DockStyle.Top; + this.s_pnlToolMenu.Location = new System.Drawing.Point(0, 0); + this.s_pnlToolMenu.Name = "s_pnlToolMenu"; + this.s_pnlToolMenu.Size = new System.Drawing.Size(592, 34); + this.s_pnlToolMenu.TabIndex = 0; + // + // Formbase + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.BackColor = System.Drawing.Color.White; + this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.ClientSize = new System.Drawing.Size(592, 426); + this.Controls.Add(this.s_pnlToolMenu); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.KeyPreview = true; + this.Name = "Formbase"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Activated += new System.EventHandler(this.Formbase_Activated); + this.Deactivate += new System.EventHandler(this.Formbase_Deactivate); + this.Load += new System.EventHandler(this.Formbase_Load); + this.Shown += new System.EventHandler(this.Formbase_Shown); + this.ResizeEnd += new System.EventHandler(this.Formbase_ResizeEnd); + this.VisibleChanged += new System.EventHandler(this.Formbase_VisibleChanged); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Formbase_KeyDown); + this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseDown); + this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseMove); + this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PnlWinTop_MouseUp); + this.Resize += new System.EventHandler(this.Formbase_Resize); + this.s_pnlWinTop.ResumeLayout(false); + this.s_pnlWinTitle.ResumeLayout(false); + this.s_pnlWinTitle.PerformLayout(); + this.s_pnMini.ResumeLayout(false); + this.s_pnMax.ResumeLayout(false); + this.s_pnClose.ResumeLayout(false); + this.s_pnlToolMenu.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel s_pnlWinTop; + private System.Windows.Forms.Panel s_pnMini; + private System.Windows.Forms.Panel s_pnMax; + private System.Windows.Forms.Panel s_pnClose; + private System.Windows.Forms.Button s_btnClose; + private System.Windows.Forms.Panel s_pnTopRight; + private System.Windows.Forms.Panel s_pnTopLeft; + private System.Windows.Forms.Panel s_pnlToolMenu; + private System.Windows.Forms.Button s_btnMax; + private System.Windows.Forms.Button s_btnmin; + private System.Windows.Forms.Panel s_pnlWinTitle; + private System.Windows.Forms.Label s_lblText; + } +} \ No newline at end of file diff --git a/Source/ryControls/Controls/Formbase.cs b/Source/ryControls/Controls/Formbase.cs new file mode 100644 index 0000000..e61eb8d --- /dev/null +++ b/Source/ryControls/Controls/Formbase.cs @@ -0,0 +1,606 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Security.Permissions; + +namespace ryControls +{ + /// + /// 窗体皮肤 + /// + [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] + [System.Runtime.InteropServices.ComVisibleAttribute(true)] + public partial class Formbase : Form + { + string PicFolder = "ryControls.Controls.FormImages."; + /// + /// 窗体皮肤 + /// + public Formbase() + { + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. + SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲 + title = base.Text; + InitializeComponent(); + SetWinTopIcons(); + try + { + if (this.Owner != null) + { + if (this.Owner.TopMost) + { + this.TopMost = true; + } + if (UseParentIcon) + { + this.Icon = this.Owner.Icon; + } + } + } + catch { } + } + string title = ""; + /// + /// 标题属性 + /// + [Browsable(true)] + new public string Text + { + get + { + return title; + } + set + { + base.Text = value; + title = value; + s_lblText.Text = value; + } + } + bool _UseParentIcon = false; + /// + /// 是否使用父窗口的图标 + /// + [Description("是否使用父窗口的图标")] + public bool UseParentIcon + { + get + { + return _UseParentIcon; + } + set + { + _UseParentIcon = value; + } + } + /// + /// 点击最小化按钮是最小化还是隐藏 + /// + [Description("点击最小化按钮是最小化还是隐藏")] + public bool MinButtonHideAction + { + get; set; + } + /// + /// 最大化按钮 + /// + new public bool MaximizeBox + { + get + { + return base.MaximizeBox; + } + set + { + base.MaximizeBox = value; + SetWinTopIcons(); + } + } + /// + /// 最小化按钮 + /// + new public bool MinimizeBox + { + get + { + return base.MinimizeBox; + } + set + { + base.MinimizeBox = value; + SetWinTopIcons(); + } + } + bool closeBox = true; + /// + /// 标题栏关闭按钮是否显示 + /// + [Description("标题栏关闭按钮是否显示")] + public bool CloseBox + { + get + { + return closeBox; + } + set + { + closeBox = value; + SetWinTopIcons(); + } + } + bool showBackTip = true; + /// + /// 当窗口位于后台时,是否标注显示。 + /// + [Description("当窗口位于后台时,是否标注显示。")] + public bool ShowBackTip + { + get + { + return showBackTip; + } + set + { + showBackTip = value; + if (!value) + { + s_lblText.Text = title; + } + } + } + /// + /// + /// + new public FormWindowState WindowState + { + get + { + return base.WindowState; + } + set + { + if (value == FormWindowState.Maximized) + { + base.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height); + } + base.WindowState = value; + } + } + private Color m_FormTitleColor = Color.White; + /// + /// 标题栏字体颜色 + /// + [Description("标题栏字体颜色。")] + public Color FormTitleColor + { + get + { + return m_FormTitleColor; + } + set + { + m_FormTitleColor = value; + s_lblText.BackColor = value; + } + } + private Color m_FormTitleLeaveColor = Color.Gray; + /// + /// 标题栏不处于活动状态时的字体颜色 + /// + [Description("标题栏不处于活动状态时的字体颜色。")] + public Color FormTitleLeaveColor + { + get + { + return m_FormTitleLeaveColor; + } + set + { + m_FormTitleLeaveColor = value; + } + } + private Color m_FormTitleBackColor = Color.FromArgb(81, 169, 251); + /// + /// 标题栏背景颜色 + /// + [Description("标题栏背景颜色。")] + public Color FormTitleBackColor + { + get + { + return m_FormTitleBackColor; + } + set + { + m_FormTitleBackColor = value; + s_pnlWinTop.BackColor = value; + } + } + private Color m_FormTitleLeaveBackColor = Color.FromArgb(235, 238, 242); + /// + /// 标题栏不处于活动状态时的背景颜色 + /// + [Description("标题栏不处于活动状态时的背景颜色。")] + public Color FormTitleLeaveBackColor + { + get + { + return m_FormTitleLeaveBackColor; + } + set + { + m_FormTitleLeaveBackColor = value; + } + } + /// + /// 是否允许拖拉窗体边缘来改变窗体大小 + /// + [Description("是否允许拖拉窗体边缘来改变窗体大小。")] + public bool CanChangeSize + { + get + { + return canChangeSize; + } + set + { + canChangeSize = value; + } + } + private bool isMouseDown = false; + private Point FormLocation; //form的location + private Point mouseOffset; //鼠标的按下位置 + private bool canChangeSize = false; + private void PnlWinTop_MouseMove(object sender, MouseEventArgs e) + { + try + { + int _x = 0; + int _y = 0; + if (isMouseDown) + { + Point pt = Control.MousePosition; + _x = mouseOffset.X - pt.X; + _y = mouseOffset.Y - pt.Y; + + this.Location = new Point(FormLocation.X - _x, FormLocation.Y - _y); + } + } + catch (Exception) { } + } + + private void PnlWinTop_MouseUp(object sender, MouseEventArgs e) + { + isMouseDown = false; + } + + private void PnlWinTop_MouseDown(object sender, MouseEventArgs e) + { + try + { + if (e.Button == MouseButtons.Left) + { + isMouseDown = true; + FormLocation = this.Location; + mouseOffset = Control.MousePosition; + } + } + catch (Exception) { } + } + + + private void SetWinTopIcons() + { + s_pnMax.Visible = MaximizeBox; + s_pnMini.Visible = MinimizeBox; + s_pnClose.Visible = CloseBox; + //if (MaximizeBox) + //{ + // pnMax.Left = pnClose.Left - pnMax.Width; + // pnMax.Visible = true; + // pnMini.Left = pnMax.Left - pnMini.Width; + // if (MinimizeBox) + // { + // pnMini.Visible = true; + // } + // else + // { + // pnMini.Visible = false; + // } + //} + //else + //{ + // pnMax.Visible = false; + // pnMini.Left = pnClose.Left - pnMini.Width; + // if (MinimizeBox) + // { + // pnMini.Visible = true; + // } + // else + // { + // pnMini.Visible = false; + // } + //} + } + private void Btnmin_MouseEnter(object sender, EventArgs e) + { + s_btnmin.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_mini_Hover.png"); + } + + private void Btnmin_MouseLeave(object sender, EventArgs e) + { + s_btnmin.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_mini.png"); + } + + private void BtnClose_Click(object sender, EventArgs e) + { + this.Close(); + } + #region 控制改变窗体大小 + const int WM_NCHITTEST = 0x0084; + const int HTLEFT = 10; //左边界 + const int HTRIGHT = 11; //右边界 + const int HTTOP = 12; //上边界 + const int HTTOPLEFT = 13; //左上角 + const int HTTOPRIGHT = 14; //右上角 + const int HTBOTTOM = 15; //下边界 + const int HTBOTTOMLEFT = 0x10; //左下角 + const int HTBOTTOMRIGHT = 17; //右下角 + /// + /// + /// + /// + protected override void WndProc(ref Message m) + { + try + { + base.WndProc(ref m); + } + catch { } + switch (m.Msg) + { + case WM_NCHITTEST: + { + Point vPoint = new Point((int)m.LParam & 0xFFFF, + (int)m.LParam >> 16 & 0xFFFF); + vPoint = PointToClient(vPoint); + //判断:仅当当前窗体状态不是最大化时,相关鼠标事件生效 + if (this.WindowState != FormWindowState.Maximized && (CanChangeSize)) + { + #region 调整窗体 + if (vPoint.X <= 5) + { + if (vPoint.Y <= 5) + { + m.Result = (IntPtr)HTTOPLEFT; + } + else if (vPoint.Y >= ClientSize.Height - 5) + { + m.Result = (IntPtr)HTBOTTOMLEFT; + } + else + { + m.Result = (IntPtr)HTLEFT; + } + } + else if (vPoint.X >= ClientSize.Width - 5) + { + if (vPoint.Y <= 5) + { + m.Result = (IntPtr)HTTOPRIGHT; + } + else if (vPoint.Y >= ClientSize.Height - 5) + { + m.Result = (IntPtr)HTBOTTOMRIGHT; + } + else + { + m.Result = (IntPtr)HTRIGHT; + } + } + else if (vPoint.Y <= 5) + { + m.Result = (IntPtr)HTTOP; + } + else if (vPoint.Y >= ClientSize.Height - 5) + { + m.Result = (IntPtr)HTBOTTOM; + } + #endregion + } + break; + } + } + } + #endregion + private void BtnMax_Click(object sender, EventArgs e) + { + if (!MaximizeBox) { return; } + if (WindowState != FormWindowState.Maximized) + { + this.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height); + this.WindowState = FormWindowState.Maximized; + } + else + { + this.WindowState = FormWindowState.Normal; + } + } + Point init_Position = new Point(); + private void Btnmin_Click(object sender, EventArgs e) + { + if (!MinimizeBox) { return; } + init_Size = new Size(Width, Height); + if (MinButtonHideAction) { this.Hide(); } + else + { + this.WindowState = FormWindowState.Minimized; + } + + } + private Size init_Size = new Size(); + private void Formbase_Load(object sender, EventArgs e) + { + s_lblText.ForeColor = m_FormTitleColor; + s_btnMax.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_max.png"); + s_btnmin.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_mini.png"); + s_btnClose.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_close.png"); + //init_Size = new Size(Width, Height); + //init_Position = new Point(Left,Top); + if (this.Site != null && this.Site.DesignMode) + { + + } + else + { + MinimumSize = new Size(Width, Height); + } + if (this.Owner != null) + { + if (this.Owner.TopMost) + { + this.TopMost = true; + } + if (UseParentIcon) + { + this.Icon = this.Owner.Icon; + } + } + } + /// + /// 画边框 + /// + /// + protected override void OnPaintBackground(PaintEventArgs e) + { + base.OnPaintBackground(e); + try + { + ControlPaint.DrawBorder(e.Graphics, new Rectangle(0, 0, this.Width, this.Height), SkinHelp.DefalutBorderColor, ButtonBorderStyle.Solid); + } + catch { } + } + + private void PnlWinTop_DoubleClick(object sender, EventArgs e) + { + if (this.WindowState != FormWindowState.Maximized && MaximizeBox) + { + this.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height); + this.WindowState = FormWindowState.Maximized; + } + else + { + this.WindowState = FormWindowState.Normal; + } + } + + private void PnMini_Paint(object sender, PaintEventArgs e) + { + + } + + private void BtnMax_MouseLeave(object sender, EventArgs e) + { + s_btnMax.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_max.png"); + } + + private void BtnMax_MouseEnter(object sender, EventArgs e) + { + s_btnMax.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_max_Hover.png"); + } + + private void BtnClose_MouseLeave(object sender, EventArgs e) + { + s_btnClose.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_close.png"); + } + + private void BtnClose_MouseEnter(object sender, EventArgs e) + { + s_btnClose.BackgroundImage = ButtonImages.ImageObject.GetResBitmap(PicFolder + "btn_close_Hover.png"); + } + + private void Formbase_Leave(object sender, EventArgs e) + { + + } + + private void Formbase_Deactivate(object sender, EventArgs e) + { + if (Width > 100 && Height > 100) + init_Size = new Size(Width, Height); + if (Left > 0 && Top > 0) + init_Position = new Point(Left, Top); + s_pnlWinTop.BackColor = m_FormTitleLeaveBackColor; + s_lblText.ForeColor = m_FormTitleLeaveColor; + if (ShowBackTip) + { + s_lblText.Text = title + " <处于后台>"; + } + } + + private void Formbase_Activated(object sender, EventArgs e) + { + s_pnlWinTop.BackColor = m_FormTitleBackColor; + s_lblText.ForeColor = m_FormTitleColor; + s_lblText.Text = title; + Form a = this; + if (Width < 10) { Width = init_Size.Width; } + if (Height < 10) { Height = init_Size.Height; } + if (Left < 0) { Left = init_Position.X; } + if (Top < 0) { Top = init_Position.Y; } + } + + private void Formbase_Shown(object sender, EventArgs e) + { + try + { + if (this.Owner != null) + { + if (this.Owner.TopMost) + { + this.TopMost = true; + } + } + } + catch { } + } + + private void Formbase_ResizeEnd(object sender, EventArgs e) + { + + } + + private void Formbase_Resize(object sender, EventArgs e) + { + try + { + if (this.WindowState == FormWindowState.Minimized) + { + for (int i = 0; i < this.OwnedForms.Length; i++) + { + Form form = this.OwnedForms[i]; + form.WindowState = FormWindowState.Normal; + form.Visible = true; + } + } + } + catch { } + } + + private void Formbase_VisibleChanged(object sender, EventArgs e) + { + + } + + private void Formbase_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Escape) + { this.Close(); } + } + } +} diff --git a/Source/ryControls/Controls/Formbase.resx b/Source/ryControls/Controls/Formbase.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/Source/ryControls/Controls/Formbase.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/Source/ryControls/Controls/Hotkey/HotkeyTextBox.Designer.cs b/Source/ryControls/Controls/Hotkey/HotkeyTextBox.Designer.cs new file mode 100644 index 0000000..9ac80db --- /dev/null +++ b/Source/ryControls/Controls/Hotkey/HotkeyTextBox.Designer.cs @@ -0,0 +1,73 @@ +namespace ryControls +{ + partial class HotkeyTextBox + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.BtnClear = new System.Windows.Forms.Button(); + this.TxtHotKey = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // BtnClear + // + this.BtnClear.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.BtnClear.Location = new System.Drawing.Point(245, 0); + this.BtnClear.Name = "BtnClear"; + this.BtnClear.Size = new System.Drawing.Size(43, 35); + this.BtnClear.TabIndex = 1; + this.BtnClear.Text = "X"; + this.BtnClear.UseVisualStyleBackColor = true; + this.BtnClear.Click += new System.EventHandler(this.BtnClear_Click); + // + // TxtHotKey + // + this.TxtHotKey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TxtHotKey.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.TxtHotKey.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.TxtHotKey.Location = new System.Drawing.Point(3, 8); + this.TxtHotKey.Name = "TxtHotKey"; + this.TxtHotKey.Size = new System.Drawing.Size(236, 19); + this.TxtHotKey.TabIndex = 2; + // + // ctlHotkey + // + this.Controls.Add(this.TxtHotKey); + this.Controls.Add(this.BtnClear); + this.Name = "ctlHotkey"; + this.Size = new System.Drawing.Size(288, 35); + this.Paint += new System.Windows.Forms.PaintEventHandler(this.CtlHotkey_Paint); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Button BtnClear; + private System.Windows.Forms.TextBox TxtHotKey; + } +} diff --git a/Source/ryControls/Controls/Hotkey/HotkeyTextBox.cs b/Source/ryControls/Controls/Hotkey/HotkeyTextBox.cs new file mode 100644 index 0000000..cfc1421 --- /dev/null +++ b/Source/ryControls/Controls/Hotkey/HotkeyTextBox.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using SysFuns; +using ryCommon; +namespace ryControls +{ + /// + /// 热键文本框 + /// + public partial class HotkeyTextBox : UserControl + { + Keys m_Modifiers =Keys.None; + Keys m_Key =Keys.None; + /// + /// 热键文本框 + /// + public HotkeyTextBox() + { + InitializeComponent(); + //定义KeyPress事件 + //base.KeyPress += delegate(object sender, KeyPressEventArgs e) { e.Handled = true; }; + TxtHotKey.ReadOnly = true; + TxtHotKey.BackColor = Color.White; + TxtHotKey.KeyDown += TxtHotKey_KeyDown; + TxtHotKey.KeyUp += TxtHotKey_KeyUp; + TxtHotKey.Top = (Height - TxtHotKey.Height) / 2; + + base.BackColor = Color.White; + } + /// + /// 在控件大小变化时发生 + /// + /// + protected override void OnSizeChanged(EventArgs e) + { + TxtHotKey.Top = (Height - TxtHotKey.Height) / 2; + TxtHotKey.Width = Width - BtnClear.Width - 2; + BtnClear.Top = 0; + BtnClear.Left = TxtHotKey.Left + TxtHotKey.Width; + BtnClear.Height = Height; + } + private void TxtHotKey_KeyDown(object sender, KeyEventArgs e) + { + OnKeyDown(e); + } + private void TxtHotKey_KeyUp(object sender, KeyEventArgs e) + { + OnKeyUp(e); + } + //使文本属性失效掉 + /// + /// 此属性无效 + /// + [Description("此属性无效")] + public new string Text + { + get { return TxtHotKey.Text; } + set + { + LoadHotKey(value); + } + } + /// + /// 载入热键配置 + /// + /// + public void LoadHotKey(string hotkey) + { + T_Modifiers = 0; + T_Key = Keys.None; + try + { + string[] item = hotkey.Split('+'); + if (item.Length == 1 && item[0].IsInt()) + { + T_Modifiers = 0; + T_Key = (Keys)item[0].ToInt(0); + } + else if (item.Length == 2 && item[0].IsInt() && item[1].IsInt()) + { + T_Modifiers = item[0].ToInt(0); + T_Key = (Keys)item[1].ToInt(0); + } + } + catch + { + + } + UpdateText(); + } + private void UpdateText() + { + HotkeyValue xvalue = new HotkeyValue(T_Modifiers, (int)T_Key); + base.Text = xvalue.ToString(); + TxtHotKey.Text = base.Text; + TxtHotKey.SelectionLength = 0; + TxtHotKey.SelectionStart = 0; + } + /// + /// 保存热键 + /// + /// + public string SaveHotKey() + { + if(T_Key==Keys.None) + { return "0+0"; } + return T_Modifiers.ToString() + "+" + ((int)T_Key).ToString(); + } + /// + /// 是否含义热键 + /// + public bool HaveHotKey + { + get { return m_Key != Keys.None || (T_Modifiers==0 && T_Key>Keys.A && T_Key + /// 读取或设置热键 + /// + public string HotKey + { + get { return SaveHotKey(); } + set { LoadHotKey(value); } + } + /// + /// 功能键 + /// + [Description("功能键")] + public int T_Modifiers + { + get + { + int i_Keys = 0; + if ((m_Modifiers & Keys.Alt) != 0) + { i_Keys |= 1; } + if ((m_Modifiers & Keys.Control) != 0) + { i_Keys |= 2; } + if ((m_Modifiers & Keys.Shift) != 0 || (m_Modifiers & Keys.LShiftKey) != 0 || (m_Modifiers & Keys.RShiftKey) != 0) + { i_Keys |= 4; } + if ((m_Modifiers & Keys.LWin) != 0 || (m_Modifiers & Keys.RWin) != 0) + { i_Keys |= 8; } + return i_Keys; + } + set + { + m_Modifiers =Keys.None; + if ((value & 1) != 0) + { m_Modifiers |=Keys.Alt; } + if ((value & 2) != 0) + { m_Modifiers |= Keys.Control; } + if ((value & 4) != 0) + { m_Modifiers |= Keys.Shift; } + if ((value & 8) != 0) + { m_Modifiers |= Keys.LWin; } + UpdateText(); + } + } + /// + /// 热键按键 + /// + [Description("热键按键")] + public Keys T_Key + { + get + { + return m_Key; + } + set + { + m_Key = value; + UpdateText(); + } + } + //TextBox的KeyDown事件 + /// + /// KeyDown事件 + /// + /// + protected override void OnKeyDown(KeyEventArgs e) + { + //if (e.Modifiers == 0) //没有修改键 + //{ + // e.Handled = true; + // return; + //} + HotkeyValue value; + if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey || e.KeyCode == Keys.Menu || e.KeyCode == Keys.None) + {//除修改键外,没有按键 + value = new HotkeyValue(e.Modifiers, Keys.None); + } + else + { + value = new HotkeyValue(e.Modifiers, e.KeyCode); + } + m_Modifiers = value.Modifiers; + m_Key = value.KeyCode; + base.Text = value.ToString();//赋值 + TxtHotKey.Text = base.Text; + e.Handled = true; + base.OnKeyDown(e); + } + //TextBox的KeyDown事件 + /// + /// KeyDown事件 + /// + /// + protected override void OnKeyUp(KeyEventArgs e) + { + if(m_Modifiers!=Keys.None && m_Key==Keys.None) + { + m_Modifiers = Keys.None; + TxtHotKey.Text = "错误的热键"; + } + e.Handled = false; + base.OnKeyUp(e); + } + private void BtnClear_Click(object sender, EventArgs e) + { + m_Modifiers =Keys.None; + m_Key = Keys.None; + UpdateText(); + } + + private void CtlHotkey_Paint(object sender, PaintEventArgs e) + { + e.Graphics.DrawRectangle(new Pen(Color.FromArgb(213, 216, 223)), new Rectangle(0, 0, this.Width - 1, this.Height - 1)); + } + } +} diff --git a/Source/ryControls/Controls/Hotkey/HotkeyTextBox.resx b/Source/ryControls/Controls/Hotkey/HotkeyTextBox.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/ryControls/Controls/Hotkey/HotkeyTextBox.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/Source/ryControls/Controls/LabelTx.cs b/Source/ryControls/Controls/LabelTx.cs new file mode 100644 index 0000000..fbc5cf7 --- /dev/null +++ b/Source/ryControls/Controls/LabelTx.cs @@ -0,0 +1,238 @@ + +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Drawing; + +namespace ryControls +{ + /// + /// 可以改变文本行距(行间距)的Label + /// + public partial class LabelTx : System.Windows.Forms.Label + { + int lineDistance = 5;//行间距 + Graphics gcs; + int iHeight = 0, height = 200; + string[] nrLine; + string[] nrLinePos; + int searchPos = 0; + int section = 1; + /// + /// 行间距 + /// + [Description("行间距")] + public int LineDistance + { + get { return lineDistance; } + set + { + lineDistance = value; + Changed(this.Font, this.Width, this.Text); + } + } + /// + /// 可以改变文本行距(行间距)的Label + /// + public LabelTx() + : base() + { + //this.TextChanged += new EventHandler(LabelTx_TextChanged); + base.SizeChanged += new EventHandler(LabelTx_SizeChanged); + base.Resize+= new EventHandler(LabelTx_SizeChanged); + base.FontChanged += new EventHandler(LabelTx_FontChanged); + //this.Font = new Font(this.Font.FontFamily, this.Font.Size, GraphicsUnit.Pixel); + } + + void LabelTx_FontChanged(object sender, EventArgs e) + { + Changed(this.Font, this.Width, this.Text); + } + + void LabelTx_SizeChanged(object sender, EventArgs e) + { + Changed(this.Font, this.Width, this.Text); + + } + /// + /// + /// + public void UpdateInfo() + { + Changed(this.Font, this.Width, this.Text); + } + /// + /// 字体高度 + /// + public int FHeight + { + get { return this.Font.Height; } + } + /// + /// + /// + protected new int Height + { + get { return height; } + set + { + height = value; + base.Height = value; + } + } + /// + /// 文本 + /// + public override string Text + { + get + { + return base.Text; + } + set + { + //is.Font.Size. + base.Text = value; + Changed(this.Font, this.Width, value); + } + } + /// + /// + /// + /// + /// + /// + protected void Changed(Font ft, int iWidth, string value) + { + iHeight = 0; + if (value != "") + { + if (gcs == null) + { + + gcs = this.CreateGraphics(); + } + SizeF sf0 = gcs.MeasureString(new string('测', 20), ft); + searchPos = (int)(iWidth * 20 / sf0.Width); + nrLine = value.Replace("\r","").Split("\n".ToCharArray()); + section = nrLine.Length; + nrLinePos = new string[section]; + SizeF sf1, sf2; + string temps, tempt; + string drawstring; + int temPos, ipos; + for (int i = 0; i < section; i++) + { + ipos = 0; + temPos = searchPos; + if (searchPos >= nrLine[i].Length) + { + ipos += nrLine[i].Length; + nrLinePos[i] += "," + ipos.ToString(); + iHeight++; + continue; + } + drawstring = nrLine[i]; + nrLinePos[i] = ""; + while (drawstring.Length > searchPos) + { + bool isfind = false; + for (int j = searchPos; j < drawstring.Length; j++) + { + temps = drawstring.Substring(0, j); + tempt = drawstring.Substring(0, j + 1); + sf1 = gcs.MeasureString(temps, ft); + sf2 = gcs.MeasureString(tempt, ft); + if (sf1.Width < iWidth && sf2.Width > iWidth) + { + iHeight++; + ipos += j; + nrLinePos[i] += "," + ipos.ToString(); + isfind = true; + drawstring = drawstring.Substring(j); + break; + + } + + } + if (!isfind) + { + //drawstring = drawstring.Substring(searchPos); + //iHeight++; + break; + } + + + } + ipos += drawstring.Length; + nrLinePos[i] += "," + ipos.ToString(); + iHeight++; + + //tempLine = (int)(sf1.Width - 1) / this.Width + 1; + //iHeight += tempLine; + } + } + this.Height = iHeight * (ft.Height + lineDistance); + } + /// + /// + /// + /// + protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) + { + //base.OnPaint(e); + //if (isPaint) return; + //isPaint = true; + Graphics g = e.Graphics; + String drawString = this.Text; + Font drawFont = this.Font; + SolidBrush drawBrush = new SolidBrush(this.ForeColor); + SizeF textSize = g.MeasureString(this.Text, this.Font);//文本的矩形区域大小 + int lineCount = Convert.ToInt32(textSize.Width / this.Width) + 1;//计算行数 + int fHeight = this.Font.Height; + int htHeight = 0; + + + this.AutoSize = false; + float x = 0.0F; + //float y = 0.0F; + StringFormat drawFormat = new StringFormat(); + //int step = 1; + //bool isFirst = true; + //SizeF sf1, sf2; + //string subN, subN1; + lineCount = drawString.Length;//行数不超过总字符数目 + int i, idx, first; + string subStr, tmpStr = "", midStr = ""; + string[] idxs; + for (i = 0; i < section; i++) + { + first = 0; + subStr = nrLine[i]; + if (nrLinePos[i] != null) tmpStr = nrLinePos[i].TrimStart(','); + midStr = subStr.Substring(first); + if (tmpStr != "") + { + idxs = tmpStr.Split(','); + for (int j = 0; j < idxs.Length; j++) + { + + idx = int.Parse(idxs[j]); + midStr = subStr.Substring(first, idx - first); + e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt32(htHeight), drawFormat); + htHeight += (fHeight + lineDistance); + first = idx; + } + //midStr = subStr.Substring(first); + } + + //e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat); + //htHeight += ( lineDistance);//fHeight + + + } + + } + } +} diff --git a/Source/ryControls/Controls/LableX.Designer.cs b/Source/ryControls/Controls/LableX.Designer.cs new file mode 100644 index 0000000..b198bf6 --- /dev/null +++ b/Source/ryControls/Controls/LableX.Designer.cs @@ -0,0 +1,36 @@ +namespace ryControls.Controls +{ + partial class LableX + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Source/ryControls/Controls/LableX.cs b/Source/ryControls/Controls/LableX.cs new file mode 100644 index 0000000..891bc6b --- /dev/null +++ b/Source/ryControls/Controls/LableX.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Security.Permissions; +using System.Text; +using System.Windows.Forms; + +namespace ryControls.Controls +{ + /// + /// + /// + public partial class LableX : Label + { + private const int WM_LBUTTONDBLCLK = 0x203; + /// + /// + /// + /// + protected override void WndProc(ref Message m) + { + if (m.Msg == WM_LBUTTONDBLCLK) + { + string sSaved = Clipboard.GetText(); + System.Drawing.Image iSaved = Clipboard.GetImage(); + base.WndProc(ref m); + if (iSaved != null) Clipboard.SetImage(iSaved); + if (!string.IsNullOrEmpty(sSaved)) Clipboard.SetText(sSaved); + } + else + { + base.WndProc(ref m); + } + } + } +} diff --git a/Source/ryControls/Controls/ListX.cs b/Source/ryControls/Controls/ListX.cs new file mode 100644 index 0000000..37d6d9e --- /dev/null +++ b/Source/ryControls/Controls/ListX.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryCommon +{ + /// + /// 自动排列控件 + /// + public class ListX + { + Control parent = null; + private int _maxColCount = 1; + /// + /// 最大列数 + /// + public int MaxColCount + { + get { return _maxColCount>0? _maxColCount:1; } + set { _maxColCount = value; } + } + /// + /// 开始排列的坐标 + /// + public Point StartPoint{ get; private set; } = new Point(0, 0); + /// + /// 下一项的位置 + /// + public Point NowPoint { get; private set; } = new Point(0, 0); + /// + /// 下一项的右下角坐标 + /// + public Point RightBottomPoint { get; private set; } = new Point(0, 0); + /// + /// 竖向间隔像素 + /// + public int spaceY = 0; + /// + /// 横向间隔像素 + /// + public int spaceX = 0; + /// + /// 最小保留右边距,只对ReDraw2有效 + /// + public int RightSpace = 20; + /// + /// 自动排列控件构造函数 + /// + /// + public ListX(Control _parent) + { parent = _parent; } + /// + /// 自动排列控件构造函数 + /// + /// + /// + /// + public ListX(Control _parent,int x,int y) + { parent = _parent; StartPoint= new Point(x, y); NowPoint = StartPoint; RightBottomPoint = StartPoint; } + /// + /// 开始排列控件 + /// + public void ReDraw() + { + NowPoint = StartPoint; + RightBottomPoint = StartPoint; + InitAdd(true); + for (int i=0;i + /// 开始排列控件,当列数超过显示空间时,自动换行 + /// + public void ReDraw2() + { + NowPoint = StartPoint; + RightBottomPoint = StartPoint; + InitAdd(true); + int max_item_width = 0; + int max_item_height = 0; + int curCol = 0; + for (int i = 0; i < ControlList.Count; i++) + { + if(ControlList[i].Width> max_item_width) { max_item_width = ControlList[i].Width; } + if (ControlList[i].Height > max_item_height) { max_item_height = ControlList[i].Height; } + if (i == 0) + { + ControlList[i].Location = new Point(StartPoint.X, StartPoint.Y); + } + else + { + ControlList[i].Location = NowPoint; + } + if (RightBottomPoint.X < NowPoint.X + ControlList[i].Width) + { RightBottomPoint = new Point(NowPoint.X + ControlList[i].Width, RightBottomPoint.Y); } + if (RightBottomPoint.Y < NowPoint.Y + ControlList[i].Height) + { RightBottomPoint = new Point(RightBottomPoint.X, NowPoint.Y + ControlList[i].Height); } + if (curCol >= MaxColCount - 1) + { + NowPoint = new Point(StartPoint.X, NowPoint.Y + spaceY + max_item_height);//开始新的一行 + max_item_width = 0; + max_item_height = 0; + curCol = 0; + } + else + { + if (NowPoint.X + spaceX + ControlList[i].Width+ ControlList[i].Width >= parent.Width- RightSpace)//超出宽度 + { + curCol = 0; + NowPoint = new Point(StartPoint.X, NowPoint.Y + spaceY + max_item_height);//开始新的一行 + max_item_width = 0; + max_item_height = 0; + } + else + { + curCol++; + NowPoint = new Point(NowPoint.X + spaceX + ControlList[i].Width, NowPoint.Y); + } + } + } + InitAdd(false); + } + /// + /// 加入的控件列表 + /// + public List ControlList + { get;private set; } = new List(); + /// + /// 初始化添加,自动将容器设置为滚动条自动显示 + /// + /// + public void InitAdd(bool isInit) + { + if (parent is Form) + { + ((Form)parent).AutoScroll = !isInit; + } + else if (parent is Panel) + { + ((Panel)parent).AutoScroll = !isInit; + } + else if (parent is TabPage) + { + ((TabPage)parent).AutoScroll = !isInit; + } + } + /// + /// 添加控件 + /// + /// + /// + public int Add(Control ctl) + { + InitAdd(true); + ctl.Parent = parent; + int curCol = ControlList.Count % MaxColCount; + ctl.Location = NowPoint; + parent.Controls.Add(ctl); + ControlList.Add(ctl); + InitAdd(false); + if (RightBottomPoint.X< NowPoint.X+ctl.Width) + { RightBottomPoint = new Point(NowPoint.X + ctl.Width, RightBottomPoint.Y); } + if (RightBottomPoint.Y < NowPoint.Y + ctl.Height) + { RightBottomPoint = new Point(RightBottomPoint.X, NowPoint.Y + ctl.Height); } + if (curCol == MaxColCount - 1) //已经是该行最后一项 + { + NowPoint = new Point(StartPoint.X, NowPoint.Y + spaceY + ctl.Height); + } + else + { + NowPoint = new Point(NowPoint.X + spaceX + ctl.Width, NowPoint.Y); + } + return ControlList.Count; + } + /// + /// 删除控件 + /// + /// + public void Delete(int index) + { + parent.Controls.Remove(ControlList[index]); + ControlList.RemoveAt(index); + ReDraw(); + if (ControlList.Count == 0) { NowPoint = StartPoint; RightBottomPoint = StartPoint; } + } + /// + /// 删除控件 + /// + /// + public void Delete(Control ctl) + { + ControlList.Remove(ctl); + parent.Controls.Remove(ctl); + ReDraw(); + if (ControlList.Count == 0) { NowPoint = StartPoint; RightBottomPoint = StartPoint; } + } + /// + /// 清空所有控件 + /// + public void Clear() + { + parent.Controls.Clear(); + ControlList.Clear(); + NowPoint = StartPoint; + RightBottomPoint = StartPoint; + } + } +} diff --git a/Source/ryControls/Controls/MsgLink.Designer.cs b/Source/ryControls/Controls/MsgLink.Designer.cs new file mode 100644 index 0000000..fd5b015 --- /dev/null +++ b/Source/ryControls/Controls/MsgLink.Designer.cs @@ -0,0 +1,117 @@ +namespace ryControls +{ + partial class MsgLink + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.lblTitle = new System.Windows.Forms.Label(); + this.pnlContent = new System.Windows.Forms.Panel(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.打开页面ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.复制文本ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // lblTitle + // + this.lblTitle.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.lblTitle.Dock = System.Windows.Forms.DockStyle.Top; + this.lblTitle.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.lblTitle.ForeColor = System.Drawing.Color.Black; + this.lblTitle.Location = new System.Drawing.Point(0, 0); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(231, 27); + this.lblTitle.TabIndex = 1; + this.lblTitle.Text = "消息标题"; + this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // pnlContent + // + this.pnlContent.AutoScroll = true; + this.pnlContent.AutoSize = true; + this.pnlContent.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlContent.Location = new System.Drawing.Point(0, 27); + this.pnlContent.Name = "pnlContent"; + this.pnlContent.Size = new System.Drawing.Size(231, 31); + this.pnlContent.TabIndex = 2; + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.打开页面ToolStripMenuItem, + this.复制文本ToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(125, 48); + // + // 打开页面ToolStripMenuItem + // + this.打开页面ToolStripMenuItem.Name = "打开页面ToolStripMenuItem"; + this.打开页面ToolStripMenuItem.Size = new System.Drawing.Size(124, 22); + this.打开页面ToolStripMenuItem.Text = "打开页面"; + this.打开页面ToolStripMenuItem.Click += new System.EventHandler(this.打开页面ToolStripMenuItem_Click); + // + // 复制文本ToolStripMenuItem + // + this.复制文本ToolStripMenuItem.Name = "复制文本ToolStripMenuItem"; + this.复制文本ToolStripMenuItem.Size = new System.Drawing.Size(124, 22); + this.复制文本ToolStripMenuItem.Text = "复制文本"; + this.复制文本ToolStripMenuItem.Click += new System.EventHandler(this.复制文本ToolStripMenuItem_Click); + // + // timer1 + // + this.timer1.Interval = 1000; + this.timer1.Tick += new System.EventHandler(this.Timer1_Tick); + // + // MsgLink + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.pnlContent); + this.Controls.Add(this.lblTitle); + this.Name = "MsgLink"; + this.Size = new System.Drawing.Size(231, 58); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.Panel pnlContent; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem 打开页面ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 复制文本ToolStripMenuItem; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.Timer timer1; + } +} diff --git a/Source/ryControls/Controls/MsgLink.cs b/Source/ryControls/Controls/MsgLink.cs new file mode 100644 index 0000000..62d6774 --- /dev/null +++ b/Source/ryControls/Controls/MsgLink.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace ryControls +{ + /// + /// + /// + public partial class MsgLink : UserControl + { + /// + /// + /// + public MsgLink() + { + InitializeComponent(); + timer1.Enabled = true; + Clear(); + } + int _MaxItemHeight = 0; + /// + /// 最大高度 + /// + [Category("Appearance"), Description("最大高度")] + public int MaxItemHeight + { + get { return _MaxItemHeight; } + set { _MaxItemHeight = value; pnlContent.MaximumSize = new Size(10000, _MaxItemHeight); } + } + private string _title = ""; + /// + /// 标题 + /// + [Category("内容"), Description("标题")] + public string Title + { + get { return _title; } + set { if (ShowDateTime) { lblTitle.Text = value+"("+ ryControls.Pram.Pram.DateDiff(AddTime, DateTime.Now)+")"; } else { lblTitle.Text = value; } _title = value; } + } + /// + /// 是否显示时间 + /// + public bool ShowDateTime { get; set; } = false; + /// + /// 添加时间 + /// + public DateTime AddTime { get; set; } = DateTime.Now; + int iTop = 3; + /// + /// + /// + public void Clear() + { + pnlContent.Controls.Clear(); + Height = lblTitle.Height; + pnlContent.Height = 0; + iTop = 6; + } + /// + /// + /// + /// + /// + public void AddItem(string title,string url) + { + LinkLabel item = new LinkLabel(); + item.LinkClicked += new LinkLabelLinkClickedEventHandler(Item_LinkClicked); + item.Text = title; + item.ContextMenuStrip = contextMenuStrip1; + item.AutoSize = false; + item.Tag= url; + item.Top = iTop; + item.Left = 3; + item.Width = pnlContent.Width-20; + toolTip1.SetToolTip(item, title); + item.Anchor =AnchorStyles.Left | AnchorStyles.Right |AnchorStyles.Top; + //item.Height = 123; + pnlContent.Controls.Add(item); + iTop += item.Height+2; + } + + void Item_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + try + { + if (e.Button == MouseButtons.Left) + { + LinkLabel item = (LinkLabel)sender; + System.Diagnostics.Process.Start(item.Tag.ToString()); + e.Link.Visited = true; + } + } + catch { } + } + + private void 打开页面ToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + LinkLabel lnk = (LinkLabel)contextMenuStrip1.SourceControl; + System.Diagnostics.Process.Start(lnk.Tag.ToString()); + lnk.LinkVisited = true; + } + catch { } + } + + private void 复制文本ToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + LinkLabel lnk = (LinkLabel)contextMenuStrip1.SourceControl; + Clipboard.SetText(lnk.Text); + } + catch { } + } + + private void Timer1_Tick(object sender, EventArgs e) + { + if (ShowDateTime) { lblTitle.Text = _title + "(" + ryControls.Pram.Pram.DateDiff(AddTime, DateTime.Now) + ")"; } + else + { lblTitle.Text = _title; } + } + } +} diff --git a/Source/ryControls/Controls/MsgLink.resx b/Source/ryControls/Controls/MsgLink.resx new file mode 100644 index 0000000..226c673 --- /dev/null +++ b/Source/ryControls/Controls/MsgLink.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 172, 17 + + + 269, 17 + + \ No newline at end of file diff --git a/Source/ryControls/Controls/MsgUI.Designer.cs b/Source/ryControls/Controls/MsgUI.Designer.cs new file mode 100644 index 0000000..d9ae080 --- /dev/null +++ b/Source/ryControls/Controls/MsgUI.Designer.cs @@ -0,0 +1,109 @@ +namespace ryControls +{ + partial class MsgUI + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.lblTitle = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.lblText = new ryControls.LabelTx(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // lblTitle + // + this.lblTitle.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lblTitle.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))))); + this.lblTitle.ForeColor = System.Drawing.Color.White; + this.lblTitle.Location = new System.Drawing.Point(0, 0); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(218, 27); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "消息标题"; + this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.lblTitle.Click += new System.EventHandler(this.LblTitle_Click); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.AutoScroll = true; + this.panel1.AutoSize = true; + this.panel1.Controls.Add(this.lblText); + this.panel1.Location = new System.Drawing.Point(2, 30); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(213, 48); + this.panel1.TabIndex = 2; + // + // lblText + // + this.lblText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lblText.AutoEllipsis = true; + this.lblText.LineDistance = 5; + this.lblText.Location = new System.Drawing.Point(5, 6); + this.lblText.Name = "lblText"; + this.lblText.Size = new System.Drawing.Size(205, 19); + this.lblText.TabIndex = 2; + this.lblText.Text = "消息内容"; + // + // timer1 + // + this.timer1.Interval = 1000; + this.timer1.Tick += new System.EventHandler(this.Timer1_Tick); + // + // MsgUI + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScroll = true; + this.AutoSize = true; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.panel1); + this.Controls.Add(this.lblTitle); + this.Name = "MsgUI"; + this.Size = new System.Drawing.Size(218, 81); + this.Load += new System.EventHandler(this.MsgUI_Load); + this.Resize += new System.EventHandler(this.MsgUI_Resize); + this.panel1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.Panel panel1; + private ryControls.LabelTx lblText; + private System.Windows.Forms.Timer timer1; + } +} diff --git a/Source/ryControls/Controls/MsgUI.cs b/Source/ryControls/Controls/MsgUI.cs new file mode 100644 index 0000000..aba94c0 --- /dev/null +++ b/Source/ryControls/Controls/MsgUI.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace ryControls +{ + /// + /// + /// + public partial class MsgUI : UserControl + { + /// + /// + /// + public MsgUI() + { + InitializeComponent(); + lblText.UpdateInfo(); + timer1.Enabled = true; + } + int _MaxItemHeight = 0; + /// + ///最大高度 + /// + [Category("Appearance"), Description("最大高度")] + public int MaxItemHeight + { + get { return _MaxItemHeight; } + set { _MaxItemHeight = value; panel1.MaximumSize = new Size(10000, _MaxItemHeight); } + } + private string _title = ""; + /// + /// 标题 + /// + [Category("内容"), Description("标题")] + public string Title + { + get { return _title; } + set { if (ShowDateTime) { lblTitle.Text = value+"(" + ryControls.Pram.Pram.DateDiff(AddTime, DateTime.Now) + ")"; } else { lblTitle.Text = value; } _title = value; } + } + /// + /// 是否显示时间 + /// + public bool ShowDateTime { get; set; } = false; + /// + /// 添加时间 + /// + public DateTime AddTime { get; set; } = DateTime.Now; + /// + /// 内容 + /// + [Browsable(true), Category("内容"), Description("内容")] + public override string Text + { + get { return lblText.Text; } + set { lblText.Text = value; lblText.UpdateInfo(); } + } + string _url = ""; + /// + /// 网址 + /// + [Category("内容"), Description("网址")] + public string Url + { + get { return _url; } + set + { + _url = value; + if (_url != "") + { + lblTitle.Font = new Font(lblTitle.Font, FontStyle.Underline); + lblTitle.Cursor = Cursors.Hand; + } + else + { + lblTitle.Font = new Font(lblTitle.Font, FontStyle.Regular); + lblTitle.Cursor = Cursors.Default; + } + } + } + private void MsgUI_Resize(object sender, EventArgs e) + { + lblText.UpdateInfo(); + } + + private void LblTitle_Click(object sender, EventArgs e) + { + if (_url != "") + { + ryCommon.RyFiles.RunFile(_url, ""); + } + } + + private void MsgUI_Load(object sender, EventArgs e) + { + + } + + private void Timer1_Tick(object sender, EventArgs e) + { + if (ShowDateTime) { lblTitle.Text = _title + "(" + ryControls.Pram.Pram.DateDiff(AddTime, DateTime.Now) + ")"; } + else + { lblTitle.Text = _title; } + } + } +} diff --git a/Source/ryControls/Controls/MsgUI.resx b/Source/ryControls/Controls/MsgUI.resx new file mode 100644 index 0000000..d55421f --- /dev/null +++ b/Source/ryControls/Controls/MsgUI.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + \ No newline at end of file diff --git a/Source/ryControls/Controls/NativeMethods.cs b/Source/ryControls/Controls/NativeMethods.cs new file mode 100644 index 0000000..6b4c271 --- /dev/null +++ b/Source/ryControls/Controls/NativeMethods.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace ryControls.Pram +{ + /// + /// + /// + public class NativeMethods + { + internal const int WS_EX_CLIENTEDGE = 512 /*0x0200*/; + internal const int WS_EX_WINDOWEDGE = 0x0100; + internal const int WM_PAINT = 15; // 0x000f + internal const int WM_NCPAINT = 133; // 0x0085 + internal const int RGN_COPY = 5; + internal const int RGN_AND = 1; + /// + /// + /// + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + /// + /// + /// + public int left; + /// + /// + /// + public int top; + /// + /// + /// + public int right; + /// + /// + /// + public int bottom; + /// + /// + /// + /// + + public RECT(Rectangle rect) + { + this.bottom = rect.Bottom; + this.left = rect.Left; + this.right = rect.Right; + this.top = rect.Top; + } + /// + /// + /// + /// + /// + /// + /// + public RECT(int left, int top, int right, int bottom) + { + this.bottom = bottom; + this.left = left; + this.right = right; + this.top = top; + } + /// + /// + /// + /// + /// + /// + /// + /// + + public static RECT FromXYWH(int x, int y, int width, int height) + { + return new RECT(x, y, x + width, y + height); + } + /// + /// + /// + public int Width + { + get + { + return this.right - this.left; + } + } + /// + /// + /// + public int Height + { + get + { + return this.bottom - this.top; + } + } + /// + /// + /// + /// + public override /*Object*/ string ToString() + { + return String.Concat( + "Left = ", + this.left, + " Top ", + this.top, + " Right = ", + this.right, + " Bottom = ", + this.bottom); + } + /// + /// + /// + /// + + public static implicit operator Rectangle(RECT rect) + { + return Rectangle.FromLTRB(rect.left, rect.top, rect.right, rect.bottom); + } + + } + + [DllImport("user32.dll")] + internal static extern bool GetWindowRect(IntPtr hwnd, ref RECT lpRect); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal static extern IntPtr CreateRectRgn(int x1, int y1, int x2, int y2); + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal static extern IntPtr GetWindowDC(IntPtr hWnd); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal static extern IntPtr CreateCompatibleDC(IntPtr hDC); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int width, int height); + + [DllImport("gdi32", CharSet = CharSet.Auto, ExactSpelling = true)] + internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal static extern int CombineRgn(IntPtr hRgn, IntPtr hRgn1, IntPtr hRgn2, int nCombineMode); + /// + /// + /// + /// + /// + /// + /// + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + public static extern int OffsetRgn(IntPtr hrgn, int nXOffset, int nYOffset); + + [DllImport("gdi32")] + internal static extern bool DeleteObject(IntPtr hObject); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + internal static extern int SelectClipRgn(IntPtr hDC, IntPtr hRgn); + /// + /// + /// + /// + /// + /// + /// + /// + /// + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] + public static extern int ExcludeClipRect(IntPtr hdc, int nLeft, int nTop, int nRight, int nBottom); + + [DllImport("gdi32.dll")] + internal static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, Int32 dwRop); + + [DllImport("gdi32", EntryPoint = "DeleteDC", CharSet = CharSet.Auto, ExactSpelling = true)] + internal static extern bool DeleteDC(IntPtr hDC); + } + /// + /// + /// + public class Pram + { + /// + /// 计算两个日期的时间间隔,返回的是日期值+ + /// + /// 时间值,将显示在返回的值里 + /// 参照时间 + /// + public static string DateDiff(DateTime date1, DateTime referTime) + { + string dateDiff = ""; + TimeSpan ts1 = new TimeSpan(date1.Ticks); + TimeSpan ts2 = new TimeSpan(referTime.Ticks); + TimeSpan ts = ts1.Subtract(ts2).Duration(); + //显示时间 + if (ts.Days != 0) + { + int day = ts.Days; + if (day == 1) { dateDiff = "昨天 "+ date1.ToString("HH:mm:ss"); } + else if (day == 2) { dateDiff = "前天 " + date1.ToString("HH:mm:ss"); }; + } + else + { + if (ts.Hours != 0) + { + dateDiff += ts.Hours.ToString() + "小时"; + } + if (ts.Minutes != 0 || dateDiff == "") + { + dateDiff += ts.Minutes.ToString() + "分钟"; + } + if (dateDiff != "") { dateDiff += "前"; } + } + if (dateDiff == "") { dateDiff = date1.ToString("yyyy-MM-dd HH:mm:ss"); } + return dateDiff; + } + } +} diff --git a/Source/ryControls/Controls/NumericUpDownEx.Designer.cs b/Source/ryControls/Controls/NumericUpDownEx.Designer.cs new file mode 100644 index 0000000..e52a7da --- /dev/null +++ b/Source/ryControls/Controls/NumericUpDownEx.Designer.cs @@ -0,0 +1,44 @@ +namespace ryControls +{ + partial class NumericUpDownEx + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); + this.SuspendLayout(); + // + // NumericUpDownEx + // + this.BorderStyle = System.Windows.Forms.BorderStyle.None; + ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + } +} diff --git a/Source/ryControls/Controls/NumericUpDownEx.cs b/Source/ryControls/Controls/NumericUpDownEx.cs new file mode 100644 index 0000000..ad99155 --- /dev/null +++ b/Source/ryControls/Controls/NumericUpDownEx.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryControls +{ + /// + /// + /// + public partial class NumericUpDownEx : NumericUpDown + { + /// + /// + /// + public NumericUpDownEx() + { + InitializeComponent(); + } + /// + /// + /// + /// + protected override void WndProc(ref Message m) + { + base.WndProc(ref m); + //WM_PAINT = 0xf; 要求一个窗口重画自己,即Paint事件时 + //WM_CTLCOLOREDIT = 0x133;当一个编辑型控件将要被绘制时发送此消息给它的父窗口; + //通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色 + if (m.Msg == 0xf || m.Msg == 0x133) + { + IntPtr hDC = Win32.GetWindowDC(m.HWnd); + if (hDC.ToInt32() == 0) //如果取设备上下文失败则返回 + { + return; + } + + //建立Graphics对像 + Graphics g = Graphics.FromHdc(hDC); + //画边框的 + ControlPaint.DrawBorder(g, new Rectangle(0, 0, Width, Height), SkinHelp.DefalutBorderColor, ButtonBorderStyle.Solid); + //画坚线 + //ControlPaint.DrawBorder(g, new Rectangle(Width - Height, 0, Height, Height), Color.Red, ButtonBorderStyle.Solid); + //g.DrawLine(new Pen(Brushes.Blue, 2), new PointF(this.Width - this.Height, 0), new PointF(this.Width - this.Height, this.Height)); + //释放DC + Win32.ReleaseDC(m.HWnd, hDC); + } + } + } +} diff --git a/Source/ryControls/Controls/NumericUpDownEx.resx b/Source/ryControls/Controls/NumericUpDownEx.resx new file mode 100644 index 0000000..e5858cc --- /dev/null +++ b/Source/ryControls/Controls/NumericUpDownEx.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + False + + \ No newline at end of file diff --git a/Source/ryControls/Controls/ObjectListView.cs b/Source/ryControls/Controls/ObjectListView.cs new file mode 100644 index 0000000..4a706ba --- /dev/null +++ b/Source/ryControls/Controls/ObjectListView.cs @@ -0,0 +1,8194 @@ +/* + * ObjectListView - A listview to show various aspects of a collection of objects + * + * Author: Phillip Piper + * Date: 9/10/2006 11:15 AM + * + * Change log: + * 2008-07-23 JPP - Consistently use copy-on-write semantics with Add/RemoveObject methods + * 2008-07-10 JPP - Enable validation on cell editors through a CellEditValidating event. + * (thanks to Artiom Chilaru for the initial suggestion and implementation). + * 2008-07-09 JPP - Added HeaderControl.Handle to allow OLV to be used within UserControls. + * (thanks to Michael Coffey for tracking this down). + * 2008-06-23 JPP - Split the more generally useful CopyObjectsToClipboard() method + * out of CopySelectionToClipboard() + * 2008-06-22 JPP - Added AlwaysGroupByColumn and AlwaysGroupBySortOrder, which + * force the list view to always be grouped by a particular column. + * 2008-05-31 JPP - Allow check boxes on FastObjectListViews + * - Added CheckedObject and CheckedObjects properties + * 2008-05-11 JPP - Allow selection foreground and background colors to be changed. + * Windows doesn't allow this, so we can only make it happen when owner + * drawing. Set the HighlightForegroundColor and HighlightBackgroundColor + * properties and then call EnableCustomSelectionColors(). + * v1.12 + * 2008-05-08 JPP - Fixed bug where the column select menu would not appear if the + * ObjectListView has a context menu installed. + * 2008-05-05 JPP - Non detail views can now be owner drawn. The renderer installed for + * primary column is given the chance to render the whole item. + * See BusinessCardRenderer in the demo for an example. + * - BREAKING CHANGE: RenderDelegate now returns a bool to indicate if default + * rendering should be done. Previously returned void. Only important if your + * code used RendererDelegate directly. Renderers derived from BaseRenderer + * are unchanged. + * 2008-05-03 JPP - Changed cell editing to use values directly when the values are Strings. + * Previously, values were always handed to the AspectToStringConverter. + * - When editing a cell, tabbing no longer tries to edit the next subitem + * when not in details view! + * 2008-05-02 JPP - MappedImageRenderer can now handle a Aspects that return a collection + * of values. Each value will be drawn as its own image. + * - Made AddObjects() and RemoveObjects() work for all flavours (or at least not crash) + * - Fixed bug with clearing virtual lists that has been scrolled vertically + * - Made TopItemIndex work with virtual lists. + * 2008-05-01 JPP - Added AddObjects() and RemoveObjects() to allow faster mods to the list + * - Reorganised public properties. Now alphabetical. + * - Made the class ObjectListViewState internal, as it always should have been. + * v1.11 + * 2008-04-29 JPP - Preserve scroll position when building the list or changing columns. + * - Added TopItemIndex property. Due to problems with the underlying control, this + * property is not always reliable. See property docs for info. + * 2008-04-27 JPP - Added SelectedIndex property. + * - Use a different, more general strategy to handle Invoke(). Removed all delegates + * that were only declared to support Invoke(). + * - Check all native structures for 64-bit correctness. + * 2008-04-25 JPP - Released on SourceForge. + * 2008-04-13 JPP - Added ColumnRightClick event. + * - Made the assembly CLS-compliant. To do this, our cell editors were made internal, and + * the constraint on FlagRenderer template parameter was removed (the type must still + * be an IConvertible, but if it isn't, the error will be caught at runtime, not compile time). + * 2008-04-12 JPP - Changed HandleHeaderRightClick() to have a columnIndex parameter, which tells + * exactly which column was right-clicked. + * 2008-03-31 JPP - Added SaveState() and RestoreState() + * - When cell editing, scrolling with a mouse wheel now ends the edit operation. + * v1.10 + * 2008-03-25 JPP - Added space filling columns. See OLVColumn.FreeSpaceProportion property for details. + * A space filling columns fills all (or a portion) of the width unoccupied by other columns. + * 2008-03-23 JPP - Finished tinkering with support for Mono. Compile with conditional compilation symbol 'MONO' + * to enable. On Windows, current problems with Mono: + * - grid lines on virtual lists crashes + * - when grouped, items sometimes are not drawn when any item is scrolled out of view + * - i can't seem to get owner drawing to work + * - when editing cell values, the editing controls always appear behind the listview, + * where they function fine -- the user just can't see them :-) + * 2008-03-16 JPP - Added some methods suggested by Chris Marlowe (thanks for the suggestions Chris) + * - ClearObjects() + * - GetCheckedObject(), GetCheckedObjects() + * - GetItemAt() variation that gets both the item and the column under a point + * 2008-02-28 JPP - Fixed bug with subitem colors when using OwnerDrawn lists and a RowFormatter. + * v1.9.1 + * 2008-01-29 JPP - Fixed bug that caused owner-drawn virtual lists to use 100% CPU + * - Added FlagRenderer to help draw bitwise-OR'ed flag values + * 2008-01-23 JPP - Fixed bug (introduced in v1.9) that made alternate row colour with groups not quite right + * - Ensure that DesignerSerializationVisibility.Hidden is set on all non-browsable properties + * - Make sure that sort indicators are shown after changing which columns are visible + * 2008-01-21 JPP - Added FastObjectListView + * v1.9 + * 2008-01-18 JPP - Added IncrementalUpdate() + * 2008-01-16 JPP - Right clicking on column header will allow the user to choose which columns are visible. + * Set SelectColumnsOnRightClick to false to prevent this behaviour. + * - Added ImagesRenderer to draw more than one images in a column + * - Changed the positioning of the empty list msg to use all the client area. Thanks to Matze. + * 2007-12-13 JPP - Added CopySelectionToClipboard(). Ctrl-C invokes this method. Supports text + * and HTML formats. + * 2007-12-12 JPP - Added support for checkboxes via CheckStateGetter and CheckStatePutter properties. + * - Made ObjectListView and OLVColumn into partial classes so that others can extend them. + * 2007-12-09 JPP - Added ability to have hidden columns, i.e. columns that the ObjectListView knows + * about but that are not visible to the user. Controlled by OLVColumn.IsVisible. + * Added ColumnSelectionForm to the project to show how it could be used in an application. + * + * v1.8 + * 2007-11-26 JPP - Cell editing fully functional + * 2007-11-21 JPP - Added SelectionChanged event. This event is triggered once when the + * selection changes, no matter how many items are selected or deselected (in + * contrast to SelectedIndexChanged which is called once for every row that + * is selected or deselected). Thanks to lupokehl42 (Daniel) for his suggestions and + * improvements on this idea. + * 2007-11-19 JPP - First take at cell editing + * 2007-11-17 JPP - Changed so that items within a group are not sorted if lastSortOrder == None + * - Only call MakeSortIndicatorImages() if we haven't already made the sort indicators + * (Corrected misspelling in the name of the method too) + * 2007-11-06 JPP - Added ability to have secondary sort criteria when sorting + * (SecondarySortColumn and SecondarySortOrder properties) + * - Added SortGroupItemsByPrimaryColumn to allow group items to be sorted by the + * primary column. Previous default was to sort by the grouping column. + * v1.7 + * No big changes to this version but made to work with ListViewPrinter and released with it. + * + * 2007-11-05 JPP - Changed BaseRenderer to use DrawString() rather than TextRenderer, since TextRenderer + * does not work when printing. + * v1.6 + * 2007-11-03 JPP - Fixed some bugs in the rebuilding of DataListView. + * 2007-10-31 JPP - Changed to use builtin sort indicators on XP and later. This also avoids alignment + * problems on Vista. (thanks to gravybod for the suggestion and example implementation) + * 2007-10-21 JPP - Added MinimumWidth and MaximumWidth properties to OLVColumn. + * - Added ability for BuildList() to preserve selection. Calling BuildList() directly + * tries to preserve selection; calling SetObjects() does not. + * - Added SelectAll() and DeselectAll() methods. Useful for working with large lists. + * 2007-10-08 JPP - Added GetNextItem() and GetPreviousItem(), which walk sequentially through the + * listview items, even when the view is grouped. + * - Added SelectedItem property + * 2007-09-28 JPP - Optimized aspect-to-string conversion. BuildList() 15% faster. + * - Added empty implementation of RefreshObjects() to VirtualObjectListView since + * RefreshObjects() cannot work on virtual lists. + * 2007-09-13 JPP - Corrected bug with custom sorter in VirtualObjectListView (thanks for mpgjunky) + * 2007-09-07 JPP - Corrected image scaling bug in DrawAlignedImage() (thanks to krita970) + * 2007-08-29 JPP - Allow item count labels on groups to be set per column (thanks to cmarlow for idea) + * 2007-08-14 JPP - Major rework of DataListView based on Ian Griffiths's great work + * 2007-08-11 JPP - When empty, the control can now draw a "List Empty" message + * - Added GetColumn() and GetItem() methods + * v1.5 + * 2007-08-03 JPP - Support animated GIFs in ImageRenderer + * - Allow height of rows to be specified - EXPERIMENTAL! + * 2007-07-26 JPP - Optimised redrawing of owner-drawn lists by remembering the update rect + * - Allow sort indicators to be turned off + * 2007-06-30 JPP - Added RowFormatter delegate + * - Allow a different label when there is only one item in a group (thanks to cmarlow) + * v1.4 + * 2007-04-12 JPP - Allow owner drawn on steriods! + * - Column headers now display sort indicators + * - ImageGetter delegates can now return ints, strings or Images + * (Images are only visible if the list is owner drawn) + * - Added OLVColumn.MakeGroupies to help with group partitioning + * - All normal listview views are now supported + * - Allow dotted aspect names, e.g. Owner.Workgroup.Name (thanks to OlafD) + * - Added SelectedObject and SelectedObjects properties + * v1.3 + * 2007-03-01 JPP - Added DataListView + * - Added VirtualObjectListView + * - Added Freeze/Unfreeze capabilities + * - Allowed sort handler to be installed + * - Simplified sort comparisons: handles 95% of cases with only 6 lines of code! + * - Fixed bug with alternative line colors on unsorted lists (thanks to cmarlow) + * 2007-01-13 JPP - Fixed bug with lastSortOrder (thanks to Kwan Fu Sit) + * - Non-OLVColumns are no longer allowed + * 2007-01-04 JPP - Clear sorter before rebuilding list. 10x faster! (thanks to aaberg) + * - Include GetField in GetAspectByName() so field values can be Invoked too. + * - Fixed subtle bug in RefreshItem() that erased background colors. + * 2006-11-01 JPP - Added alternate line colouring + * 2006-10-20 JPP - Refactored all sorting comparisons and made it extendable. See ComparerManager. + * - Improved IDE integration + * - Made control DoubleBuffered + * - Added object selection methods + * 2006-10-13 JPP Implemented grouping and column sorting + * 2006-10-09 JPP Initial version + * + * TO DO: + * - Extend MappedImageRender to be able to draw more than image if its Aspect returns an ICollection. + * + * Copyright (C) 2006-2008 Phillip Piper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using System.Runtime.Serialization.Formatters.Binary; + +namespace BrightIdeasSoftware +{ + /// + /// An object list displays 'aspects' of a collection of objects in a listview control. + /// + /// + /// + /// The intelligence for this control is in the columns. OLVColumns are + /// extended so they understand how to fetch an 'aspect' from each row + /// object. They also understand how to sort by their aspect, and + /// how to group them. + /// + /// + /// Aspects are extracted by giving the name of a method to be called or a + /// property to be fetched. These names can be simple names or they can be dotted + /// to chain property access e.g. "Owner.Address.Postcode". + /// Aspects can also be extracted by installing a delegate. + /// + /// + /// Sorting by column clicking and grouping by column are handled automatically. + /// + /// + /// Right clicking on the column header should present a popup menu that allows the user to + /// choose which columns will be visible in the list. This behaviour can be disabled by + /// setting SelectColumnsOnRightClick to false. + /// + /// + /// This list puts sort indicators in the column headers to show the column sorting direction. + /// On Windows XP and later, the system standard images are used. + /// If you wish to replace the standard images with your own images, put entries in the small image list + /// with the key values "sort-indicator-up" and "sort-indicator-down". + /// + /// + /// For these classes to build correctly, the project must have references to these assemblies: + /// + /// System.Data + /// System.Design + /// System.Drawing + /// System.Windows.Forms (obviously) + /// + /// + /// + public partial class ObjectListView : ListView, ISupportInitialize + { + /// + /// Create an ObjectListView + /// + public ObjectListView() + : base() + { + this.ColumnClick += new ColumnClickEventHandler(this.HandleColumnClick); + this.ItemCheck += new ItemCheckEventHandler(this.HandleItemCheck); + this.Layout += new LayoutEventHandler(this.HandleLayout); + this.ColumnWidthChanging += new ColumnWidthChangingEventHandler(this.HandleColumnWidthChanging); + this.ColumnWidthChanged += new ColumnWidthChangedEventHandler(this.HandleColumnWidthChanged); + + base.View = View.Details; + this.DoubleBuffered = true; // kill nasty flickers. hiss... me hates 'em + this.AlternateRowBackColor = Color.Empty; + this.ShowSortIndicators = true; + this.isOwnerOfObjects = false; + } + + #region Public properties + + /// + /// Get or set all the columns that this control knows about. + /// Only those columns where IsVisible is true will be seen by the user. + /// + /// If you want to add new columns programmatically, add them to + /// AllColumns and then call RebuildColumns(). Normally, you do not have to + /// deal with this property directly. Just use the IDE. + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public List AllColumns + { + get + { + // If someone has wiped out the columns, put the list back + if (allColumns == null) + allColumns = new List(); + + // If we don't know the columns, use the columns from the control. + // This handles legacy cases + if (allColumns.Count == 0 && this.Columns.Count > 0) { + for (int i = 0; i < this.Columns.Count; i++) { + this.allColumns.Add(this.GetColumn(i)); + } + } + return allColumns; + } + set { allColumns = value; } + } + private List allColumns = new List(); + + /// + /// If every second row has a background different to the control, what color should it be? + /// + [Category("Appearance"), + Description("If using alternate colors, what color should alterate rows be?"), + DefaultValue(typeof(Color), "Empty")] + public Color AlternateRowBackColor + { + get { return alternateRowBackColor; } + set { alternateRowBackColor = value; } + } + private Color alternateRowBackColor = Color.Empty; + + /// + /// Return the alternate row background color that has been set, or the default color + /// + [Browsable(false)] + public Color AlternateRowBackColorOrDefault + { + get + { + if (alternateRowBackColor == Color.Empty) + return Color.LemonChiffon; + else + return alternateRowBackColor; + } + } + + /// + /// This property forces the ObjectListView to always group items by the given column. + /// + public OLVColumn AlwaysGroupByColumn + { + get { return alwaysGroupByColumn; } + set { alwaysGroupByColumn = value; } + } + private OLVColumn alwaysGroupByColumn; + + /// + /// If AlwaysGroupByColumn is not null, this property will be used to decide how + /// those groups are sorted. If this property has the value SortOrder.None, then + /// the sort order will toggle according to the users last header click. + /// + public SortOrder AlwaysGroupBySortOrder + { + get { return alwaysGroupBySortOrder; } + set { alwaysGroupBySortOrder = value; } + } + private SortOrder alwaysGroupBySortOrder = SortOrder.None; + + /// + /// Give access to the image list that is actually being used by the control + /// + [Browsable(false)] + public ImageList BaseSmallImageList + { + get { return base.SmallImageList; } + } + + /// + /// How does a user indicate that they want to edit cells? + /// + public enum CellEditActivateMode + { + /// + /// This list cannot be edited. F2 does nothing. + /// + None = 0, + + /// + /// A single click on a subitem will edit the value. Single clicking the primary column, + /// selects the row just like normal. The user must press F2 to edit the primary column. + /// + SingleClick = 1, + + /// + /// Double clicking a subitem or the primary column will edit that cell. + /// F2 will edit the primary column. + /// + DoubleClick = 2, + + /// + /// Pressing F2 is the only way to edit the cells. Once the primary column is being edited, + /// the other cells in the row can be edited by pressing Tab. + /// + F2Only = 3 + } + + /// + /// How does the user indicate that they want to edit a cell? + /// None means that the listview cannot be edited. + /// + /// Columns can also be marked as editable. + [Category("Behavior"), + Description("How does the user indicate that they want to edit a cell?"), + DefaultValue(CellEditActivateMode.None)] + public CellEditActivateMode CellEditActivation + { + get { return cellEditActivation; } + set { cellEditActivation = value; } + } + private CellEditActivateMode cellEditActivation = CellEditActivateMode.None; + + /// + /// Return the model object of the row that is checked or null if no row is checked + /// or more than one row is checked + /// + public Object CheckedObject + { + get { + ArrayList checkedObjects = this.GetCheckedObjects(); + if (checkedObjects.Count == 1) + return checkedObjects[0]; + else + return null; + } + } + + /// + /// Get or set the collection of model objects that are checked. + /// When setting this property, any row whose model object isn't + /// in the given collection will be unchecked. Setting to null is + /// equivilent to unchecking all. + /// + /// + /// + /// This property returns a simple collection. Changes made to the returned + /// collection do NOT affect the list. This is different to the behaviour of + /// CheckedIndicies collection. + /// + /// + /// The CheckedItems property is not helpful. It is just a short-hand for + /// iterating through the list looking for items that are checked. + /// + /// + /// The performance of this method is O(n). Be careful on long lists. + /// + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IList CheckedObjects + { + get { + ArrayList objects = new ArrayList(); + if (this.CheckBoxes) { + for (int i = 0; i < this.GetItemCount(); i++) { + OLVListItem olvi = this.GetItem(i); + if (olvi.Checked) + objects.Add(olvi.RowObject); + } + } + return objects; + } + set { + if (this.CheckBoxes) { + if (value == null) + value = new ArrayList(); + + for (int i = 0; i < this.GetItemCount(); i++) { + OLVListItem olvi = this.GetItem(i); + bool newValue = value.Contains(olvi.RowObject); + if (olvi.Checked != newValue) + this.ChangeCheckItem(olvi, olvi.Checked, newValue); + } + } + } + } + + /// + /// Get/set the list of columns that should be used when the list switches to tile view. + /// + /// If no list of columns has been installed, this value will default to the + /// first column plus any column where IsTileViewColumn is true. + [Browsable(false), + Obsolete("Use GetFilteredColumns() and OLVColumn.IsTileViewColumn instead"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List ColumnsForTileView + { + get { return this.GetFilteredColumns(View.Tile); } + } + + /// + /// Return the visible columns in the order they are displayed to the user + /// + [Browsable(false)] + public List ColumnsInDisplayOrder + { + get + { + List columnsInDisplayOrder = new List(this.Columns.Count); + for (int i = 0; i < this.Columns.Count; i++) + columnsInDisplayOrder.Add(null); + for (int i = 0; i < this.Columns.Count; i++) { + OLVColumn col = this.GetColumn(i); + columnsInDisplayOrder[col.DisplayIndex] = col; + } + return columnsInDisplayOrder; + } + } + + /// + /// If there are no items in this list view, what message should be drawn onto the control? + /// + [Category("Appearance"), + Description("When the list has no items, show this message in the control"), + DefaultValue("")] + public String EmptyListMsg + { + get { return emptyListMsg; } + set + { + if (emptyListMsg != value) { + emptyListMsg = value; + this.Invalidate(); + } + } + } + private String emptyListMsg = ""; + + /// + /// What font should the 'list empty' message be drawn in? + /// + [Category("Appearance"), + Description("What font should the 'list empty' message be drawn in?"), + DefaultValue(null)] + public Font EmptyListMsgFont + { + get { return emptyListMsgFont; } + set { emptyListMsgFont = value; } + } + private Font emptyListMsgFont; + + /// + /// Return the font for the 'list empty' message or a default + /// + [Browsable(false)] + public Font EmptyListMsgFontOrDefault + { + get + { + if (this.EmptyListMsgFont == null) + return new Font("Tahoma", 14); + else + return this.EmptyListMsgFont; + } + } + + /// + /// Get or set whether or not the listview is frozen. When the listview is + /// frozen, it will not update itself. + /// + /// The Frozen property is similar to the methods Freeze()/Unfreeze() + /// except that changes to the Frozen property do not nest. + /// objectListView1.Frozen = false; // unfreeze the control regardless of the number of Freeze() calls + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool Frozen + { + get { return freezeCount > 0; } + set + { + if (value) + Freeze(); + else if (freezeCount > 0) { + freezeCount = 1; + Unfreeze(); + } + } + } + private int freezeCount = 0; + + /// + /// When a group title has an item count, how should the lable be formatted? + /// + /// + /// The given format string can/should have two placeholders: + /// + /// {0} - the original group title + /// {1} - the number of items in the group + /// + /// + /// "{0} [{1} items]" + [Category("Behavior"), + Description("The format to use when suffixing item counts to group titles"), + DefaultValue(null)] + public string GroupWithItemCountFormat + { + get { return groupWithItemCountFormat; } + set { groupWithItemCountFormat = value; } + } + private string groupWithItemCountFormat; + + /// + /// Return this.GroupWithItemCountFormat or a reasonable default + /// + [Browsable(false)] + public string GroupWithItemCountFormatOrDefault + { + get + { + if (String.IsNullOrEmpty(this.GroupWithItemCountFormat)) + return "{0} [{1} items]"; + else + return this.GroupWithItemCountFormat; + } + } + + /// + /// When a group title has an item count, how should the lable be formatted if + /// there is only one item in the group? + /// + /// + /// The given format string can/should have two placeholders: + /// + /// {0} - the original group title + /// {1} - the number of items in the group (always 1) + /// + /// + /// "{0} [{1} item]" + [Category("Behavior"), + Description("The format to use when suffixing item counts to group titles"), + DefaultValue(null)] + public string GroupWithItemCountSingularFormat + { + get { return groupWithItemCountSingularFormat; } + set { groupWithItemCountSingularFormat = value; } + } + private string groupWithItemCountSingularFormat; + + /// + /// Return this.GroupWithItemCountSingularFormat or a reasonable default + /// + [Browsable(false)] + public string GroupWithItemCountSingularFormatOrDefault + { + get + { + if (String.IsNullOrEmpty(this.GroupWithItemCountSingularFormat)) + return "{0} [{1} item]"; + else + return this.GroupWithItemCountSingularFormat; + } + } + + /// + /// Does this listview have a message that should be drawn when the list is empty? + /// + [Browsable(false)] + public bool HasEmptyListMsg + { + get { return !String.IsNullOrEmpty(this.EmptyListMsg); } + } + + /// + /// What color should be used for the background of selected rows? + /// + /// Windows does not give the option of changing the selection background. + /// So this color is only used when control is owner drawn and when columns have a + /// renderer installed -- a basic new BaseRenderer() will suffice. + [Category("Appearance"), + Description("The background color of selected rows when the control is owner drawn"), + DefaultValue(typeof(Color), "Empty")] + public Color HighlightBackgroundColor + { + get { return highlightBackgroundColor; } + set { highlightBackgroundColor = value; } + } + private Color highlightBackgroundColor = Color.Empty; + + /// + /// Return the color should be used for the background of selected rows or a reasonable default + /// + [Browsable(false)] + public Color HighlightBackgroundColorOrDefault + { + get { + if (this.HighlightBackgroundColor.IsEmpty) + return SystemColors.Highlight; + else + return this.HighlightBackgroundColor; + } + } + + /// + /// Setup the list so it will draw selected rows using custom colours. + /// + /// + /// This method makes the list owner drawn, and ensures that all columns have at + /// least a BaseRender installed. + /// + public void EnableCustomSelectionColors() + { + this.OwnerDraw = true; + + foreach (OLVColumn column in this.AllColumns) { + if (column.RendererDelegate == null) + column.Renderer = new BaseRenderer(); + } + } + /// + /// What color should be used for the foreground of selected rows? + /// + /// Windows does not give the option of changing the selection foreground (text color). + /// So this color is only used when control is owner drawn and when columns have a + /// renderer installed -- a basic new BaseRenderer() will suffice. + [Category("Appearance"), + Description("The foreground color of selected rows when the control is owner drawn"), + DefaultValue(typeof(Color), "Empty")] + public Color HighlightForegroundColor + { + get { return highlightForegroundColor; } + set { highlightForegroundColor = value; } + } + private Color highlightForegroundColor = Color.Empty; + + /// + /// Return the color should be used for the foreground of selected rows or a reasonable default + /// + public Color HighlightForegroundColorOrDefault + { + get { + if (this.HighlightForegroundColor.IsEmpty) + return SystemColors.HighlightText; + else + return this.HighlightForegroundColor; + } + } + + /// + /// Return true if a cell edit operation is currently happening + /// + [Browsable(false)] + public bool IsCellEditing + { + get { return this.cellEditor != null; } + } + + /// + /// Get/set the collection of objects that this list will show + /// + /// The contents of the control will be updated immediately after setting this property + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public IEnumerable Objects + { + get { return this.objects; } + set { this.SetObjects(value); } + } + private IEnumerable objects; + + /// + /// Take ownership of the 'objects' collection. This separats our collection from the source. + /// + /// + /// + /// This method + /// separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject + /// calls will modify our collection and not the original colleciton. + /// + /// + /// This method has the intentional side-effect of converting our list of objects to an ArrayList. + /// + /// + virtual protected void TakeOwnershipOfObjects() + { + if (this.isOwnerOfObjects) + return; + + this.isOwnerOfObjects = true; + + if (this.objects == null) + this.objects = new ArrayList(); + else if (this.objects is ICollection) + this.objects = new ArrayList((ICollection)this.objects); + else { + ArrayList newObjects = new ArrayList(); + foreach (object x in this.objects) + newObjects.Add(x); + this.objects = newObjects; + } + } + + /// + /// Specify the height of each row in the control in pixels. + /// + /// The row height in a listview is normally determined by the font size and the small image list size. + /// This setting allows that calculation to be overridden (within reason: you still cannot set the line height to be + /// less than the line height of the font used in the control). + /// Setting it to -1 means use the normal calculation method. + /// This feature is experiemental! Strange things may happen to your program, + /// your spouse or your pet if you use it. + /// + [Category("Appearance"), + DefaultValue(-1)] + public int RowHeight + { + get { return rowHeight; } + set + { + if (value < 1) + rowHeight = -1; + else + rowHeight = value; + this.SetupExternalImageList(); + } + } + private int rowHeight = -1; + + /// + /// Get/set the column that will be used to resolve comparisons that are equal when sorting. + /// + /// There is no user interface for this setting. It must be set programmatically. + /// The default is the first column. + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public OLVColumn SecondarySortColumn + { + get + { + if (this.secondarySortColumn == null) { + if (this.Columns.Count > 0) + return this.GetColumn(0); + else + return null; + } else + return this.secondarySortColumn; + } + set + { + this.secondarySortColumn = value; + } + } + private OLVColumn secondarySortColumn; + + /// + /// When the SecondarySortColumn is used, in what order will it compare results? + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SortOrder SecondarySortOrder + { + get { return this.secondarySortOrder; } + set { this.secondarySortOrder = value; } + } + private SortOrder secondarySortOrder = SortOrder.Ascending; + + /// + /// When the user right clicks on the column headers, should a menu be presented which will allow + /// them to choose which columns will be shown in the view? + /// + [Category("Behavior"), + Description("When the user right clicks on the column headers, should a menu be presented which will allow them to choose which columns will be shown in the view?"), + DefaultValue(true)] + public bool SelectColumnsOnRightClick + { + get { return selectColumnsOnRightClick; } + set { selectColumnsOnRightClick = value; } + } + private bool selectColumnsOnRightClick = true; + + /// + /// When the column select menu is open, should it stay open after an item is selected? + /// Staying open allows the user to turn more than one column on or off at a time. + /// + [Category("Behavior"), + Description("When the column select menu is open, should it stay open after an item is selected?"), + DefaultValue(true)] + public bool SelectColumnsMenuStaysOpen + { + get { return selectColumnsMenuStaysOpen; } + set { selectColumnsMenuStaysOpen = value; } + } + private bool selectColumnsMenuStaysOpen = true; + + /// + /// Return the index of the row that is currently selected. If no row is selected, + /// or more than one is selected, return -1. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int SelectedIndex + { + get + { + if (this.SelectedIndices.Count == 1) + return this.SelectedIndices[0]; + else + return -1; + } + set + { + this.SelectedIndices.Clear(); + if (value >= 0 && value < this.Items.Count) + this.SelectedIndices.Add(value); + } + } + + /// + /// Get the ListViewItem that is currently selected . If no row is selected, or more than one is selected, return null. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ListViewItem SelectedItem + { + get + { + if (this.SelectedIndices.Count == 1) + return this.GetItem(this.SelectedIndices[0]); + else + return null; + } + set + { + this.SelectedIndices.Clear(); + if (value != null) + this.SelectedIndices.Add(value.Index); + } + } + + /// + /// Get the model object from the currently selected row. If no row is selected, or more than one is selected, return null. + /// Select the row that is displaying the given model object. All other rows are deselected. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Object SelectedObject + { + get { return this.GetSelectedObject(); } + set { this.SelectObject(value); } + } + + /// + /// Get the model objects from the currently selected rows. If no row is selected, the returned List will be empty. + /// When setting this value, select the rows that is displaying the given model objects. All other rows are deselected. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ArrayList SelectedObjects + { + get { return this.GetSelectedObjects(); } + set { this.SelectObjects(value); } + } + + /// + /// Should the list view show a bitmap in the column header to show the sort direction? + /// + /// + /// The only reason for not wanting to have sort indicators is that, on pre-XP versions of + /// Windows, having sort indicators required the ListView to have a small image list, and + /// as soon as you give a ListView a SmallImageList, the text of column 0 is bumped 16 + /// pixels to the right, even if you never used an image. + /// + [Category("Behavior"), + Description("Should the list view show sort indicators in the column headers?"), + DefaultValue(true)] + public bool ShowSortIndicators + { + get { return showSortIndicators; } + set { showSortIndicators = value; } + } + private bool showSortIndicators; + + /// + /// Should the list view show images on subitems? + /// + /// + /// Under Windows, this works by sending messages to the underlying + /// Windows control. To make this work under Mono, we would have to owner drawing the items :-( + [Category("Behavior"), + Description("Should the list view show images on subitems?"), + DefaultValue(false)] + public bool ShowImagesOnSubItems + { + get + { +#if MONO + return false; +#else + return showImagesOnSubItems; +#endif + } + set { showImagesOnSubItems = value; } + } + private bool showImagesOnSubItems; + + /// + /// This property controls whether group labels will be suffixed with a count of items. + /// + /// + /// The format of the suffix is controlled by GroupWithItemCountFormat/GroupWithItemCountSingularFormat properties + /// + [Category("Behavior"), + Description("Will group titles be suffixed with a count of the items in the group?"), + DefaultValue(false)] + public bool ShowItemCountOnGroups + { + get { return showItemCountOnGroups; } + set { showItemCountOnGroups = value; } + } + private bool showItemCountOnGroups; + + /// + /// Override the SmallImageList property so we can correctly shadow its operations. + /// + /// If you use the RowHeight property to specify the row height, the SmallImageList + /// must be fully initialised before setting/changing the RowHeight. If you add new images to the image + /// list after setting the RowHeight, you must assign the imagelist to the control again. Something as simple + /// as this will work: + /// listView1.SmallImageList = listView1.SmallImageList; + /// + new public ImageList SmallImageList + { + get { return this.shadowedImageList; } + set + { + this.shadowedImageList = value; + this.SetupExternalImageList(); + } + } + private ImageList shadowedImageList = null; + + /// + /// When the listview is grouped, should the items be sorted by the primary column? + /// If this is false, the items will be sorted by the same column as they are grouped. + /// + [Category("Behavior"), + Description("When the listview is grouped, should the items be sorted by the primary column? If this is false, the items will be sorted by the same column as they are grouped."), + DefaultValue(true)] + public bool SortGroupItemsByPrimaryColumn + { + get { return this.sortGroupItemsByPrimaryColumn; } + set { this.sortGroupItemsByPrimaryColumn = value; } + } + private bool sortGroupItemsByPrimaryColumn = true; + + /// + /// When resizing a column by dragging its divider, should any space filling columns be + /// resized at each mouse move? If this is false, the filling columns will be + /// updated when the mouse is released. + /// + /// + /// I think that this looks very ugly, but it does give more immediate feedback. + /// It looks ugly because every + /// column to the right of the divider being dragged gets updated twice: once when + /// the column be resized changes size (this moves + /// all the columns slightly to the right); then again when the filling columns are updated, but they will be shrunk + /// so that the combined width is not more than the control, so everything jumps slightly back to the left again. + /// + [Category("Behavior"), + Description("When resizing a column by dragging its divider, should any space filling columns be resized at each mouse move?"), + DefaultValue(false)] + public bool UpdateSpaceFillingColumnsWhenDraggingColumnDivider + { + get { return updateSpaceFillingColumnsWhenDraggingColumnDivider; } + set { updateSpaceFillingColumnsWhenDraggingColumnDivider = value; } + } + private bool updateSpaceFillingColumnsWhenDraggingColumnDivider = false; + + /// + /// Should the list give a different background color to every second row? + /// + /// The color of the alternate rows is given by AlternateRowBackColor. + /// There is a "feature" in .NET for listviews in non-full-row-select mode, where + /// selected rows are not drawn with their correct background color. + [Category("Appearance"), + Description("Should the list view use a different backcolor to alternate rows?"), + DefaultValue(false)] + public bool UseAlternatingBackColors + { + get { return useAlternatingBackColors; } + set { useAlternatingBackColors = value; } + } + private bool useAlternatingBackColors; + + + /// + /// Get/set the style of view that this listview is using + /// + /// Switching to tile or details view installs the columns appropriate to that view. + /// Confusingly, in tile view, every column is shown as a row of information. + new public View View + { + get { return base.View; } + set + { + if (base.View == value) + return; + + if (this.Frozen) { + base.View = value; + return; + } + + this.Freeze(); + + // If we are switching to a Detail or Tile view, setup the columns needed for that view + if (value == View.Details || value == View.Tile) { + this.ChangeToFilteredColumns(value); + + if (value == View.Tile) + this.CalculateReasonableTileSize(); + } + + base.View = value; + this.Unfreeze(); + } + } + + #endregion + + #region Callbacks + + /// + /// This delegate can be used to sort the table in a custom fasion. + /// + /// + /// + /// What the delegate has to do depends on the type of ObjectListView it is sorting: + /// + /// + /// + /// If it is sorting a normal ObjectListView, the delegate must install a ListViewItemSorter on the ObjectListView. This install ItemSorter will actually do the work of sorting the ListViewItems. See ColumnComparer in the code for an example of what an ItemSorter has to do. + /// + /// + /// If the delegate is sorting a VirtualObjectListView or a FastObjectListView, the delegate must sort the model objects that are sourcing the list (remember, in a virtual list, the application holds the model objects and the list just askes for them as it needs them). + /// + /// + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public SortDelegate CustomSorter + { + get { return customSorter; } + set { customSorter = value; } + } + private SortDelegate customSorter; + + /// + /// This delegate can be used to format a OLVListItem before it is added to the control. + /// + /// + /// The model object for the row can be found through the RowObject property of the OLVListItem object. + /// All subitems normally have the same style as list item, so setting the forecolor on one + /// subitem changes the forecolor of all subitems. + /// To allow subitems to have different attributes, do this:myListViewItem.UseItemStyleForSubItems = false;. + /// + /// If UseAlternatingBackColors is true, the backcolor of the listitem will be calculated + /// by the control and cannot be controlled by the RowFormatter delegate. In general, trying to use a RowFormatter + /// when UseAlternatingBackColors is true does not work well. + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public RowFormatterDelegate RowFormatter + { + get { return rowFormatter; } + set { rowFormatter = value; } + } + private RowFormatterDelegate rowFormatter; + + /// + /// This delegate will be called whenever the ObjectListView needs to know the check state + /// of the row associated with a given model object + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CheckStateGetterDelegate CheckStateGetter + { + get { return checkStateGetter; } + set { checkStateGetter = value; } + } + private CheckStateGetterDelegate checkStateGetter; + + /// + /// This delegate will be called whenever the user tries to change the check state + /// of a row. The delegate should return the value that the listview should actuall + /// use, which may be different to the one given to the delegate. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public CheckStatePutterDelegate CheckStatePutter + { + get { return checkStatePutter; } + set { checkStatePutter = value; } + } + private CheckStatePutterDelegate checkStatePutter; + + #endregion + + #region List commands + + /// + /// Set the collection of objects that will be shown in this list view. + /// + /// This method can safely be called from background threads. + /// The list is updated immediately + /// The objects to be displayed + virtual public void SetObjects(IEnumerable collection) + { + if (this.InvokeRequired) { + this.Invoke((MethodInvoker)delegate { this.SetObjects(collection); }); + return; + } + // If we own the current list and they change to another list, we don't own it anymore + if (this.isOwnerOfObjects && this.objects != collection) + this.isOwnerOfObjects = false; + this.objects = collection; + this.BuildList(false); + } + + /// + /// Add the given model object to this control. + /// + /// The model object to be displayed + /// See AddObjects() for more details + public void AddObject(object modelObject) + { + this.AddObjects(new object[] { modelObject }); + } + + /// + /// Add the given collection of model objects to this control. + /// + /// A collection of model objects + /// + /// The added objects will appear in their correct sort position, if sorting + /// is active. Otherwise, they will appear at the end of the list. + /// No check is performed to see if any of the objects are already in the ListView. + /// The method uses the ObjectsAsList property. See that property for a + /// description of what is does. + /// Null objects are silently ignored. + /// + virtual public void AddObjects(ICollection modelObjects) + { + if (modelObjects == null) + return; + + this.BeginUpdate(); + + this.TakeOwnershipOfObjects(); + ArrayList ourObjects = (ArrayList)this.Objects; + List itemList = new List(); + foreach (object modelObject in modelObjects) { + if (modelObject != null) { + ourObjects.Add(modelObject); + OLVListItem lvi = new OLVListItem(modelObject); + this.FillInValues(lvi, modelObject); + itemList.Add(lvi); + } + } + this.Items.AddRange(itemList.ToArray()); + this.Sort(this.lastSortColumn); + + foreach (OLVListItem lvi in itemList) { + this.SetSubItemImages(lvi.Index, lvi); + } + + this.EndUpdate(); + } + + /// + /// Remove the given model object from the ListView + /// + /// The model to be removed + /// See RemoveObjects() for more details + public void RemoveObject(object modelObject) + { + this.RemoveObjects(new object[] { modelObject }); + } + + /// + /// Remove all of the given objects from the control + /// + /// Collection of objects to be removed + /// + /// Nulls and model objects that are not in the ListView are silently ignored. + /// + virtual public void RemoveObjects(ICollection modelObjects) + { + if (modelObjects == null) + return; + + this.BeginUpdate(); + + this.TakeOwnershipOfObjects(); + ArrayList ourObjects = (ArrayList)this.Objects; + foreach (object modelObject in modelObjects) { + if (modelObject != null) { + ourObjects.Remove(modelObject); + int i = this.IndexOf(modelObject); + if (i >= 0) + this.Items.RemoveAt(i); + } + } + + this.EndUpdate(); + } + + /// + /// Update the list to reflect the contents of the given collection, without affecting + /// the scrolling position, selection or sort order. + /// + /// The objects to be displayed + /// + /// This method is about twice as slow as SetObjects(). + /// This method is experimental -- it may disappear in later versions of the code. + /// There has to be a better way to do this! JPP 15/1/2008 + /// In most situations, if you need this functionality, use a FastObjectListView instead. JPP 2/2/2008 + /// + [Obsolete("Use a FastObjectListView instead of this method.", false)] + virtual public void IncrementalUpdate(IEnumerable collection) + { + if (this.InvokeRequired) { + this.Invoke((MethodInvoker)delegate { this.IncrementalUpdate(collection); }); + return; + } + + this.BeginUpdate(); + + this.ListViewItemSorter = null; + ArrayList previousSelection = this.SelectedObjects; + + // Replace existing rows, creating new listviewitems if we get to the end of the list + List newItems = new List(); + int rowIndex = 0; + int itemCount = this.Items.Count; + foreach (object model in collection) { + if (rowIndex < itemCount) { + OLVListItem lvi = this.GetItem(rowIndex); + lvi.RowObject = model; + this.RefreshItem(lvi); + } else { + OLVListItem lvi = new OLVListItem(model); + this.FillInValues(lvi, model); + newItems.Add(lvi); + } + rowIndex++; + } + + // Delete any excess rows + int numRowsToDelete = itemCount - rowIndex; + for (int i = 0; i < numRowsToDelete; i++) + this.Items.RemoveAt(rowIndex); + + this.Items.AddRange(newItems.ToArray()); + this.Sort(this.lastSortColumn); + + SetAllSubItemImages(); + + this.SelectedObjects = previousSelection; + + this.EndUpdate(); + + this.objects = collection; + } + + /// + /// Remove all items from this list + /// + /// This method can safely be called from background threads. + virtual public void ClearObjects() + { + if (this.InvokeRequired) + this.Invoke(new MethodInvoker(ClearObjects)); + else + this.Items.Clear(); + } + + /// + /// Build/rebuild all the list view items in the list + /// + virtual public void BuildList() + { + this.BuildList(true); + } + + /// + /// Build/rebuild all the list view items in the list + /// + /// If this is true, the control will try to preserve the selection + /// and the scroll position (see Remarks) + /// + /// + /// + /// Use this method in situations were the contents of the list is basically the same + /// as previously. + /// + /// + /// Due to limitations in .NET's ListView, the scroll position is only preserved if + /// the control is in Details view AND it is not showing groups. + /// + /// + virtual public void BuildList(bool shouldPreserveState) + { + if (this.Frozen) + return; + + ArrayList previousSelection = new ArrayList(); + int previousTopIndex = this.TopItemIndex; + if (shouldPreserveState && this.objects != null) + previousSelection = this.SelectedObjects; + + this.BeginUpdate(); + this.Items.Clear(); + this.ListViewItemSorter = null; + + if (this.objects != null) { + // Build a list of all our items and then display them. (Building + // a list and then doing one AddRange is about 10-15% faster than individual adds) + List itemList = new List(); + foreach (object rowObject in this.objects) { + OLVListItem lvi = new OLVListItem(rowObject); + this.FillInValues(lvi, rowObject); + itemList.Add(lvi); + } + this.Items.AddRange(itemList.ToArray()); + this.SetAllSubItemImages(); + this.Sort(this.lastSortColumn); + + if (shouldPreserveState) + this.SelectedObjects = previousSelection; + } + + this.EndUpdate(); + + // We can only restore the scroll position after the EndUpdate() because + // of caching that the ListView does internally during a BeginUpdate/EndUpdate pair. + if (shouldPreserveState) + this.TopItemIndex = previousTopIndex; + } + + /// + /// Get or set the index of the top item of this listview + /// + /// + /// + /// This property only works when the listview is in Details view and not showing groups. + /// + /// + /// The reason that it does not work when showing groups is that, when groups are enabled, + /// the Windows message LVM_GETTOPINDEX always returns 0, regardless of the + /// scroll position. + /// + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int TopItemIndex + { + get + { + if (this.View == View.Details && this.TopItem != null) + return this.TopItem.Index; + else + return -1; + } + set + { + int newTopIndex = Math.Min(value, this.GetItemCount() - 1); + if (this.View == View.Details && newTopIndex >= 0) { + this.TopItem = this.Items[newTopIndex]; + + // Setting the TopItem sometimes gives off by one errors, + // that (bizarrely) are correct on a second attempt + if (this.TopItem != null && this.TopItem.Index != newTopIndex) + this.TopItem = this.GetItem(newTopIndex); + } + } + } + + /// + /// Sort the items by the last sort column + /// + new public void Sort() + { + this.Sort(this.lastSortColumn); + } + + /// + /// Organise the view items into groups, based on the last sort column or the first column + /// if there is no last sort column + /// + public void BuildGroups() + { + this.BuildGroups(this.lastSortColumn); + } + + /// + /// Organise the view items into groups, based on the given column + /// + /// If the AlwaysGroupByColumn property is not null, + /// the list view items will be organisd by that column, + /// and the 'column' parameter will be ignored. + /// The column whose values should be used for sorting. + virtual public void BuildGroups(OLVColumn column) + { + if (column == null) + column = this.GetColumn(0); + + // If a specific column has been given as the group by column, we always + // group by that column, regardless of what the user just clicked. + OLVColumn groupByColumn = this.AlwaysGroupByColumn; + if (groupByColumn == null) + groupByColumn = column; + + SortOrder groupSortOrder = this.AlwaysGroupBySortOrder; + if (groupSortOrder == SortOrder.None) + groupSortOrder = this.lastSortOrder; + + this.Groups.Clear(); + + // Getting the Count forces any internal cache of the ListView to be flushed. Without + // this, iterating over the Items will not work correctly if the ListView handle + // has not yet been created. + int dummy = this.Items.Count; + + // Separate the list view items into groups, using the group key as the descrimanent + Dictionary> map = new Dictionary>(); + foreach (OLVListItem olvi in this.Items) { + object key = groupByColumn.GetGroupKey(olvi.RowObject); + if (key == null) + key = "{null}"; // null can't be used as the key for a dictionary + if (!map.ContainsKey(key)) + map[key] = new List(); + map[key].Add(olvi); + } + + // Make a list of the required groups + List groups = new List(); + foreach (object key in map.Keys) { + ListViewGroup lvg = new ListViewGroup(groupByColumn.ConvertGroupKeyToTitle(key)); + lvg.Tag = key; + groups.Add(lvg); + } + + // Sort the groups + groups.Sort(new ListViewGroupComparer(groupSortOrder)); + + // Put each group into the list view, and give each group its member items. + // The order of statements is important here: + // - the header must be calculate before the group is added to the list view, + // otherwise changing the header causes a nasty redraw (even in the middle of a BeginUpdate...EndUpdate pair) + // - the group must be added before it is given items, otherwise an exception is thrown (is this documented?) + string fmt = groupByColumn.GroupWithItemCountFormatOrDefault; + string singularFmt = groupByColumn.GroupWithItemCountSingularFormatOrDefault; + ColumnComparer itemSorter = new ColumnComparer((this.SortGroupItemsByPrimaryColumn ? this.GetColumn(0) : column), + this.lastSortOrder, this.SecondarySortColumn, this.SecondarySortOrder); + foreach (ListViewGroup group in groups) { + if (this.ShowItemCountOnGroups) { + int count = map[group.Tag].Count; + group.Header = String.Format((count == 1 ? singularFmt : fmt), group.Header, count); + } + this.Groups.Add(group); + // If there is no sort order, don't sort since the sort isn't stable + if (this.lastSortOrder != SortOrder.None) + map[group.Tag].Sort(itemSorter); + group.Items.AddRange(map[group.Tag].ToArray()); + } + } + + /// + /// Pause (or unpause) all animations in the list + /// + /// true to pause, false to unpause + public void PauseAnimations(bool isPause) + { + for (int i = 0; i < this.Columns.Count; i++) { + OLVColumn col = this.GetColumn(i); + if (col.Renderer is ImageRenderer) + ((ImageRenderer)col.Renderer).Paused = isPause; + } + } + + /// + /// Give the listview a reasonable size of its tiles, based on the number of lines of + /// information that each tile is going to display. + /// + public void CalculateReasonableTileSize() + { + if (this.Columns.Count <= 0) + return; + + int imageHeight = (this.LargeImageList == null ? 16 : this.LargeImageList.ImageSize.Height); + int dataHeight = (this.Font.Height + 1) * this.Columns.Count; + int tileWidth = (this.TileSize.Width == 0 ? 200 : this.TileSize.Width); + int tileHeight = Math.Max(this.TileSize.Height, Math.Max(imageHeight, dataHeight)); + this.TileSize = new Size(tileWidth, tileHeight); + } + + /// + /// Rebuild this list for the given view + /// + /// + internal void ChangeToFilteredColumns(View view) + { + // Store the state + ArrayList previousSelection = this.SelectedObjects; + int previousTopIndex = this.TopItemIndex; + + this.Freeze(); + this.Clear(); + List cols = this.GetFilteredColumns(view); + this.Columns.AddRange(cols.ToArray()); + if (view == View.Details) { + foreach (OLVColumn x in cols) { + if (x.LastDisplayIndex == -1 || x.LastDisplayIndex > cols.Count - 1) + x.DisplayIndex = cols.Count - 1; + else + x.DisplayIndex = x.LastDisplayIndex; + } + this.ShowSortIndicator(); + } + this.BuildList(); + this.Unfreeze(); + + // Restore the state + this.SelectedObjects = previousSelection; + this.TopItemIndex = previousTopIndex; + } + + /// + /// Rebuild the columns based upon its current view and column visibility settings + /// + public void RebuildColumns() + { + this.ChangeToFilteredColumns(this.View); + } + + /// + /// Copy a text and html representation of the selected rows onto the clipboard. + /// + /// Be careful when using this with virtual lists. If the user has selected + /// 10,000,000 rows, this method will faithfully try to copy all of them to the clipboard. + /// From the user's point of view, your program will appear to have hung. + public void CopySelectionToClipboard() + { + //THINK: Do we want to include something like this? + //if (this.SelectedIndices.Count > 10000) + // return; + + this.CopyObjectsToClipboard(this.SelectedObjects); + } + + /// + /// Copy a text and html representation of the given objects onto the clipboard. + /// + public void CopyObjectsToClipboard(IList objectsToCopy) + { + if (objectsToCopy.Count == 0) + return; + + List columns = this.ColumnsInDisplayOrder; + + // Build text and html versions of the selection + StringBuilder sbText = new StringBuilder(); + StringBuilder sbHtml = new StringBuilder(""); + + foreach (object modelObject in objectsToCopy) { + sbHtml.Append(""); + } + sbHtml.AppendLine("
"); + foreach (OLVColumn col in columns) { + if (col != columns[0]) { + sbText.Append("\t"); + sbHtml.Append(""); + } + string strValue = col.GetStringValue(modelObject); + sbText.Append(strValue); + sbHtml.Append(strValue); //TODO: Should encode the string value + } + sbText.AppendLine(); + sbHtml.AppendLine("
"); + + // Put both the text and html versions onto the clipboard + DataObject dataObject = new DataObject(); + dataObject.SetText(sbText.ToString(), TextDataFormat.UnicodeText); + dataObject.SetText(ConvertToHtmlFragment(sbHtml.ToString()), TextDataFormat.Html); + Clipboard.SetDataObject(dataObject); + } + + + + /// + /// Convert the fragment of HTML into the Clipboards HTML format. + /// + /// The HTML format is found here http://msdn2.microsoft.com/en-us/library/aa767917.aspx + /// + /// The HTML to put onto the clipboard. It must be valid HTML! + /// A string that can be put onto the clipboard and will be recognized as HTML + private string ConvertToHtmlFragment(string fragment) + { + // Minimal implementation of HTML clipboard format + string source = "http://www.codeproject.com/KB/list/ObjectListView.aspx"; + + const String MARKER_BLOCK = + "Version:1.0\r\n" + + "StartHTML:{0,8}\r\n" + + "EndHTML:{1,8}\r\n" + + "StartFragment:{2,8}\r\n" + + "EndFragment:{3,8}\r\n" + + "StartSelection:{2,8}\r\n" + + "EndSelection:{3,8}\r\n" + + "SourceURL:{4}\r\n" + + "{5}"; + + int prefixLength = String.Format(MARKER_BLOCK, 0, 0, 0, 0, source, "").Length; + + const String DEFAULT_HTML_BODY = + "" + + "{0}"; + + string html = String.Format(DEFAULT_HTML_BODY, fragment); + int startFragment = prefixLength + html.IndexOf(fragment); + int endFragment = startFragment + fragment.Length; + + return String.Format(MARKER_BLOCK, prefixLength, prefixLength + html.Length, startFragment, endFragment, source, html); + } + + /// + /// Return a byte array that represents the current state of the ObjectListView, such + /// that the state can be restored by RestoreState() + /// + /// + /// The state of an ObjectListView includes the attributes that the user can modify: + /// + /// current view (i.e. Details, Tile, Large Icon...) + /// sort column and direction + /// column order + /// column widths + /// column visibility + /// + /// + /// + /// It does not include selection or the scroll position. + /// + /// + /// A byte array representing the state of the ObjectListView + public byte[] SaveState() + { + ObjectListViewState olvState = new ObjectListViewState(); + olvState.VersionNumber = 1; + olvState.NumberOfColumns = this.AllColumns.Count; + olvState.CurrentView = this.View; + + // If we have a sort column, it is possible that it is not currently being shown, in which + // case, it's Index will be -1. So we calculate its index directly. Technically, the sort + // column does not even have to a member of AllColumns, in which case IndexOf will return -1, + // which is works fine since we have no way of restoring such a column anyway. + if (this.lastSortColumn != null) + olvState.SortColumn = this.AllColumns.IndexOf(this.lastSortColumn); + olvState.LastSortOrder = this.lastSortOrder; + olvState.IsShowingGroups = this.ShowGroups; + + if (this.AllColumns.Count > 0 && this.AllColumns[0].LastDisplayIndex == -1) + this.RememberDisplayIndicies(); + + foreach (OLVColumn column in this.AllColumns) { + olvState.ColumnIsVisible.Add(column.IsVisible); + olvState.ColumnDisplayIndicies.Add(column.LastDisplayIndex); + olvState.ColumnWidths.Add(column.Width); + } + + // Now that we have stored our state, convert it to a byte array + MemoryStream ms = new MemoryStream(); + BinaryFormatter serializer = new BinaryFormatter(); + serializer.Serialize(ms, olvState); + + return ms.ToArray(); + } + + /// + /// Restore the state of the control from the given string, which must have been + /// produced by SaveState() + /// + /// A byte array returned from SaveState() + /// Returns true if the state was restored + public bool RestoreState(byte[] state) + { + MemoryStream ms = new MemoryStream(state); + BinaryFormatter deserializer = new BinaryFormatter(); + ObjectListViewState olvState; + try { + olvState = deserializer.Deserialize(ms) as ObjectListViewState; + } catch (System.Runtime.Serialization.SerializationException) { + return false; + } + + // The number of columns has changed. We have no way to match old + // columns to the new ones, so we just give up. + if (olvState.NumberOfColumns != this.AllColumns.Count) + return false; + + if (olvState.SortColumn == -1) { + this.lastSortColumn = null; + this.lastSortOrder = SortOrder.None; + } else { + this.lastSortColumn = this.AllColumns[olvState.SortColumn]; + this.lastSortOrder = olvState.LastSortOrder; + } + + for (int i = 0; i < olvState.NumberOfColumns; i++) { + OLVColumn column = this.AllColumns[i]; + column.Width = (int)olvState.ColumnWidths[i]; + column.IsVisible = (bool)olvState.ColumnIsVisible[i]; + column.LastDisplayIndex = (int)olvState.ColumnDisplayIndicies[i]; + } + + if (olvState.IsShowingGroups != this.ShowGroups) + this.ShowGroups = olvState.IsShowingGroups; + + if (this.View == olvState.CurrentView) + this.RebuildColumns(); + else + this.View = olvState.CurrentView; + + return true; + } + + /// + /// Instances of this class are used to store the state of an ObjectListView. + /// + [Serializable] + internal class ObjectListViewState + { + public int VersionNumber = 1; + public int NumberOfColumns = 1; + public View CurrentView; + public int SortColumn = -1; + public bool IsShowingGroups; + public SortOrder LastSortOrder = SortOrder.None; + public ArrayList ColumnIsVisible = new ArrayList(); + public ArrayList ColumnDisplayIndicies = new ArrayList(); + public ArrayList ColumnWidths = new ArrayList(); + } + + #endregion + + #region Event handlers + + /// + /// Event handler for the column click event + /// + virtual protected void HandleColumnClick(object sender, ColumnClickEventArgs e) + { + if (!this.PossibleFinishCellEditing()) + return; + + // Toggle the sorting direction on successive clicks on the same column + if (this.lastSortColumn != null && e.Column == this.lastSortColumn.Index) + this.lastSortOrder = (this.lastSortOrder == SortOrder.Descending ? SortOrder.Ascending : SortOrder.Descending); + else + this.lastSortOrder = SortOrder.Ascending; + + this.BeginUpdate(); + this.Sort(e.Column); + this.EndUpdate(); + } + + /// + /// Handle when a user checks/unchecks a row + /// + protected void HandleItemCheck(object sender, ItemCheckEventArgs e) + { + if (this.CheckStatePutter != null) + e.NewValue = this.CheckStatePutter(this.GetModelObject(e.Index), e.NewValue); + } + + #endregion + + #region Low level Windows message handling + + /// + /// Override the basic message pump for this control + /// + /// + protected override void WndProc(ref Message m) + { + switch (m.Msg) { + case 0x0F: // WM_PAINT + this.HandlePrePaint(); + base.WndProc(ref m); + this.HandlePostPaint(); + break; + case 0x4E: // WM_NOTIFY + if (!this.HandleNotify(ref m)) + base.WndProc(ref m); + break; + case 0x114: // WM_HSCROLL: + case 0x115: // WM_VSCROLL: + case 0x201: // WM_LBUTTONDOWN: + case 0x20A: // WM_MOUSEWHEEL: + case 0x20E: // WM_MOUSEHWHEEL: + if (this.PossibleFinishCellEditing()) + base.WndProc(ref m); + break; + case 0x7B: // WM_CONTEXTMENU + if (!this.HandleContextMenu(ref m)) + base.WndProc(ref m); + break; + default: + base.WndProc(ref m); + break; + } + } + + #endregion + + #region Empty List Msg handling + + /// + /// Perform any steps needed before painting the control + /// + protected void HandlePrePaint() + { + // When we get a WM_PAINT msg, remember the rectangle that is being updated. + // We can't get this information later, since the BeginPaint call wipes it out. + this.lastUpdateRectangle = NativeMethods.GetUpdateRect(this); + + // When the list is empty, we want to handle the drawing of the control by ourselves. + // Unfortunately, there is no easy way to tell our superclass that we want to do this. + // So we resort to guile and deception. We validate the list area of the control, which + // effectively tells our superclass that this area does not need to be painted. + // Our superclass will then not paint the control, leaving us free to do so ourselves. + // Without doing this trickery, the superclass will draw the + // list as empty, and then moments later, we will draw the empty msg, giving a nasty flicker + if (this.GetItemCount() == 0 && this.HasEmptyListMsg) + NativeMethods.ValidateRect(this, this.ClientRectangle); + } + + /// + /// Perform any steps needed after painting the control + /// + protected void HandlePostPaint() + { + // If the list isn't empty or there isn't an emptyList msg, do nothing + if (this.GetItemCount() != 0 || !this.HasEmptyListMsg) + return; + + // Draw the empty list msg centered in the client area of the control + using (BufferedGraphics buffered = BufferedGraphicsManager.Current.Allocate(this.CreateGraphics(), this.ClientRectangle)) { + Graphics g = buffered.Graphics; + g.Clear(this.BackColor); + StringFormat sf = new StringFormat(); + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + sf.Trimming = StringTrimming.EllipsisCharacter; + g.DrawString(this.EmptyListMsg, this.EmptyListMsgFontOrDefault, SystemBrushes.ControlDark, this.ClientRectangle, sf); + buffered.Render(); + } + } + + #endregion + + #region Column header clicking, column hiding and resizing + + /// + /// When the control is created capture the messages for the header. + /// + protected override void OnCreateControl() + { + base.OnCreateControl(); +#if !MONO + hdrCtrl = new HeaderControl(this); +#endif + } +#if !MONO + private HeaderControl hdrCtrl = null; + + /// + /// Class used to capture window messages for the header of the list view + /// control. + /// + /// We only need this class in order to not change the cursor + /// when the cursor is over the divider of a fixed width column. It + /// really is a little too perfectionist even for me. + private class HeaderControl : NativeWindow + { + private ObjectListView parentListView = null; + + public HeaderControl(ObjectListView olv) + { + this.parentListView = olv; + this.AssignHandle(NativeMethods.GetHeaderControl(olv)); + } + + /// + /// Return the Windows handle behind this control + /// + /// + /// When an ObjectListView is initialized as part of a UserControl, the + /// GetHeaderControl() method returns 0 until the UserControl is + /// completely initialized. So the AssignHandle() call in the constructor + /// doesn't work. So we override the Handle property so value is always + /// current. + /// + public new IntPtr Handle + { + get { return NativeMethods.GetHeaderControl(this.parentListView); } + } + + protected override void WndProc(ref Message message) + { + const int WM_SETCURSOR = 0x0020; + + switch (message.Msg) { + case WM_SETCURSOR: + if (IsCursorOverLockedDivider()) { + message.Result = (IntPtr)1; // Don't change the cursor + return; + } + break; + } + + base.WndProc(ref message); + } + + private bool IsCursorOverLockedDivider() + { + Point pt = this.parentListView.PointToClient(Cursor.Position); + pt.X += NativeMethods.GetScrollPosition(this.parentListView.Handle, true); + int dividerIndex = NativeMethods.GetDividerUnderPoint(this.Handle, pt); + if (dividerIndex >= 0 && dividerIndex < this.parentListView.Columns.Count) { + OLVColumn column = this.parentListView.GetColumn(dividerIndex); + return column.IsFixedWidth || column.FillsFreeSpace; + } else + return false; + } + + /// + /// Return the index of the column under the current cursor position, + /// or -1 if the cursor is not over a column + /// + /// Index of the column under the cursor, or -1 + public int GetColumnIndexUnderCursor() + { + Point pt = this.parentListView.PointToClient(Cursor.Position); + pt.X += NativeMethods.GetScrollPosition(this.parentListView.Handle, true); + return NativeMethods.GetColumnUnderPoint(this.Handle, pt); + } + } +#endif + /// + /// The user wants to see the context menu. + /// + /// The windows message + /// A bool indicating if this message has been handled + /// + /// We want to ignore context menu requests that are triggered by right clicks on the header + /// + protected bool HandleContextMenu(ref Message m) + { + // Don't try to handle context menu commands at design time. + if (this.DesignMode) + return false; + + // If the context menu command was generated by the keyboard, LParam will be -1. + // We don't want to process these. + if (((int)m.LParam) == -1) + return false; + + // If the context menu came from somewhere other than the header control, + // we also don't want to ignore it + if (m.WParam != this.hdrCtrl.Handle) + return false; + + // OK. Looks like a right click in the header + if (!this.PossibleFinishCellEditing()) + return true; + + int columnIndex = this.hdrCtrl.GetColumnIndexUnderCursor(); + return this.HandleHeaderRightClick(columnIndex); + } + + /// + /// In the notification messages, we handle attempts to change the width of our columns + /// + /// The msg to be processed + /// bool to indicate if the msg has been handled + protected bool HandleNotify(ref Message m) + { + bool isMsgHandled = false; + + const int HDN_FIRST = (0 - 300); + const int HDN_ITEMCHANGINGA = (HDN_FIRST - 0); + const int HDN_ITEMCHANGINGW = (HDN_FIRST - 20); + const int HDN_ITEMCLICKA = (HDN_FIRST - 2); + const int HDN_ITEMCLICKW = (HDN_FIRST - 22); + const int HDN_DIVIDERDBLCLICKA = (HDN_FIRST - 5); + const int HDN_DIVIDERDBLCLICKW = (HDN_FIRST - 25); + const int HDN_BEGINTRACKA = (HDN_FIRST - 6); + const int HDN_BEGINTRACKW = (HDN_FIRST - 26); + //const int HDN_ENDTRACKA = (HDN_FIRST - 7); + //const int HDN_ENDTRACKW = (HDN_FIRST - 27); + const int HDN_TRACKA = (HDN_FIRST - 8); + const int HDN_TRACKW = (HDN_FIRST - 28); + + // Handle the notification, remembering to handle both ANSI and Unicode versions + NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR)); + //if (nmhdr.code < HDN_FIRST) + // System.Diagnostics.Debug.WriteLine(nmhdr.code); + + // In KB Article #183258, MS states that when a header control has the HDS_FULLDRAG style, it will receive + // ITEMCHANGING events rather than TRACK events. Under XP SP2 (at least) this is not always true, which may be + // why MS has withdrawn that particular KB article. It is true that the header is always given the HDS_FULLDRAG + // style. But even while window style set, the control doesn't always received ITEMCHANGING events. + // The controlling setting seems to be the Explorer option "Show Window Contents While Dragging"! + // In the category of "truly bizarre side effects", if the this option is turned on, we will receive + // ITEMCHANGING events instead of TRACK events. But if it is turned off, we receive lots of TRACK events and + // only one ITEMCHANGING event at the very end of the process. + // If we receive HDN_TRACK messages, it's harder to control the resizing process. If we return a result of 1, we + // cancel the whole drag operation, not just that particular track event, which is clearly not what we want. + // If we are willing to compile with unsafe code enabled, we can modify the size of the column in place, using the + // commented out code below. But without unsafe code, the best we can do is allow the user to drag the column to + // any width, and then spring it back to within bounds once they release the mouse button. UI-wise it's very ugly. + NativeMethods.NMHEADER nmheader; + switch (nmhdr.code) { + + case HDN_ITEMCLICKA: + case HDN_ITEMCLICKW: + if (!this.PossibleFinishCellEditing()) { + m.Result = (IntPtr)1; // prevent the change from happening + isMsgHandled = true; + } + break; + + case HDN_DIVIDERDBLCLICKA: + case HDN_DIVIDERDBLCLICKW: + case HDN_BEGINTRACKA: + case HDN_BEGINTRACKW: + if (!this.PossibleFinishCellEditing()) { + m.Result = (IntPtr)1; // prevent the change from happening + isMsgHandled = true; + break; + } + nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER)); + if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) { + OLVColumn column = this.GetColumn(nmheader.iItem); + // Space filling columns can't be dragged or double-click resized + if (column.FillsFreeSpace) { + m.Result = (IntPtr)1; // prevent the change from happening + isMsgHandled = true; + } + } + break; + + case HDN_TRACKA: + case HDN_TRACKW: + nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER)); + if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) { + // unsafe { + // NativeMethods.HDITEM *hditem = (NativeMethods.HDITEM*)nmheader.pHDITEM; + // OLVColumn column = this.GetColumn(nmheader.iItem); + // if (hditem->cxy < column.MiniumWidth) + // hditem->cxy = column.MiniumWidth; + // else if (column.MaxiumWidth != -1 && hditem->cxy > column.MaxiumWidth) + // hditem->cxy = column.MaxiumWidth; + // } + } + break; + + case HDN_ITEMCHANGINGA: + case HDN_ITEMCHANGINGW: + nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER)); + if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) { + NativeMethods.HDITEM hditem = (NativeMethods.HDITEM)Marshal.PtrToStructure(nmheader.pHDITEM, typeof(NativeMethods.HDITEM)); + OLVColumn column = this.GetColumn(nmheader.iItem); + // Check the mask to see if the width field is valid, and if it is, make sure it's within range + if ((hditem.mask & 1) == 1) { + if (hditem.cxy < column.MinimumWidth || + (column.MaximumWidth != -1 && hditem.cxy > column.MaximumWidth)) { + m.Result = (IntPtr)1; // prevent the change from happening + isMsgHandled = true; + } + } + } + break; + + default: + break; + } + + return isMsgHandled; + } + + /// + /// The user has right clicked on the column headers. Do whatever is required + /// + /// Return true if this event has been handle + virtual protected bool HandleHeaderRightClick(int columnIndex) + { + ColumnClickEventArgs eventArgs = new ColumnClickEventArgs(columnIndex); + this.OnColumnRightClick(eventArgs); + + if (this.SelectColumnsOnRightClick) + this.ShowColumnSelectMenu(Cursor.Position); + + return this.SelectColumnsOnRightClick; + } + + /// + /// The user has right clicked on the column headers. Do whatever is required + /// + /// Return true if this event has been handle + [Obsolete("Use HandleHeaderRightClick(int) instead")] + virtual protected bool HandleHeaderRightClick() + { + return false; + } + + /// + /// Tell the world when a cell is about to finish being edited. + /// + protected virtual void OnColumnRightClick(ColumnClickEventArgs e) + { + if (this.ColumnRightClick != null) + this.ColumnRightClick(this, e); + } + + /// + /// The callbacks for RightColumnClick events + /// + public delegate void ColumnRightClickEventHandler(object sender, ColumnClickEventArgs e); + + /// + /// Triggered when a column header is right clicked. + /// + [Category("Behavior")] + public event ColumnRightClickEventHandler ColumnRightClick; + + /// + /// Show a popup menu at the given point which will allow the user to choose which columns + /// are visible on this listview + /// + /// Where should the menu be placed + protected void ShowColumnSelectMenu(Point pt) + { + ContextMenuStrip m = this.MakeColumnSelectMenu(null); + m.Show(pt); + } + + /// + /// Append the column selection menu items to the given menu strip. + /// + /// The menu to which the items will be added. If this is null, a new + /// ContextMenuStrip will be created + /// Return the menu to which the items were added + public ContextMenuStrip MakeColumnSelectMenu(ContextMenuStrip strip) + { + if (strip == null) + strip = new ContextMenuStrip(); + + strip.ItemClicked += new ToolStripItemClickedEventHandler(ColumnSelectMenu_ItemClicked); + strip.Closing += new ToolStripDropDownClosingEventHandler(ColumnSelectMenu_Closing); + + List columns = new List(this.AllColumns); + columns.Sort(delegate(OLVColumn x, OLVColumn y) { return String.Compare(x.Text, y.Text, true); }); + foreach (OLVColumn col in columns) { + ToolStripMenuItem mi = new ToolStripMenuItem(col.Text); + mi.Checked = col.IsVisible; + mi.Tag = col; + + // The 'Index' property returns -1 when the column is not visible, so if the + // column isn't visible we have to enable the item. Also the first column can't be turned off + mi.Enabled = !col.IsVisible || (col.Index > 0); + strip.Items.Add(mi); + } + + return strip; + } + + private void ColumnSelectMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e) + { + ToolStripMenuItem mi = (ToolStripMenuItem)e.ClickedItem; + OLVColumn col = (OLVColumn)mi.Tag; + mi.Checked = !mi.Checked; + col.IsVisible = mi.Checked; + this.BeginInvoke(new MethodInvoker(this.RebuildColumns)); + } + + private void ColumnSelectMenu_Closing(object sender, ToolStripDropDownClosingEventArgs e) + { + e.Cancel = (this.SelectColumnsMenuStaysOpen && + e.CloseReason == ToolStripDropDownCloseReason.ItemClicked); + } + + /// + /// Override the OnColumnReordered method to do what we want + /// + /// + protected override void OnColumnReordered(ColumnReorderedEventArgs e) + { + base.OnColumnReordered(e); + + // The internal logic of the .NET code behind a ENDDRAG event means that, + // at this point, the DisplayIndex's of the columns are not yet as they are + // going to be. So we have to invoke a method to run later that will remember + // what the real DisplayIndex's are. + this.BeginInvoke(new MethodInvoker(this.RememberDisplayIndicies)); + } + + private void RememberDisplayIndicies() + { + // Remember the display indexes so we can put them back at a later date + foreach (OLVColumn x in this.AllColumns) + x.LastDisplayIndex = x.DisplayIndex; + } + + void HandleColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e) + { + if (this.UpdateSpaceFillingColumnsWhenDraggingColumnDivider && !this.GetColumn(e.ColumnIndex).FillsFreeSpace) + this.ResizeFreeSpaceFillingColumns(); + } + + void HandleColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e) + { + if (!this.GetColumn(e.ColumnIndex).FillsFreeSpace) + this.ResizeFreeSpaceFillingColumns(); + } + + void HandleLayout(object sender, LayoutEventArgs e) + { + this.ResizeFreeSpaceFillingColumns(); + } + + /// + /// Resize our space filling columns so they fill any unoccupied width in the control + /// + protected void ResizeFreeSpaceFillingColumns() + { + // It's too confusing to dynamically resize columns at design time. + if (this.DesignMode) + return; + + // Calculate the free space available + int freeSpace = this.ClientSize.Width - 2; + int totalProportion = 0; + List spaceFillingColumns = new List(); + for (int i = 0; i < this.Columns.Count; i++) { + OLVColumn col = this.GetColumn(i); + if (col.FillsFreeSpace) { + spaceFillingColumns.Add(col); + totalProportion += col.FreeSpaceProportion; + } else + freeSpace -= col.Width; + } + freeSpace = Math.Max(0, freeSpace); + + // Any space filling column that would hit it's Minimum or Maximum + // width must be treated as a fixed column. + foreach (OLVColumn col in spaceFillingColumns.ToArray()) { + int newWidth = (freeSpace * col.FreeSpaceProportion) / totalProportion; + + if (col.MinimumWidth != -1 && newWidth < col.MinimumWidth) + newWidth = col.MinimumWidth; + else if (col.MaximumWidth != -1 && newWidth > col.MaximumWidth) + newWidth = col.MaximumWidth; + else + newWidth = 0; + + if (newWidth > 0) { + col.Width = newWidth; + freeSpace -= newWidth; + totalProportion -= col.FreeSpaceProportion; + spaceFillingColumns.Remove(col); + } + } + + // Distribute the free space between the columns + foreach (OLVColumn col in spaceFillingColumns) { + col.Width = (freeSpace * col.FreeSpaceProportion) / totalProportion; + } + } + + #endregion + + #region Checkboxes + + /// + /// Change the given item from the old check value to a new one + /// + /// The item to be change + /// The old value of the check + /// The new value of the check + protected void ChangeCheckItem(OLVListItem olvi, bool oldValue, bool newValue) + { + this.ChangeCheckItem(olvi, + (oldValue ? CheckState.Checked : CheckState.Unchecked), + (newValue ? CheckState.Checked : CheckState.Unchecked)); + } + + /// + /// Change the given item from the old check value to a new one + /// + /// The item to be change + /// The old value of the check + /// The new value of the check + protected void ChangeCheckItem(OLVListItem olvi, CheckState oldValue, CheckState newValue) + { + olvi.Checked = (newValue == CheckState.Checked); + if (this.CheckStatePutter != null) + this.CheckStatePutter(olvi.RowObject, newValue); + this.RefreshItem(olvi); + } + + /// + /// Return true of the given object is checked + /// + /// The model object whose checkedness is returned + /// Is the given object checked? + /// If the given object is not in the list, this method returns false. + public bool IsChecked(object modelObject) + { + OLVListItem olvi = this.ModelToItem(modelObject); + if (olvi == null) + return false; + else + return olvi.Checked; + } + + /// + /// Return the OLVListItem that displays the given model object + /// + /// The modelObject whose item is to be found + /// The OLVListItem that displays the model, or null + /// This method has O(n) performance. + protected OLVListItem ModelToItem(object modelObject) + { + if (modelObject == null) + return null; + + OLVListItem olvi; + foreach (ListViewItem lvi in this.Items) { + olvi = (OLVListItem)lvi; + if (olvi.RowObject == modelObject) + return olvi; + } + return null; + } + + /// + /// Toggle the checkedness of the given object + /// + /// The model object to be checked + public void ToggleCheckObject(object modelObject) + { + OLVListItem olvi = this.ModelToItem(modelObject); + if (olvi != null) + this.ChangeCheckItem(olvi, olvi.Checked, !olvi.Checked); + } + + /// + /// Mark the given object as checked in the list + /// + /// The model object to be checked + public void CheckObject(object modelObject) + { + OLVListItem olvi = this.ModelToItem(modelObject); + if (olvi != null && !olvi.Checked) + this.ChangeCheckItem(olvi, false, true); + } + + /// + /// Mark the given object as unchecked in the list + /// + /// The model object to be unchecked + public void UncheckObject(object modelObject) + { + OLVListItem olvi = this.ModelToItem(modelObject); + if (olvi != null && olvi.Checked) + this.ChangeCheckItem(olvi, true, false); + } + + #endregion + + #region OLV accessing + + /// + /// Return the column at the given index + /// + /// Index of the column to be returned + /// An OLVColumn + public OLVColumn GetColumn(int index) + { + return (OLVColumn)this.Columns[index]; + } + + /// + /// Return the column at the given title. + /// + /// Name of the column to be returned + /// An OLVColumn + public OLVColumn GetColumn(string name) + { + foreach (ColumnHeader column in this.Columns) { + if (column.Text == name) + return (OLVColumn)column; + } + return null; + } + + /// + /// Return the number of items in the list + /// + /// the number of items in the list + virtual public int GetItemCount() + { + return this.Items.Count; + } + + /// + /// Return the item at the given index + /// + /// Index of the item to be returned + /// An OLVListItem + virtual public OLVListItem GetItem(int index) + { + if (index >= 0 && index < this.GetItemCount()) + return (OLVListItem)this.Items[index]; + else + return null; + } + + /// + /// Return the model object at the given index + /// + /// Index of the model object to be returned + /// A model object + virtual public object GetModelObject(int index) + { + return this.GetItem(index).RowObject; + } + + /// + /// Find the item and column that are under the given co-ords + /// + /// X co-ord + /// Y co-ord + /// The column under the given point + /// The item under the given point. Can be null. + public OLVListItem GetItemAt(int x, int y, out OLVColumn selectedColumn) + { + selectedColumn = null; + ListViewHitTestInfo info = this.HitTest(x, y); + if (info.Item == null) + return null; + + if (info.SubItem != null) { + int subItemIndex = info.Item.SubItems.IndexOf(info.SubItem); + selectedColumn = this.GetColumn(subItemIndex); + } + + return (OLVListItem)info.Item; + } + + #endregion + + #region Object manipulation + + /// + /// Select all rows in the listview + /// + public void SelectAll() + { + NativeMethods.SelectAllItems(this); + } + + /// + /// Deselect all rows in the listview + /// + public void DeselectAll() + { + NativeMethods.DeselectAllItems(this); + } + + /// + /// Return the model object of the row that is selected or null if there is no selection or more than one selection + /// + /// Model object or null + virtual public object GetSelectedObject() + { + if (this.SelectedIndices.Count == 1) + return this.GetModelObject(this.SelectedIndices[0]); + else + return null; + } + + /// + /// Return the model objects of the rows that are selected or an empty collection if there is no selection + /// + /// ArrayList + virtual public ArrayList GetSelectedObjects() + { + ArrayList objects = new ArrayList(this.SelectedIndices.Count); + foreach (int index in this.SelectedIndices) + objects.Add(this.GetModelObject(index)); + + return objects; + } + + /// + /// Return the model object of the row that is checked or null if no row is checked + /// or more than one row is checked + /// + /// Model object or null + /// Use CheckedObject property instead of this method + virtual public object GetCheckedObject() + { + return this.CheckedObject; + } + + /// + /// Get the collection of model objects that are checked. + /// + /// Use CheckedObjects property instead of this method + virtual public ArrayList GetCheckedObjects() + { + return (ArrayList)this.CheckedObjects; + } + + /// + /// Select the row that is displaying the given model object. All other rows are deselected. + /// + /// The object to be selected or null to deselect all + virtual public void SelectObject(object modelObject) + { + // If the given model is already selected, don't do anything else (prevents an flicker) + if (this.SelectedItems.Count == 1 && ((OLVListItem)this.SelectedItems[0]).RowObject == modelObject) + return; + + this.SelectedItems.Clear(); + + OLVListItem olvi = this.ModelToItem(modelObject); + if (olvi != null) + olvi.Selected = true; + } + + /// + /// Select the rows that is displaying any of the given model object. All other rows are deselected. + /// + /// A collection of model objects + virtual public void SelectObjects(IList modelObjects) + { + this.SelectedItems.Clear(); + + foreach (object modelObject in modelObjects) { + OLVListItem olvi = this.ModelToItem(modelObject); + if (olvi != null) + olvi.Selected = true; + } + } + + /// + /// Update the ListViewItem with the data from its associated model. + /// + /// This method does not resort or regroup the view. It simply updates + /// the displayed data of the given item + virtual public void RefreshItem(OLVListItem olvi) + { + // For some reason, clearing the subitems also wipes out the back color, + // so we need to store it and then put it back again later + Color c = olvi.BackColor; + olvi.SubItems.Clear(); + this.FillInValues(olvi, olvi.RowObject); + this.SetSubItemImages(olvi.Index, olvi, true); + olvi.BackColor = c; + } + + /// + /// Update the rows that are showing the given objects + /// + /// This method does not resort or regroup the view. + virtual public void RefreshObject(object modelObject) + { + this.RefreshObjects(new object[] { modelObject }); + } + + /// + /// Update the rows that are showing the given objects + /// + /// + /// This method does not resort or regroup the view. + /// This method can safely be called from background threads. + /// + virtual public void RefreshObjects(IList modelObjects) + { + if (this.InvokeRequired) { + this.Invoke((MethodInvoker)delegate { this.RefreshObjects(modelObjects); }); + return; + } + foreach (object modelObject in modelObjects) { + OLVListItem olvi = this.ModelToItem(modelObject); + if (olvi != null) + this.RefreshItem(olvi); + } + } + + /// + /// Update the rows that are selected + /// + /// This method does not resort or regroup the view. + public void RefreshSelectedObjects() + { + foreach (ListViewItem lvi in this.SelectedItems) + this.RefreshItem((OLVListItem)lvi); + } + + /// + /// Find the given model object within the listview and return its index + /// + /// Technically, this method will work with virtual lists, but it will + /// probably be very slow. + /// The model object to be found + /// The index of the object. -1 means the object was not present + public int IndexOf(Object modelObject) + { + for (int i = 0; i < this.GetItemCount(); i++) { + if (this.GetModelObject(i) == modelObject) + return i; + } + return -1; + } + + /// + /// Return the ListViewItem that appears immediately after the given item. + /// If the given item is null, the first item in the list will be returned. + /// Return null if the given item is the last item. + /// + /// The item that is before the item that is returned, or null + /// A ListViewItem + public ListViewItem GetNextItem(ListViewItem itemToFind) + { + if (this.ShowGroups) { + bool isFound = (itemToFind == null); + foreach (ListViewGroup group in this.Groups) { + foreach (ListViewItem lvi in group.Items) { + if (isFound) + return lvi; + isFound = (lvi == itemToFind); + } + } + return null; + } else { + if (this.GetItemCount() == 0) + return null; + if (itemToFind == null) + return this.GetItem(0); + if (itemToFind.Index == this.GetItemCount() - 1) + return null; + return this.GetItem(itemToFind.Index + 1); + } + } + + /// + /// Return the ListViewItem that appears immediately before the given item. + /// If the given item is null, the last item in the list will be returned. + /// Return null if the given item is the first item. + /// + /// The item that is before the item that is returned + /// A ListViewItem + public ListViewItem GetPreviousItem(ListViewItem itemToFind) + { + if (this.ShowGroups) { + ListViewItem previousItem = null; + foreach (ListViewGroup group in this.Groups) { + foreach (ListViewItem lvi in group.Items) { + if (lvi == itemToFind) + return previousItem; + else + previousItem = lvi; + } + } + if (itemToFind == null) + return previousItem; + else + return null; + } else { + if (this.GetItemCount() == 0) + return null; + if (itemToFind == null) + return this.GetItem(this.GetItemCount() - 1); + if (itemToFind.Index == 0) + return null; + return this.GetItem(itemToFind.Index - 1); + } + } + + #endregion + + #region Freezing + + /// + /// Freeze the listview so that it no longer updates itself. + /// + /// Freeze()/Unfreeze() calls nest correctly + public void Freeze() + { + freezeCount++; + } + + /// + /// Unfreeze the listview. If this call is the outermost Unfreeze(), + /// the contents of the listview will be rebuilt. + /// + /// Freeze()/Unfreeze() calls nest correctly + public void Unfreeze() + { + if (freezeCount <= 0) + return; + + freezeCount--; + if (freezeCount == 0) + DoUnfreeze(); + } + + /// + /// Do the actual work required when the listview is unfrozen + /// + virtual protected void DoUnfreeze() + { + BuildList(); + } + + #endregion + + #region Column Sorting + + /// + /// Sort the items in the list view by the values in the given column. + /// If ShowGroups is true, the rows will be grouped by the given column, + /// otherwise, it will be a straight sort. + /// + /// The name of the column whose values will be used for the sorting + public void Sort(string columnToSortName) + { + this.Sort(this.GetColumn(columnToSortName)); + } + + /// + /// Sort the items in the list view by the values in the given column. + /// If ShowGroups is true, the rows will be grouped by the given column, + /// otherwise, it will be a straight sort. + /// + /// The index of the column whose values will be used for the sorting + public void Sort(int columnToSortIndex) + { + if (columnToSortIndex >= 0 && columnToSortIndex < this.Columns.Count) + this.Sort(this.GetColumn(columnToSortIndex)); + } + + /// + /// Sort the items in the list view by the values in the given column. + /// If ShowGroups is true, the rows will be grouped by the given column, + /// otherwise, it will be a straight sort. + /// + /// The column whose values will be used for the sorting + virtual public void Sort(OLVColumn columnToSort) + { + if (this.InvokeRequired) { + this.Invoke((MethodInvoker)delegate { this.Sort(columnToSort); }); + return; + } + + if (this.Columns.Count < 1) + return; + + if (columnToSort == null) + columnToSort = this.GetColumn(0); + + if (lastSortOrder == SortOrder.None) + lastSortOrder = this.Sorting; + + if (this.ShowGroups) + this.BuildGroups(columnToSort); + else if (this.CustomSorter != null) + this.CustomSorter(columnToSort, lastSortOrder); + else + this.ListViewItemSorter = new ColumnComparer(columnToSort, lastSortOrder, this.SecondarySortColumn, this.SecondarySortOrder); + + if (this.ShowSortIndicators) + this.ShowSortIndicator(columnToSort, lastSortOrder); + + if (this.UseAlternatingBackColors && this.View == View.Details) + PrepareAlternateBackColors(); + + this.lastSortColumn = columnToSort; + } + + + /// + /// Put a sort indicator next to the text of the sort column + /// + public void ShowSortIndicator() + { + if (this.ShowSortIndicators && this.lastSortOrder != SortOrder.None) + this.ShowSortIndicator(this.lastSortColumn, this.lastSortOrder); + } + + + /// + /// Put a sort indicator next to the text of the given given column + /// + /// The column to be marked + /// The sort order in effect on that column + protected void ShowSortIndicator(OLVColumn columnToSort, SortOrder sortOrder) + { + int imageIndex = -1; + + if (!NativeMethods.HasBuiltinSortIndicators()) { + // If we can't use builtin image, we have to make and then locate the index of the + // sort indicator we want to use. SortOrder.None doesn't show an image. + if (this.SmallImageList == null || !this.SmallImageList.Images.ContainsKey(SORT_INDICATOR_UP_KEY)) + MakeSortIndicatorImages(); + + if (sortOrder == SortOrder.Ascending) + imageIndex = this.SmallImageList.Images.IndexOfKey(SORT_INDICATOR_UP_KEY); + else if (sortOrder == SortOrder.Descending) + imageIndex = this.SmallImageList.Images.IndexOfKey(SORT_INDICATOR_DOWN_KEY); + } + + // Set the image for each column + for (int i = 0; i < this.Columns.Count; i++) { + if (i == columnToSort.Index) + NativeMethods.SetColumnImage(this, i, sortOrder, imageIndex); + else + NativeMethods.SetColumnImage(this, i, SortOrder.None, -1); + } + } + + /// + /// The name of the image used when a column is sorted ascending + /// + /// This image is only used on pre-XP systems. System images are used for XP and later + public const string SORT_INDICATOR_UP_KEY = "sort-indicator-up"; + + /// + /// The name of the image used when a column is sorted descending + /// + /// This image is only used on pre-XP systems. System images are used for XP and later + public const string SORT_INDICATOR_DOWN_KEY = "sort-indicator-down"; + + /// + /// If the sort indicator images don't already exist, this method will make and install them + /// + protected void MakeSortIndicatorImages() + { + ImageList il = this.SmallImageList; + if (il == null) { + il = new ImageList(); + il.ImageSize = new Size(16, 16); + } + + // This arrangement of points works well with (16,16) images, and OK with others + int midX = il.ImageSize.Width / 2; + int midY = (il.ImageSize.Height / 2) - 1; + int deltaX = midX - 2; + int deltaY = deltaX / 2; + + if (il.Images.IndexOfKey(SORT_INDICATOR_UP_KEY) == -1) { + Point pt1 = new Point(midX - deltaX, midY + deltaY); + Point pt2 = new Point(midX, midY - deltaY - 1); + Point pt3 = new Point(midX + deltaX, midY + deltaY); + il.Images.Add(SORT_INDICATOR_UP_KEY, this.MakeTriangleBitmap(il.ImageSize, new Point[] { pt1, pt2, pt3 })); + } + + if (il.Images.IndexOfKey(SORT_INDICATOR_DOWN_KEY) == -1) { + Point pt1 = new Point(midX - deltaX, midY - deltaY); + Point pt2 = new Point(midX, midY + deltaY); + Point pt3 = new Point(midX + deltaX, midY - deltaY); + il.Images.Add(SORT_INDICATOR_DOWN_KEY, this.MakeTriangleBitmap(il.ImageSize, new Point[] { pt1, pt2, pt3 })); + } + + this.SmallImageList = il; + } + + private Bitmap MakeTriangleBitmap(Size sz, Point[] pts) + { + Bitmap bm = new Bitmap(sz.Width, sz.Height); + Graphics g = Graphics.FromImage(bm); + g.FillPolygon(new SolidBrush(Color.Gray), pts); + return bm; + } + + #endregion + + #region Utilities + + /// + /// Fill in the given OLVListItem with values of the given row + /// + /// the OLVListItem that is to be stuff with values + /// the model object from which values will be taken + protected void FillInValues(OLVListItem lvi, object rowObject) + { + if (this.Columns.Count == 0) + return; + + OLVColumn column = this.GetColumn(0); + lvi.Text = column.GetStringValue(rowObject); + lvi.ImageSelector = column.GetImage(rowObject); + + for (int i = 1; i < this.Columns.Count; i++) { + column = this.GetColumn(i); + lvi.SubItems.Add(new OLVListSubItem(column.GetStringValue(rowObject), + column.GetImage(rowObject))); + } + + // Give the row formatter a chance to mess with the item + if (this.RowFormatter != null) + this.RowFormatter(lvi); + + this.CorrectSubItemColors(lvi); + + // Get the check state of the row, if we are showing check boxes + if (this.CheckBoxes && this.CheckStateGetter != null) + lvi.Checked = this.CheckStateGetter(lvi.RowObject); + } + + /// + /// Setup all subitem images on all rows + /// + protected void SetAllSubItemImages() + { + if (!this.ShowImagesOnSubItems) + return; + + this.ForceSubItemImagesExStyle(); + + for (int rowIndex = 0; rowIndex < this.GetItemCount(); rowIndex++) + SetSubItemImages(rowIndex, this.GetItem(rowIndex)); + } + + /// + /// Tell the underlying list control which images to show against the subitems + /// + /// the index at which the item occurs + /// the item whose subitems are to be set + protected void SetSubItemImages(int rowIndex, OLVListItem item) + { + this.SetSubItemImages(rowIndex, item, false); + } + + /// + /// Tell the underlying list control which images to show against the subitems + /// + /// the index at which the item occurs + /// the item whose subitems are to be set + /// will existing images be cleared if no new image is provided? + protected void SetSubItemImages(int rowIndex, OLVListItem item, bool shouldClearImages) + { + if (!this.ShowImagesOnSubItems) + return; + + for (int i = 1; i < item.SubItems.Count; i++) { + int imageIndex = this.GetActualImageIndex(((OLVListSubItem)item.SubItems[i]).ImageSelector); + if (shouldClearImages || imageIndex != -1) + this.SetSubItemImage(rowIndex, i, imageIndex); + } + } + + /// + /// Prepare the listview to show alternate row backcolors + /// + /// We cannot rely on lvi.Index in this method. + /// In a straight list, lvi.Index is the display index, and can be used to determine + /// whether the row should be colored. But when organised by groups, lvi.Index is not + /// useable because it still refers to the position in the overall list, not the display order. + /// + virtual protected void PrepareAlternateBackColors() + { + Color rowBackColor = this.AlternateRowBackColorOrDefault; + int i = 0; + + if (this.ShowGroups) { + foreach (ListViewGroup group in this.Groups) { + foreach (ListViewItem lvi in group.Items) { + if (i % 2 == 0) + lvi.BackColor = this.BackColor; + else + lvi.BackColor = rowBackColor; + CorrectSubItemColors(lvi); + i++; + } + } + } else { + foreach (ListViewItem lvi in this.Items) { + if (i % 2 == 0) + lvi.BackColor = this.BackColor; + else + lvi.BackColor = rowBackColor; + CorrectSubItemColors(lvi); + i++; + } + } + } + + /// + /// For some reason, UseItemStyleForSubItems doesn't work for the colors + /// when owner drawing the list, so we have to specifically give each subitem + /// the desired colors + /// + /// The item whose subitems are to be corrected + protected void CorrectSubItemColors(ListViewItem olvi) + { + if (this.OwnerDraw && olvi.UseItemStyleForSubItems) + foreach (ListViewItem.ListViewSubItem si in olvi.SubItems) { + si.BackColor = olvi.BackColor; + si.ForeColor = olvi.ForeColor; + } + } + + /// + /// Convert the given image selector to an index into our image list. + /// Return -1 if that's not possible + /// + /// + /// Index of the image in the imageList, or -1 + public int GetActualImageIndex(Object imageSelector) + { + if (imageSelector == null) + return -1; + + if (imageSelector is Int32) + return (int)imageSelector; + + if (imageSelector is String && this.SmallImageList != null) + return this.SmallImageList.Images.IndexOfKey((String)imageSelector); + + return -1; + } + + /// + /// Make sure the ListView has the extended style that says to display subitem images. + /// + /// This method must be called after any .NET call that update the extended styles + /// since they seem to erase this setting. + protected void ForceSubItemImagesExStyle() + { + NativeMethods.ForceSubItemImagesExStyle(this); + } + + /// + /// For the given item and subitem, make it display the given image + /// + /// row number (0 based) + /// subitem (0 is the item itself) + /// index into the image list + protected void SetSubItemImage(int itemIndex, int subItemIndex, int imageIndex) + { + NativeMethods.SetSubItemImage(this, itemIndex, subItemIndex, imageIndex); + } + + #endregion + + #region ISupportInitialize Members + + void ISupportInitialize.BeginInit() + { + this.Frozen = true; + } + + void ISupportInitialize.EndInit() + { + this.Frozen = false; + } + + #endregion + + #region Image list manipulation + + /// + /// Update our externally visible image list so it holds the same images as our shadow list, but sized correctly + /// + private void SetupExternalImageList() + { + // If a row height hasn't been set, or an image list has been give which is the required size, just assign it + if (rowHeight == -1 || (this.shadowedImageList != null && this.shadowedImageList.ImageSize.Height == rowHeight)) + base.SmallImageList = this.shadowedImageList; + else + base.SmallImageList = this.MakeResizedImageList(rowHeight, shadowedImageList); + } + + /// + /// Return a copy of the given source image list, where each image has been resized to be height x height in size. + /// If source is null, an empty image list of the given size is returned + /// + /// Height and width of the new images + /// Source of the images (can be null) + /// A new image list + private ImageList MakeResizedImageList(int height, ImageList source) + { + ImageList il = new ImageList(); + il.ImageSize = new Size(height, height); + + // If there's nothing to copy, just return the new list + if (source == null) + return il; + + il.TransparentColor = source.TransparentColor; + il.ColorDepth = source.ColorDepth; + + // Fill the imagelist with resized copies from the source + for (int i = 0; i < source.Images.Count; i++) { + Bitmap bm = this.MakeResizedImage(height, source.Images[i], source.TransparentColor); + il.Images.Add(bm); + } + + // Give each image the same key it has in the original + foreach (String key in source.Images.Keys) { + il.Images.SetKeyName(source.Images.IndexOfKey(key), key); + } + + return il; + } + + /// + /// Return a bitmap of the given height x height, which shows the given image, centred. + /// + /// Height and width of new bitmap + /// Image to be centred + /// The background color + /// A new bitmap + private Bitmap MakeResizedImage(int height, Image image, Color transparent) + { + Bitmap bm = new Bitmap(height, height); + Graphics g = Graphics.FromImage(bm); + g.Clear(transparent); + int x = Math.Max(0, (bm.Size.Width - image.Size.Width) / 2); + int y = Math.Max(0, (bm.Size.Height - image.Size.Height) / 2); + g.DrawImage(image, x, y, image.Size.Width, image.Size.Height); + return bm; + } + + #endregion + + #region Owner drawing + + /// + /// Owner draw the column header + /// + /// + protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e) + { + e.DrawDefault = true; + base.OnDrawColumnHeader(e); + } + + /// + /// Owner draw the item + /// + /// + protected override void OnDrawItem(DrawListViewItemEventArgs e) + { + // If there is a custom renderer installed for the primary column, + // and we're not in details view, give it a chance to draw the item. + // So the renderer on the primary column can have two distinct tasks, + // in details view, it draws the primary cell; in non-details view, + // it draws the whole item. + OLVColumn column = this.GetColumn(0); + if (this.View != View.Details && column.RendererDelegate != null) { + Object row = ((OLVListItem)e.Item).RowObject; + e.DrawDefault = !column.RendererDelegate(e, e.Graphics, e.Bounds, row); + } else + e.DrawDefault = (this.View != View.Details); + + if (e.DrawDefault) + base.OnDrawItem(e); + } + + int[] columnRightEdge = new int[256]; // will anyone ever want more than 256 columns?? + + /// + /// Owner draw a single subitem + /// + /// + protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e) + { + // Get the special renderer for this column. + // If there isn't one, use the default draw mechanism. + OLVColumn column = this.GetColumn(e.ColumnIndex); + if (column.RendererDelegate == null) { + e.DrawDefault = true; + return; + } + + // Calculate where the subitem should be drawn + // It should be as simple as 'e.Bounds', but it isn't :-( + + // There seems to be a bug in .NET where the left edge of the bounds of subitem 0 + // is always 0. This is normally what is required, but it's wrong when + // someone drags column 0 to somewhere else in the listview. We could + // drop down into Windows-ville and use LVM_GETSUBITEMRECT, but just to be different + // we keep track of the right edge of all columns, and when subitem 0 + // isn't being shown at column 0, we make its left edge to be the right + // edge of the previous column plus a little bit. + //TODO: Replace with LVM_GETSUBITEMRECT + Rectangle r = e.Bounds; + if (e.ColumnIndex == 0 && e.Header.DisplayIndex != 0) { + r.X = this.columnRightEdge[e.Header.DisplayIndex - 1] + 1; + } else + this.columnRightEdge[e.Header.DisplayIndex] = e.Bounds.Right; + + // Optimize drawing by only redrawing subitems that touch the area that was damaged +#if !MONO + if (!r.IntersectsWith(this.lastUpdateRectangle)) { + return; + } +#endif + // Get a graphics context for the renderer to use. + // But we have more complications. Virtual lists have a nasty habit of drawing column 0 + // whenever there is any mouse move events over a row, and doing it in an un-double buffered manner, + // which results in nasty flickers! There are also some unbuffered draw when a mouse is first + // hovered over column 0 of a normal row. So, to avoid all complications, + // we always manually double-buffer the drawing. + // Except with Mono, which doesn't seem to handle double buffering at all :-( + Graphics g = e.Graphics; + BufferedGraphics buffer = null; +#if !MONO + bool avoidFlickerMode = true; // set this to false to see the probems with flicker + if (avoidFlickerMode) { + buffer = BufferedGraphicsManager.Current.Allocate(e.Graphics, r); + g = buffer.Graphics; + } +#endif + // Finally, give the renderer a chance to draw something + Object row = ((OLVListItem)e.Item).RowObject; + e.DrawDefault = !column.RendererDelegate(e, g, r, row); + + if (!e.DrawDefault && buffer != null) { + buffer.Render(); + buffer.Dispose(); + } + } + + #endregion + + #region Selection Event Handling + + /// + /// This method is called every time a row is selected or deselected. This can be + /// a pain if the user shift-clicks 100 rows. We override this method so we can + /// trigger one event for any number of select/deselects that come from one user action + /// + /// + protected override void OnSelectedIndexChanged(EventArgs e) + { + base.OnSelectedIndexChanged(e); + + // If we haven't already scheduled an event, schedule it to be triggered + // By using idle time, we will wait until all select events for the same + // user action have finished before triggering the event. + if (!this.hasIdleHandler) { + this.hasIdleHandler = true; + Application.Idle += new EventHandler(Application_Idle); + } + } + private bool hasIdleHandler = false; + + /// + /// The application is idle. Trigger a SelectionChanged event. + /// + /// + /// + protected void Application_Idle(object sender, EventArgs e) + { + // Remove the handler before triggering the event + Application.Idle -= new EventHandler(Application_Idle); + this.hasIdleHandler = false; + + this.OnSelectionChanged(new EventArgs()); + } + + /// + /// This event is triggered once per user action that changes the selection state + /// of one or more rows. + /// + [Category("Behavior"), + Description("This event is triggered once per user action that changes the selection state of one or more rows.")] + public event EventHandler SelectionChanged; + + /// + /// Trigger the SelectionChanged event + /// + /// + virtual protected void OnSelectionChanged(EventArgs e) + { + if (this.SelectionChanged != null) + this.SelectionChanged(this, e); + } + + #endregion + + #region Cell editing + + // NOTES: + // + // - What event should we listen to? + // + // We can't use OnMouseClick, OnMouseDoubleClick, OnClick, or OnDoubleClick + // since they are not triggered for clicks on subitems without Full Row Select. + // + // We could use OnMouseDown, but selecting rows is done in OnMouseUp. This means + // that if we start the editing during OnMouseDown, the editor will automatically + // lose focus when mouse up happens. + // + + /// + /// We need the click count in the mouse up event, but that is always 1. + /// So we have to remember the click count from the preceding mouse down event. + /// + /// + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + this.lastMouseDownClickCount = e.Clicks; + } + private int lastMouseDownClickCount = 0; + + /// + /// Check to see if we need to start editing a cell + /// + /// + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + + // If it was an unmodified left click, check to see if we should start editing + if (this.ShouldStartCellEdit(e)) { + ListViewHitTestInfo info = this.HitTest(e.Location); + if (info.Item != null && info.SubItem != null) { + int subItemIndex = info.Item.SubItems.IndexOf(info.SubItem); + + // We don't edit the primary column by single clicks -- only subitems. + if (this.CellEditActivation != CellEditActivateMode.SingleClick || subItemIndex > 0) + this.EditSubItem((OLVListItem)info.Item, subItemIndex); + } + } + } + + /// + /// Should we start editing the cell? + /// + /// + /// + protected bool ShouldStartCellEdit(MouseEventArgs e) + { + if (e.Button != MouseButtons.Left) + return false; + + if ((Control.ModifierKeys & (Keys.Shift | Keys.Control | Keys.Alt)) != 0) + return false; + + if (this.lastMouseDownClickCount == 1 && this.CellEditActivation == CellEditActivateMode.SingleClick) + return true; + + return (this.lastMouseDownClickCount == 2 && this.CellEditActivation == CellEditActivateMode.DoubleClick); + } + + /// + /// Handle a key press on this control. We specifically look for F2 which edits the primary column, + /// or a Tab character during an edit operation, which tries to start editing on the next (or previous) cell. + /// + /// + /// + protected override bool ProcessDialogKey(Keys keyData) + { + bool isSimpleTabKey = ((keyData & Keys.KeyCode) == Keys.Tab) && ((keyData & (Keys.Alt | Keys.Control)) == Keys.None); + + if (isSimpleTabKey && this.IsCellEditing) { // Tab key while editing + // If the cell editing was cancelled, don't handle the tab + if (!this.PossibleFinishCellEditing()) + return true; + + // We can only Tab between columns when we are in Details view + if (this.View != View.Details) + return true; + + OLVListItem olvi = this.cellEditEventArgs.ListViewItem; + int subItemIndex = this.cellEditEventArgs.SubItemIndex; + int displayIndex = this.GetColumn(subItemIndex).DisplayIndex; + + // Move to the next or previous editable subitem, depending on Shift key. Wrap at the edges + List columnsInDisplayOrder = this.ColumnsInDisplayOrder; + do { + if ((keyData & Keys.Shift) == Keys.Shift) + displayIndex = (olvi.SubItems.Count + displayIndex - 1) % olvi.SubItems.Count; + else + displayIndex = (displayIndex + 1) % olvi.SubItems.Count; + } while (!columnsInDisplayOrder[displayIndex].IsEditable); + + // If we found a different editable cell, start editing it + subItemIndex = columnsInDisplayOrder[displayIndex].Index; + if (this.cellEditEventArgs.SubItemIndex != subItemIndex) { + this.StartCellEdit(olvi, subItemIndex); + return true; + } + } + + // Treat F2 as a request to edit the primary column + if (keyData == Keys.F2 && !this.IsCellEditing) { + this.EditSubItem((OLVListItem)this.FocusedItem, 0); + return true; + } + + // We have to catch Return/Enter/Escape here since some types of controls + // (e.g. ComboBox, UserControl) don't trigger key events that we can listen for. + // Treat Return or Enter as committing the current edit operation + if ((keyData == Keys.Return || keyData == Keys.Enter) && this.IsCellEditing) { + this.PossibleFinishCellEditing(); + return true; + } + + // Treat Escaoe as cancel the current edit operation + if (keyData == Keys.Escape && this.IsCellEditing) { + this.CancelCellEdit(); + return true; + } + + // Treat Ctrl-C as Copy To Clipboard. We still allow the default processing + if ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.KeyCode) == Keys.C) + this.CopySelectionToClipboard(); + + return base.ProcessDialogKey(keyData); + } + + /// + /// Begin an edit operation on the given cell. + /// + /// This performs various sanity checks and passes off the real work to StartCellEdit(). + /// The row to be edited + /// The index of the cell to be edited + public void EditSubItem(OLVListItem item, int subItemIndex) + { + if (item == null) + return; + + if (subItemIndex < 0 && subItemIndex >= item.SubItems.Count) + return; + + if (this.CellEditActivation == CellEditActivateMode.None) + return; + + if (!this.GetColumn(subItemIndex).IsEditable) + return; + + this.StartCellEdit(item, subItemIndex); + } + + /// + /// Really start an edit operation on a given cell. The parameters are assumed to be sane. + /// + /// The row to be edited + /// The index of the cell to be edited + protected void StartCellEdit(OLVListItem item, int subItemIndex) + { + OLVColumn column = this.GetColumn(subItemIndex); + Rectangle r = this.CalculateCellBounds(item, subItemIndex); + Control c = this.GetCellEditor(item, subItemIndex); + c.Bounds = r; + + // Try to align the control as the column is aligned. Not all controls support this property + PropertyInfo pinfo = c.GetType().GetProperty("TextAlign"); + if (pinfo != null) + pinfo.SetValue(c, column.TextAlign, null); + + // Give the control the value from the model + this.SetControlValue(c, column.GetValue(item.RowObject), column.GetStringValue(item.RowObject)); + + // Give the outside world the chance to munge with the process + this.cellEditEventArgs = new CellEditEventArgs(column, c, r, item, subItemIndex); + this.OnCellEditStarting(this.cellEditEventArgs); + if (this.cellEditEventArgs.Cancel) + return; + + // The event handler may have completely changed the control, so we need to remember it + this.cellEditor = this.cellEditEventArgs.Control; + + // If the control isn't the height of the cell, centre it vertically. We don't + // need to do this when in Tile view. + if (this.View != View.Tile && this.cellEditor.Height != r.Height) + this.cellEditor.Top += (r.Height - this.cellEditor.Height) / 2; + + this.Controls.Add(this.cellEditor); + this.ConfigureControl(); + this.PauseAnimations(true); + } + private Control cellEditor = null; + private CellEditEventArgs cellEditEventArgs = null; + + /// + /// Try to give the given value to the provided control. Fall back to assigning a string + /// if the value assignment fails. + /// + /// A control + /// The value to be given to the control + /// The string to be given if the value doesn't work + protected void SetControlValue(Control c, Object value, String stringValue) + { + // Look for a property called "Value". We have to look twice, the first time might get an ambiguous + PropertyInfo pinfo = null; + try { + pinfo = c.GetType().GetProperty("Value"); + } catch (AmbiguousMatchException) { + // The lowest level class of the control must have overridden the "Value" property. + // We now have to specifically look for only public instance properties declared in the lowest level class. + pinfo = c.GetType().GetProperty("Value", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); + } + + // If we found it, use it to assign a value, otherwise simply set the text + if (pinfo != null) { + try { + pinfo.SetValue(c, value, null); + return; + } catch (TargetInvocationException) { + // Not a lot we can do about this one. Something went wrong in the bowels + // of the method. Let's take the ostrich approach and just ignore it :-) + } catch (ArgumentException) { + } + } + + // There wasn't a Value property, or we couldn't set it, so set the text instead + try { + if (value is String) + c.Text = (String)value; + else + c.Text = stringValue; + } catch (ArgumentOutOfRangeException) { + // The value couldn't be set via the Text property. + } + } + + /// + /// Setup the given control to be a cell editor + /// + protected void ConfigureControl() + { + this.cellEditor.Validating += new CancelEventHandler(CellEditor_Validating); + this.cellEditor.Select(); + } + + /// + /// Return the value that the given control is showing + /// + /// + /// + protected Object GetControlValue(Control c) + { + try { + return c.GetType().InvokeMember("Value", BindingFlags.GetProperty, null, c, null); + } catch (MissingMethodException) { // Microsoft throws this + return c.Text; + } catch (MissingFieldException) { // Mono throws this + return c.Text; + } + } + + /// + /// Called when the cell editor could be about to lose focus. Time to commit the change + /// + /// + /// + private void CellEditor_Validating(object sender, CancelEventArgs e) + { + this.cellEditEventArgs.Cancel = false; + this.OnCellEditorValidating(this.cellEditEventArgs); + + if (this.cellEditEventArgs.Cancel) { + this.cellEditEventArgs.Control.Select(); + e.Cancel = true; + } else + FinishCellEdit(); + } + + /// + /// Return the bounds of the given cell + /// + /// The row to be edited + /// The index of the cell to be edited + /// A Rectangle + protected Rectangle CalculateCellBounds(OLVListItem item, int subItemIndex) + { + // Item 0 is special. Its bounds include all subitems. To get just the bounds + // of cell for item 0, we have to use GetItemRect(). + if (subItemIndex == 0) { + return this.GetItemRect(item.Index, ItemBoundsPortion.Label); + } else + return item.SubItems[subItemIndex].Bounds; + } + + /// + /// Return a control that can be used to edit the value of the given cell. + /// + /// The row to be edited + /// The index of the cell to be edited + /// + protected Control GetCellEditor(OLVListItem item, int subItemIndex) + { + OLVColumn column = this.GetColumn(subItemIndex); + Object value = column.GetValue(item.RowObject); + + //THINK: Do we want to use a Registry instead of this cascade? + if (value is Boolean) + return new BooleanCellEditor(); + + if (value is DateTime) { + DateTimePicker c = new DateTimePicker(); + c.Format = DateTimePickerFormat.Short; + return c; + } + if (value is Int32 || value is Int16 || value is Int64) + return new IntUpDown(); + + if (value is UInt16 || value is UInt32 || value is UInt64) + return new UintUpDown(); + + if (value is Single || value is Double) + return new FloatCellEditor(); + + return this.MakeDefaultCellEditor(column); + } + + /// + /// Return a TextBox that can be used as a default cell editor. + /// + /// What column does the cell belong to? + /// + private Control MakeDefaultCellEditor(OLVColumn column) + { + TextBox tb = new TextBox(); + String str; + + // Build a list of unique values, to be used as autocomplete on the editor + Dictionary alreadySeen = new Dictionary(); + for (int i = 0; i < Math.Min(this.GetItemCount(), 1000); i++) { + Object value = column.GetValue(this.GetModelObject(i)); + if (value is String) + str = (String)value; + else + str = column.ValueToString(value); + if (!alreadySeen.ContainsKey(str)) { + tb.AutoCompleteCustomSource.Add(str); + alreadySeen[str] = true; + } + } + + tb.AutoCompleteSource = AutoCompleteSource.CustomSource; + tb.AutoCompleteMode = AutoCompleteMode.Append; + + return tb; + } + + /// + /// Stop editing a cell and throw away any changes. + /// + protected void CancelCellEdit() + { + // Let the world know that the user has cancelled the edit operation + this.cellEditEventArgs.Cancel = true; + this.OnCellEditFinishing(this.cellEditEventArgs); + + // Now cleanup the editing process + this.CleanupCellEdit(); + } + + /// + /// If a cell edit is in progress, finish the edit + /// + /// Returns false if the finishing process was cancelled + /// (i.e. the cell editor is still on screen) + protected bool PossibleFinishCellEditing() + { + if (this.IsCellEditing) { + this.cellEditEventArgs.Cancel = false; + this.OnCellEditorValidating(this.cellEditEventArgs); + + if (this.cellEditEventArgs.Cancel) + return false; + + FinishCellEdit(); + } + + return true; + } + + /// + /// Finish the cell edit operation, writing changed data back to the model object + /// + protected void FinishCellEdit() + { + this.cellEditEventArgs.Cancel = false; + this.OnCellEditFinishing(this.cellEditEventArgs); + + // If someone doesn't cancel the editing process, write the value back into the model + if (!this.cellEditEventArgs.Cancel) { + Object value = this.GetControlValue(this.cellEditor); + this.cellEditEventArgs.Column.PutValue(this.cellEditEventArgs.RowObject, value); + this.RefreshItem(this.cellEditEventArgs.ListViewItem); + } + + this.CleanupCellEdit(); + } + + /// + /// Remove all trace of any existing cell edit operation + /// + protected void CleanupCellEdit() + { + if (this.cellEditor == null) + return; + + this.cellEditor.Validating -= new CancelEventHandler(CellEditor_Validating); + this.Controls.Remove(this.cellEditor); + this.cellEditor.Dispose(); //THINK: do we need to call this? + this.cellEditor = null; + this.Select(); + this.PauseAnimations(false); + } + + /// + /// The callbacks for CellEditing events + /// + public delegate void CellEditEventHandler(object sender, CellEditEventArgs e); + + /// + /// Triggered when a cell is about to be edited. + /// + /// Set Cancel to true to prevent the cell being edited. + /// You can change the the Control to be something completely different. + [Category("Behavior")] + public event CellEditEventHandler CellEditStarting; + + /// + /// Triggered when a cell editor needs to be validated + /// + /// + /// If this event is cancelled, focus will remain on the cell editor. + /// + [Category("Behavior")] + public event CellEditEventHandler CellEditValidating; + + /// + /// Triggered when a cell is about to finish being edited. + /// + /// If Cancel is already true, the user is cancelling the edit operation. + /// Set Cancel to true to prevent the value from the cell being written into the model. + /// You cannot prevent the editing from finishing. + [Category("Behavior")] + public event CellEditEventHandler CellEditFinishing; + + /// + /// Tell the world when a cell is about to be edited. + /// + protected virtual void OnCellEditStarting(CellEditEventArgs e) + { + if (this.CellEditStarting != null) + this.CellEditStarting(this, e); + } + + /// + /// Tell the world when a cell is about to finish being edited. + /// + protected virtual void OnCellEditorValidating(CellEditEventArgs e) + { + // Hack. ListView is an imperfect control container. It does not manage validation + // perfectly. If the ListView is part of a TabControl, and the cell editor loses + // focus by the user clicking on another tab, the TabControl processes the click + // and switches tabs, even if this Validating event cancels. This results in the + // strange situation where the cell editor is active, but isn't visible. When the + // user switches back to the tab with the ListView, composite controls like spin + // controls, DateTimePicker and ComboBoxes do not work properly. Specifically, + // keyboard input still works fine, but the controls do not respond to mouse + // input. SO, if the validation fails, we have to specifically give focus back to + // the cell editor. (this is the Select() call in the code below). But (there is + // always a 'but'), doing that changes the focus so the cell editor + // triggers another Validating event -- which fails again. From the user's point + // of view, they click away from the cell editor, and the validating code + // complains twice. So we only trigger a Validating event if more than 0.1 seconds + // has elapsed since the last validate event. + // I know it's a hack. I'm very open to hear a neater solution. + + // Also, this timed response stops us from sending a series of validation events + // if the user clicks and holds on the OLV scroll bar. + if ((Environment.TickCount - lastValidatingEvent) < 500) { + e.Cancel = true; + } else { + lastValidatingEvent = Environment.TickCount; + if (this.CellEditValidating != null) + this.CellEditValidating(this, e); + } + lastValidatingEvent = Environment.TickCount; + } + private int lastValidatingEvent = 0; + + /// + /// Tell the world when a cell is about to finish being edited. + /// + protected virtual void OnCellEditFinishing(CellEditEventArgs e) + { + if (this.CellEditFinishing != null) + this.CellEditFinishing(this, e); + } + + /// + /// Let the world know that a cell edit operation is beginning or ending + /// + public class CellEditEventArgs : EventArgs + { + /// + /// Create an event args + /// + /// + /// + /// + /// + /// + public CellEditEventArgs(OLVColumn column, Control c, Rectangle r, OLVListItem item, int subItemIndex) + { + this.Cancel = false; + this.Control = c; + this.column = column; + this.cellBounds = r; + this.listViewItem = item; + this.rowObject = item.RowObject; + this.subItemIndex = subItemIndex; + this.value = column.GetValue(item.RowObject); + } + + /// + /// Change this to true to cancel the cell editing operation. + /// + /// + /// During the CellEditStarting event, setting this to true will prevent the cell from being edited. + /// During the CellEditFinishing event, if this value is already true, this indicates that the user has + /// cancelled the edit operation and that the handler should perform cleanup only. Setting this to true, + /// will prevent the ObjectListView from trying to write the new value into the model object. + /// + public bool Cancel = false; + + /// + /// During the CellEditStarting event, this can be modified to be the control that you want + /// to edit the value. You must fully configure the control before returning from the event, + /// including its bounds and the value it is showing. + /// During the CellEditFinishing event, you can use this to get the value that the user + /// entered and commit that value to the model. Changing the control during the finishing + /// event has no effect. + /// + public Control Control = null; + + /// + /// The column of the cell that is going to be or has been edited. + /// + public OLVColumn Column + { + get { return this.column; } + } + private OLVColumn column; + + /// + /// The model object of the row of the cell that is going to be or has been edited. + /// + public Object RowObject + { + get { return this.rowObject; } + } + private Object rowObject; + + /// + /// The listview item of the cell that is going to be or has been edited. + /// + public OLVListItem ListViewItem + { + get { return this.listViewItem; } + } + private OLVListItem listViewItem; + + /// + /// The index of the cell that is going to be or has been edited. + /// + public int SubItemIndex + { + get { return this.subItemIndex; } + } + private int subItemIndex; + + /// + /// The data value of the cell before the edit operation began. + /// + public Object Value + { + get { return this.value; } + } + private Object value; + + /// + /// The bounds of the cell that is going to be or has been edited. + /// + public Rectangle CellBounds + { + get { return this.cellBounds; } + } + private Rectangle cellBounds; + } + + //----------------------------------------------------------------------- + // Cell editors + // These classes are simple cell editors that make it easier to get and set + // the value that the control is showing. + + /// + /// This editor simply shows and edits integer values. + /// + internal class IntUpDown : NumericUpDown + { + public IntUpDown() + { + this.DecimalPlaces = 0; + this.Minimum = -9999999; + this.Maximum = 9999999; + } + + new public int Value + { + get { return Decimal.ToInt32(base.Value); } + set { base.Value = new Decimal(value); } + } + } + + /// + /// This editor simply shows and edits unsigned integer values. + /// + internal class UintUpDown : NumericUpDown + { + public UintUpDown() + { + this.DecimalPlaces = 0; + this.Minimum = 0; + this.Maximum = 9999999; + } + + new public uint Value + { + get { return Decimal.ToUInt32(base.Value); } + set { base.Value = new Decimal(value); } + } + } + + /// + /// This editor simply shows and edits boolean values. + /// + /// You can intercept the CellEditStarting event if you want + /// to change the characteristics of the editor. For example, by changing + /// the labels to "No" and "Yes". The false value must come first. + internal class BooleanCellEditor : ComboBox + { + public BooleanCellEditor() + { + this.DropDownStyle = ComboBoxStyle.DropDownList; + this.Items.AddRange(new String[] { "False", "True" }); // needs to be localizable + } + + public bool Value + { + get { return this.SelectedIndex == 1; } + set + { + if (value) + this.SelectedIndex = 1; + else + this.SelectedIndex = 0; + } + } + } + + /// + /// This editor simply shows and edits floating point values. + /// + /// You can intercept the CellEditStarting event if you want + /// to change the characteristics of the editor. For example, by increasing + /// the number of decimal places. + internal class FloatCellEditor : NumericUpDown + { + public FloatCellEditor() + { + this.DecimalPlaces = 2; + this.Minimum = -9999999; + this.Maximum = 9999999; + } + + new public double Value + { + get { return Convert.ToDouble(base.Value); } + set { base.Value = Convert.ToDecimal(value); } + } + } + + /// + /// This editor shows and auto completes values from the given listview column. + /// + internal class AutoCompleteCellEditor : ComboBox + { + public AutoCompleteCellEditor(ObjectListView lv, OLVColumn column) + { + this.DropDownStyle = ComboBoxStyle.DropDown; + + Dictionary alreadySeen = new Dictionary(); + for (int i = 0; i < Math.Min(lv.GetItemCount(), 1000); i++) { + String str = column.GetStringValue(lv.GetModelObject(i)); + if (!alreadySeen.ContainsKey(str)) { + this.Items.Add(str); + alreadySeen[str] = true; + } + } + + this.Sorted = true; + this.AutoCompleteSource = AutoCompleteSource.ListItems; + this.AutoCompleteMode = AutoCompleteMode.Append; + } + } + + /// + /// Return a collection of columns that are appropriate to the given view. + /// Only Tile and Details have columns; all other views have 0 columns. + /// + /// Which view are the columns being calculate for? + /// A list of columns + public List GetFilteredColumns(View view) + { + // For both detail and tile view, the first column must be included. Normally, we would + // use the ColumnHeader.Index property, but if the header is not currently part of a ListView + // that property returns -1. So, we track the index of + // the column header, and always include the first header. + + int index = 0; + switch (view) { + case View.Details: + return this.AllColumns.FindAll(delegate(OLVColumn x) { return (index++ == 0) || x.IsVisible; }); + case View.Tile: + return this.AllColumns.FindAll(delegate(OLVColumn x) { return (index++ == 0) || x.IsTileViewColumn; }); + default: + return new List(); ; + } + } + + #endregion + + #region Design Time + + /// + /// This class works in conjunction with the OLVColumns property to allow OLVColumns + /// to be added to the ObjectListView. + /// + internal class OLVColumnCollectionEditor : System.ComponentModel.Design.CollectionEditor + { + public OLVColumnCollectionEditor(Type t) + : base(t) + { + } + + protected override Type CreateCollectionItemType() + { + return typeof(OLVColumn); + } + + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + ListView.ColumnHeaderCollection cols = (ListView.ColumnHeaderCollection)value; + + // Hack to figure out which ObjectListView we are working on + ObjectListView olv; + if (cols.Count == 0) { + cols.Add(new OLVColumn()); + olv = (ObjectListView)cols[0].ListView; + cols.Clear(); + olv.AllColumns.Clear(); + } else + olv = (ObjectListView)cols[0].ListView; + + // Edit all the columns, not just the ones that are visible + base.EditValue(context, provider, olv.AllColumns); + + // Calculate just the visible columns + List newColumns = olv.GetFilteredColumns(View.Details); + olv.Columns.Clear(); + olv.Columns.AddRange(newColumns.ToArray()); + + return olv.Columns; + } + } + + /// + /// Return Columns for this list. We hide the original so we can associate + /// a specialised editor with it. + /// + [Editor(typeof(OLVColumnCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))] + new public ListView.ColumnHeaderCollection Columns + { + get + { + return base.Columns; + } + } + + #endregion + + + /// + /// Which column did we last sort by + /// + public OLVColumn LastSortColumn + { + get { return lastSortColumn; } + set { lastSortColumn = value; } + } + private OLVColumn lastSortColumn; + + /// + /// Which direction did we last sort + /// + public SortOrder LastSortOrder + { + get { return lastSortOrder; } + set { lastSortOrder = value; } + } + private SortOrder lastSortOrder; + + private Rectangle lastUpdateRectangle; // remember the update rect from the last WM_PAINT msg + private bool isOwnerOfObjects; // does this ObjectListView own the Objects collection? + } + + /// + /// Wrapper for all native method calls on ListView controls + /// + internal class NativeMethods + { + + private const int LVM_FIRST = 0x1000; + private const int LVM_GETHEADER = LVM_FIRST + 31; + private const int LVM_SETITEMSTATE = LVM_FIRST + 43; + private const int LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54; + private const int LVM_SETITEM = LVM_FIRST + 76; + private const int LVM_GETCOLUMN = LVM_FIRST + 95; + private const int LVM_SETCOLUMN = LVM_FIRST + 96; + + private const int LVS_EX_SUBITEMIMAGES = 0x0002; + + private const int LVIF_TEXT = 0x0001; + private const int LVIF_IMAGE = 0x0002; + private const int LVIF_PARAM = 0x0004; + private const int LVIF_STATE = 0x0008; + private const int LVIF_INDENT = 0x0010; + private const int LVIF_NORECOMPUTE = 0x0800; + + private const int LVCF_FMT = 0x0001; + private const int LVCF_WIDTH = 0x0002; + private const int LVCF_TEXT = 0x0004; + private const int LVCF_SUBITEM = 0x0008; + private const int LVCF_IMAGE = 0x0010; + private const int LVCF_ORDER = 0x0020; + private const int LVCFMT_LEFT = 0x0000; + private const int LVCFMT_RIGHT = 0x0001; + private const int LVCFMT_CENTER = 0x0002; + private const int LVCFMT_JUSTIFYMASK = 0x0003; + + private const int LVCFMT_IMAGE = 0x0800; + private const int LVCFMT_BITMAP_ON_RIGHT = 0x1000; + private const int LVCFMT_COL_HAS_IMAGES = 0x8000; + + private const int HDM_FIRST = 0x1200; + private const int HDM_HITTEST = HDM_FIRST + 6; + private const int HDM_GETITEM = HDM_FIRST + 11; + private const int HDM_SETITEM = HDM_FIRST + 12; + + private const int HDI_WIDTH = 0x0001; + private const int HDI_TEXT = 0x0002; + private const int HDI_FORMAT = 0x0004; + private const int HDI_BITMAP = 0x0010; + private const int HDI_IMAGE = 0x0020; + + private const int HDF_LEFT = 0x0000; + private const int HDF_RIGHT = 0x0001; + private const int HDF_CENTER = 0x0002; + private const int HDF_JUSTIFYMASK = 0x0003; + private const int HDF_RTLREADING = 0x0004; + private const int HDF_STRING = 0x4000; + private const int HDF_BITMAP = 0x2000; + private const int HDF_BITMAP_ON_RIGHT = 0x1000; + private const int HDF_IMAGE = 0x0800; + private const int HDF_SORTUP = 0x0400; + private const int HDF_SORTDOWN = 0x0200; + + private const int SB_HORZ = 0; + private const int SB_VERT = 1; + private const int SB_CTL = 2; + private const int SB_BOTH = 3; + + private const int SIF_RANGE = 0x0001; + private const int SIF_PAGE = 0x0002; + private const int SIF_POS = 0x0004; + private const int SIF_DISABLENOSCROLL = 0x0008; + private const int SIF_TRACKPOS = 0x0010; + private const int SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS); + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + private struct LVITEM + { + public int mask; + public int iItem; + public int iSubItem; + public int state; + public int stateMask; + [MarshalAs(UnmanagedType.LPTStr)] + public string pszText; + public int cchTextMax; + public int iImage; + public IntPtr lParam; + // These are available in Common Controls >= 0x0300 + public int iIndent; + // These are available in Common Controls >= 0x056 + public int iGroupId; + public int cColumns; + public IntPtr puColumns; + }; + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + private struct LVCOLUMN + { + public int mask; + public int fmt; + public int cx; + [MarshalAs(UnmanagedType.LPTStr)] + public string pszText; + public int cchTextMax; + public int iSubItem; + // These are available in Common Controls >= 0x0300 + public int iImage; + public int iOrder; + }; + + /// + /// Notify message header structure. + /// + [StructLayout(LayoutKind.Sequential)] + public struct NMHDR + { + public IntPtr hwndFrom; + public IntPtr idFrom; + public int code; + } + + [StructLayout(LayoutKind.Sequential)] + public struct NMHEADER + { + public NMHDR nhdr; + public int iItem; + public int iButton; + public IntPtr pHDITEM; + } + + [StructLayout(LayoutKind.Sequential)] + public struct HDITEM + { + public int mask; + public int cxy; + public IntPtr pszText; + public IntPtr hbm; + public int cchTextMax; + public int fmt; + public IntPtr lParam; + public int iImage; + public int iOrder; + //if (_WIN32_IE >= 0x0500) + public int type; + public IntPtr pvFilter; + } + + [StructLayout(LayoutKind.Sequential)] + public class HDHITTESTINFO + { + public int pt_x; + public int pt_y; + public int flags; + public int iItem; + } + + [StructLayout(LayoutKind.Sequential)] + public class SCROLLINFO + { + public int cbSize; + public int fMask; + public int nMin; + public int nMax; + public int nPage; + public int nPos; + public int nTrackPos; + public SCROLLINFO() + { + this.cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO)); + } + } + + // Various flavours of SendMessage: plain vanilla, and passing references to various structures + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); + [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] + private static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi); + [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] + private static extern IntPtr SendMessageLVColumn(IntPtr hWnd, int msg, int wParam, ref LVCOLUMN lvc); + [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] + private static extern IntPtr SendMessageHDItem(IntPtr hWnd, int msg, int wParam, ref HDITEM hdi); + [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] + public static extern IntPtr SendMessageHDHITTESTINFO(IntPtr hWnd, int Msg, IntPtr wParam, [In, Out] HDHITTESTINFO lParam); + + // Entry points used by this code + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, SCROLLINFO si); + + [DllImport("user32.dll", EntryPoint = "GetUpdateRect", CharSet = CharSet.Auto)] + private static extern IntPtr GetUpdateRectInternal(IntPtr hWnd, ref Rectangle r, bool eraseBackground); + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern bool SetScrollInfo(IntPtr hWnd, int fnBar, SCROLLINFO si, bool fRedraw); + + [DllImport("user32.dll", EntryPoint = "ValidateRect", CharSet = CharSet.Auto)] + private static extern IntPtr ValidatedRectInternal(IntPtr hWnd, ref Rectangle r); + + /// + /// Make sure the ListView has the extended style that says to display subitem images. + /// + /// This method must be called after any .NET call that update the extended styles + /// since they seem to erase this setting. + /// The listview to send a message to + public static void ForceSubItemImagesExStyle(ListView list) + { + SendMessage(list.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_SUBITEMIMAGES, LVS_EX_SUBITEMIMAGES); + } + + /// + /// For the given item and subitem, make it display the given image + /// + /// The listview to send a message to + /// row number (0 based) + /// subitem (0 is the item itself) + /// index into the image list + public static void SetSubItemImage(ListView list, int itemIndex, int subItemIndex, int imageIndex) + { + LVITEM lvItem = new LVITEM(); + lvItem.mask = LVIF_IMAGE; + lvItem.iItem = itemIndex; + lvItem.iSubItem = subItemIndex; + lvItem.iImage = imageIndex; + SendMessageLVItem(list.Handle, LVM_SETITEM, 0, ref lvItem); + } + + /// + /// Setup the given column of the listview to show the given image to the right of the text. + /// If the image index is -1, any previous image is cleared + /// + /// The listview to send a message to + /// Index of the column to modifiy + /// + /// Index into the small image list + public static void SetColumnImage(ListView list, int columnIndex, SortOrder order, int imageIndex) + { + IntPtr hdrCntl = NativeMethods.GetHeaderControl(list); + if (hdrCntl.ToInt32() == 0) + return; + + HDITEM item = new HDITEM(); + item.mask = HDI_FORMAT; + IntPtr result = SendMessageHDItem(hdrCntl, HDM_GETITEM, columnIndex, ref item); + + item.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN | HDF_IMAGE | HDF_BITMAP_ON_RIGHT); + + if (NativeMethods.HasBuiltinSortIndicators()) { + if (order == SortOrder.Ascending) + item.fmt |= HDF_SORTUP; + if (order == SortOrder.Descending) + item.fmt |= HDF_SORTDOWN; + } else { + item.mask |= HDI_IMAGE; + item.fmt |= (HDF_IMAGE | HDF_BITMAP_ON_RIGHT); + item.iImage = imageIndex; + } + + result = SendMessageHDItem(hdrCntl, HDM_SETITEM, columnIndex, ref item); + } + + /// + /// Does this version of the operating system have builtin sort indicators? + /// + /// Are there builtin sort indicators + /// XP and later have these + public static bool HasBuiltinSortIndicators() + { + return OSFeature.Feature.GetVersionPresent(OSFeature.Themes) != null; + } + + /// + /// Return the bounds of the update region on the given control. + /// + /// The BeginPaint() system call validates the update region, effectively wiping out this information. + /// So this call has to be made before the BeginPaint() call. + /// The control whose update region is be calculated + /// A rectangle + public static Rectangle GetUpdateRect(Control cntl) + { + Rectangle r = new Rectangle(); + GetUpdateRectInternal(cntl.Handle, ref r, false); + return r; + } + + /// + /// Validate an area of the given control. A validated area will not be repainted at the next redraw. + /// + /// The control to be validated + /// The area of the control to be validated + public static void ValidateRect(Control cntl, Rectangle r) + { + ValidatedRectInternal(cntl.Handle, ref r); + } + + /// + /// Select all rows on the given listview + /// + /// The listview whose items are to be selected + public static void SelectAllItems(ListView list) + { + NativeMethods.SetItemState(list, -1, 2, 2); + } + + /// + /// Deselect all rows on the given listview + /// + /// The listview whose items are to be deselected + public static void DeselectAllItems(ListView list) + { + NativeMethods.SetItemState(list, -1, 2, 0); + } + + /// + /// Set the item state on the given item + /// + /// The listview whose item's state is to be changed + /// The index of the item to be changed + /// Which bits of the value are to be set? + /// The value to be set + public static void SetItemState(ListView list, int itemIndex, int mask, int value) + { + LVITEM lvItem = new LVITEM(); + lvItem.stateMask = mask; + lvItem.state = value; + SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem); + } + + /// + /// Return the handle to the header control on the given list + /// + /// The listview whose header control is to be returned + /// The handle to the header control + public static IntPtr GetHeaderControl(ListView list) + { + return SendMessage(list.Handle, LVM_GETHEADER, 0, 0); + } + + /// + /// Return the index of the divider under the given point. Return -1 if no divider is under the pt + /// + /// The list we are interested in + /// The client co-ords + /// The index of the divider under the point, or -1 if no divider is under that point + public static int GetDividerUnderPoint(IntPtr handle, Point pt) + { + const int HHT_ONDIVIDER = 4; + return NativeMethods.HeaderControlHitTest(handle, pt, HHT_ONDIVIDER); + } + + /// + /// Return the index of the column of the header that is under the given point. + /// Return -1 if no column is under the pt + /// + /// The list we are interested in + /// The client co-ords + /// The index of the column under the point, or -1 if no column header is under that point + public static int GetColumnUnderPoint(IntPtr handle, Point pt) + { + const int HHT_ONHEADER = 2; + return NativeMethods.HeaderControlHitTest(handle, pt, HHT_ONHEADER); + } + + private static int HeaderControlHitTest(IntPtr handle, Point pt, int flag) + { + HDHITTESTINFO testInfo = new HDHITTESTINFO(); + testInfo.pt_x = pt.X; + testInfo.pt_y = pt.Y; + IntPtr result = NativeMethods.SendMessageHDHITTESTINFO(handle, HDM_HITTEST, IntPtr.Zero, testInfo); + if ((testInfo.flags & flag) != 0) + return result.ToInt32(); + else + return -1; + } + + /// + /// Get the scroll position of the given scroll bar + /// + /// + /// + /// + public static int GetScrollPosition(IntPtr handle, bool horizontalBar) + { + int fnBar = (horizontalBar ? SB_HORZ : SB_VERT); + + SCROLLINFO si = new SCROLLINFO(); + si.fMask = SIF_POS; + if (GetScrollInfo(handle, fnBar, si)) + return si.nPos; + else + return -1; + } + } + + /// + /// A virtual object list view operates in virtual mode, that is, it only gets model objects for + /// a row when it is needed. This gives it the ability to handle very large numbers of rows with + /// minimal resources. + /// + /// A listview is not a great user interface for a large number of items. But if you've + /// ever wanted to have a list with 10 million items, go ahead, knock yourself out. + /// Virtual lists can never iterate their contents. That would defeat the whole purpose. + /// Given the above, grouping and sorting are not possible on virtual lists. But if the backing data store has + /// a sorting mechanism, a CustomSorter can be installed which will be called when the sorting is required. + /// For the same reason, animate GIFs should not be used in virtual lists. Animated GIFs require some state + /// information to be stored for each animation, but virtual lists specifically do not keep any state information. + /// You really do not want to keep state information for 10 million animations! + /// + public class VirtualObjectListView : ObjectListView + { + /// + /// Create a VirtualObjectListView + /// + public VirtualObjectListView() + : base() + { + this.ShowGroups = false; // virtual lists can never show groups + this.VirtualMode = true; + this.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(this.HandleRetrieveVirtualItem); + + // Install a null custom sorter to turn off sorting. Who wants to fetch and sort 10 million items? + this.CustomSorter = delegate(OLVColumn column, SortOrder sortOrder) { }; + } + + #region Public Properties + + /// + /// This delegate is used to fetch a rowObject, given it's index within the list + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public RowGetterDelegate RowGetter + { + get { return rowGetter; } + set { rowGetter = value; } + } + + #endregion + + #region OLV accessing + + /// + /// Return the number of items in the list + /// + /// the number of items in the list + override public int GetItemCount() + { + return this.VirtualListSize; + } + + /// + /// Return the item at the given index + /// + /// Index of the item to be returned + /// An OLVListItem + override public OLVListItem GetItem(int index) + { + return (OLVListItem)this.Items[index]; + } + + /// + /// Return the model object at the given index + /// + /// Index of the model object to be returned + /// A model object + override public object GetModelObject(int index) + { + return this.GetRowObjectAt(index); + } + + #endregion + + #region Object manipulation + + /// + /// Remove all items from this list + /// + /// This method can safely be called from background threads. + override public void ClearObjects() + { + if (this.InvokeRequired) + this.Invoke(new MethodInvoker(ClearObjects)); + else { + this.ClearCachedInfo(); + this.VirtualListSize = 0; + } + } + + /// + /// Select the row that is displaying the given model object. + /// This does nothing in virtual lists. + /// + /// This is a no-op for virtual lists, since there is no way to map the model + /// object back to the ListViewItem that represents it. + /// The object that gave data + override public void SelectObject(object modelObject) + { + // do nothing + } + + /// + /// Select the rows that is displaying any of the given model object. + /// This does nothing in virtual lists. + /// + /// This is a no-op for virtual lists, since there is no way to map the model + /// objects back to the ListViewItem that represents them. + /// A collection of model objects + override public void SelectObjects(IList modelObjects) + { + // do nothing + } + + /// + /// Update the rows that are showing the given objects + /// + /// This is a no-op for virtual lists, since there is no way to map the model + /// objects back to the ListViewItem that represents them. + override public void RefreshObjects(IList modelObjects) + { + // do nothing + } + + /// + /// Add the given collection of model objects to this control. + /// + /// A collection of model objects + /// This is a no-op for virtual lists, since the control + /// does not have a list of model objects to which it can add this new one. + /// All model object management is done by the application. + override public void AddObjects(ICollection modelObjects) + { + } + + /// + /// Remove all of the given objects from the control + /// + /// Collection of objects to be removed + /// This is a no-op for virtual lists, since the control + /// does not have a list of model objects from which it can remove these ones. + /// All model object management is done by the application. + override public void RemoveObjects(ICollection modelObjects) + { + } + + #endregion + + #region Commands + + /// + /// Invalidate any cached information when we rebuild the list. + /// + public override void BuildList(bool shouldPreserveSelection) + { + this.ClearCachedInfo(); + this.Invalidate(); + } + + /// + /// Prepare the listview to show alternate row backcolors + /// + /// Alternate colored backrows can't be handle in the same way as our base class. + /// With virtual lists, they are handled at RetrieveVirtualItem time. + protected override void PrepareAlternateBackColors() + { + // do nothing + } + + /// + /// Refresh the given item in the list + /// + /// The item to refresh + public override void RefreshItem(OLVListItem olvi) + { + this.ClearCachedInfo(); + this.Invalidate(); + } + + #endregion + + #region Event handlers + + /// + /// Handle a mouse down event + /// + /// + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + // Did the user click the state icon? If so and check boxes are enable, toggle + // the clicked row. If the given row is selected, all selected rows are given + // the same checkedness. + ListViewHitTestInfo htInfo = this.HitTest(e.Location); + if (this.CheckBoxes && (htInfo.Location & ListViewHitTestLocations.StateImage) != 0) { + OLVListItem clickedItem = (OLVListItem)htInfo.Item; + this.ChangeCheckItem(clickedItem, clickedItem.Checked, !clickedItem.Checked); + if (clickedItem.Selected) { + foreach (int i in this.SelectedIndices) { + OLVListItem olvi = this.GetItem(i); + if (olvi.Checked != clickedItem.Checked) + this.ChangeCheckItem(olvi, olvi.Checked, clickedItem.Checked); + } + } + } + } + + + /// + /// Handle a RetrieveVirtualItem + /// + /// + /// + protected void HandleRetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) + { + // .NET 2.0 seems to generate a lot of these events. Before drawing *each* sub-item, + // this event is triggered 4-8 times for the same index. So we save lots of CPU time + // by caching the last result. + if (this.lastRetrieveVirtualItemIndex != e.ItemIndex) { + this.lastRetrieveVirtualItemIndex = e.ItemIndex; + this.lastRetrieveVirtualItem = this.MakeListViewItem(e.ItemIndex); + } + e.Item = this.lastRetrieveVirtualItem; + } + + /// + /// Create a OLVListItem for given row index + /// + /// The index of the row that is needed + /// An OLVListItem + public OLVListItem MakeListViewItem(int itemIndex) + { + OLVListItem olvi = new OLVListItem(this.GetRowObjectAt(itemIndex)); + this.FillInValues(olvi, olvi.RowObject); + if (this.UseAlternatingBackColors) { + if (this.View == View.Details && itemIndex % 2 == 1) + olvi.BackColor = this.AlternateRowBackColorOrDefault; + else + olvi.BackColor = this.BackColor; + + this.CorrectSubItemColors(olvi); + } + if (this.CheckBoxes) + olvi.StateImageIndex = (olvi.Checked ? 1 : 0); + + this.SetSubItemImages(itemIndex, olvi); + return olvi; + } + + /// + /// Return the row object for the given row index + /// + /// index of the row whose object is to be fetched + /// A model object or null if no delegate is installed + virtual protected object GetRowObjectAt(int index) + { + if (this.RowGetter == null) + return null; + else + return this.RowGetter(index); + } + + /// + /// Clear any cached info this list may have been using + /// + public void ClearCachedInfo() + { + this.lastRetrieveVirtualItemIndex = -1; + } + + #endregion + + #region Variable declaractions + + private RowGetterDelegate rowGetter; + private int lastRetrieveVirtualItemIndex = -1; + private OLVListItem lastRetrieveVirtualItem; + + #endregion + } + + /// + /// A FastObjectListView trades function for speed. + /// + /// + /// On my mid-range laptop, this view builds a list of 10,000 objects in 0.1 seconds, + /// as opposed to a normal ObjectListView which takes 10-15 seconds. Lists of up to 50,000 items should be + /// able to be handled with sub-second response times even on low end machines. + /// + /// A FastObjectListView is implemented as a virtual list with some of the virtual modes limits (e.g. no sorting) + /// fixed through coding. There are some functions that simply cannot be provided. Specifically, a FastObjectListView cannot: + /// + /// shows groups + /// use Tile view + /// display images on subitems + /// + /// + /// You can circumvent the limit on subitem images by making the list owner drawn, and giving the column + /// a Renderer of BaseRenderer, e.g. myColumnWithImage.Renderer = new BaseRenderer(); + /// + /// Although it isn't documented, virtual lists cannot have checkboxes. A FastObjectListView codes around this limitation, + /// but you must use the functions provided by FastObjectListView. If you call the normal "CheckedItems", it will throw an + /// exception. If you use CheckedObjects and its friends (declared in ObjectListView), you should not have any trouble. + /// The only exception is the "CheckBoxes" property itself. Once this is set, trying to unset it will throw an exception, + /// since the list is a virtual list. + /// + /// + public class FastObjectListView : VirtualObjectListView + { + /// + /// Make a FastObjectListView + /// + public FastObjectListView() + { + this.SearchForVirtualItem += new SearchForVirtualItemEventHandler(FastObjectListView_SearchForVirtualItem); + + this.CustomSorter = delegate(OLVColumn column, SortOrder sortOrder) { + this.ClearCachedInfo(); + if (sortOrder != SortOrder.None) + this.objectList.Sort(new ModelObjectComparer(column, sortOrder, this.SecondarySortColumn, this.SecondarySortOrder)); + this.RebuildIndexMap(); + }; + } + + #region Public properties + + /// + /// Get/set the list of objects that are shown by the control. + /// + /// + /// This method preserves selection, if possible. Use SetObjects() if + /// you do not want to preserve the selection. Preserving selection is the slowest part of this + /// code and performance is O(n) where n is the number of selected rows. + /// This method is not thread safe. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + new public ArrayList Objects + { + get { return this.objectList; } + set + { + this.BeginUpdate(); + ArrayList previousSelection = this.SelectedObjects; + this.SetObjects(value); + this.SelectedObjects = previousSelection; + this.EndUpdate(); + } + } + private ArrayList objectList = new ArrayList(); + + /// + /// When the user types into a list, should the values in the current sort column be searched to find a match? + /// If this is false, the primary column will always be used regardless of the sort column. + /// + /// When this is true, the behavior is like that of ITunes. + [Category("Behavior"), + Description("When the user types into a list, should the values in the current sort column be searched to find a match?"), + DefaultValue(false)] + public bool IsSearchOnSortColumn + { + get { return isSearchOnSortColumn; } + set { isSearchOnSortColumn = value; } + } + private bool isSearchOnSortColumn = false; + + #endregion + + #region Commands + + /// + /// Set the collection of objects that this control will show. + /// + /// + /// This method can safely be called from background threads. + override public void SetObjects(IEnumerable collection) + { + if (this.InvokeRequired) { + this.Invoke((MethodInvoker)delegate { this.SetObjects(collection); }); + return; + } + + //if (this.CheckBoxes && this.StateImageList == null) + // this.InitializeStateImageList(); + + this.BeginUpdate(); + ArrayList newObjects = new ArrayList(); + if (collection != null) { + if (collection is ICollection) + newObjects = new ArrayList((ICollection)collection); + else { + foreach (object x in collection) + newObjects.Add(x); + } + } + // There is a bug in ListView where if a virtual ListView is cleared + // (i.e. VirtuaListSize set to 0) when it is + // scrolled vertically, the scroll position is wrong when the list is subsequently + // filled in again. To avoid this, before clearing a virtual list, + // we make sure the list is scrolled to the top. + if (newObjects.Count == 0 && this.TopItemIndex > 0) + this.TopItemIndex = 0; + + this.objectList = newObjects; + this.VirtualListSize = this.objectList.Count; + this.Sort(); + this.EndUpdate(); + } + + private void InitializeStateImageList() + { + this.StateImageList = new ImageList(); + this.StateImageList.ImageSize = new Size(16, 16); + + this.AddCheckedImage(this.StateImageList, System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal); + this.AddCheckedImage(this.StateImageList, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal); + } + + private void AddCheckedImage(ImageList imageList, System.Windows.Forms.VisualStyles.CheckBoxState checkBoxState) + { + Bitmap bm = new Bitmap(imageList.ImageSize.Width, imageList.ImageSize.Height); + Graphics g = Graphics.FromImage(bm); + g.Clear(imageList.TransparentColor); + CheckBoxRenderer.DrawCheckBox(g, new Point(0, 0), checkBoxState); + imageList.Images.Add(bm); + } + + + /// + /// Add the given collection of model objects to this control. + /// + /// A collection of model objects + /// + /// The added objects will appear in their correct sort position, if sorting + /// is active. Otherwise, they will appear at the end of the list. + /// No check is performed to see if any of the objects are already in the ListView. + /// Null objects are silently ignored. + /// + override public void AddObjects(ICollection modelObjects) + { + this.TakeOwnershipOfObjects(); + foreach (object modelObject in modelObjects) { + if (modelObject != null) + this.objectList.Add(modelObject); + } + this.Objects = this.objectList; + } + + /// + /// Remove all of the given objects from the control + /// + /// Collection of objects to be removed + /// + /// Nulls and model objects that are not in the ListView are silently ignored. + /// + override public void RemoveObjects(ICollection modelObjects) + { + this.TakeOwnershipOfObjects(); + ArrayList selectedObjects = this.SelectedObjects; + foreach (object modelObject in modelObjects) { + if (modelObject != null) { + this.objectList.Remove(modelObject); + selectedObjects.Remove(modelObject); + } + } + this.SetObjects(this.objectList); + this.SelectedObjects = selectedObjects; + } + + /// + /// Take ownership of the 'objects' collection. This separats our collection from the source. + /// + /// + /// + /// This method + /// separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject + /// calls will modify our collection and not the original colleciton. + /// + /// + /// FastObjectListViews always own their collections, so this is a no-op. + /// + /// + override protected void TakeOwnershipOfObjects() + { + // FastObjectListViews always own their collections, so we don't need to do anything. + } + #endregion + + #region Event Handlers + + /// + /// Event handler for the column click event + /// + /// + /// This differs from its base version by trying to preserve selection. The base class, + /// being a pure virtual list, cannot maintain selection since it cannot map a + /// model objects to the row that is responsible for displaying it. This class can do that. + /// + override protected void HandleColumnClick(object sender, ColumnClickEventArgs e) + { + if (!this.PossibleFinishCellEditing()) + return; + + // Toggle the sorting direction on successive clicks on the same column + if (this.LastSortColumn != null && e.Column == this.LastSortColumn.Index) + this.LastSortOrder = (this.LastSortOrder == SortOrder.Descending ? SortOrder.Ascending : SortOrder.Descending); + else + this.LastSortOrder = SortOrder.Ascending; + + this.BeginUpdate(); + ArrayList previousSelection = this.SelectedObjects; + this.Sort(e.Column); + this.SelectedObjects = previousSelection; + this.EndUpdate(); + } + + void FastObjectListView_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) + { + // The event has e.IsPrefixSearch, but as far as I can tell, this is always false (maybe that's different under Vista) + // So we ignore IsPrefixSearch and IsTextSearch and always to a case insensitve prefix match + + int increment = (e.Direction == SearchDirectionHint.Up ? -1 : 1); + OLVColumn column = this.GetColumn(0); + if (this.IsSearchOnSortColumn && this.View == View.Details && this.LastSortColumn != null) + column = this.LastSortColumn; + + int i; + for (i = e.StartIndex; i >= 0 && i < this.objectList.Count; i += increment) { + string data = column.GetStringValue(this.objectList[i]); + if (data.StartsWith(e.Text, StringComparison.CurrentCultureIgnoreCase)) { + e.Index = i; + return; + } + } + + // Also the LVFINDINFO has a LV_WRAP flag, but the SearchForVirtualItemEventArgs does not. Why? + // We always wrap + i = (increment < 0 ? this.objectList.Count : 0); + while ((increment < 0 && i > e.StartIndex) || (increment > 0 && i < e.StartIndex)) { + string data = column.GetStringValue(this.objectList[i]); + if (data.StartsWith(e.Text, StringComparison.CurrentCultureIgnoreCase)) { + e.Index = i; + return; + } + i += increment; + } + } + + #endregion + + #region Object manipulation + + /// + /// Select the row that is displaying the given model object. + /// + /// The object that gave data + override public void SelectObject(object modelObject) + { + if (modelObject == null) + return; + + if (!this.objectsToIndexMap.ContainsKey(modelObject)) + return; + + int index = (int)this.objectsToIndexMap[modelObject]; + + // If this object is already selected, we don't need to do anything + if (this.SelectedIndices.Count == 1 && this.SelectedIndices[0] == index) + return; + + this.SelectedIndices.Clear(); + if (index >= 0) + this.SelectedIndices.Add(index); + } + + /// + /// Select the rows that is displaying any of the given model object. + /// + /// A collection of model objects + override public void SelectObjects(IList modelObjects) + { + this.SelectedIndices.Clear(); + + foreach (object model in modelObjects) { + if (this.objectsToIndexMap.ContainsKey(model)) { + int index = (int)this.objectsToIndexMap[model]; + if (index >= 0) + this.SelectedIndices.Add(index); + } + } + } + + /// + /// Update the rows that are showing the given objects + /// + override public void RefreshObjects(IList modelObjects) + { + this.Invalidate(); + } + + #endregion + + #region Implementation + + /// + /// Rebuild the map that remembers which model object is displayed at which line + /// + protected void RebuildIndexMap() + { + this.objectsToIndexMap.Clear(); + for (int i = 0; i < this.objectList.Count; i++) + this.objectsToIndexMap[this.objectList[i]] = i; + } + Hashtable objectsToIndexMap = new Hashtable(); + + /// + /// Return the row object for the given row index + /// + /// index of the row whose object is to be fetched + /// A model object or null if no delegate is installed + override protected object GetRowObjectAt(int index) + { + if (index >= 0 && index < this.objectList.Count) + return this.objectList[index]; + else + return null; + } + + + internal class ModelObjectComparer : IComparer + { + public ModelObjectComparer(OLVColumn col, SortOrder order) + { + this.column = col; + this.sortOrder = order; + this.secondComparer = null; + } + + public ModelObjectComparer(OLVColumn col, SortOrder order, OLVColumn col2, SortOrder order2) + : this(col, order) + { + // There is no point in secondary sorting on the same column + if (col != col2) + this.secondComparer = new ModelObjectComparer(col2, order2); + } + + public int Compare(object x, object y) + { + int result = 0; + object x1 = this.column.GetValue(x); + object y1 = this.column.GetValue(y); + + if (this.sortOrder == SortOrder.None) + return 0; + + // Handle nulls. Null values come last + bool xIsNull = (x1 == null || x1 == System.DBNull.Value); + bool yIsNull = (y1 == null || y1 == System.DBNull.Value); + if (xIsNull || yIsNull) { + if (xIsNull && yIsNull) + result = 0; + else + result = (xIsNull ? -1 : 1); + } else { + result = this.CompareValues(x1, y1); + } + + if (this.sortOrder == SortOrder.Descending) + result = 0 - result; + + // If the result was equality, use the secondary comparer to resolve it + if (result == 0 && this.secondComparer != null) + result = this.secondComparer.Compare(x, y); + + return result; + } + + public int CompareValues(object x, object y) + { + // Force case insensitive compares on strings + if (x is String) + return String.Compare((String)x, (String)y, true); + else { + IComparable comparable = x as IComparable; + if (comparable != null) + return comparable.CompareTo(y); + else + return 0; + } + } + + private OLVColumn column; + private SortOrder sortOrder; + private ModelObjectComparer secondComparer; + } + + #endregion + } + + /// + /// A DataListView is a ListView that can be bound to a datasource (which would normally be a DataTable or DataView). + /// + /// + /// This listview keeps itself in sync with its source datatable by listening for change events. + /// If the listview has no columns when given a data source, it will automatically create columns to show all of the datatables columns. + /// This will be only the simplest view of the world, and would look more interesting with a few delegates installed. + /// This listview will also automatically generate missing aspect getters to fetch the values from the data view. + /// Changing data sources is possible, but error prone. Before changing data sources, the programmer is responsible for modifying/resetting + /// the column collection to be valid for the new data source. + /// + public class DataListView : ObjectListView + { + /// + /// Make a DataListView + /// + public DataListView() + : base() + { + } + + #region Public Properties + + /// + /// Get or set the DataSource that will be displayed in this list view. + /// + /// The DataSource should implement either , , + /// or . Some common examples are the following types of objects: + /// + /// + /// + /// + /// + /// + /// + /// When binding to a list container (i.e. one that implements the + /// interface, such as ) + /// you must also set the property in order + /// to identify which particular list you would like to display. You + /// may also set the property even when + /// DataSource refers to a list, since can + /// also be used to navigate relations between lists. + /// + [Category("Data"), + TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")] + public Object DataSource + { + get { return dataSource; } + set + { + //THINK: Should we only assign it if it is changed? + //if (dataSource != value) { + dataSource = value; + this.RebindDataSource(true); + //} + } + } + private Object dataSource; + + /// + /// Gets or sets the name of the list or table in the data source for which the DataListView is displaying data. + /// + /// If the data source is not a DataSet or DataViewManager, this property has no effect + [Category("Data"), + Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor)), + DefaultValue("")] + public string DataMember + { + get { return dataMember; } + set + { + if (dataMember != value) { + dataMember = value; + RebindDataSource(); + } + } + } + private string dataMember = ""; + + #endregion + + #region Initialization + + private CurrencyManager currencyManager = null; + + /// + /// Our data source has changed. Figure out how to handle the new source + /// + protected void RebindDataSource() + { + RebindDataSource(false); + } + + /// + /// Our data source has changed. Figure out how to handle the new source + /// + protected void RebindDataSource(bool forceDataInitialization) + { + if (this.BindingContext == null) + return; + + // Obtain the CurrencyManager for the current data source. + CurrencyManager tempCurrencyManager = null; + + if (this.DataSource != null) { + tempCurrencyManager = (CurrencyManager)this.BindingContext[this.DataSource, this.DataMember]; + } + + // Has our currency manager changed? + if (this.currencyManager != tempCurrencyManager) { + + // Stop listening for events on our old currency manager + if (this.currencyManager != null) { + this.currencyManager.MetaDataChanged -= new EventHandler(currencyManager_MetaDataChanged); + this.currencyManager.PositionChanged -= new EventHandler(currencyManager_PositionChanged); + this.currencyManager.ListChanged -= new ListChangedEventHandler(currencyManager_ListChanged); + } + + this.currencyManager = tempCurrencyManager; + + // Start listening for events on our new currency manager + if (this.currencyManager != null) { + this.currencyManager.MetaDataChanged += new EventHandler(currencyManager_MetaDataChanged); + this.currencyManager.PositionChanged += new EventHandler(currencyManager_PositionChanged); + this.currencyManager.ListChanged += new ListChangedEventHandler(currencyManager_ListChanged); + } + + // Our currency manager has changed so we have to initialize a new data source + forceDataInitialization = true; + } + + if (forceDataInitialization) + InitializeDataSource(); + } + + /// + /// The data source for this control has changed. Reconfigure the control for the new source + /// + protected void InitializeDataSource() + { + if (this.Frozen || this.currencyManager == null) + return; + + this.CreateColumnsFromSource(); + this.CreateMissingAspectGettersAndPutters(); + this.SetObjects(this.currencyManager.List); + + // If we have some data, resize the new columns based on the data available. + if (this.Items.Count > 0) { + foreach (ColumnHeader column in this.Columns) { + if (column.Width == 0) + this.AutoResizeColumn(column.Index, ColumnHeaderAutoResizeStyle.ColumnContent); + } + } + } + + /// + /// Create columns for the listview based on what properties are available in the data source + /// + /// + /// This method will not replace existing columns. + /// + protected void CreateColumnsFromSource() + { + if (this.currencyManager == null || this.Columns.Count != 0) + return; + + PropertyDescriptorCollection properties = this.currencyManager.GetItemProperties(); + if (properties.Count == 0) + return; + + for (int i = 0; i < properties.Count; i++) { + // Make a stack variable to hold the property so it can be used in the AspectGetter delegate + PropertyDescriptor property = properties[i]; + + // Relationships to other tables turn up as IBindibleLists. Don't make columns to show them. + // CHECK: Is this always true? What other things could be here? Constraints? Triggers? + if (property.PropertyType == typeof(IBindingList)) + continue; + + // Create a column + OLVColumn column = new OLVColumn(property.DisplayName, property.Name); + column.Width = 0; // zero-width since we will resize it once we have some data + column.AspectGetter = delegate(object row) { + return property.GetValue(row); + }; + // If our column is a BLOB, it could be an image, so assign a renderer to draw it. + // CONSIDER: Is this a common enough case to warrant this code? + if (property.PropertyType == typeof(System.Byte[])) + column.Renderer = new ImageRenderer(); + + // Add it to our list + this.Columns.Add(column); + } + } + + /// + /// Generate aspect getters and putters for any columns that are missing them (and for which we have + /// enough information to actually generate a getter) + /// + protected void CreateMissingAspectGettersAndPutters() + { + for (int i = 0; i < this.Columns.Count; i++) { + OLVColumn column = this.GetColumn(i); + if (column.AspectGetter == null && !String.IsNullOrEmpty(column.AspectName)) { + column.AspectGetter = delegate(object row) { + // In most cases, rows will be DataRowView objects + DataRowView drv = row as DataRowView; + if (drv != null) + return drv[column.AspectName]; + else + return column.GetAspectByName(row); + }; + } + if (column.IsEditable && column.AspectPutter == null && !String.IsNullOrEmpty(column.AspectName)) { + column.AspectPutter = delegate(object row, object newValue) { + // In most cases, rows will be DataRowView objects + DataRowView drv = row as DataRowView; + if (drv != null) + drv[column.AspectName] = newValue; + else + column.PutAspectByName(row, newValue); + }; + } + } + } + + #endregion + + #region Object manipulations + + /// + /// Add the given collection of model objects to this control. + /// + /// A collection of model objects + /// This is a no-op for data lists, since the data + /// is controlled by the DataSource. Manipulate the data source + /// rather than this view of the data source. + override public void AddObjects(ICollection modelObjects) + { + } + + /// + /// Remove the given collection of model objects from this control. + /// + /// This is a no-op for data lists, since the data + /// is controlled by the DataSource. Manipulate the data source + /// rather than this view of the data source. + override public void RemoveObjects(ICollection modelObjects) + { + } + + #endregion + + #region Event Handlers + + /// + /// What should we do when the list is unfrozen + /// + override protected void DoUnfreeze() + { + // Clear any previous currency manager so the rebind will always work from scratch + this.RebindDataSource(true); + } + + /// + /// Handles binding context changes + /// + /// The EventArgs that will be passed to any handlers + /// of the BindingContextChanged event. + protected override void OnBindingContextChanged(EventArgs e) + { + base.OnBindingContextChanged(e); + + // If our binding context changes, we must rebind, since we will + // have a new currency managers, even if we are still bound to the + // same data source. + this.RebindDataSource(false); + } + + + /// + /// Handles parent binding context changes + /// + /// Unused EventArgs. + protected override void OnParentBindingContextChanged(EventArgs e) + { + base.OnParentBindingContextChanged(e); + + // BindingContext is an ambient property - by default it simply picks + // up the parent control's context (unless something has explicitly + // given us our own). So we must respond to changes in our parent's + // binding context in the same way we would changes to our own + // binding context. + this.RebindDataSource(false); + } + + // CurrencyManager ListChanged event handler. + // Deals with fine-grained changes to list items. + // It's actually difficult to deal with these changes in a fine-grained manner. + // If our listview is grouped, then any change may make a new group appear or + // an old group disappear. It is rarely enough to simply update the affected row. + private void currencyManager_ListChanged(object sender, ListChangedEventArgs e) + { + switch (e.ListChangedType) { + + // Well, usually fine-grained... The whole list has changed utterly, so reload it. + case ListChangedType.Reset: + this.InitializeDataSource(); + break; + + // A single item has changed, so just refresh that. + // TODO: Even in this simple case, we should probably rebuild the list. + case ListChangedType.ItemChanged: + Object changedRow = this.currencyManager.List[e.NewIndex]; + this.RefreshObject(changedRow); + break; + + // A new item has appeared, so add that. + // We get this event twice if certain grid controls are used to add a new row to a + // datatable: once when the editing of a new row begins, and once again when that + // editing commits. (If the user cancels the creation of the new row, we never see + // the second creation.) We detect this by seeing if this is a view on a row in a + // DataTable, and if it is, testing to see if it's a new row under creation. + case ListChangedType.ItemAdded: + Object newRow = this.currencyManager.List[e.NewIndex]; + DataRowView drv = newRow as DataRowView; + if (drv == null || !drv.IsNew) { + // Either we're not dealing with a view on a data table, or this is the commit + // notification. Either way, this is the final notification, so we want to + // handle the new row now! + this.InitializeDataSource(); + } + break; + + // An item has gone away. + case ListChangedType.ItemDeleted: + this.InitializeDataSource(); + break; + + // An item has changed its index. + case ListChangedType.ItemMoved: + this.InitializeDataSource(); + break; + + // Something has changed in the metadata. + // CHECK: When are these events actually fired? + case ListChangedType.PropertyDescriptorAdded: + case ListChangedType.PropertyDescriptorChanged: + case ListChangedType.PropertyDescriptorDeleted: + this.InitializeDataSource(); + break; + } + } + + + // The CurrencyManager calls this if the data source looks + // different. We just reload everything. + // CHECK: Do we need this if we are handle ListChanged metadata events? + private void currencyManager_MetaDataChanged(object sender, EventArgs e) + { + this.InitializeDataSource(); + } + + + // Called by the CurrencyManager when the currently selected item + // changes. We update the ListView selection so that we stay in sync + // with any other controls bound to the same source. + private void currencyManager_PositionChanged(object sender, EventArgs e) + { + int index = this.currencyManager.Position; + + // Make sure the index is sane (-1 pops up from time to time) + if (index < 0 || index >= this.Items.Count) + return; + + // Avoid recursion. If we are currently changing the index, don't + // start the process again. + if (this.isChangingIndex) + return; + + try { + this.isChangingIndex = true; + + // We can't use the index directly, since our listview may be sorted + this.SelectedObject = this.currencyManager.List[index]; + + // THINK: Do we always want to bring it into view? + if (this.SelectedItems.Count > 0) + this.SelectedItems[0].EnsureVisible(); + + } finally { + this.isChangingIndex = false; + } + } + private bool isChangingIndex = false; + + /// + /// Handle a SelectedIndexChanged event + /// + /// The event + /// + /// Called by Windows Forms when the currently selected index of the + /// control changes. This usually happens because the user clicked on + /// the control. In this case we want to notify the CurrencyManager so + /// that any other bound controls will remain in sync. This method will + /// also be called when we changed our index as a result of a + /// notification that originated from the CurrencyManager, and in that + /// case we avoid notifying the CurrencyManager back! + /// + protected override void OnSelectedIndexChanged(EventArgs e) + { + base.OnSelectedIndexChanged(e); + + // Prevent recursion + if (this.isChangingIndex) + return; + + // If we are bound to a datasource, and only one item is selected, + // tell the currency manager which item is selected. + if (this.SelectedIndices.Count == 1 && this.currencyManager != null) { + try { + this.isChangingIndex = true; + + // We can't use the selectedIndex directly, since our listview may be sorted. + // So we have to find the index of the selected object within the original list. + this.currencyManager.Position = this.currencyManager.List.IndexOf(this.SelectedObject); + } finally { + this.isChangingIndex = false; + } + } + } + + #endregion + + } + + #region Delegate declarations + + /// + /// These delegates are used to extract an aspect from a row object + /// + public delegate Object AspectGetterDelegate(Object rowObject); + + /// + /// These delegates are used to put a changed value back into a model object + /// + public delegate void AspectPutterDelegate(Object rowObject, Object newValue); + + /// + /// These delegates can be used to convert an aspect value to a display string, + /// instead of using the default ToString() + /// + public delegate string AspectToStringConverterDelegate(Object value); + + /// + /// These delegates are used to the state of the checkbox for a row object. + /// + /// For reasons known only to someone in Microsoft, we can only set + /// a boolean on the ListViewItem to indicate it's "checked-ness", but when + /// we receive update events, we have to use a tristate CheckState. So we can + /// be told about an indeterminate state, but we can't set it ourselves. + public delegate bool CheckStateGetterDelegate(Object rowObject); + + /// + /// These delegates are used to put a changed check state back into a model object + /// + public delegate CheckState CheckStatePutterDelegate(Object rowObject, CheckState newValue); + + /// + /// These delegates are used to retrieve the object that is the key of the group to which the given row belongs. + /// + public delegate Object GroupKeyGetterDelegate(Object rowObject); + + /// + /// These delegates are used to convert a group key into a title for the group + /// + public delegate string GroupKeyToTitleConverterDelegate(Object groupKey); + + /// + /// These delegates are used to fetch the image selector that should be used + /// to choose an image for this column. + /// + public delegate Object ImageGetterDelegate(Object rowObject); + + /// + /// These delegates are used to draw a cell + /// + public delegate bool RenderDelegate(EventArgs e, Graphics g, Rectangle r, Object rowObject); + + /// + /// These delegates are used to fetch a row object for virtual lists + /// + public delegate Object RowGetterDelegate(int rowIndex); + + /// + /// These delegates are used to format a listviewitem before it is added to the control. + /// + public delegate void RowFormatterDelegate(OLVListItem olvItem); + + /// + /// These delegates are used to sort the listview in some custom fashion + /// + public delegate void SortDelegate(OLVColumn column, SortOrder sortOrder); + + #endregion + + #region Column + + /// + /// An OLVColumn knows which aspect of an object it should present. + /// + /// + /// The column knows how to: + /// + /// extract its aspect from the row object + /// convert an aspect to a string + /// calculate the image for the row object + /// extract a group "key" from the row object + /// convert a group "key" into a title for the group + /// + /// For sorting to work correctly, aspects from the same column + /// must be of the same type, that is, the same aspect cannot sometimes + /// return strings and other times integers. + /// + [Browsable(false)] + public partial class OLVColumn : ColumnHeader + { + /// + /// Create an OLVColumn + /// + public OLVColumn() + : base() + { + } + + /// + /// Initialize a column to have the given title, and show the given aspect + /// + /// The title of the column + /// The aspect to be shown in the column + public OLVColumn(string title, string aspect) + : this() + { + this.Text = title; + this.AspectName = aspect; + } + + #region Public Properties + + /// + /// The name of the property or method that should be called to get the value to display in this column. + /// This is only used if a ValueGetterDelegate has not been given. + /// + /// This name can be dotted to chain references to properties or methods. + /// "DateOfBirth" + /// "Owner.HomeAddress.Postcode" + [Category("Behavior"), + Description("The name of the property or method that should be called to get the aspect to display in this column")] + public string AspectName + { + get { return aspectName; } + set { aspectName = value; } + } + private string aspectName; + + /// + /// This format string will be used to convert an aspect to its string representation. + /// + /// + /// This string is passed as the first parameter to the String.Format() method. + /// This is only used if ToStringDelegate has not been set. + /// "{0:C}" to convert a number to currency + [Category("Behavior"), + Description("The format string that will be used to convert an aspect to its string representation"), + DefaultValue(null)] + public string AspectToStringFormat + { + get { return aspectToStringFormat; } + set { aspectToStringFormat = value; } + } + private string aspectToStringFormat; + + /// + /// Group objects by the initial letter of the aspect of the column + /// + /// + /// One common pattern is to group column by the initial letter of the value for that group. + /// The aspect must be a string (obviously). + /// + [Category("Behavior"), + Description("The name of the property or method that should be called to get the aspect to display in this column"), + DefaultValue(false)] + public bool UseInitialLetterForGroup + { + get { return useInitialLetterForGroup; } + set { useInitialLetterForGroup = value; } + } + private bool useInitialLetterForGroup; + + /// + /// Get/set whether this column should be used when the view is switched to tile view. + /// + /// Column 0 is always included in tileview regardless of this setting. + /// Tile views do not work well with many "columns" of information, 2 or 3 works best. + [Category("Behavior"), + Description("Will this column be used when the view is switched to tile view"), + DefaultValue(false)] + public bool IsTileViewColumn + { + get { return isTileViewColumn; } + set { isTileViewColumn = value; } + } + private bool isTileViewColumn = false; + + /// + /// This delegate will be used to extract a value to be displayed in this column. + /// + /// + /// If this is set, AspectName is ignored. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AspectGetterDelegate AspectGetter + { + get { return aspectGetter; } + set + { + aspectGetter = value; + aspectGetterAutoGenerated = false; + } + } + private AspectGetterDelegate aspectGetter; + + /// + /// The delegate that will be used to translate the aspect to display in this column into a string. + /// + /// If this value is set, ValueToStringFormat will be ignored. + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AspectToStringConverterDelegate AspectToStringConverter + { + get { return aspectToStringConverter; } + set { aspectToStringConverter = value; } + } + private AspectToStringConverterDelegate aspectToStringConverter; + + /// + /// This delegate is called to get the image selector of the image that should be shown in this column. + /// It can return an int, string, Image or null. + /// + /// This delegate can use these return value to identify the image: + /// + /// null or -1 -- indicates no image + /// an int -- the int value will be used as an index into the image list + /// a String -- the string value will be used as a key into the image list + /// an Image -- the Image will be drawn directly (only in OwnerDrawn mode) + /// + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ImageGetterDelegate ImageGetter + { + get { return imageGetter; } + set { imageGetter = value; } + } + private ImageGetterDelegate imageGetter; + + /// + /// This delegate is called to get the object that is the key for the group + /// to which the given row belongs. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GroupKeyGetterDelegate GroupKeyGetter + { + get { return groupKeyGetter; } + set { groupKeyGetter = value; } + } + private GroupKeyGetterDelegate groupKeyGetter; + + /// + /// This delegate is called to convert a group key into a title for that group. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public GroupKeyToTitleConverterDelegate GroupKeyToTitleConverter + { + get { return groupKeyToTitleConverter; } + set { groupKeyToTitleConverter = value; } + } + private GroupKeyToTitleConverterDelegate groupKeyToTitleConverter; + + /// + /// This delegate is called when a cell needs to be drawn in OwnerDrawn mode. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public RenderDelegate RendererDelegate + { + get { return rendererDelegate; } + set { rendererDelegate = value; } + } + private RenderDelegate rendererDelegate; + + /// + /// Get/set the renderer that will be invoked when a cell needs to be redrawn + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public BaseRenderer Renderer + { + get { return renderer; } + set + { + renderer = value; + if (renderer == null) + this.RendererDelegate = null; + else { + renderer.Column = this; + this.RendererDelegate = new RenderDelegate(renderer.HandleRendering); + } + } + } + private BaseRenderer renderer; + + /// + /// Remember if this aspect getter for this column was generated internally, and can therefore + /// be regenerated at will + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool AspectGetterAutoGenerated + { + get { return aspectGetterAutoGenerated; } + set { aspectGetterAutoGenerated = value; } + } + private bool aspectGetterAutoGenerated; + + /// + /// When the listview is grouped by this column and group title has an item count, + /// how should the lable be formatted? + /// + /// + /// The given format string can/should have two placeholders: + /// + /// {0} - the original group title + /// {1} - the number of items in the group + /// + /// If this value is not set, the values from the list view will be used + /// + /// "{0} [{1} items]" + [Category("Behavior"), + Description("The format to use when suffixing item counts to group titles"), + DefaultValue(null)] + public string GroupWithItemCountFormat + { + get { return groupWithItemCountFormat; } + set { groupWithItemCountFormat = value; } + } + private string groupWithItemCountFormat; + + /// + /// Return this.GroupWithItemCountFormat or a reasonable default + /// + [Browsable(false)] + public string GroupWithItemCountFormatOrDefault + { + get + { + if (String.IsNullOrEmpty(this.GroupWithItemCountFormat)) + // There is one rare but pathelogically possible case where the ListView can + // be null, so we have to provide a workable default for that rare case. + if (this.ListView == null) + return "{0} [{1} items]"; + else + return ((ObjectListView)this.ListView).GroupWithItemCountFormatOrDefault; + else + return this.GroupWithItemCountFormat; + } + } + + /// + /// When the listview is grouped by this column and a group title has an item count, + /// how should the lable be formatted if there is only one item in the group? + /// + /// + /// The given format string can/should have two placeholders: + /// + /// {0} - the original group title + /// {1} - the number of items in the group (always 1) + /// + /// If this value is not set, the values from the list view will be used + /// + /// "{0} [{1} item]" + [Category("Behavior"), + Description("The format to use when suffixing item counts to group titles"), + DefaultValue(null)] + public string GroupWithItemCountSingularFormat + { + get { return groupWithItemCountSingularFormat; } + set { groupWithItemCountSingularFormat = value; } + } + private string groupWithItemCountSingularFormat; + + /// + /// Return this.GroupWithItemCountSingularFormat or a reasonable default + /// + [Browsable(false)] + public string GroupWithItemCountSingularFormatOrDefault + { + get + { + if (String.IsNullOrEmpty(this.GroupWithItemCountSingularFormat)) + // There is one pathelogically rare but still possible case where the ListView can + // be null, so we have to provide a workable default for that rare case. + if (this.ListView == null) + return "{0} [{1} item]"; + else + return ((ObjectListView)this.ListView).GroupWithItemCountSingularFormatOrDefault; + else + return this.GroupWithItemCountSingularFormat; + } + } + + /// + /// What is the minimum width that the user can give to this column? + /// + /// -1 means there is no minimum width. Give this the same value as MaximumWidth to make a fixed width column. + [Category("Misc"), + Description("What is the minimum width to which the user can resize this column?"), + DefaultValue(-1)] + public int MinimumWidth + { + get { return minWidth; } + set + { + minWidth = value; + if (this.Width < minWidth) + this.Width = minWidth; + } + } + private int minWidth = -1; + + /// + /// What is the maximum width that the user can give to this column? + /// + /// -1 means there is no maximum width. Give this the same value as MinimumWidth to make a fixed width column. + [Category("Misc"), + Description("What is the maximum width to which the user can resize this column?"), + DefaultValue(-1)] + public int MaximumWidth + { + get { return maxWidth; } + set + { + maxWidth = value; + if (maxWidth != -1 && this.Width > maxWidth) + this.Width = maxWidth; + } + } + private int maxWidth = -1; + + /// + /// Is this column a fixed width column? + /// + [Browsable(false)] + public bool IsFixedWidth + { + get + { + return (this.MinimumWidth != -1 && this.MaximumWidth != -1 && this.MinimumWidth >= this.MaximumWidth); + } + } + + /// + /// What proportion of the unoccupied horizontal space in the control should be given to this column? + /// + /// + /// + /// There are situations where it would be nice if a column (normally the rightmost one) would expand as + /// the list view expands, so that as much of the column was visible as possible without having to scroll + /// horizontally (you should never, ever make your users have to scroll anything horizontally!). + /// + /// + /// A space filling column is resized to occupy a proportion of the unoccupied width of the listview (the + /// unoccupied width is the width left over once all the the non-filling columns have been given their space). + /// This property indicates the relative proportion of that unoccupied space that will be given to this column. + /// The actual value of this property is not important -- only its value relative to the value in other columns. + /// For example: + /// + /// + /// If there is only one space filling column, it will be given all the free space, regardless of the value in FreeSpaceProportion. + /// + /// + /// If there are two or more space filling columns and they all have the same value for FreeSpaceProportion, + /// they will share the free space equally. + /// + /// + /// If there are three space filling columns with values of 3, 2, and 1 + /// for FreeSpaceProportion, then the first column with occupy half the free space, the second will + /// occupy one-third of the free space, and the third column one-sixth of the free space. + /// + /// + /// + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int FreeSpaceProportion + { + get { return freeSpaceProportion; } + set { freeSpaceProportion = Math.Max(0, value); } + } + private int freeSpaceProportion = 0; + + /// + /// Should this column resize to fill the free space in the listview? + /// + /// + /// + /// If you want two (or more) columns to equally share the available free space, set this property to True. + /// If you want this column to have a larger or smaller share of the free space, you must + /// set the FreeSpaceProportion property explicitly. + /// + /// + /// Space filling columns are still governed by the MinimumWidth and MaximumWidth properties. + /// + /// /// + [Category("Misc"), + Description("Will this column resize to fill unoccupied horizontal space in the listview?"), + DefaultValue(false)] + public bool FillsFreeSpace + { + get { return this.FreeSpaceProportion > 0; } + set + { + if (value) + this.freeSpaceProportion = 1; + else + this.freeSpaceProportion = 0; + } + } + + /// + /// This delegate will be used to put an edited value back into the model object. + /// + /// + /// This does nothing if IsEditable == false. + /// + [Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public AspectPutterDelegate AspectPutter + { + get { return aspectPutter; } + set { aspectPutter = value; } + } + private AspectPutterDelegate aspectPutter; + + /// + /// Can the values shown in this column be edited? + /// + /// This defaults to true, since the primary means to control the editability of a listview + /// is on the listview itself. Once a listview is editable, all the columns are too, unless the + /// programmer explicitly marks them as not editable + [Category("Misc"), + Description("Can the value in this column be edited?"), + DefaultValue(true)] + public bool IsEditable + { + get { return isEditable; } + set { isEditable = value; } + } + private bool isEditable = true; + + /// + /// Return the control that should be used to edit cells in this column + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Control CellEditor + { + get { return cellEditor; } + set { cellEditor = value; } + } + private Control cellEditor; + + /// + /// Can this column be seen by the user? + /// + /// After changing this value, you must call RebuildColumns() before the changes will be effected. + [Category("Misc"), + Description("Can this column be seen by the user?"), + DefaultValue(true)] + public bool IsVisible + { + get { return isVisible; } + set { isVisible = value; } + } + private bool isVisible = true; + + /// + /// Where was this column last positioned within the Detail view columns + /// + /// DisplayIndex is volatile. Once a column is removed from the control, + /// there is no way to discover where it was in the display order. This property + /// guards that information even when the column is not in the listview's active columns. + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int LastDisplayIndex = -1; + + #endregion + + /// + /// For a given row object, return the object that is to be displayed in this column. + /// + /// The row object that is being displayed + /// An object, which is the aspect to be displayed + public object GetValue(object rowObject) + { + if (this.aspectGetter == null) + return this.GetAspectByName(rowObject); + else + return this.aspectGetter(rowObject); + } + + /// + /// For a given row object, extract the value indicated by the AspectName property of this column. + /// + /// The row object that is being displayed + /// An object, which is the aspect named by AspectName + public object GetAspectByName(object rowObject) + { + if (string.IsNullOrEmpty(this.aspectName)) + return null; + + //CONSIDER: Should we include NonPublic in this list? + BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | + BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.GetField; + object source = rowObject; + foreach (string property in this.aspectName.Split('.')) { + try { + source = source.GetType().InvokeMember(property, flags, null, source, null); + if (source == null) + break; + } catch (System.MissingMethodException) { + return String.Format("Cannot invoke '{0}' on a {1}", property, source.GetType()); + } + } + return source; + } + + /// + /// Update the given model object with the given value + /// + /// The model object to be updated + /// The value to be put into the model + public void PutValue(Object rowObject, Object newValue) + { + if (this.aspectPutter == null) + this.PutAspectByName(rowObject, newValue); + else + this.aspectPutter(rowObject, newValue); + } + + /// + /// Update the given model object with the given value using the column's + /// AspectName. + /// + /// The model object to be updated + /// The value to be put into the model + public void PutAspectByName(Object rowObject, Object newValue) + { + if (string.IsNullOrEmpty(this.aspectName)) + return; + + // Navigated through the dotted path until we reach the target object. + // We then try to set the last property on the dotted path on that target. + // So, if rowObject is a Person, then an aspect named "HomeAddress.Postcode" + // will first fetch the "HomeAddress" property, and then try to set the + // "Postcode" property on the home address object. + + //CONSIDER: Should we include NonPublic in this list? + BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | + BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.GetField; + Object target = rowObject; + List parentProperties = new List(this.aspectName.Split('.')); + String lastProperty = parentProperties[parentProperties.Count - 1]; + parentProperties.RemoveAt(parentProperties.Count - 1); + foreach (string property in parentProperties) { + try { + target = target.GetType().InvokeMember(property, flags, null, target, null); + } catch (System.MissingMethodException) { + System.Diagnostics.Debug.WriteLine(String.Format("Cannot invoke '{0}' on a {1}", property, target.GetType())); + return; + } + } + + // Now try to set the value + try { + BindingFlags flags2 = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.SetField; + target.GetType().InvokeMember(lastProperty, flags2, null, target, new Object[] { newValue }); + } catch (System.MissingMethodException ex) { + System.Diagnostics.Debug.WriteLine("Invoke PutAspectByName failed:"); + System.Diagnostics.Debug.WriteLine(ex); + } + } + + /// + /// For a given row object, return the string representation of the value shown in this column. + /// + /// + /// For aspects that are string (e.g. aPerson.Name), the aspect and its string representation are the same. + /// For non-strings (e.g. aPerson.DateOfBirth), the string representation is very different. + /// + /// + /// + public string GetStringValue(object rowObject) + { + return this.ValueToString(this.GetValue(rowObject)); + } + + /// + /// Convert the aspect object to its string representation. + /// + /// + /// If the column has been given a ToStringDelegate, that will be used to do + /// the conversion, otherwise just use ToString(). Nulls are always converted + /// to empty strings. + /// + /// The value of the aspect that should be displayed + /// A string representation of the aspect + public string ValueToString(object value) + { + // CONSIDER: Should we give aspect-to-string converters a chance to work on a null value? + if (value == null) + return ""; + + if (this.aspectToStringConverter != null) + return this.aspectToStringConverter(value); + + string fmt = this.AspectToStringFormat; + if (String.IsNullOrEmpty(fmt)) + return value.ToString(); + else + return String.Format(fmt, value); + } + + /// + /// For a given row object, return the image selector of the image that should displayed in this column. + /// + /// The row object that is being displayed + /// int or string or Image. int or string will be used as index into image list. null or -1 means no image + public Object GetImage(object rowObject) + { + if (this.imageGetter != null) + return this.imageGetter(rowObject); + + if (!String.IsNullOrEmpty(this.ImageKey)) + return this.ImageKey; + + return this.ImageIndex; + } + + /// + /// For a given row object, return the object that is the key of the group that this row belongs to. + /// + /// The row object that is being displayed + /// Group key object + public object GetGroupKey(object rowObject) + { + if (this.groupKeyGetter == null) { + object key = this.GetValue(rowObject); + if (key is string && this.UseInitialLetterForGroup) { + String keyAsString = (String)key; + if (keyAsString.Length > 0) + key = keyAsString.Substring(0, 1).ToUpper(); + } + return key; + } else + return this.groupKeyGetter(rowObject); + } + + /// + /// For a given group value, return the string that should be used as the groups title. + /// + /// The group key that is being converted to a title + /// string + public string ConvertGroupKeyToTitle(object value) + { + if (this.groupKeyToTitleConverter == null) + return this.ValueToString(value); + else + return this.groupKeyToTitleConverter(value); + } + + #region Utilities + + /// + /// Install delegates that will group the columns aspects into progressive partitions. + /// If an aspect is less than value[n], it will be grouped with description[n]. + /// If an aspect has a value greater than the last element in "values", it will be grouped + /// with the last element in "descriptions". + /// + /// Array of values. Values must be able to be + /// compared to the aspect (using IComparable) + /// The description for the matching value. The last element is the default description. + /// If there are n values, there must be n+1 descriptions. + /// + /// this.salaryColumn.MakeGroupies( + /// new UInt32[] { 20000, 100000 }, + /// new string[] { "Lowly worker", "Middle management", "Rarified elevation"}); + /// + public void MakeGroupies(T[] values, string[] descriptions) + { + if (values.Length + 1 != descriptions.Length) + throw new ArgumentException("descriptions must have one more element than values."); + + // Install a delegate that returns the index of the description to be shown + this.GroupKeyGetter = delegate(object row) { + Object aspect = this.GetValue(row); + if (aspect == null || aspect == System.DBNull.Value) + return -1; + IComparable comparable = (IComparable)aspect; + for (int i = 0; i < values.Length; i++) { + if (comparable.CompareTo(values[i]) < 0) + return i; + } + + // Display the last element in the array + return descriptions.Length - 1; + }; + + // Install a delegate that simply looks up the given index in the descriptions. + this.GroupKeyToTitleConverter = delegate(object key) { + if ((int)key < 0) + return ""; + + return descriptions[(int)key]; + }; + } + + #endregion + + #region Private Variables + + + + #endregion + + } + + #endregion + + #region OLVListItem and OLVListSubItem + + /// + /// OLVListItems are specialized ListViewItems that know which row object they came from, + /// and the row index at which they are displayed, even when in group view mode. They + /// also know the image they should draw against themselves + /// + public class OLVListItem : ListViewItem + { + /// + /// Create a OLVListItem for the given row object + /// + public OLVListItem(object rowObject) + : base() + { + this.rowObject = rowObject; + } + + /// + /// Create a OLVListItem for the given row object, represented by the given string and image + /// + public OLVListItem(object rowObject, string text, Object image) + : base(text, -1) + { + this.rowObject = rowObject; + this.imageSelector = image; + } + + /// + /// RowObject is the model object that is source of the data for this list item. + /// + public object RowObject + { + get { return rowObject; } + set { rowObject = value; } + } + private object rowObject; + + /// + /// DisplayIndex is the index of the row where this item is displayed. For flat lists, + /// this is the same as ListViewItem.Index, but for grouped views, it is different. + /// + public int DisplayIndex + { + get { return displayIndex; } + set { displayIndex = value; } + } + private int displayIndex; + + /// + /// Get or set the image that should be shown against this item + /// + /// This can be an Image, a string or an int. A string or an int will + /// be used as an index into the small image list. + public Object ImageSelector + { + get { return imageSelector; } + set + { + imageSelector = value; + if (value is Int32) + this.ImageIndex = (Int32)value; + else if (value is String) + this.ImageKey = (String)value; + else + this.ImageIndex = -1; + } + } + private Object imageSelector; + } + + /// + /// A ListViewSubItem that knows which image should be drawn against it. + /// + [Browsable(false)] + public class OLVListSubItem : ListViewItem.ListViewSubItem + { + /// + /// Create a OLVListSubItem + /// + public OLVListSubItem() + : base() + { + } + + /// + /// Create a OLVListSubItem that shows the given string and image + /// + public OLVListSubItem(string text, Object image) + : base() + { + this.Text = text; + this.ImageSelector = image; + } + + /// + /// Get or set the image that should be shown against this item + /// + /// This can be an Image, a string or an int. A string or an int will + /// be used as an index into the small image list. + public Object ImageSelector + { + get { return imageSelector; } + set { imageSelector = value; } + } + private Object imageSelector; + + + /// + /// Return the state of the animatation of the image on this subitem. + /// Null means there is either no image, or it is not an animation + /// + internal ImageRenderer.AnimationState AnimationState + { + get { return animationState; } + set { animationState = value; } + } + private ImageRenderer.AnimationState animationState; + + } + + #endregion + + #region Comparers + + /// + /// This comparer sort list view groups. + /// It does this on the basis of the values in the Tags, if we can figure out how to compare + /// objects of that type. Failing that, it uses a case insensitive compare on the group header. + /// + internal class ListViewGroupComparer : IComparer + { + public ListViewGroupComparer(SortOrder order) + { + this.sortOrder = order; + } + + public int Compare(ListViewGroup x, ListViewGroup y) + { + // If we know how to compare the tags, do that. + // Otherwise do a case insensitive compare on the group header. + // We have explicitly catch the "almost-null" value of DBNull.Value, + // since comparing to that value always produces a type exception. + int result; + IComparable comparable = x.Tag as IComparable; + if (comparable != null && y.Tag != System.DBNull.Value) + result = comparable.CompareTo(y.Tag); + else + result = String.Compare(x.Header, y.Header, true); + + if (this.sortOrder == SortOrder.Descending) + result = 0 - result; + + return result; + } + + private SortOrder sortOrder; + } + + /// + /// ColumnComparer is the workhorse for all comparison between two values of a particular column. + /// If the column has a specific comparer, use that to compare the values. Otherwise, do + /// a case insensitive string compare of the string representations of the values. + /// + /// This class inherits from both IComparer and its generic counterpart + /// so that it can be used on untyped and typed collections. + internal class ColumnComparer : IComparer, IComparer + { + public ColumnComparer(OLVColumn col, SortOrder order) + { + this.column = col; + this.sortOrder = order; + this.secondComparer = null; + } + + public ColumnComparer(OLVColumn col, SortOrder order, OLVColumn col2, SortOrder order2) + : this(col, order) + { + // There is no point in secondary sorting on the same column + if (col != col2) + this.secondComparer = new ColumnComparer(col2, order2); + } + + public int Compare(object x, object y) + { + return this.Compare((OLVListItem)x, (OLVListItem)y); + } + + public int Compare(OLVListItem x, OLVListItem y) + { + int result = 0; + object x1 = this.column.GetValue(x.RowObject); + object y1 = this.column.GetValue(y.RowObject); + + if (this.sortOrder == SortOrder.None) + return 0; + + // Handle nulls. Null values come last + bool xIsNull = (x1 == null || x1 == System.DBNull.Value); + bool yIsNull = (y1 == null || y1 == System.DBNull.Value); + if (xIsNull || yIsNull) { + if (xIsNull && yIsNull) + result = 0; + else + result = (xIsNull ? -1 : 1); + } else { + result = this.CompareValues(x1, y1); + } + + if (this.sortOrder == SortOrder.Descending) + result = 0 - result; + + // If the result was equality, use the secondary comparer to resolve it + if (result == 0 && this.secondComparer != null) + result = this.secondComparer.Compare(x, y); + + return result; + } + + public int CompareValues(object x, object y) + { + // Force case insensitive compares on strings + if (x is String) + return String.Compare((String)x, (String)y, true); + else { + IComparable comparable = x as IComparable; + if (comparable != null) + return comparable.CompareTo(y); + else + return 0; + } + } + + private OLVColumn column; + private SortOrder sortOrder; + private ColumnComparer secondComparer; + } + + #endregion + + #region Renderers + + /// + /// Renderers are responsible for drawing a single cell within an owner drawn ObjectListView. + /// + /// + /// Methods on this class are called during the DrawItem or DrawSubItemEvent. + /// Subclasses can tell which type of event they are handling by examining DrawItemEvent: if this + /// is not null, it is a DrawItem event. + /// Subclasses will normally override the RenderWithDefault or Render method, and use the other + /// methods as helper functions. + /// If a renderer is installed on the primary column (column 0), it will be given a chance + /// to draw the whole item in all views (Details, Tile, etc.). If the renderer returns true, + /// default processing will continue. If it returns false, no other rendering will happen. + /// This means that when an ObjectListView is in Details view, the renderer on column 0 + /// will be called twice: once to handle the DrawItem event, and then again to draw only the + /// first cell. Subclasses must distinguish between these two very different events (using + /// the "this.DrawItemEvent == null" test). + /// + [Browsable(false)] + public class BaseRenderer + { + /// + /// Make a simple renderer + /// + public BaseRenderer() + { + } + + #region Properties + + /// + /// Get/set the event that caused this renderer to be called + /// + public DrawListViewSubItemEventArgs Event + { + get { return eventArgs; } + set { eventArgs = value; } + } + private DrawListViewSubItemEventArgs eventArgs; + + /// + /// Get/set the event that caused this renderer to be called + /// + public DrawListViewItemEventArgs DrawItemEvent + { + get { return drawItemEventArgs; } + set { drawItemEventArgs = value; } + } + private DrawListViewItemEventArgs drawItemEventArgs; + + /// + /// Get/set the listview for which the drawing is to be done + /// + public ObjectListView ListView + { + get { return objectListView; } + set { objectListView = value; } + } + private ObjectListView objectListView; + + /// + /// Get or set the OLVColumn that this renderer will draw + /// + public OLVColumn Column + { + get { return column; } + set { column = value; } + } + private OLVColumn column; + + /// + /// Get or set the model object that this renderer should draw + /// + public Object RowObject + { + get { return rowObject; } + set { rowObject = value; } + } + private Object rowObject; + + /// + /// Get or set the aspect of the model object that this renderer should draw + /// + public Object Aspect + { + get + { + if (aspect == null) + aspect = column.GetValue(this.rowObject); + return aspect; + } + set { aspect = value; } + } + private Object aspect; + + /// + /// Get or set the listitem that this renderer will be drawing + /// + public OLVListItem ListItem + { + get { return listItem; } + set { listItem = value; } + } + private OLVListItem listItem; + + /// + /// Get or set the list subitem that this renderer will be drawing + /// + public ListViewItem.ListViewSubItem SubItem + { + get { return listSubItem; } + set { listSubItem = value; } + } + private ListViewItem.ListViewSubItem listSubItem; + + /// + /// Get the specialized OLVSubItem that this renderer is drawing + /// + /// This returns null for column 0. + public OLVListSubItem OLVSubItem + { + get { return listSubItem as OLVListSubItem; } + } + + /// + /// Cache whether or not our item is selected + /// + public bool IsItemSelected + { + get { return isItemSelected; } + set { isItemSelected = value; } + } + private bool isItemSelected; + + + /// + /// Return the font to be used for text in this cell + /// + /// The font of the subitem + public Font Font + { + get + { + if (this.font == null) { + if (this.ListItem.UseItemStyleForSubItems) + return this.ListItem.Font; + else + return this.SubItem.Font; + } else + return this.font; + } + set + { + this.font = value; + } + } + private Font font; + + /// + /// The brush that will be used to paint the text + /// + public Brush TextBrush + { + get + { + if (textBrush == null) + return new SolidBrush(this.GetForegroundColor()); + else + return this.textBrush; + } + set { textBrush = value; } + } + private Brush textBrush; + + /// + /// Should this renderer fill in the background before drawing? + /// + public bool IsDrawBackground + { + get { return isDrawBackground; } + set { isDrawBackground = value; } + } + private bool isDrawBackground = true; + + /// + /// Can the renderer wrap lines that do not fit completely within the cell? + /// + /// This value is currently only used when printing a list view using ListViewPrinter. + public bool CanWrap + { + get { return canWrap; } + set { canWrap = value; } + } + private bool canWrap = false; + + /// + /// When rendering multiple images, how many pixels should be between each image? + /// + public int Spacing + { + get { return spacing; } + set { spacing = value; } + } + private int spacing = 1; + + #endregion + + #region Utilities + + /// + /// Return the string that should be drawn within this + /// + /// + public string GetText() + { + if (this.SubItem == null) + return this.ListItem.Text; + else + return this.SubItem.Text; + } + + /// + /// Return the image that should be drawn against this subitem + /// + /// An Image or null if no image should be drawn. + public Image GetImage() + { + if (this.Column.Index == 0) + return this.GetImage(this.ListItem.ImageSelector); + else + return this.GetImage(this.OLVSubItem.ImageSelector); + } + + /// + /// Return the actual image that should be drawn when keyed by the given image selector. + /// An image selector can be: + /// an int, giving the index into the image list + /// a string, giving the image key into the image list + /// an Image, being the image itself + /// + /// + /// The value that indicates the image to be used + /// An Image or null + public Image GetImage(Object imageSelector) + { + if (imageSelector == null || imageSelector == System.DBNull.Value) + return null; + + ImageList il = this.ListView.BaseSmallImageList; + if (il != null) { + if (imageSelector is Int32) { + Int32 index = (Int32)imageSelector; + if (index < 0 || index >= il.Images.Count) + return null; + else + return il.Images[index]; + } + + if (imageSelector is String) { + if (il.Images.ContainsKey((String)imageSelector)) + return il.Images[(String)imageSelector]; + else + return null; + } + } + + return imageSelector as Image; + } + + /// + /// Return the Color that is the background color for this item's cell + /// + /// The background color of the subitem + public Color GetBackgroundColor() + { + if (this.IsItemSelected && this.ListView.FullRowSelect) { + if (this.ListView.Focused) + return this.ListView.HighlightBackgroundColorOrDefault; + else + if (!this.ListView.HideSelection) + return SystemColors.Control; //TODO: What color should this be? + } + if (this.ListItem.UseItemStyleForSubItems) + return this.ListItem.BackColor; + else + return this.SubItem.BackColor; + } + + /// + /// Return the Color that is the background color for this item's text + /// + /// The background color of the subitem's text + protected Color GetTextBackgroundColor() + { + if (this.IsItemSelected && (this.Column.Index == 0 || this.ListView.FullRowSelect)) + return this.ListView.HighlightBackgroundColorOrDefault; + else + if (this.ListItem.UseItemStyleForSubItems) + return this.ListItem.BackColor; + else + return this.SubItem.BackColor; + } + + /// + /// Return the color to be used for text in this cell + /// + /// The text color of the subitem + protected Color GetForegroundColor() + { + if (this.IsItemSelected && (this.Column.Index == 0 || this.ListView.FullRowSelect)) + return this.ListView.HighlightForegroundColorOrDefault; + else + if (this.ListItem.UseItemStyleForSubItems) + return this.ListItem.ForeColor; + else + return this.SubItem.ForeColor; + } + + + /// + /// Align the second rectangle with the first rectangle, + /// according to the alignment of the column + /// + /// The cell's bounds + /// The rectangle to be aligned within the bounds + /// An aligned rectangle + protected Rectangle AlignRectangle(Rectangle outer, Rectangle inner) + { + Rectangle r = new Rectangle(outer.Location, inner.Size); + + // Centre horizontally depending on the column alignment + if (inner.Width < outer.Width) { + switch (this.Column.TextAlign) { + case HorizontalAlignment.Left: + r.X = outer.Left; + break; + case HorizontalAlignment.Center: + r.X = outer.Left + ((outer.Width - inner.Width) / 2); + break; + case HorizontalAlignment.Right: + r.X = outer.Right - inner.Width - 1; + break; + } + } + // Centre vertically too + if (inner.Height < outer.Height) + r.Y = outer.Top + ((outer.Height - inner.Height) / 2); + + return r; + } + + /// + /// Draw the given image aligned horizontally within the column. + /// + /// + /// Over tall images are scaled to fit. Over-wide images are + /// truncated. This is by design! + /// + /// Graphics context to use for drawing + /// Bounds of the cell + /// The image to be drawn + protected void DrawAlignedImage(Graphics g, Rectangle r, Image image) + { + if (image == null) + return; + + // By default, the image goes in the top left of the rectangle + Rectangle imageBounds = new Rectangle(r.Location, image.Size); + + // If the image is too tall to be drawn in the space provided, proportionally scale it down. + // Too wide images are not scaled. + if (image.Height > r.Height) { + float scaleRatio = (float)r.Height / (float)image.Height; + imageBounds.Width = (int)((float)image.Width * scaleRatio); + imageBounds.Height = r.Height - 1; + } + + // Align and draw our (possibly scaled) image + g.DrawImage(image, this.AlignRectangle(r, imageBounds)); + } + + /// + /// Fill in the background of this cell + /// + /// Graphics context to use for drawing + /// Bounds of the cell + protected void DrawBackground(Graphics g, Rectangle r) + { + if (this.IsDrawBackground) { + using (Brush brush = new SolidBrush(this.GetBackgroundColor())) { + g.FillRectangle(brush, r); + } + } + } + + #endregion + + + /// + /// The delegate that is called from the list view. This is the main entry point, but + /// subclasses should override Render instead of this method. + /// + /// The event that caused this redraw + /// The context that our drawing should be done using + /// The bounds of the cell within which the renderer can draw + /// The model object for this row + /// A boolean indicating whether the default process should occur + public bool HandleRendering(EventArgs e, Graphics g, Rectangle r, Object rowObject) + { + this.ListView = (ObjectListView)this.Column.ListView; + if (e is DrawListViewSubItemEventArgs) { + this.Event = (DrawListViewSubItemEventArgs)e; + this.ListItem = this.Event.Item as OLVListItem; + this.SubItem = this.Event.SubItem; + this.Column = this.ListView.GetColumn(this.Event.ColumnIndex); + } else { + this.DrawItemEvent = (DrawListViewItemEventArgs)e; + this.ListItem = this.DrawItemEvent.Item as OLVListItem; + this.SubItem = null; + this.Column = this.ListView.GetColumn(0); + } + this.RowObject = rowObject; + this.Aspect = null; // uncache previous result + this.IsItemSelected = this.ListItem.Selected; // ((e.ItemState & ListViewItemStates.Selected) == ListViewItemStates.Selected); + this.IsDrawBackground = true; + this.Font = null; + this.TextBrush = null; + return this.OptionalRender(g, r); + } + + /// + /// Draw our data into the given rectangle using the given graphics context. + /// + /// + /// Subclasses should override this method. + /// The graphics context that should be used for drawing + /// The bounds of the subitem cell + /// Returns whether the renderering has already taken place. + /// If this returns false, the default processing will take over. + /// + virtual public bool OptionalRender(Graphics g, Rectangle r) + { + this.Render(g, r); + return true; + } + + /// + /// Draw our data into the given rectangle using the given graphics context. + /// + /// + /// Subclasses should override this method if they never want + /// to fall back on the default processing + /// The graphics context that should be used for drawing + /// The bounds of the subitem cell + virtual public void Render(Graphics g, Rectangle r) + { + this.DrawBackground(g, r); + + // Adjust the rectangle to match the padding used by the native mode of the ListView + Rectangle r2 = r; + r2.X += 4; + r2.Width -= 4; + this.DrawImageAndText(g, r2); + } + + /// + /// Draw our subitems image and text + /// + /// Graphics context to use for drawing + /// Bounds of the cell + protected void DrawImageAndText(Graphics g, Rectangle r) + { + this.DrawImageAndText(g, r, this.GetText(), this.GetImage()); + } + + /// + /// Draw the given text and optional image in the "normal" fashion + /// + /// Graphics context to use for drawing + /// Bounds of the cell + /// The string to be drawn + /// The optional image to be drawn + protected void DrawImageAndText(Graphics g, Rectangle r, String txt, Image image) + { + // Draw the image + if (image != null) { + int top = r.Y; + if (image.Size.Height < r.Height) + top += ((r.Height - image.Size.Height) / 2); + + g.DrawImageUnscaled(image, r.X, top); + r.X += image.Width; + r.Width -= image.Width; + } + + StringFormat fmt = new StringFormat(); + fmt.LineAlignment = StringAlignment.Center; + fmt.Trimming = StringTrimming.EllipsisCharacter; + if (!this.CanWrap) + fmt.FormatFlags = StringFormatFlags.NoWrap; + switch (this.Column.TextAlign) { + case HorizontalAlignment.Center: fmt.Alignment = StringAlignment.Center; break; + case HorizontalAlignment.Left: fmt.Alignment = StringAlignment.Near; break; + case HorizontalAlignment.Right: fmt.Alignment = StringAlignment.Far; break; + } + + // Draw the background of the text as selected, if it's the primary column + // and it's selected and it's not in FullRowSelect mode. + if (this.IsDrawBackground && this.IsItemSelected && this.Column.Index == 0 && !this.ListView.FullRowSelect) { + SizeF size = g.MeasureString(txt, this.Font, r.Width, fmt); + // This is a tighter selection box + //Rectangle r2 = this.AlignRectangle(r, new Rectangle(0, 0, (int)(size.Width + 1), (int)(size.Height + 1))); + Rectangle r2 = r; + r2.Width = (int)size.Width + 1; + using (Brush brush = new SolidBrush(this.ListView.HighlightBackgroundColorOrDefault)) + g.FillRectangle(brush, r2); + } + + RectangleF rf = r; + g.DrawString(txt, this.Font, this.TextBrush, rf, fmt); + + // We should put a focus rectange around the column 0 text if it's selected -- + // but we don't because: + // - I really dislike this UI convention + // - we are using buffered graphics, so the DrawFocusRecatangle method of the event doesn't work + + //if (this.Column.Index == 0) { + // Size size = TextRenderer.MeasureText(this.SubItem.Text, this.ListView.ListFont); + // if (r.Width > size.Width) + // r.Width = size.Width; + // this.Event.DrawFocusRectangle(r); + //} + } + } + + /// + /// This class maps a data value to an image that should be drawn for that value. + /// + /// It is useful for drawing data that is represented as an enum or boolean. + public class MappedImageRenderer : BaseRenderer + { + /// + /// Return a renderer that draw boolean values using the given images + /// + /// Draw this when our data value is true + /// Draw this when our data value is false + /// A Renderer + static public MappedImageRenderer Boolean(Object trueImage, Object falseImage) + { + return new MappedImageRenderer(true, trueImage, false, falseImage); + } + + /// + /// Return a renderer that draw tristate boolean values using the given images + /// + /// Draw this when our data value is true + /// Draw this when our data value is false + /// Draw this when our data value is null + /// A Renderer + static public MappedImageRenderer TriState(Object trueImage, Object falseImage, Object nullImage) + { + return new MappedImageRenderer(new Object[] { true, trueImage, false, falseImage, null, nullImage }); + } + + /// + /// Make a new empty renderer + /// + public MappedImageRenderer() + : base() + { + map = new System.Collections.Hashtable(); + } + + /// + /// Make a new renderer that will show the given image when the given key is the aspect value + /// + /// The data value to be matched + /// The image to be shown when the key is matched + public MappedImageRenderer(Object key, Object image) + : this() + { + this.Add(key, image); + } + + /// + /// Make a new renderer that will show the given images when it receives the given keys + /// + /// + /// + /// + /// + public MappedImageRenderer(Object key1, Object image1, Object key2, Object image2) + : this() + { + this.Add(key1, image1); + this.Add(key2, image2); + } + + /// + /// Build a renderer from the given array of keys and their matching images + /// + /// An array of key/image pairs + public MappedImageRenderer(Object[] keysAndImages) + : this() + { + if ((keysAndImages.GetLength(0) % 2) != 0) + throw new ArgumentException("Array must have key/image pairs"); + + for (int i = 0; i < keysAndImages.GetLength(0); i += 2) + this.Add(keysAndImages[i], keysAndImages[i + 1]); + } + + /// + /// Register the image that should be drawn when our Aspect has the data value. + /// + /// Value that the Aspect must match + /// An ImageSelector -- an int, string or image + public void Add(Object value, Object image) + { + if (value == null) + this.nullImage = image; + else + map[value] = image; + } + + /// + /// Render our value + /// + /// + /// + public override void Render(Graphics g, Rectangle r) + { + this.DrawBackground(g, r); + + if (this.Aspect is ICollection) + this.RenderCollection(g, r, (ICollection)this.Aspect); + else + this.RenderOne(g, r, this.Aspect); + } + + private void RenderCollection(Graphics g, Rectangle r, ICollection imageSelectors) + { + Image image = null; + Point pt = r.Location; + foreach (Object selector in imageSelectors) { + if (selector == null) + image = this.GetImage(this.nullImage); + else if (map.ContainsKey(selector)) + image = this.GetImage(map[selector]); + else + image = null; + + if (image != null) { + g.DrawImage(image, pt); + pt.X += (image.Width + this.Spacing); + } + } + } + + private void RenderOne(Graphics g, Rectangle r, Object selector) + { + Image image = null; + if (selector == null) + image = this.GetImage(this.nullImage); + else + if (map.ContainsKey(selector)) + image = this.GetImage(map[selector]); + + if (image != null) + this.DrawAlignedImage(g, r, image); + } + + #region Private variables + + private Hashtable map; // Track the association between values and images + private Object nullImage; // image to be drawn for null values (since null can't be a key) + + #endregion + } + + /// + /// Render an image that comes from our data source. + /// + /// The image can be sourced from: + /// + /// a byte-array (normally when the image to be shown is + /// stored as a value in a database) + /// an int, which is treated as an index into the image list + /// a string, which is treated first as a file name, and failing that as an index into the image list + /// + /// If an image is an animated GIF, it's state is stored in the SubItem object. + /// By default, the image renderer does not render animations (it begins life with animations paused). + /// To enable animations, you must call Unpause(). + /// + public class ImageRenderer : BaseRenderer + { + /// + /// Make an empty image renderer + /// + public ImageRenderer() + : base() + { + this.tickler = new System.Threading.Timer(new TimerCallback(this.OnTimer), null, Timeout.Infinite, Timeout.Infinite); + this.stopwatch = new Stopwatch(); + } + + /// + /// Make an empty image renderer that begins life ready for animations + /// + public ImageRenderer(bool startAnimations) + : this() + { + this.Paused = !startAnimations; + } + + /// + /// Draw our image + /// + /// + /// + public override void Render(Graphics g, Rectangle r) + { + this.DrawBackground(g, r); + this.DrawAlignedImage(g, r, this.GetImageFromAspect()); + } + + /// + /// Translate our Aspect into an image. + /// + /// The strategy is: + /// If its a byte array, we treat it as an in-memory image + /// If it's an int, we use that as an index into our image list + /// If it's a string, we try to load a file by that name. If we can't, we use the string as an index into our image list. + /// + /// An image + protected Image GetImageFromAspect() + { + if (this.Aspect == null || this.Aspect == System.DBNull.Value) + return null; + + // If we've already figured out the image, don't do it again + if (this.OLVSubItem != null && this.OLVSubItem.ImageSelector is Image) { + if (this.OLVSubItem.AnimationState == null) + return (Image)this.OLVSubItem.ImageSelector; + else + return this.OLVSubItem.AnimationState.image; + } + + // Try to convert our Aspect into an Image + // If its a byte array, we treat it as an in-memory image + // If it's an int, we use that as an index into our image list + // If it's a string, we try to find a file by that name. + // If we can't, we use the string as an index into our image list. + Image image = null; + if (this.Aspect is System.Byte[]) { + using (MemoryStream stream = new MemoryStream((System.Byte[])this.Aspect)) { + try { + image = Image.FromStream(stream); + } catch (ArgumentException) { + // ignore + } + } + } else if (this.Aspect is Int32) { + image = this.GetImage(this.Aspect); + } else if (this.Aspect is String && ((String)this.Aspect) != "") { + try { + image = Image.FromFile((String)this.Aspect); + } catch (FileNotFoundException) { + image = this.GetImage(this.Aspect); + } catch (OutOfMemoryException) { + image = this.GetImage(this.Aspect); + } + } + + // If this image is an animation, initialize the animation process + if (this.OLVSubItem != null && AnimationState.IsAnimation(image)) { + this.OLVSubItem.AnimationState = new AnimationState(image); + } + + // Cache the image so we don't repeat this dreary process + if (this.OLVSubItem != null) + this.OLVSubItem.ImageSelector = image; + + return image; + } + + /// + /// Should the animations in this renderer be paused? + /// + public bool Paused + { + get { return isPaused; } + set + { + if (isPaused != value) { + isPaused = value; + if (isPaused) { + this.tickler.Change(Timeout.Infinite, Timeout.Infinite); + this.stopwatch.Stop(); + } else { + this.tickler.Change(1, Timeout.Infinite); + this.stopwatch.Start(); + } + } + } + } + private bool isPaused = true; + + /// + /// Pause any animations + /// + public void Pause() + { + this.Paused = true; + } + + /// + /// Unpause any animations + /// + public void Unpause() + { + this.Paused = false; + } + + /// + /// This is the method that is invoked by the timer. It basically switches control to the listview thread. + /// + /// not used + public void OnTimer(Object state) + { + if (this.ListView == null || this.Paused) + this.tickler.Change(1000, Timeout.Infinite); + else { + if (this.ListView.InvokeRequired) + this.ListView.Invoke((MethodInvoker)delegate { this.OnTimer(state); }); + else + this.OnTimerInThread(); + } + } + + /// + /// This is the OnTimer callback, but invoked in the same thread as the creator of the ListView. + /// This method can use all of ListViews methods without creating a CrossThread exception. + /// + protected void OnTimerInThread() + { + // MAINTAINER NOTE: This method must renew the tickler. If it doesn't the animations will stop. + + // If this listview has been destroyed, we can't do anything, so we return without + // renewing the tickler, effectively killing all animations on this renderer + if (this.ListView.IsDisposed) + return; + + // If we're not in Detail view or our column has been removed from the list, + // we can't do anything at the moment, but we still renew the tickler because the view may change later. + if (this.ListView.View != System.Windows.Forms.View.Details || this.Column.Index < 0) { + this.tickler.Change(1000, Timeout.Infinite); + return; + } + + long elapsedMilliseconds = this.stopwatch.ElapsedMilliseconds; + int subItemIndex = this.Column.Index; + long nextCheckAt = elapsedMilliseconds + 1000; // wait at most one second before checking again + Rectangle updateRect = new Rectangle(); // what part of the view must be updated to draw the changed gifs? + + // Run through all the subitems in the view for our column, and for each one that + // has an animation attached to it, see if the frame needs updating. + foreach (ListViewItem lvi in this.ListView.Items) { + // Get the gif state from the subitem. If there isn't an animation state, skip this row. + OLVListSubItem lvsi = (OLVListSubItem)lvi.SubItems[subItemIndex]; + AnimationState state = lvsi.AnimationState; + if (state == null || !state.IsValid) + continue; + + // Has this frame of the animation expired? + if (elapsedMilliseconds >= state.currentFrameExpiresAt) { + state.AdvanceFrame(elapsedMilliseconds); + + // Track the area of the view that needs to be redrawn to show the changed images + if (updateRect.IsEmpty) + updateRect = lvsi.Bounds; + else + updateRect = Rectangle.Union(updateRect, lvsi.Bounds); + } + + // Remember the minimum time at which a frame is next due to change + nextCheckAt = Math.Min(nextCheckAt, state.currentFrameExpiresAt); + } + + // Update the part of the listview where frames have changed + if (!updateRect.IsEmpty) + this.ListView.Invalidate(updateRect); + + // Renew the tickler in time for the next frame change + this.tickler.Change(nextCheckAt - elapsedMilliseconds, Timeout.Infinite); + } + + /// + /// Instances of this class kept track of the animation state of a single image. + /// + internal class AnimationState + { + const int PropertyTagTypeShort = 3; + const int PropertyTagTypeLong = 4; + const int PropertyTagFrameDelay = 0x5100; + const int PropertyTagLoopCount = 0x5101; + + /// + /// Is the given image an animation + /// + /// The image to be tested + /// Is the image an animation? + static public bool IsAnimation(Image image) + { + if (image == null) + return false; + else + return (new List(image.FrameDimensionsList)).Contains(FrameDimension.Time.Guid); + } + + /// + /// Create an AnimationState in a quiet state + /// + public AnimationState() + { + this.currentFrame = 0; + this.frameCount = 0; + this.imageDuration = new List(); + this.image = null; + } + + /// + /// Create an animation state for the given image, which may or may not + /// be an animation + /// + /// The image to be rendered + public AnimationState(Image image) + : this() + { + if (!AnimationState.IsAnimation(image)) + return; + + // How many frames in the animation? + this.image = image; + this.frameCount = this.image.GetFrameCount(FrameDimension.Time); + + // Find the delay between each frame. + // The delays are stored an array of 4-byte ints. Each int is the + // number of 1/100th of a second that should elapsed before the frame expires + foreach (PropertyItem pi in this.image.PropertyItems) { + if (pi.Id == PropertyTagFrameDelay) { + for (int i = 0; i < pi.Len; i += 4) { + //TODO: There must be a better way to convert 4-bytes to an int + int delay = (pi.Value[i + 3] << 24) + (pi.Value[i + 2] << 16) + (pi.Value[i + 1] << 8) + pi.Value[i]; + this.imageDuration.Add(delay * 10); // store delays as milliseconds + } + break; + } + } + + // There should be as many frame durations as frames + Debug.Assert(this.imageDuration.Count == this.frameCount, "There should be as many frame durations as there are frames."); + } + + /// + /// Does this state represent a valid animation + /// + public bool IsValid + { + get + { + return (this.image != null && this.frameCount > 0); + } + } + + /// + /// Advance our images current frame and calculate when it will expire + /// + public void AdvanceFrame(long millisecondsNow) + { + this.currentFrame = (this.currentFrame + 1) % this.frameCount; + this.currentFrameExpiresAt = millisecondsNow + this.imageDuration[this.currentFrame]; + this.image.SelectActiveFrame(FrameDimension.Time, this.currentFrame); + } + + internal int currentFrame; + internal long currentFrameExpiresAt; + internal Image image; + internal List imageDuration; + internal int frameCount; + } + + #region Private variables + + private System.Threading.Timer tickler; // timer used to tickle the animations + private Stopwatch stopwatch; // clock used to time the animation frame changes + + #endregion + } + + /// + /// Render our Aspect as a progress bar + /// + public class BarRenderer : BaseRenderer + { + #region Constructors + + /// + /// Make a BarRenderer + /// + public BarRenderer() + : base() + { + this.Pen = new Pen(Color.Blue, 1); + this.Brush = Brushes.Aquamarine; + this.BackgroundBrush = Brushes.White; + this.StartColor = Color.Empty; + } + + /// + /// Make a BarRenderer for the given range of data values + /// + public BarRenderer(int minimum, int maximum) + : this() + { + this.MinimumValue = minimum; + this.MaximumValue = maximum; + } + + /// + /// Make a BarRenderer using a custom bar scheme + /// + public BarRenderer(Pen aPen, Brush aBrush) + : this() + { + this.Pen = aPen; + this.Brush = aBrush; + this.UseStandardBar = false; + } + + /// + /// Make a BarRenderer using a custom bar scheme + /// + public BarRenderer(int minimum, int maximum, Pen aPen, Brush aBrush) + : this(minimum, maximum) + { + this.Pen = aPen; + this.Brush = aBrush; + this.UseStandardBar = false; + } + + /// + /// Make a BarRenderer that uses a horizontal gradient + /// + public BarRenderer(Pen aPen, Color start, Color end) + : this() + { + this.Pen = aPen; + this.SetGradient(start, end); + } + + /// + /// Make a BarRenderer that uses a horizontal gradient + /// + public BarRenderer(int minimum, int maximum, Pen aPen, Color start, Color end) + : this(minimum, maximum) + { + this.Pen = aPen; + this.SetGradient(start, end); + } + + #endregion + + #region Public variables + + /// + /// Should this bar be drawn in the system style + /// + public bool UseStandardBar = true; + + /// + /// How many pixels in from our cell border will this bar be drawn + /// + public int Padding = 2; + + /// + /// The Pen that will draw the frame surrounding this bar + /// + public Pen Pen; + + /// + /// The brush that will be used to fill the bar + /// + public Brush Brush; + + /// + /// The brush that will be used to fill the background of the bar + /// + public Brush BackgroundBrush; + + /// + /// The first color when a gradient is used to fill the bar + /// + public Color StartColor; + + /// + /// The end color when a gradient is used to fill the bar + /// + public Color EndColor; + + /// + /// Regardless of how wide the column become the progress bar will never be wider than this + /// + public int MaximumWidth = 100; + + /// + /// Regardless of how high the cell is the progress bar will never be taller than this + /// + public int MaximumHeight = 16; + + /// + /// The minimum data value expected. Values less than this will given an empty bar + /// + public int MinimumValue = 0; + + /// + /// The maximum value for the range. Values greater than this will give a full bar + /// + public int MaximumValue = 100; + + #endregion + + /// + /// Draw this progress bar using a gradient + /// + /// + /// + public void SetGradient(Color start, Color end) + { + this.StartColor = start; + this.EndColor = end; + this.UseStandardBar = false; + } + + /// + /// Draw our aspect + /// + /// + /// + public override void Render(Graphics g, Rectangle r) + { + this.DrawBackground(g, r); + + Rectangle frameRect = Rectangle.Inflate(r, 0 - this.Padding, 0 - this.Padding); + frameRect.Width = Math.Min(frameRect.Width, this.MaximumWidth); + frameRect.Height = Math.Min(frameRect.Width, this.MaximumHeight); + frameRect = this.AlignRectangle(r, frameRect); + + // Convert our aspect to a numeric value + // CONSIDER: Is this the best way to do this? + if (!(this.Aspect is IConvertible)) + return; + double aspectValue = ((IConvertible)this.Aspect).ToDouble(NumberFormatInfo.InvariantInfo); + + Rectangle fillRect = Rectangle.Inflate(frameRect, -1, -1); + if (aspectValue <= this.MinimumValue) + fillRect.Width = 0; + else if (aspectValue < this.MaximumValue) + fillRect.Width = (int)(fillRect.Width * (aspectValue - this.MinimumValue) / this.MaximumValue); + + if (this.UseStandardBar && ProgressBarRenderer.IsSupported) { + ProgressBarRenderer.DrawHorizontalBar(g, frameRect); + ProgressBarRenderer.DrawHorizontalChunks(g, fillRect); + } else { + g.FillRectangle(this.BackgroundBrush, frameRect); + if (fillRect.Width > 0) { + fillRect.Height++; + if (this.StartColor == Color.Empty) + g.FillRectangle(this.Brush, fillRect); + else { + using (LinearGradientBrush gradient = new LinearGradientBrush(frameRect, this.StartColor, this.EndColor, LinearGradientMode.Horizontal)) { + g.FillRectangle(gradient, fillRect); + } + } + } + g.DrawRectangle(this.Pen, frameRect); + } + } + } + + /// + /// An ImagesRenderer draws zero or more images depending on the data returned by its Aspect. + /// + /// This renderer's Aspect must return a ICollection of ints, strings or Images, + /// each of which will be drawn horizontally one after the other. + public class ImagesRenderer : BaseRenderer + { + + /// + /// Draw our data value + /// + /// + /// + public override void Render(Graphics g, Rectangle r) + { + this.DrawBackground(g, r); + + ICollection imageSelectors = this.Aspect as ICollection; + if (imageSelectors == null) + return; + + Point pt = r.Location; + foreach (Object selector in imageSelectors) { + Image image = this.GetImage(selector); + if (image != null) { + g.DrawImage(image, pt); + pt.X += (image.Width + this.Spacing); + } + } + } + } + + /// + /// A MultiImageRenderer draws the same image a number of times based on our data value + /// + /// The stars in the Rating column of iTunes is a good example of this type of renderer. + public class MultiImageRenderer : BaseRenderer + { + /// + /// Make a quiet rendererer + /// + public MultiImageRenderer() + : base() + { + } + + /// + /// Make an image renderer that will draw the indicated image, at most maxImages times. + /// + /// + /// + /// + /// + public MultiImageRenderer(Object imageSelector, int maxImages, int minValue, int maxValue) + : this() + { + this.ImageSelector = imageSelector; + this.MaxNumberImages = maxImages; + this.MinimumValue = minValue; + this.MaximumValue = maxValue; + } + + /// + /// The image selector that will give the image to be drawn + /// + public Object ImageSelector; + + /// + /// What is the maximum number of images that this renderer should draw? + /// + public int MaxNumberImages = 10; + + /// + /// Values less than or equal to this will have 0 images drawn + /// + public int MinimumValue = 0; + + /// + /// Values greater than or equal to this will have MaxNumberImages images drawn + /// + public int MaximumValue = 100; + + /// + /// Draw our data value + /// + /// + /// + public override void Render(Graphics g, Rectangle r) + { + this.DrawBackground(g, r); + + Image image = this.GetImage(this.ImageSelector); + if (image == null) + return; + + // Convert our aspect to a numeric value + // CONSIDER: Is this the best way to do this? + if (!(this.Aspect is IConvertible)) + return; + double aspectValue = ((IConvertible)this.Aspect).ToDouble(NumberFormatInfo.InvariantInfo); + + // Calculate how many images we need to draw to represent our aspect value + int numberOfImages; + if (aspectValue <= this.MinimumValue) + numberOfImages = 0; + else if (aspectValue < this.MaximumValue) + numberOfImages = 1 + (int)(this.MaxNumberImages * (aspectValue - this.MinimumValue) / this.MaximumValue); + else + numberOfImages = this.MaxNumberImages; + + // If we need to shrink the image, what will its on-screen dimensions be? + int imageScaledWidth = image.Width; + int imageScaledHeight = image.Height; + if (r.Height < image.Height) { + imageScaledWidth = (int)((float)image.Width * (float)r.Height / (float)image.Height); + imageScaledHeight = r.Height; + } + // Calculate where the images should be drawn + Rectangle imageBounds = r; + imageBounds.Width = (this.MaxNumberImages * (imageScaledWidth + this.Spacing)) - this.Spacing; + imageBounds.Height = imageScaledHeight; + imageBounds = this.AlignRectangle(r, imageBounds); + + // Finally, draw the images + for (int i = 0; i < numberOfImages; i++) { + g.DrawImage(image, imageBounds.X, imageBounds.Y, imageScaledWidth, imageScaledHeight); + imageBounds.X += (imageScaledWidth + this.Spacing); + } + } + } + + + /// + /// A class to render a value that contains a bitwise-OR'ed collection of values. + /// + /// The type of value that holds the bit-OR'ed flag + public class FlagRenderer : BaseRenderer //where T : IConvertible + { + /// + /// Register the given image to the given value + /// + /// When this flag is present... + /// ...draw this image + public void Add(T key, Object imageSelector) + { + Int32 k2 = ((IConvertible)key).ToInt32(NumberFormatInfo.InvariantInfo); + + this.imageMap[k2] = imageSelector; + this.keysInOrder.Remove(k2); + this.keysInOrder.Add(k2); + } + + /// + /// Draw the flags + /// + /// + /// + public override void Render(Graphics g, Rectangle r) + { + this.DrawBackground(g, r); + + Int32 v2 = ((IConvertible)this.Aspect).ToInt32(NumberFormatInfo.InvariantInfo); + + Point pt = r.Location; + foreach (Int32 key in this.keysInOrder) { + if ((v2 & key) == key) { + Image image = this.GetImage(this.imageMap[key]); + if (image != null) { + g.DrawImage(image, pt); + pt.X += (image.Width + this.Spacing); + } + } + } + } + + private List keysInOrder = new List(); + private Dictionary imageMap = new Dictionary(); + } + #endregion + +} diff --git a/Source/ryControls/Controls/PanelEx.Designer.cs b/Source/ryControls/Controls/PanelEx.Designer.cs new file mode 100644 index 0000000..395e924 --- /dev/null +++ b/Source/ryControls/Controls/PanelEx.Designer.cs @@ -0,0 +1,43 @@ +namespace ryControls +{ + partial class PanelEx + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // PanelEx + // + this.Paint += new System.Windows.Forms.PaintEventHandler(this.PanelEx_Paint); + this.Resize += new System.EventHandler(this.PanelEx_Resize); + this.ResumeLayout(false); + + } + + #endregion + } +} diff --git a/Source/ryControls/Controls/PanelEx.cs b/Source/ryControls/Controls/PanelEx.cs new file mode 100644 index 0000000..6a3c312 --- /dev/null +++ b/Source/ryControls/Controls/PanelEx.cs @@ -0,0 +1,115 @@ +using ryControls; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryControls +{ + /// + /// + /// + public partial class PanelEx : Panel + { + /// + /// + /// + public PanelEx() + { + InitializeComponent(); + this.BorderStyle = BorderStyle.None; + } + private int _radius = 10; + private RoundStyle _roundeStyle; + + private Color _borderColor = SkinHelp.DefalutBorderColor; + /// + /// 控件边框颜色 + /// + [DefaultValue(typeof(Color), "23, 169, 254"), Description("控件边框颜色")] + public Color BorderColor + { + get { return _borderColor; } + set + { + _borderColor = value; + base.Invalidate(); + } + } + /// + /// 控件背景颜色 + /// + [DefaultValue(typeof(Color), "23, 169, 254"), Description("控件背景颜色")] + public Color TileBackColor + { + get; set; + } = Color.White; + /// + /// 圆角弧度大小 + /// + [DefaultValue(typeof(int), "10"), Description("圆角弧度大小")] + public int Radius + { + get { return _radius; } + set + { + _radius = value; + base.Invalidate(); + } + } + /// + /// 圆角风格 + /// + public RoundStyle RoundeStyle + { + get { return _roundeStyle; } + set + { + _roundeStyle = value; + base.Invalidate(); + } + } + + private void PanelEx_Paint(object sender, PaintEventArgs e) + { + if (this.Radius > 0) + { + using (Graphics g = Graphics.FromHwnd(this.Handle)) + { + Rectangle r = new Rectangle + { + Width = this.Width, + Height = this.Height + }; + DrawBorder(g, r, this.RoundeStyle, this.Radius); + } + } + else + e.Graphics.DrawRectangle(new Pen(this.BorderColor), new Rectangle(0, 0, this.Width - 1, this.Height - 1)); + } + private void DrawBorder(Graphics g, Rectangle rect, RoundStyle roundStyle, int radius) + { + rect.Width -= 1; + rect.Height -= 1; + using (GraphicsPath path = Drawing.CreatePath(rect, radius, roundStyle, false)) + { + SolidBrush myBrush = new SolidBrush(TileBackColor); + using (Pen pen = new Pen(this.BorderColor)) + { + g.FillPath(myBrush, path); + g.DrawPath(pen, path); + } + } + } + + private void PanelEx_Resize(object sender, EventArgs e) + { + this.Refresh(); + } + } +} diff --git a/Source/ryControls/Controls/PanelEx.resx b/Source/ryControls/Controls/PanelEx.resx new file mode 100644 index 0000000..e5858cc --- /dev/null +++ b/Source/ryControls/Controls/PanelEx.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + False + + \ No newline at end of file diff --git a/Source/ryControls/Controls/PicButton.Designer.cs b/Source/ryControls/Controls/PicButton.Designer.cs new file mode 100644 index 0000000..65de065 --- /dev/null +++ b/Source/ryControls/Controls/PicButton.Designer.cs @@ -0,0 +1,100 @@ +namespace ryControls +{ + partial class PicButton + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PicButton)); + this.label1 = new System.Windows.Forms.Label(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.zhLoading1 = new ryControls.ZhLoading(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.ForeColor = System.Drawing.Color.Gray; + this.label1.Location = new System.Drawing.Point(3, 63); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(77, 17); + this.label1.TabIndex = 1; + this.label1.Text = "未知"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // pictureBox1 + // + this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pictureBox1.Location = new System.Drawing.Point(12, 0); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(60, 60); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // zhLoading1 + // + this.zhLoading1.Alpha = 80; + this.zhLoading1.BackColor = System.Drawing.Color.White; + this.zhLoading1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("zhLoading1.BackgroundImage"))); + this.zhLoading1.ByControl = null; + this.zhLoading1.IsTransparent = true; + this.zhLoading1.LoadingImage = null; + this.zhLoading1.Location = new System.Drawing.Point(0, 0); + this.zhLoading1.Name = "zhLoading1"; + this.zhLoading1.Size = new System.Drawing.Size(80, 80); + this.zhLoading1.TabIndex = 2; + this.zhLoading1.Visible = false; + // + // PicButton + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.label1); + this.Controls.Add(this.zhLoading1); + this.Controls.Add(this.pictureBox1); + this.Name = "PicButton"; + this.Size = new System.Drawing.Size(80, 80); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Label label1; + private ryControls.ZhLoading zhLoading1; + private System.Windows.Forms.ToolTip toolTip1; + } +} diff --git a/Source/ryControls/Controls/PicButton.cs b/Source/ryControls/Controls/PicButton.cs new file mode 100644 index 0000000..d2ceaa8 --- /dev/null +++ b/Source/ryControls/Controls/PicButton.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryControls +{ + /// + /// + /// + [DefaultEvent("Click")] + public partial class PicButton : UserControl + { + private bool Mouse_Enter = false; + /// + /// + /// + public PicButton() + { + InitializeComponent(); + SetEvent(this); + SetEvent(pictureBox1); + SetEvent(label1); + SetEvent(zhLoading1); + void SetEvent(Control ct) + { + ct.Click+= Button_Click; + ct.MouseDown += Ct_MouseDown; + ct.MouseEnter += Button_MouseEnter; + ct.MouseLeave += Button_MouseLeave; + ct.MouseMove += Button_MouseMove; + } + } + + private void Ct_MouseDown(object sender, MouseEventArgs e) + { + if (!(sender is UserControl)) + { + base.OnMouseDown(e); + } + } + + private void Button_MouseMove(object sender, MouseEventArgs e) + { + if (!Mouse_Enter) + { + Mouse_Enter = true; + zhLoading1.Location = new Point(0, 0); + zhLoading1.Size = new Size(this.Width, this.Height); + zhLoading1.ShowLoad(); + } + } + + private void Button_MouseEnter(object sender, EventArgs e) + { + //if (this.Bounds.Contains(MousePosition.X, MousePosition.Y); + { + zhLoading1.Location = new Point(0, 0); + zhLoading1.Size = new Size(this.Width, this.Height); + zhLoading1.ShowLoad(); + } + } + + private void Button_MouseLeave(object sender, EventArgs e) + { + switch (sender) + { + case ryControls.ZhLoading k: + if (Mouse_Enter) + { + Mouse_Enter = false; + zhLoading1.HideLoad(); + } + break; + } + } + + private void Button_Click(object sender, EventArgs e) + { + if (!(sender is UserControl)) + { + base.OnClick(e); + } + Selected = !Selected; + } + + /// + /// 图标 + /// + public Image Image + { + get { return pictureBox1.Image; } + set { pictureBox1.Image = value; } + } + /// + /// 标题 + /// + public string Title + { + get { return label1.Text; } + set { label1.Text = value; } + } + private string _ToolTip = ""; + /// + /// 悬浮提示 + /// + public string ToolTip + { + get { return _ToolTip; } + set + { + _ToolTip = value; + toolTip1.SetToolTip(pictureBox1, value); + toolTip1.SetToolTip(this, value); + toolTip1.SetToolTip(label1, value); + toolTip1.SetToolTip(zhLoading1, value); + } + } + /// + /// 标题颜色 + /// + public Color TitleColor + { + get { return label1.ForeColor; } + set { label1.ForeColor = value; } + } + /// + /// 设置按钮 + /// + /// + /// + public void SetButton(string title,Image img) + { + Title = title; + Image = img; + } + private bool _selected = false; + /// + /// 判断和设置是否选择 + /// + public bool Selected + { + get { return _selected; } + set + { + if (_selected != value) + { + _selected = value; + if (_selected) + { + zhLoading1.Location = new Point(0, 0); + zhLoading1.Size = new Size(this.Width, this.Height); + zhLoading1.ShowLoad(); + } + else + { + zhLoading1.HideLoad(); + } + } + } + } + } +} diff --git a/Source/ryControls/Controls/PicButton.resx b/Source/ryControls/Controls/PicButton.resx new file mode 100644 index 0000000..a58e3f6 --- /dev/null +++ b/Source/ryControls/Controls/PicButton.resx @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1 + MAAA6mAAADqYAAAXb5JfxUYAAAAJcEhZcwAACxMAAAsTAQCanBgAAACzSURBVHhe7dAxAQAgAAQhW9o/ + ydvBWxkowNl2+ScwEhgJjARGAiOBkcBIYCQwEhgJjARGAiOBkcBIYCQwEhgJjARGAiOBkcBIYCQwEhgJ + jARGAiOBkcBIYCQwEhgJjARGAiOBkcBIYCQwEhgJjARGAiOBkcBIYCQwEhgJjARGAiOBkcBIYCQwEhgJ + jARGAiOBkcBIYCQwEhgJjARGAiOBkcBIYCQwEhgJjARGAiOBkcBk9wG1azjerO/MpwAAAABJRU5ErkJg + gg== + + + \ No newline at end of file diff --git a/Source/ryControls/Controls/QQButton.cs b/Source/ryControls/Controls/QQButton.cs new file mode 100644 index 0000000..aed46eb --- /dev/null +++ b/Source/ryControls/Controls/QQButton.cs @@ -0,0 +1,1114 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel; +using System.QQ; + +namespace System.QQ +{ + /// + /// 鼠标的当前位置 + /// + public enum ButtonMousePosition + { + /// + /// + /// + None, + /// + /// + /// + Button, + /// + /// + /// + Splitebutton, + } + + /// + /// 控件的状态。 + /// + public enum ControlState + { + /// + /// 正常 + /// + Normal, + /// + /// 鼠标经过 + /// + Hover, + /// + /// 鼠标按下 + /// + Pressed, + } + + /// + /// 建立圆角路径的样式。 + /// + public enum RoundStyle + { + /// + /// 四个角都不是圆角。 + /// + None = 0, + /// + /// 四个角都为圆角。 + /// + All = 1, + /// + /// 左边两个角为圆角。 + /// + Left = 2, + /// + /// 右边两个角为圆角。 + /// + Right = 3, + /// + /// 上边两个角为圆角。 + /// + Top = 4, + /// + /// 下边两个角为圆角。 + /// + Bottom = 5, + /// + /// 左下角为圆角。 + /// + BottomLeft = 6, + /// + /// 右下角为圆角。 + /// + BottomRight = 7, + } + /// + /// + /// + public class QQButton : System.Windows.Forms.Button + { + private Color _borderColor = Color.FromArgb(161, 162, 160); + private Color _innerBorderColor = Color.FromArgb(200, 255, 255, 255); + private Color _baseColor = Color.FromArgb(10, 66, 204, 255); + private Color _baseColorEnd = Color.FromArgb(200, 66, 204, 255); + private Color _arrowColor = Color.FromArgb(64, 64, 64); + private int _imageWidth = 24; + private int _imageHeight = 24; + private RoundStyle _roundStyle = RoundStyle.All; + private int _radius = 2; + private int _imageTextSpace = 2; + private bool _pressOffset = true; + private bool _alwaysShowBorder = false; + private bool _showSpliteButton = false; + private int _spliteButtonWidth = 18; + private ControlState _controlState; + private ButtonMousePosition _mousePosition; + + private bool _contextHandle; + private bool _contextOpened; + private int _contextOffset = 5; + + /// + /// 普通按钮按下事件 + /// + public event EventHandler OnButtonClick; + /// + /// 分割按钮按下事件 + /// + public event EventHandler OnSpliteButtonClick; + + + /// + /// + /// + public QQButton() + : base() + { + SetStyle( + ControlStyles.SupportsTransparentBackColor | + ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer | + ControlStyles.ResizeRedraw | + ControlStyles.SupportsTransparentBackColor, true); + SetStyle(ControlStyles.Opaque, false); + + this.BackColor = Color.Transparent; + } + /// + /// 下拉菜单与按钮的距离 + /// + [DefaultValue(5)] + [Description("下拉菜单与按钮的距离")] + public int ContextOffset + { + get { return _contextOffset; } + set + { + _contextOffset = value; + } + } + /// + /// 图片高度 + /// + [DefaultValue(false)] + [Description("是否启用分割按钮")] + public bool ShowSpliteButton + { + get { return _showSpliteButton; } + set + { + if (_showSpliteButton != value) + { + _showSpliteButton = value; + base.Invalidate(); + } + } + } + /// + /// 分割按钮的宽度 + /// + [DefaultValue(18)] + [Description("分割按钮的宽度")] + public int SpliteButtonWidth + { + get { return _spliteButtonWidth; } + set + { + if (_spliteButtonWidth != value) + { + _spliteButtonWidth = value; + base.Invalidate(); + } + } + } + /// + /// 当鼠标按下时图片和文字是否产生偏移 + /// + [DefaultValue(true)] + [Description("当鼠标按下时图片和文字是否产生偏移")] + public bool PressOffset + { + get { return _pressOffset; } + set + { + _pressOffset = value; + } + } + /// + /// 是否一直显示按钮边框,设置为false则只在鼠标经过和按下时显示边框 + /// + [DefaultValue(false)] + [Description("是否一直显示按钮边框,设置为false则只在鼠标经过和按下时显示边框")] + public bool AlwaysShowBorder + { + get { return _alwaysShowBorder; } + set + { + if (_alwaysShowBorder != value) + { + _alwaysShowBorder = value; + base.Invalidate(); + } + } + } + /// + /// 当显示分割按钮时,分割按钮的箭头颜色 + /// + [DefaultValue(typeof(Color), "64,64,64")] + [Description("当显示分割按钮时,分割按钮的箭头颜色")] + public Color ArrowColor + { + get { return _arrowColor; } + set + { + if (_arrowColor != value) + { + _arrowColor = value; + base.Invalidate(); + } + } + } + /// + /// 按钮的边框颜色 + /// + [DefaultValue(typeof(Color), "161, 162, 160")] + [Description("按钮的边框颜色")] + public Color BorderColor + { + get { return _borderColor; } + set + { + if (_borderColor != value) + { + _borderColor = value; + base.Invalidate(); + } + } + } + /// + /// 按钮内边框颜色 + /// + [DefaultValue(typeof(Color), "200, 255, 255, 255")] + [Description("按钮内边框颜色")] + public Color InnerBorderColor + { + get { return _innerBorderColor; } + set + { + if (_innerBorderColor != value) + { + _innerBorderColor = value; + base.Invalidate(); + } + } + } + + /// + /// 鼠标经过和按下时按钮的渐变背景颜色 + /// + [DefaultValue(typeof(Color), "10 ,66, 204, 160")] + [Description("鼠标经过和按下时按钮的渐变背景颜色")] + public Color BaseColor + { + get { return _baseColor; } + set + { + if (_baseColor != value) + { + _baseColor = value; + } + } + } + /// + /// 鼠标经过和按下时按钮的渐变背景颜色 + /// + [DefaultValue(typeof(Color), "200 ,66, 204, 160")] + [Description("鼠标经过和按下时按钮的渐变背景颜色")] + public Color BaseColorEnd + { + get { return _baseColorEnd; } + set + { + if (_baseColorEnd != value) + { + _baseColorEnd = value; + } + } + } + /// + /// 图片宽度 + /// + [DefaultValue(24)] + [Description("图片宽度")] + public int ImageWidth + { + get { return _imageWidth; } + set + { + if (value != _imageWidth) + { + + _imageWidth = value < 12 ? 12 : value; + base.Invalidate(); + } + } + } + /// + /// 图片高度 + /// + [DefaultValue(24)] + [Description("图片高度")] + public int ImageHeight + { + get { return _imageHeight; } + set + { + if (value != _imageHeight) + { + + _imageHeight = value < 12 ? 12 : value; + base.Invalidate(); + } + } + } + /// + /// 按钮圆角样式 + /// + [DefaultValue(typeof(RoundStyle), "1")] + [Description("按钮圆角样式")] + public RoundStyle RoundStyle + { + get { return _roundStyle; } + set + { + if (_roundStyle != value) + { + _roundStyle = value; + base.Invalidate(); + } + } + } + /// + /// 按钮圆角弧度 + /// + [DefaultValue(2)] + [Description("按钮圆角弧度")] + public int Radius + { + get { return _radius; } + set + { + if (_radius != value) + { + _radius = value < 2 ? 2 : value; + base.Invalidate(); + } + } + } + /// + /// 图片与文字之间的间距 + /// + [DefaultValue(2)] + [Description("图片与文字之间的间距")] + public int ImageTextSpace + { + get { return _imageTextSpace; } + set + { + if (_imageTextSpace != value) + { + _imageTextSpace = value < 0 ? 0 : value; + base.Invalidate(); + } + } + } + + /// + /// 按钮当前状态 + /// + internal ControlState ControlState + { + get { return _controlState; } + set + { + if (_controlState != value) + { + _controlState = value; + base.Invalidate(); + } + } + } + + /// + /// 鼠标当前所在位置 + /// + internal ButtonMousePosition CurrentMousePosition + { + get { return _mousePosition; } + set + { + if (_mousePosition != value) + { + _mousePosition = value; + base.Invalidate(); + } + } + } + + /// + /// 普通按钮矩形位置 + /// + internal Rectangle ButtonRect + { + get + { + if (ShowSpliteButton) + { + return new Rectangle(0, 0, ClientRectangle.Width - SpliteButtonWidth, ClientRectangle.Height); + } + else + { + return ClientRectangle; + } + } + } + + /// + /// 分割按钮矩形位置 + /// + internal Rectangle SpliteButtonRect + { + get + { + if (ShowSpliteButton) + { + return new Rectangle(ClientRectangle.Width - SpliteButtonWidth, 0, SpliteButtonWidth, ClientRectangle.Height); + } + else + { + return Rectangle.Empty; + } + } + } + + /// + /// + /// + /// + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + if (!_contextOpened) + { + ControlState = ControlState.Normal; + CurrentMousePosition = ButtonMousePosition.None; + } + } + /// + /// + /// + /// + protected override void OnMouseMove(MouseEventArgs mevent) + { + base.OnMouseMove(mevent); + if (ClientRectangle.Contains(mevent.Location)) + { + ControlState = ControlState.Hover; + if (ShowSpliteButton) + { + CurrentMousePosition = ButtonRect.Contains(mevent.Location) ? ButtonMousePosition.Button : ButtonMousePosition.Splitebutton; + } + else + { + CurrentMousePosition = ButtonMousePosition.Button; + } + } + else + { + ControlState = ControlState.Normal; + CurrentMousePosition = ButtonMousePosition.None; + } + } + + /// + /// + /// + /// + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + if (e.Button == MouseButtons.Left && e.Clicks == 1) + { + ControlState = ControlState.Pressed; + if (ShowSpliteButton) + { + CurrentMousePosition = ButtonRect.Contains(e.Location) ? ButtonMousePosition.Button : ButtonMousePosition.Splitebutton; + } + else + { + CurrentMousePosition = ButtonMousePosition.Button; + } + } + } + /// + /// + /// + /// + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + if (e.Button == MouseButtons.Left && e.Clicks == 1) + { + if (ClientRectangle.Contains(e.Location)) + { + ControlState = ControlState.Hover; + if (ShowSpliteButton) + { + CurrentMousePosition = ButtonRect.Contains(e.Location) ? ButtonMousePosition.Button : ButtonMousePosition.Splitebutton; + if (CurrentMousePosition == ButtonMousePosition.Splitebutton) + { + OnSpliteButtonClick?.Invoke(this, EventArgs.Empty); + if (this.ContextMenuStrip != null) + { + if (!_contextHandle) + { + _contextHandle = true; + this.ContextMenuStrip.Opening += new CancelEventHandler(ContextMenuStrip_Opening); + this.ContextMenuStrip.Closed += new ToolStripDropDownClosedEventHandler(ContextMenuStrip_Closed); + } + this.ContextMenuStrip.Opacity = 1.0; + this.ContextMenuStrip.Show(this, 0, this.Height + ContextOffset); + } + } + else + { + OnButtonClick?.Invoke(this, EventArgs.Empty); + } + } + else + { + CurrentMousePosition = ButtonMousePosition.Button; + } + } + else + { + ControlState = ControlState.Normal; + CurrentMousePosition = ButtonMousePosition.None; + } + } + } + + private void ContextMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e) + { + _contextOpened = false; + ControlState = ControlState.Normal; + CurrentMousePosition = ButtonMousePosition.None; + base.Invalidate(); + } + + + private void ContextMenuStrip_Opening(object sender, CancelEventArgs e) + { + _contextOpened = true; + } + + /// + /// + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + base.OnPaintBackground(e); + + Graphics g = e.Graphics; + //Rectangle imageRect; + //Rectangle textRect; + + CalculateRect(out Rectangle imageRect, out Rectangle textRect, g); + g.SmoothingMode = SmoothingMode.AntiAlias; + + + //画边框与背景 + RenderBackGroundInternal( + g, + ClientRectangle, + RoundStyle, + Radius + ); + //画图像 + if (Image != null) + { + g.InterpolationMode = InterpolationMode.HighQualityBilinear; + g.DrawImage( + Image, + imageRect, + 0, + 0, + Image.Width, + Image.Height, + GraphicsUnit.Pixel); + } + //画文字 + if (Text != "") + { + TextRenderer.DrawText( + g, + Text, + Font, + textRect, + ForeColor, + GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes)); + } + //画分割按钮 + if (ShowSpliteButton) + { + RenderSpliteButton(g, ClientRectangle); + } + } + + /// + /// 获取图像以及文字的位置 + /// + /// + /// + /// + private void CalculateRect( + out Rectangle imageRect, out Rectangle textRect, Graphics g) + { + imageRect = Rectangle.Empty; + textRect = Rectangle.Empty; + SizeF textSize = g.MeasureString(Text, Font); + if (Image == null) + { + switch (TextAlign) + { + case ContentAlignment.BottomCenter: + textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.BottomLeft: + textRect = new Rectangle(2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.BottomRight: + textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.MiddleCenter: + textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.MiddleLeft: + textRect = new Rectangle(2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.MiddleRight: + textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.TopCenter: + textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.TopLeft: + textRect = new Rectangle(2, 2, (int)textSize.Width, (int)textSize.Height); + break; + case ContentAlignment.TopRight: + textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, 2, (int)textSize.Width, (int)textSize.Height); + break; + } + if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button) + { + textRect.X += 1; + textRect.Y += 1; + } + if (RightToLeft == RightToLeft.Yes) + { + textRect.X = ButtonRect.Width - textRect.Right; + } + return; + } + if (this.Text == "") + { + switch (ImageAlign) + { + case ContentAlignment.BottomCenter: + imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, Height - ImageHeight - 3, ImageWidth, ImageHeight); + break; + case ContentAlignment.BottomLeft: + imageRect = new Rectangle(2, Height - ImageHeight - 3, ImageWidth, ImageHeight); + break; + case ContentAlignment.BottomRight: + imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, Height - ImageHeight - 3, ImageWidth, ImageHeight); + break; + case ContentAlignment.MiddleCenter: + imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.MiddleLeft: + imageRect = new Rectangle(2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.MiddleRight: + imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, (Height - ImageHeight) / 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.TopCenter: + imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.TopLeft: + imageRect = new Rectangle(2, 2, ImageWidth, ImageHeight); + break; + case ContentAlignment.TopRight: + imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, 2, ImageWidth, ImageHeight); + break; + } + if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button) + { + imageRect.X += 1; + imageRect.Y += 1; + } + if (RightToLeft == RightToLeft.Yes) + { + imageRect.X = ButtonRect.Width - imageRect.Right; + } + return; + } + switch (TextImageRelation) + { + case TextImageRelation.Overlay: + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2, + (Height - ImageHeight) / 2, + ImageWidth, + ImageHeight); + textRect = new Rectangle( + imageRect.Right + ImageTextSpace, + (Height - (int)textSize.Height) / 2, + (int)textSize.Width, + (int)textSize.Height); + break; + case TextImageRelation.ImageAboveText: + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth) / 2, + (Height - ImageHeight - (int)textSize.Height - ImageTextSpace) / 2, + ImageWidth, + ImageHeight); + textRect = new Rectangle( + (ButtonRect.Width - (int)textSize.Width) / 2, + imageRect.Bottom + ImageTextSpace, + (int)textSize.Width, + (int)textSize.Height); + break; + case TextImageRelation.ImageBeforeText: + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2, + (Height - ImageHeight) / 2, + ImageWidth, + ImageHeight); + textRect = new Rectangle( + imageRect.Right + ImageTextSpace, + (Height - (int)textSize.Height) / 2, + (int)textSize.Width, + (int)textSize.Height); + break; + case TextImageRelation.TextAboveImage: + textRect = new Rectangle( + (ButtonRect.Width - (int)textSize.Width) / 2, + (Height - (int)textSize.Height - ImageHeight - ImageTextSpace) / 2, + (int)textSize.Width, + (int)textSize.Height); + imageRect = new Rectangle( + (ButtonRect.Width - ImageWidth) / 2, + textRect.Bottom + ImageTextSpace, + ImageWidth, + ImageHeight); + break; + case TextImageRelation.TextBeforeImage: + textRect = new Rectangle( + (ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2, + (Height - (int)textSize.Height) / 2, + (int)textSize.Width, + (int)textSize.Height); + imageRect = new Rectangle( + textRect.Right + ImageTextSpace, + (Height - ImageHeight) / 2, + ImageWidth, + ImageHeight); + break; + } + if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button) + { + imageRect.X += 1; + imageRect.Y += 1; + textRect.X += 1; + textRect.Y += 1; + } + + if (RightToLeft == RightToLeft.Yes) + { + imageRect.X = ButtonRect.Width - imageRect.Right; + textRect.X = ButtonRect.Width - textRect.Right; + } + } + + /// + /// 画边框与背景 + /// + internal void RenderBackGroundInternal( + Graphics g, + Rectangle rect, + RoundStyle style, + int roundWidth + ) + { + if (ControlState != ControlState.Normal || AlwaysShowBorder) + { + rect.Width--; + rect.Height--; + if (style != RoundStyle.None) + { + using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false)) + { + if (ControlState != ControlState.Normal) + { + using (LinearGradientBrush brush = (ControlState == ControlState.Pressed) ? new LinearGradientBrush(rect, BaseColorEnd, BaseColor, LinearGradientMode.ForwardDiagonal) : new LinearGradientBrush(rect, BaseColor, BaseColorEnd, LinearGradientMode.Vertical)) + { + if (!ShowSpliteButton) + { + g.FillPath(brush, path); + } + else + { + if (CurrentMousePosition == ButtonMousePosition.Button) + { + using (GraphicsPath buttonpath = GraphicsPathHelper.CreatePath(ButtonRect, roundWidth, RoundStyle.Left, true)) + { + g.FillPath(brush, buttonpath); + } + } + else + { + using (GraphicsPath splitepath = GraphicsPathHelper.CreatePath(SpliteButtonRect, roundWidth, RoundStyle.Right, true)) + { + g.FillPath(brush, splitepath); + } + } + } + } + } + using (Pen pen = new Pen(_borderColor)) + { + g.DrawPath(pen, path); + } + } + rect.Inflate(-1, -1); + using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false)) + { + using (Pen pen = new Pen(InnerBorderColor)) + { + g.DrawPath(pen, path); + } + } + } + else + { + if (ControlState != ControlState.Normal) + { + using (LinearGradientBrush brush = (ControlState == ControlState.Pressed) ? new LinearGradientBrush(rect, BaseColorEnd, BaseColor, LinearGradientMode.ForwardDiagonal) : new LinearGradientBrush(rect, BaseColor, BaseColorEnd, LinearGradientMode.Vertical)) + { + if (!ShowSpliteButton) + { + g.FillRectangle(brush, rect); + } + else + { + if (CurrentMousePosition == ButtonMousePosition.Button) + { + g.FillRectangle(brush, ButtonRect); + } + else + { + g.FillRectangle(brush, SpliteButtonRect); + } + } + } + } + using (Pen pen = new Pen(_borderColor)) + { + g.DrawRectangle(pen, rect); + } + rect.Inflate(-1, -1); + using (Pen pen = new Pen(InnerBorderColor)) + { + g.DrawRectangle(pen, rect); + } + } + } + } + + /// + /// 画分割按钮 + /// + /// + /// + internal void RenderSpliteButton(Graphics g, Rectangle rect) + { + Point[] points = new Point[3]; + points[0] = new Point(rect.Width - SpliteButtonWidth + 2, (rect.Height - 4) / 2); + points[1] = new Point(rect.Width - SpliteButtonWidth + 2 + 8, (rect.Height - 4) / 2); + points[2] = new Point(rect.Width - SpliteButtonWidth + 2 + 4, (rect.Height - 4) / 2 + 4); + + if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Splitebutton) + { + points[0].X += 1; + points[0].Y += 1; + points[1].X += 1; + points[1].Y += 1; + points[2].X += 1; + points[2].Y += 1; + } + using (SolidBrush brush = new SolidBrush(ArrowColor)) + { + g.FillPolygon(brush, points); + } + } + + internal static TextFormatFlags GetTextFormatFlags( + ContentAlignment alignment, + bool rightToleft) + { + TextFormatFlags flags = TextFormatFlags.WordBreak | + TextFormatFlags.SingleLine; + if (rightToleft) + { + flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right; + } + + switch (alignment) + { + case ContentAlignment.BottomCenter: + flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter; + break; + case ContentAlignment.BottomLeft: + flags |= TextFormatFlags.Bottom | TextFormatFlags.Left; + break; + case ContentAlignment.BottomRight: + flags |= TextFormatFlags.Bottom | TextFormatFlags.Right; + break; + case ContentAlignment.MiddleCenter: + flags |= TextFormatFlags.HorizontalCenter | + TextFormatFlags.VerticalCenter; + break; + case ContentAlignment.MiddleLeft: + flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left; + break; + case ContentAlignment.MiddleRight: + flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right; + break; + case ContentAlignment.TopCenter: + flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter; + break; + case ContentAlignment.TopLeft: + flags |= TextFormatFlags.Top | TextFormatFlags.Left; + break; + case ContentAlignment.TopRight: + flags |= TextFormatFlags.Top | TextFormatFlags.Right; + break; + } + return flags; + } + } +} +/// +/// +/// +public static class GraphicsPathHelper +{ + /// + /// 建立带有圆角样式的矩形路径 + /// + /// 用来建立路径的矩形。 + /// 圆角的大小 + /// 圆角的样式 + /// 是否把矩形长宽减 1,以便画出边框 + /// 建立的路径 + public static GraphicsPath CreatePath( + Rectangle rect, int radius, RoundStyle style, bool correction) + { + GraphicsPath path = new GraphicsPath(); + int radiusCorrection = correction ? 1 : 0; + switch (style) + { + case RoundStyle.None: + path.AddRectangle(rect); + break; + case RoundStyle.All: + path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Y, + radius, + radius, + 270, + 90); + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Bottom - radius - radiusCorrection, + radius, + radius, 0, 90); + path.AddArc( + rect.X, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 90, + 90); + break; + case RoundStyle.Left: + path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); + path.AddLine( + rect.Right - radiusCorrection, rect.Y, + rect.Right - radiusCorrection, rect.Bottom - radiusCorrection); + path.AddArc( + rect.X, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 90, + 90); + break; + case RoundStyle.Right: + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Y, + radius, + radius, + 270, + 90); + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 0, + 90); + path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y); + break; + case RoundStyle.Top: + path.AddArc(rect.X, rect.Y, radius, radius, 180, 90); + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Y, + radius, + radius, + 270, + 90); + path.AddLine( + rect.Right - radiusCorrection, rect.Bottom - radiusCorrection, + rect.X, rect.Bottom - radiusCorrection); + break; + case RoundStyle.Bottom: + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 0, + 90); + path.AddArc( + rect.X, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 90, + 90); + path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y); + break; + case RoundStyle.BottomLeft: + path.AddArc( + rect.X, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 90, + 90); + path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y); + path.AddLine( + rect.Right - radiusCorrection, + rect.Y, + rect.Right - radiusCorrection, + rect.Bottom - radiusCorrection); + break; + case RoundStyle.BottomRight: + path.AddArc( + rect.Right - radius - radiusCorrection, + rect.Bottom - radius - radiusCorrection, + radius, + radius, + 0, + 90); + path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y); + path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y); + break; + } + path.CloseFigure(); + + return path; + } +} \ No newline at end of file diff --git a/Source/ryControls/Controls/RichTextBox2.Designer.cs b/Source/ryControls/Controls/RichTextBox2.Designer.cs new file mode 100644 index 0000000..c3a7761 --- /dev/null +++ b/Source/ryControls/Controls/RichTextBox2.Designer.cs @@ -0,0 +1,47 @@ + +namespace ryControls.Controls +{ + partial class RichTextBox2 + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.contextMenuStripRichText1 = new ryControls.Controls.ContextMenuStripRichText(); + this.SuspendLayout(); + // + // contextMenuStripRichText1 + // + this.contextMenuStripRichText1.Name = "contextMenuStripRichText1"; + this.contextMenuStripRichText1.Size = new System.Drawing.Size(101, 142); + this.ResumeLayout(false); + + } + + #endregion + + private ContextMenuStripRichText contextMenuStripRichText1; + } +} diff --git a/Source/ryControls/Controls/RichTextBox2.cs b/Source/ryControls/Controls/RichTextBox2.cs new file mode 100644 index 0000000..2c97b1a --- /dev/null +++ b/Source/ryControls/Controls/RichTextBox2.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryControls.Controls +{ + public partial class RichTextBox2 : RichTextBox + { + /// + /// RichTextBox + /// + public RichTextBox2() + { + InitializeComponent(); + this.DetectUrls = false; + contextMenuStripRichText1.Opening += ContextMenuStripRichText1_Opening; + } + /// + /// 在自带菜单弹出前激发 + /// + [Description("在自带菜单弹出前激发")] + public event CancelEventHandler OnMenuOpening; + private void ContextMenuStripRichText1_Opening(object sender, CancelEventArgs e) + { + OnMenuOpening?.Invoke(sender,e); + } + /// + /// 根据标签获得菜单项 + /// + /// + /// + public ToolStripItem GetMenuItem(string tag) + { + for (int i = 0; i < contextMenuStripRichText1.Items.Count; i++) + { + var item = contextMenuStripRichText1.Items[i]; + if (item.Tag == null) { continue; } + if(tag== item.Tag.ToString()) + { + return item; + } + } + return null; + } + /// + /// 只允许输入文本(只对设置之后的人工输入有效) + /// + [Description("只允许输入文本(只对设置之后的人工输入有效)")] + public bool OnlyInputText { get; set; } = false; + /// + /// 按下按键 + /// + /// + protected override void OnKeyDown(KeyEventArgs e) + { + if (OnlyInputText && e.Control && e.KeyCode == Keys.V) + { + e.SuppressKeyPress = true; + this.Paste(DataFormats.GetFormat(DataFormats.Text)); + return; + } + base.OnKeyDown(e); + } + /// + /// + /// + /// + protected override void OnLostFocus(EventArgs e) + { + base.Invalidate(); + base.OnLostFocus(e); + } + /// + /// + /// + /// + protected override void OnEnter(EventArgs e) + { + if (base.Text.Length == 0) + { + base.Invalidate(); + } + base.OnEnter(e); + } + /// + /// + /// + /// + protected override void OnMouseLeave(EventArgs e) + { + if (base.Text.Length == 0) + { + base.Invalidate(); + } + base.OnMouseLeave(e); + } + /// + /// 鼠标按下 + /// + /// + protected override void OnMouseDown(MouseEventArgs e) + { + if(e.Button==MouseButtons.Right && this.ContextMenuStrip==null) + { + contextMenuStripRichText1.Show(this, e.Location); + } + } + /// + /// + /// + /// + protected override void WndProc(ref Message m) + { + base.WndProc(ref m); + if (m.Msg == 0xf || m.Msg == 0x133) + { + if (this.BorderStyle == BorderStyle.None) + { + System.Drawing.Pen pen = new Pen(SkinHelp.DefalutBorderColor, 1); + Graphics g = Graphics.FromHwnd(m.HWnd); + g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1); + pen.Dispose(); + } + if(!base.Focused && this.Text.Length==0) + { + Graphics g = Graphics.FromHwnd(m.HWnd); + Brush brush = new SolidBrush(Color.FromArgb(175, 185, 200)); + g.DrawString(EmptyText,Font, brush, 3, 3); + brush.Dispose(); + } + //返回结果 + m.Result = IntPtr.Zero; + } + } + /// + /// 当文本框为空时,显示的内容。 + /// + [Description("当文本框为空时,显示的内容。")] + public string EmptyText + { + get { return _EmptyText; } + set + { + _EmptyText = value; + base.Invalidate(); + } + } + private string _EmptyText = ""; + /// + /// 添加菜单分隔线 + /// + /// + public ToolStripSeparator AddSeparatorMenu() + { + return contextMenuStripRichText1.AddSeparatorMenu(); + } + /// + /// 添加菜单 + /// + /// + /// + /// + public ToolStripMenuItem AddMenu(string name, string tag) + { + return contextMenuStripRichText1.AddMenu(name, tag); + } + } +} diff --git a/Source/ryControls/Controls/RichTextBox2.resx b/Source/ryControls/Controls/RichTextBox2.resx new file mode 100644 index 0000000..a0a3b2f --- /dev/null +++ b/Source/ryControls/Controls/RichTextBox2.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + False + + \ No newline at end of file diff --git a/Source/ryControls/Controls/RyCheckBox.Designer.cs b/Source/ryControls/Controls/RyCheckBox.Designer.cs new file mode 100644 index 0000000..8f806c8 --- /dev/null +++ b/Source/ryControls/Controls/RyCheckBox.Designer.cs @@ -0,0 +1,59 @@ +namespace ryControls.Controls +{ + partial class RyCheckBox + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // pictureBox1 + // + this.pictureBox1.Location = new System.Drawing.Point(3, 7); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(26, 18); + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // RyCheckBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.pictureBox1); + this.Name = "RyCheckBox"; + this.Size = new System.Drawing.Size(195, 28); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBox1; + } +} diff --git a/Source/ryControls/Controls/RyCheckBox.cs b/Source/ryControls/Controls/RyCheckBox.cs new file mode 100644 index 0000000..bc4a02a --- /dev/null +++ b/Source/ryControls/Controls/RyCheckBox.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ryControls.Controls +{ + /// + /// + /// + public partial class RyCheckBox : UserControl + { + /// + /// + /// + public RyCheckBox() + { + InitializeComponent(); + } + } +} diff --git a/Source/ryControls/Controls/RyCheckBox.resx b/Source/ryControls/Controls/RyCheckBox.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/ryControls/Controls/RyCheckBox.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/Source/ryControls/Controls/RyContextMenuStrip.cs b/Source/ryControls/Controls/RyContextMenuStrip.cs new file mode 100644 index 0000000..22f54a4 --- /dev/null +++ b/Source/ryControls/Controls/RyContextMenuStrip.cs @@ -0,0 +1,146 @@ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Text; +using System.Windows.Forms; +using System.Drawing.Drawing2D; +using System.Drawing; +using ryControls; + +namespace ryControls +{ + /// + /// 类说明:CContextMenuStrip控件的实现用来代替系统的ContextMenuStrip控件 + /// + //可以使用一个图标来表示控件 ContextMenuStrip快捷菜单 + [ToolboxBitmap(typeof(System.Windows.Forms.ContextMenuStrip))] + public class RyContextMenuStrip : System.Windows.Forms.ContextMenuStrip + { + //窗口的边框长 + readonly int borderWidth = SystemInformation.BorderSize.Width; + + + /// + /// + /// + public RyContextMenuStrip() + : base() + { + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + + //Office格式颜色 + ProfessionalColorTable ColorTable = new ProfessionalColorTable() + { + UseSystemColors = true + }; + //是否为设计模式 + if (!DesignMode) + { + this.Renderer = new ryControls.ToolStripRenderer(ColorTable); + } + else + { + this.Renderer = new ToolStripProfessionalRenderer(ColorTable); + } + this.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.Font = new Font(this.Font.FontFamily, 10); + } + /// + /// + /// + /// + public RyContextMenuStrip(IContainer container) + : base(container) + { + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); + + ProfessionalColorTable ColorTable = new ProfessionalColorTable() + { + UseSystemColors = true + }; + if (!DesignMode) + { + this.Renderer = new ryControls.ToolStripRenderer(ColorTable); + } + else + { + this.Renderer = new ToolStripProfessionalRenderer(ColorTable); + } + this.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.Font = new Font(this.Font.FontFamily, 10); + + } + + /// + /// 重写OnCreateControl + /// + protected override void OnCreateControl() + { + base.OnCreateControl(); + + if (!DesignMode) + { + int Rgn = ryControls.Win32.CreateRoundRectRgn(1, 1, ClientSize.Width, Height, 7, 7); + ryControls.Win32.SetWindowRgn(this.Handle, Rgn, true); + } + + int result = ryControls.Win32.SetClassLong(this.Handle, ryControls.Win32.GCL_STYLE, 0); + } + + /// + /// 重写OnPaint事件 + /// + /// + protected override void OnPaint(PaintEventArgs e) + { + if (!DesignMode) + { + Graphics g = e.Graphics; + + SolidBrush bruch = new SolidBrush(Color.FromArgb(51, 166, 239)); + + g.FillRectangle(bruch, 0, 0, 25, this.Height); + + bruch = new SolidBrush(Color.White); + g.FillRectangle(bruch, 27, 0, this.Width - 27, this.Height); + + Pen pen = new Pen(Color.FromArgb(51, 132, 223), 1f); + e.Graphics.DrawPath(pen, CreateRoundedRectanglePath(new Rectangle(1, 1, ClientSize.Width - 3, Height - 3), 5)); + } + + base.OnPaint(e); + + } + + /// + /// CreateRoundedRectanglePath + /// + /// Rectangle + /// + /// + internal static GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int cornerRadius) + { + GraphicsPath roundedRect = new GraphicsPath(); + roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90); + roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y); + roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90); + roundedRect.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2); + roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90); + roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom); + roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90); + roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2); + roundedRect.CloseFigure(); + return roundedRect; + } + } +} diff --git a/Source/ryControls/Controls/RyHotkey.Designer.cs b/Source/ryControls/Controls/RyHotkey.Designer.cs new file mode 100644 index 0000000..4851dd9 --- /dev/null +++ b/Source/ryControls/Controls/RyHotkey.Designer.cs @@ -0,0 +1,36 @@ +namespace ryControls +{ + partial class RyHotkey + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Source/ryControls/Controls/RyHotkey.cs b/Source/ryControls/Controls/RyHotkey.cs new file mode 100644 index 0000000..4baaf3b --- /dev/null +++ b/Source/ryControls/Controls/RyHotkey.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using SysFuns; + +namespace ryControls +{ + /// + /// 系统热键数据类。 + /// + public partial class RyHotkey : TextBox + { + Keys m_Modifiers =Keys.None; + Keys m_Key =Keys.None; + /// + /// 系统热键数据类 + /// + public RyHotkey() + { + InitializeComponent(); + //定义KeyPress事件 + //base.KeyPress += delegate(object sender, KeyPressEventArgs e) { e.Handled = true; }; + base.ReadOnly = true; + base.BackColor = Color.White; + } + /// + /// 使多行属性失效掉 + /// + [Description("此属性无效")] + public new bool Multiline + { + get{return false;} + } + /// + /// 使只读属性失效掉 + /// + [Description("此属性无效")] + public new bool ReadOnly + { + get { return false; } + } + /// + ///获取热键文本 + /// + [Description("此属性无效")] + public new string Text + { + get { return base.Text; } + set { } + } + /// + /// 功能键 + /// + [Description("功能键")] + public int T_Modifiers + { + get + { + int i_Keys = 0; + if ((m_Modifiers & Keys.Alt) != 0) + { i_Keys =i_Keys | 1; } + if ((m_Modifiers & Keys.Control) != 0) + { i_Keys = i_Keys | 2; } + if ((m_Modifiers & Keys.Shift) != 0 || (m_Modifiers & Keys.LShiftKey) != 0 || (m_Modifiers & Keys.RShiftKey) != 0) + { i_Keys = i_Keys | 4; } + if ((m_Modifiers & Keys.LWin) != 0 || (m_Modifiers & Keys.RWin) != 0) + { i_Keys = i_Keys | 8; } + return i_Keys; + } + set + { + m_Modifiers =Keys.None; + if ((value & 1) != 0) + { m_Modifiers =m_Modifiers | Keys.Alt; } + if ((value & 2) != 0) + { m_Modifiers = m_Modifiers | Keys.Control; } + if ((value & 4) != 0) + { m_Modifiers = m_Modifiers | Keys.Shift; } + if ((value & 8) != 0) + { m_Modifiers = m_Modifiers | Keys.LWin; } + HotkeyValue xvalue; + xvalue = new HotkeyValue(m_Modifiers, m_Key); + base.Text = xvalue.ToStr(); + } + } + /// + /// 热键按键 + /// + [Description("热键按键")] + public Keys T_Key + { + get + { + return m_Key; + } + set + { + m_Key = value; + HotkeyValue xvalue = null; + xvalue = new HotkeyValue(m_Modifiers, m_Key); + base.Text = xvalue.ToStr(); + } + } + /// + /// + /// + /// + protected override void OnKeyDown(KeyEventArgs e) + { + //if (e.Modifiers == 0) //没有修改键 + //{ + // e.Handled = true; + // return; + //} + + HotkeyValue value = null; + if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey || e.KeyCode == Keys.Menu || e.KeyCode == Keys.None) + {//除修改键外,没有按键 + value = new HotkeyValue(e.Modifiers, Keys.None); + } + else + { + value = new HotkeyValue(e.Modifiers, e.KeyCode); + } + m_Modifiers = value.Modifiers; + m_Key = value.KeyCode; + base.Text = value.ToStr();//赋值 + e.Handled = true; + base.OnKeyDown(e); + } + + } +} diff --git a/Source/ryControls/Controls/SkinCommon.cs b/Source/ryControls/Controls/SkinCommon.cs new file mode 100644 index 0000000..b59d4d8 --- /dev/null +++ b/Source/ryControls/Controls/SkinCommon.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; + +namespace ryControls.Skin +{ + /// + ///皮肤公共类 + /// + public class SkinCommon + { + /// + /// 是否使用默认皮肤 + /// + public static bool UseDefSkin = true; + /// + /// 按钮皮肤 + /// + public static ButtonSkinInfo ButtonSkin = new ButtonSkinInfo(); + } + /// + /// 按钮皮肤类 + /// + public class ButtonSkinInfo + { + /// + /// 背景颜色 + /// + public Color BackColor = Color.FromArgb(51, 76, 95); + /// + /// 字体颜色 + /// + public Color ForeColor = Color.White; + } +} diff --git a/Source/ryControls/Controls/SkinHelp.cs b/Source/ryControls/Controls/SkinHelp.cs new file mode 100644 index 0000000..68c07d5 --- /dev/null +++ b/Source/ryControls/Controls/SkinHelp.cs @@ -0,0 +1,359 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.Windows.Forms; +using System.Drawing; +using System.Runtime.InteropServices; +using ryControls; + +namespace ryControls +{ + /// + /// 类说明:帮助类 + /// + public abstract class SkinHelp + { + private static SkinColor _currentSkinColor = SkinColor.Default; + private static BackgroundStripe _currentStripe = BackgroundStripe.Default; + //private static Assembly _assemblyWinUI = null; + //private static Bitmap drawButton = null; + //private static Bitmap scrollbarButton = null; + + //private static Color defaultcontextMenuColor; + + + //public static Assembly AssemblyWinUI + //{ + // get + // { + // if (_assemblyWinUI == null) + // { + // _assemblyWinUI = Assembly.Load("bxyztSkin"); + // } + + // return _assemblyWinUI; + // } + //} + /// + /// + /// + public static string SkinFolder + { + get { return "ryControls.Controls."; } + } + /// + /// + /// + public static SkinColor CurrentSkinColor + { + get { return _currentSkinColor; } + set { _currentSkinColor = value; } + } + /// + /// + /// + public static BackgroundStripe CurrentBackgroundStripe + { + get { return _currentStripe; } + set { _currentStripe = value; } + } + /// + /// + /// + public static bool UseGlobalSkin + { + get; + set; + } + /// + /// + /// + public static Color FormTitleLeaveBackColor = Color.OrangeRed; + /// + /// + /// + public static Color FormTitleBackColor = SystemColors.Highlight; + /// + /// + /// + public static Color ButtonColor=Color.FromArgb(12, 125, 182); + /// + /// + /// + public static Color ButtonMouseOverColor = Color.DodgerBlue; + /// + /// + /// + public static Color ButtonForeColor = Color.White; + private static Color defalutborder = Color.FromArgb(213, 216, 223); + /// + /// + /// + public static Color DefalutBorderColor + { + get { return SkinHelp.defalutborder; } + set { SkinHelp.defalutborder = value; } + } + //public static Color ControlBorderBackColor + //{ + // get + // { + // Bitmap bitmap = ButtonImages.ImageObject.GetResBitmap(SkinFolder + "FormImages.borderbm.bmp"); + // return bitmap.GetPixel(1, 3); + // } + //} + /// + /// + /// + public static Color FontColor + { + get { return Color.FromArgb(22, 61, 101); } + } + + //public static Bitmap ScrollBarButton + //{ + // get + // { + // if (scrollbarButton == null) + // { + // scrollbarButton = new Bitmap(ryControl.Properties.Resources.scroll); + // } + // return scrollbarButton; + // } + //} + + //public static Image ScrollBarUpButton + //{ + // get { return ScrollBarButton.Clone(new Rectangle(0, 0, 16, 16), System.Drawing.Imaging.PixelFormat.Format32bppPArgb); } + //} + + //public static Bitmap DrawButton + //{ + // get + // { + // if (drawButton == null) + // { + // drawButton = new Bitmap(ryControl.Properties.Resources.arrow); + // } + // return drawButton; + // } + //} + + //public static Image NomalDrawButton + //{ + // get { return DrawButton.Clone(new Rectangle(0, 0, 16, 16), System.Drawing.Imaging.PixelFormat.Format32bppPArgb); } + //} + + //public static Image MouseDownDrawButton + //{ + // get { return DrawButton.Clone(new Rectangle(16, 0, 16, 16), System.Drawing.Imaging.PixelFormat.Format32bppPArgb); } + //} + + //public static Image MouseMoveDrawButton + //{ + // get { return DrawButton.Clone(new Rectangle(32, 0, 16, 16), System.Drawing.Imaging.PixelFormat.Format32bppPArgb); } + //} + + //public static Image NotEnableDrawButton + //{ + // get { return DrawButton.Clone(new Rectangle(48, 0, 16, 16), System.Drawing.Imaging.PixelFormat.Format32bppPArgb); } + //} + + #region ChangeSkinColor + + #endregion + + #region FlushMemory + /// + /// + /// + public static void GarbageCollect() + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + GC.Collect(); + } + /// + /// + /// + public static void FlushMemory() + { + GarbageCollect(); + + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + Win32.SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1); + } + } + #endregion + + #region Suspend / Resume Redraw + + internal static void SuspendRedraw(Control control) + { + if (!control.IsHandleCreated) return; + + IntPtr hWnd = control.Handle; + IntPtr eventMask = IntPtr.Zero; + + // Stop redrawing: + Win32.SendMessage(hWnd, Win32.WM_SETREDRAW, 0, 0); + + // Stop sending of events: + Win32.SendMessage(hWnd, Win32.EM_GETEVENTMASK, 0, 0); + } + + internal static void ResumeRedraw(Control control) + { + if (!control.IsHandleCreated) return; + + IntPtr hWnd = control.Handle; + IntPtr eventMask = IntPtr.Zero; + + // turn on events + Win32.SendMessage(hWnd, Win32.EM_SETEVENTMASK, 0, eventMask.ToInt32()); + + // turn on redrawing + Win32.SendMessage(hWnd, Win32.WM_SETREDRAW, 1, 0); + + control.Invalidate(true); + } + + internal static void LockWindowUpdate(Form form, bool lockUpdate) + { + if (lockUpdate) + { + Win32.LockWindowUpdate(form.Handle); + } + else + { + Win32.LockWindowUpdate(IntPtr.Zero); + form.Invalidate(true); + form.Update(); + } + } + #endregion + /// + /// 修改控件或窗体的边框,例如Textbox或是Form窗体 + /// + /// 消息 + /// 控件对象 + /// 边框像素 + /// 边框颜色 + internal static void ResetBorderColor(Message m, Control control, int Nwidth, Color objcolor) + { + //根据颜色和边框像素取得一条线 + System.Drawing.Pen pen = pen = new Pen(objcolor, Nwidth); + //得到当前的句柄 + IntPtr hDC = Win32.GetWindowDC(m.HWnd); + if (hDC==IntPtr.Zero) + { + return; + } + + if (pen != null) + { + try + { + //绘制边框 + System.Drawing.Graphics g = Graphics.FromHdc(hDC); + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.DrawRectangle(pen, 0, 0, control.Width - Nwidth, control.Height - Nwidth); + pen.Dispose(); + g.Dispose(); + } + catch { } + } + + //释放 + Win32.ReleaseDC(m.HWnd, hDC); + } + } + /// + /// + /// + + public enum SkinColor + { + /// + /// + /// + Default, + /// + /// + /// + 草莓, + /// + /// + /// + 橘子, + /// + /// + /// + 青草, + /// + /// + /// + 灰蓝, + /// + /// + /// + 紫罗兰, + /// + /// + /// + 巧克力, + /// + /// + /// + OFFICE, + /// + /// + /// + Undefault + } + /// + /// + /// + + public enum BackgroundStripe + { + /// + /// + /// + Default, + /// + /// + /// + 淡淡墨绿, + /// + /// + /// + 芙蓉轻粉, + /// + /// + /// + 荷叶嫩绿, + /// + /// + /// + 橘黄雪花, + /// + /// + /// + 清雅幽兰, + /// + /// + /// + 空灵淡蓝, + /// + /// + /// + 柔和雅灰, + /// + /// + /// + 腊梅飘香 + } +} diff --git a/Source/ryControls/Controls/SuperPictureBox.Designer.cs b/Source/ryControls/Controls/SuperPictureBox.Designer.cs new file mode 100644 index 0000000..8a0e4af --- /dev/null +++ b/Source/ryControls/Controls/SuperPictureBox.Designer.cs @@ -0,0 +1,36 @@ +namespace ryControls +{ + partial class SuperPictureBox + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Source/ryControls/Controls/SuperPictureBox.cs b/Source/ryControls/Controls/SuperPictureBox.cs new file mode 100644 index 0000000..c1a18be --- /dev/null +++ b/Source/ryControls/Controls/SuperPictureBox.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using System.Net; +using System.IO; +using System.Threading; + +namespace ryControls +{ + /// + /// 超级图片控件,支持加载工程内部图片、异步加载网络图片 + /// + public partial class SuperPictureBox : PictureBox + { + /// + /// 超级图片控件,支持加载工程内部图片、异步加载网络图片 + /// + public SuperPictureBox() + { + InitializeComponent(); + } + /// + /// 图片所在上级域名 + /// + [Description("图片所在上级域名")] + public string ImageDomain { get; set; } + /// + /// 图片资源所在上级文件夹 + /// + [Description("图片资源所在上级文件夹")] + public string ImageResFolder { get; set; } + /// + /// 根据不同前缀,加载不同格式图片。i:表示工程内置图片;s:表示T_ImageDomain域名下的图片,u:表示指定url的图片;f:表示本地图片 + /// + /// + public void LoadPicBySUrl(string sUrl) + { + string HeadStr = sUrl; + if (HeadStr.Length > 2) + { + string keyStr = HeadStr.Substring(0, 2); + if (keyStr == "i:")//内置 + { + this.Image = ButtonImages.ImageObject.GetResBitmap(Application.ExecutablePath, ImageResFolder + HeadStr.Substring(2)); + } + else if (keyStr == "s:") //服务器上的地址 + { + LoadFromUrl(ImageDomain + HeadStr.Substring(2), true); + } + else if (keyStr == "u:") //URL地址 + { + LoadFromUrl(HeadStr.Substring(2), true); + } + else if (keyStr == "f:") //本地图片 + { + LoadFromFile(HeadStr.Substring(2)); + } + } + } + private void LoadPic(string url) + { + Image image=null; + try + { + WebRequest webreq = WebRequest.Create(url); + WebResponse webres = webreq.GetResponse(); + Stream stream = webres.GetResponseStream(); + image = Image.FromStream(stream); + stream.Close(); + } + catch { } + try + { + DateTime dt = DateTime.Now.AddSeconds(5); + while(!this.IsHandleCreated) + { + Thread.Sleep(10); + if (dt < DateTime.Now) { break; } + } + this.Invoke(new Action(() => + { + this.Image = image; + })); + } + catch { } + } + /// + /// 加载本地图片,加载完毕不会占用本地图片 + /// + /// + public void LoadFromFile(string path) + { + this.Image = ryCommon.RyFiles.LoadPicFromFile(path); + } + /// + /// 加载指定url图片 + /// + /// url位置 + /// 是否异步 + public void LoadFromUrl(string url, bool isAsyn) + { + if (isAsyn) + { + void starter() { LoadPic(url); } + new Thread(starter).Start(); + } + else + { + LoadPic(url); + } + } + } +} diff --git a/Source/ryControls/Controls/TabBar.Designer.cs b/Source/ryControls/Controls/TabBar.Designer.cs new file mode 100644 index 0000000..4689bb3 --- /dev/null +++ b/Source/ryControls/Controls/TabBar.Designer.cs @@ -0,0 +1,64 @@ +namespace ryControls +{ + partial class TabBar + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TabBar)); + this.PicTabSelect = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.PicTabSelect)).BeginInit(); + this.SuspendLayout(); + // + // PicTabSelect + // + this.PicTabSelect.Image = ((System.Drawing.Image)(resources.GetObject("PicTabSelect.Image"))); + this.PicTabSelect.Location = new System.Drawing.Point(0, 24); + this.PicTabSelect.Name = "PicTabSelect"; + this.PicTabSelect.Size = new System.Drawing.Size(50, 4); + this.PicTabSelect.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.PicTabSelect.TabIndex = 47; + this.PicTabSelect.TabStop = false; + // + // TabBar + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.PicTabSelect); + this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.Name = "TabBar"; + this.Size = new System.Drawing.Size(472, 28); + this.ForeColorChanged += new System.EventHandler(this.TabBar_ForeColorChanged); + this.SizeChanged += new System.EventHandler(this.TabBar_SizeChanged); + ((System.ComponentModel.ISupportInitialize)(this.PicTabSelect)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.PictureBox PicTabSelect; + } +} diff --git a/Source/ryControls/Controls/TabBar.cs b/Source/ryControls/Controls/TabBar.cs new file mode 100644 index 0000000..3a60852 --- /dev/null +++ b/Source/ryControls/Controls/TabBar.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using ryCommon; + +namespace ryControls +{ + /// + /// 多标签控件 + /// + [DefaultEvent("SelectedIndexChanged")] + [Description("多标签控件")] + public partial class TabBar : UserControl + { + /// + /// + /// + public TabBar() + { + InitializeComponent(); + } + /// + /// 选项发生变化时激发 + /// + [Description("选项发生变化时")] + public event EventHandler SelectedIndexChanged; + private int _SelectedIndex = 0; + /// + /// 标签选择的序号 + /// + public int SelectedIndex + { + get { return _SelectedIndex; } + set + { + if (_SelectedIndex != value) + { + _SelectedIndex = value; + if (TabControlEx != null) + { + if (TabControlEx.TabCount > value) + { + TabControlEx.SelectedIndex = value; + } + } + else + { + for (int m = 0; m < list_ctl.Count; m++) + { + Label lbl2 = list_ctl[m]; + if (m == value) + { + lbl2.ForeColor = Selected_Color; + PicTabSelect.Left = lbl2.Left; + PicTabSelect.Top = this.Height - PicTabSelect.Height; + PicTabSelect.BringToFront(); + PicTabSelect.Width = lbl2.Width; + } + else + { + lbl2.ForeColor = this.ForeColor; + } + } + SelectedIndexChanged?.Invoke(this, new EventArgs()); + } + } + } + } + private string _tab_list = ""; + /// + /// + /// + public string TabList + { + get { return _tab_list; } + set { _tab_list = value; ReDraw(); } + } + private Color _Selected_Color = Color.RoyalBlue; + /// + /// 选择的颜色 + /// + public Color Selected_Color + { + get { return _Selected_Color; } + set { _Selected_Color = value; ReDraw(); } + } + private Color _TabControl_Color = Color.FromArgb(233, 233, 233); + /// + /// 多标签控件颜色 + /// + public Color TabControl_Color + { + get { return _TabControl_Color; } + set { + _TabControl_Color = value; + if (TabControlEx != null) + { + TabControlEx.TabBackColor = TabControl_Color; + for (int i = 0; i < TabControlEx.TabCount; i++) + { + TabControlEx.TabPages[i].BackColor = TabControl_Color; + } + } + } + } + private TabControlEx tabControlEx; + /// + /// + /// + public TabControlEx TabControlEx + { + get + { + return this.tabControlEx; + } + set + { + if (this.tabControlEx != value) + { + if (this.tabControlEx != null) + { + this.tabControlEx.SelectedIndexChanged -= TabControlEx_SelectedIndexChanged; + } + if (this.tabControlEx != null && this.tabControlEx.TabBar == this) + { + this.tabControlEx.InternalTabBar = null; + } + this.tabControlEx = value; + if (value != null) + { + value.InternalTabBar = this; + value.SelectedIndexChanged += TabControlEx_SelectedIndexChanged; + value.BringToFront(); + value.TabBackground = null; + value.ItemSize = new Size(0, 1); + value.TabBackColor = TabControl_Color; + for (int i = 0; i < value.TabCount; i++) + { + value.TabPages[i].BackColor = TabControl_Color; + } + value.Location = new Point(this.Left, this.Top + this.Height); + } + } + } + } + private void TabControlEx_SelectedIndexChanged(object o, EventArgs e) + { + TabControlEx tab = (TabControlEx)o; + for (int m = 0; m < list_ctl.Count; m++) + { + Label lbl2 = list_ctl[m]; + if (m == tab.SelectedIndex) + { + lbl2.ForeColor = Selected_Color; + PicTabSelect.Left = lbl2.Left; + PicTabSelect.Top = this.Height - PicTabSelect.Height; + PicTabSelect.BringToFront(); + PicTabSelect.Width = lbl2.Width; + } + else + { + lbl2.ForeColor = this.ForeColor; + } + } + _SelectedIndex = tab.SelectedIndex; + SelectedIndexChanged?.Invoke(this, new EventArgs()); + } + private List