Thinkai's Blog

Autohotkey|Python|php|aardio|VOIP|IT 爱好者

上传管理SQL Server的图片(image数据类型) Autohotkey 5097

作者为 发表

Autohotkey

应网友小古要求写的,这里仅贴出最终版

功能:

1、可以按照自己的查询语句执行

2、自适应显示内容和上传图片

3、可以编辑可插入内容(屏蔽包含“id”字段)

4、点击图片保存图片

5、保存数据库信息方便下次使用

6、兼容SQL SERVER 2000/2005/2008/2012/2014各版本 采用ADO连接方式

程序下载:

Upload_image_2_mssqlv2.1.zip

Upload_image_2_mssqlv2.2.zip

;2.2版本改进
;1、修复无图片列上传图片后回显失败问题
;2、修复addmsg()显示消息记录函数
;3、修复编辑、插入后手动执行问题
;2.1版本改进
;1、修复“修改”、“插入”gui重复问题
;2、修复无图片项目显示问题并内置图片到脚本

;注意事项:部分 SQL Sever远程连接会有明显延迟情况,这可能是ADO连接方式的问题。建议在服务器所属环境下运行或者在本地上传完再生成sql执行

;By Thinkai

;字符化图片预置
nopic = 424dfe2b[6_00]3e[3_00]28[3_00]fa[3_00]5e01[2_00]010001[5_00]c02b[2_00]415c[2_00]415c[14_00][3_ff]00[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[11_ff]1f[10_ff]fd[3_ff]e1[4_ff]c0[5_ff]9f[3_ff]3fff1fffc007ffc3[4_ff]c7f8[3_ff]e1[4_ff]c0[4_ff]7f03[2_ff]f81fff1fffc003ffc3[4_ff]c7f07f[2_ff]e1[4_ff]c0[3_ff]f87f00[2_ff]e01fff1fffc001ffc0[4_00]07f07f[2_ff]e1[4_ff]c0[3_ff]f87e001fff000fff1fffc000ffc0[4_00]07f03f[2_ff]e1[4_ff]c0[3_ff]f83fc007fc007fff1f[2_ff]e0ffc0[4_00]07f81f[2_ff]e1[4_ff]c0[3_ff]fc3ff801f803[2_ff]1f[2_ff]f0ffc0[4_00]07fc1f[2_ff]e1[4_ff]c0[3_ff]fc3fff00601f[2_ff]1f[2_ff]f0ffc3[4_ff]c7fc0f[2_ff]e1[4_ff]c0[3_ff]fc1fffc0007f[2_ff]1f[2_ff]f0ffc3[3_ff]9fc7fe0f[2_ff]e1[4_ff]c0[3_ff]fe1ffff001[3_ff]1f[2_ff]f0ffc3[2_ff]f81fc7ff07[2_ff]e1[4_ff]c0[3_ff]fe1ffffc03[3_ff]1f[2_ff]f0ffc3[2_ff]801fc7ff07[2_ff]e1[4_ff]c0[3_ff]fe0ffffc03[3_ff]1f[2_ff]f0ffc3fff0000fc7ff87[2_ff]e1[4_ff]c0[4_ff]0ffff801[3_ff][4_00]ffc3fe[2_00]ffc7ff83[2_ff]e1[4_ff]c0[4_ff]0ffff000[3_ff][4_00]ffc3e0001fffc7ff83[2_ff]e1[4_ff]c0[4_ff]07fff0607f[2_ff][4_00]ffc3f007[2_ff]c7ffc3[2_ff]e1[4_ff]c0[4_ff]87ffe0f83f[2_ff]1f[2_ff]f0ffc3f3[3_ff]c7ffc3[2_ff]e1[4_ff]c0[4_ff]87ffc1fc1f[2_ff]1f[2_ff]f0ffc3[2_ff]fdffc7ffc3[2_ff]e1[4_ff]c0[4_ff]83ff83fe1f[2_ff]1f[2_ff]f0ffc3[2_ff]80ffc7ffc1[2_ff]e1[4_ff]c0[4_ff]c3ff87fe0f[2_ff]1f[2_ff]f0ffc3fff000ffc7ffc0[2_00]01[4_ff]c0[4_ff]c3ff0fff07fe7f1f[2_ff]f0ffc3ff8007ffc7ffe0[2_00]01[4_ff]c0[4_ff]c3ff0fff87fc3f1f[2_ff]f0ffc33f80[2_ff]c7ffe0[2_00]01[4_ff]c0[4_ff]effe1fff83fc1f[4_00]ffc3079ffffdc7ffe0[2_00]01[4_ff]c0[5_ff]fe1fffc3fc0f[4_00]ffc200[2_ff]c0c7ffe1[7_ff]c0[5_ff]fc3fffe1ff07[4_00]ffc3c01ffe00c7ffe1[7_ff]c0[5_ff]f0[2_00]01ff831f[2_ff]f0ffc3f807f000c7ffe1[7_ff]c0[5_ff]f0[2_00]01ffc11f[2_ff]f0ffc3ff01c007c7ffe1[7_ff]c0[5_ff]f0[2_00]01ffe01f[2_ff]f0ffc3ffc000ffc7ffe1[7_ff]c0[4_ff]c7e7[4_ff]f01f[2_ff]f0ffc3fff007ffc7ffe1[7_ff]c0[4_ff]83c3[4_ff]f81f[2_ff]f0ffc3fff007ffc7ffe1[7_ff]c0[4_ff]0181[4_ff]fc1f[2_ff]f0ffc3dfe003ffc7ffe1[7_ff]c0[3_ff]fe07c0[2_ff]e00ffc1f[2_ff]f0ffc38fc1c0ffc7ffe0[4_00]3f[2_ff]c0[3_ff]fc0ff07fffc00ffe[4_00]ffc30787f07fc7ffe0[4_00]3f[2_ff]c0[3_ff]f01ff83fff800fff[4_00]ffc3830ff83fc7ffe0[4_00]3f[2_ff]c0[3_ff]f03ffc1fff800fff80[3_00]ffc3c01ffc1fc7ffe0[4_00]3f[2_ff]c0[3_ff]f8fffe1fff87[2_ff]83[4_ff]c3f03ffe0fc7ffe1[2_ff]87[4_ff]c0[3_ff]fdfffe1fff87[2_ff]c3[4_ff]c3f87fff07c7ffe1[2_ff]87[4_ff]c0[6_ff]0fff87[2_ff]e1[4_ff]c3fc[2_00]07c7ffe1[2_ff]87[4_ff]c0[6_ff]0fff87[2_ff]e0[4_ff]c3fe[2_00]07c7ffe1[2_ff]87[4_ff]c0[4_ff]fbff0fff87[2_ff]f0[4_ff]c3fe[2_00]07c7ffe1[2_ff]87[4_ff]c0[4_ff]f1ff0fff87fe[5_00]03c3ff0f[2_ff]c7ffe1[2_ff]87[4_ff]c0[4_ff]e0ff0fff87fe[5_00]03c3ff87[2_ff]c7ffe1[2_ff]87[4_ff]c0[4_ff]c0ff0fff87fe[5_00]03c3ffc3[2_ff]c7ffe1[2_ff]87[4_ff]c0[4_ff]81ff[2_00]07fe[5_00]03c3ffcf[2_ff]c7ffe1[2_ff]87[4_ff]c0[4_ff]03ff[2_00]07[2_ff]fc1f[3_ff]c0[4_00]07ffe1[2_ff]87[4_ff]c0[3_ff]fe0fff[2_00]07[2_ff]fe1f[3_ff]c0[4_00]07ffe1[2_ff]87[4_ff]c0[3_ff]fc1fff[2_00]07[2_ff]fe1f[3_ff]c0[4_00]07ffe1[2_ff]87[4_ff]c0[3_ff]fe3f[7_ff]0f[3_ff]c0[4_00]07ffe1[2_ff]87[4_ff]c0[4_ff]7f[7_ff]0f[13_ff]87[4_ff]c0[12_ff]3f[18_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0[31_ff]c0

;创建界面
;加main限定
gui, main:add, text, x10 y10 w60 h20, 查询SQL:
gui, main:add, edit, x70 y10 w630 h20 vsql, select * from test
gui, main:add, button, x700 y10 w100 h20 Default gexec, 执行
gui, main:add, listview, x10 y40 w530 h350 vlv glv
gui, main:add, edit, x10 y400 w530 h100 vmsg ReadOnly,
gui, main:add, picture, x550 y40 w250 h359 vpic gpic
gui, main:add, button, x550 y410 w120 h20 gedit, 修改
gui, main:add, button, x680 y410 w120 h20 ginsert, 插入
gui, main:add, button, x550 y440 w250 h30 gupload, 上传图片
gui, main:add, button, x550 y480 w250 h20 gsetserver, 修改数据库信息
gui, main:show, ,上传图片到数据库
gui, main:default
addmsg("初始化配置文件")
IfExist, server.ini
	{
	IniRead, host, server.ini, server, host
	IniRead, user, server.ini, server, user
	IniRead, pass, server.ini, server, pass
	IniRead, db, server.ini, server, db
	}
Else
	goto, setserver
Return

;获取数据并显示图片函数
showpic(){
FileDelete, %A_Temp%\show.jpg ;删除已存在临时文件
;函数内全局变量
global pic_id
global row_id
;获取image列文本
LV_GetText(text,row_id,pic_id)
IfInString, text, image_ ;显示图片
	{
	key = % %text%
	file = %A_Temp%\show.jpg
	blob2file(key,file)
	GuiControl, main:, pic, %file%
	}
Else ;显示“没有图片”
	{
	global nopic
	picdata := unzip(nopic)
	file = %A_Temp%\show.jpg
	blob2file(picdata,file)
	GuiControl, main:, pic, %file%
	}
LV_GetText(id,row_id,1)
Return id
}

;HEX字符解压函数
unzip(a){
StringSplit, var, a, ]
Loop % var0-1
{
tmp_var = % var%A_Index%
StringSplit, key, tmp_var, [
StringSplit, xx, key2, _
unzip_var =
Loop % xx1
{
unzip_var = % unzip_var xx2
}
out = % out key1 unzip_var
}
out := out var%var0%
Return out
}

;variant Objiect 写入文件函数 加入了上传图片后直接赋值字符的处理
blob2file(blob,file){
if (IsObject(blob))
	{
	blob_string =
	;枚举
	tmp_file := FileOpen(file, "w")
	SetFormat, IntegerFast, hex
	For key in blob
		tmp_file.WriteUChar(key)
	SetFormat, IntegerFast, d
	}
Else ;字符
	{
	tmp_file := FileOpen(file, "w")
	StringLen, len, blob
	loop % len/2
	{
	if blob =
		break
	StringLeft, tmp_hex, blob, 2
	StringTrimLeft, blob, blob, 2
	tmp_hex := "0x" tmp_hex
	tmp_file.WriteUChar(tmp_hex)
	}
	}
tmp_file.Close()
tmp_file =
}


;追加消息
addmsg(message){
GuiControlGet, msg

;针对多GUI的bug
if !msg
	{
	ControlGetText, msg, Edit2, 上传图片到数据库
	}

msg = %msg%%A_Hour%:%A_Min%:%A_Sec%.%A_MSec%->%message%`n
msg := RegExReplace(msg,".*\n(.*\n.*\n.*\n.*\n.*\n.*)","$1")
GuiControl, main:, msg, %msg%
}

;文件转HEX函数
file2hex(file){
tmp_file := FileOpen(file, "r")
while not tmp_file.AtEOF {
    tmp_file.RawRead(Data, 1)
	SetFormat, IntegerFast, hex
	tmp_hex := asc(Data)
	StringReplace, tmp_hex, tmp_hex, 0x, , All
	SetFormat, IntegerFast, d
	if StrLen(tmp_hex) = 1
	tmp_hex = 0%tmp_hex%
	hex = % hex tmp_hex
    }
tmp_file.Close()
Return hex
}


exec:
pic_id=
pic_name=
addmsg("获取SQL")
GuiControlGet, sql
conn := ComObjCreate("ADODB.connection") ;初始化COM
conn.Open("driver={SQL Server};server=" host ";uid=" user ";pwd=" pass ";database=" db) ;打开连接
addmsg("打开数据库连接")
connected = 1
query := conn.Execute(sql) ;执行
addmsg(sql)
;判断sql类型
StringLower, lower_sql, sql
IfInString, lower_sql, select
	{
	lower_sql = %lower_sql% `n ;添加结束标志
	table := RegExReplace(lower_sql,"select.*from\s+(\w+)\s+.*\n", "$1") ;截取table名

	;删除原有lv信息
	LV_Delete()
	Loop, % LV_GetCount("Column")
	   LV_DeleteCol(1)

	;枚举对象内所有字段名称
	for field in query.Fields
		fields := fields field.Name "|"
	fields := fields "`n" ;添加结尾
	StringReplace, fields, fields, |`n, , All ;去掉末尾|
	StringSplit, names, fields, | ;分割字段
	update_string =
	Loop % names0 ;添加到ListView 保存到update特征语句
	{
	tmp_name = % names%A_index% ;取出变量
	LV_InsertCol(A_Index, , tmp_name)
	}
	fetchedArray := query.GetRows() ;取出数据(二维数组)
	colSize := fetchedArray.MaxIndex(1) + 1 ;列最大值 tips:从0开始 所以要+1
	rowSize := fetchedArray.MaxIndex(2) + 1 ;行最大值 tips:从0开始 所以要+1
	addmsg("查询到" rowSize "个结果")
	loop, % rowSize
	{
	i := A_index - 1
	y := A_index
	loop, % colSize
	{
	j := A_index - 1
	x := A_index
	tmp_var := fetchedArray[j,i] ;取出二维数组内值
	if (IsObject(tmp_var)) ;variant Objiect 改变显示名称为变量名
		{
		pic_id := x
		pic_name = % names%x%
		image_%y% := tmp_var
		data_%y%_%x% = image_%y%
		}
	Else ;字符值直接显示
		{
		data_%y%_%x% := tmp_var
		}
	}
	;自适应添加,超过失效
	LV_Add("",data_%y%_1,data_%y%_2,data_%y%_3,data_%y%_4,data_%y%_5,data_%y%_6,data_%y%_7,data_%y%_8,data_%y%_9,data_%y%_10,data_%y%_11,data_%y%_12,data_%y%_13,data_%y%_14,data_%y%_15,data_%y%_16,data_%y%_17,data_%y%_18,data_%y%_19,data_%y%_20,data_%y%_21,data_%y%_22,data_%y%_23,data_%y%_24,data_%y%_25,data_%y%_26,data_%y%_27,data_%y%_28,data_%y%_29,data_%y%_30) ;添加到列表
	}

	;清空变量
	fields =
	blob_hex =
	blob_string =
	query =
	;自动调整列宽
	LV_ModifyCol()
	addmsg("为您显示第一条内容")
	;自动显示第一张图
	row_id = 1
	id := showpic()
	}
Else
	{
	addmsg(conn.Errors)
	}
Return


lv:
update_string=
row_id := A_EventInfo
addmsg("选中并显示第" row_id "行")
id := showpic()
Return

upload:
Gui +OwnDialogs
if pic_id=
	{
	MsgBox, 64, 提示, 您没有任何现有图片数据的列,请先定义字段类型或上传一个!
	Return
	}
update_string=
if row_id > 0
	{
	FileSelectFile, file, , , 请选择要上传的图片, 图片文件(*.jpg;*.png;*.gif;*.bmp)
	if file <>
		{
		GuiControl, , pic, %file%
		addmsg("读取" file)
		hex := file2hex(file)
		;Clipboard := hex
		addmsg("上传" file)
		loop % names0
		{
		LV_GetText(tmp_value,row_id,A_index)
		if A_index <> %pic_id%
			{
			if tmp_value <>
				update_string := update_string "[" names%A_index% "]='" tmp_value "' and "
			}
		}
		update_string = %update_string%`n
		StringReplace, update_string, update_string, %A_Space%and `n
		sql = % "update " table " set " pic_name "=0x" hex " where " update_string ;查询语句
		query := conn.Execute(sql)
		sql =
		addmsg("上传完成!请稍等···")
		LV_GetText(text,row_id,pic_id)
		if text <>
			%text% := hex
		Else
			goto, exec
		hex =
		id := showpic()
		addmsg("回显图片修改完成!")
		}
	}
Else
	MsgBox, 64, 提示, 请先双击一列!
Return


set:GuiClose:
Gui set:+OwnDialogs
addmsg("保存配置信息")
GuiControlGet, host
if host =
	{
	MsgBox, 64, 错误, 您未填写内容!
	Return
	}
Else
	{
	gui, set:Submit
	IniWrite, %host%, server.ini, server, host
	IniWrite, %user%, server.ini, server, user
	IniWrite, %pass%, server.ini, server, pass
	IniWrite, %db%, server.ini, server, db
	}
Return

subset:
Gui set:+OwnDialogs
addmsg("保存配置信息")
gui, set:Submit
gui, set:Destroy
IniWrite, %host%, server.ini, server, host
IniWrite, %user%, server.ini, server, user
IniWrite, %pass%, server.ini, server, pass
IniWrite, %db%, server.ini, server, db
Return

edit:
Gui edit:+OwnDialogs
update_string2=
if row_id > 0
	{
	tmp_y = 0
	IfWinExist,  编辑信息
		gui, edit:Destroy
	loop % names0
	{
	if A_index <> %pic_id%
		{
		tmp_name = % names%A_index%
		IfNotInString, tmp_name, id ;排除各种id字段
			{
			Gui,edit:Add,Text,x0 y%tmp_y% w80 h20, % names%A_index% ":"
			Gui,edit:Add,Edit,x70 y%tmp_y% w200 h20 vedit_%A_Index%,
			tmp_y += 20
			}
		}
	}
	Gui,edit:Add,Button,x0 y%tmp_y% w270 h20 gsubedit, 确定
	Gui,edit:Show, , 编辑信息
	gui, edit:+AlwaysOnTop
	loop % names0
	{
	if A_index <> %pic_id%
		{
		LV_GetText(tmp_value,row_id,A_index)
		IfNotInString, tmp_name, id ;排除各种id字段
			{
			GuiControl, edit:, edit_%A_Index%, %tmp_value%
			update_string2 := update_string2 "[" names%A_index% "]='" tmp_value "' and "
			}
		}
	}
	update_string2 = %update_string2%`n
	StringReplace, update_string2, update_string2, %A_Space%and `n
	}
Else
	MsgBox, 64, 提示, 请先双击一列!
Return

subedit:
Gui edit:+OwnDialogs
set_string=
addmsg("保存编辑信息")
gui, edit:Submit
gui, edit:Destroy
loop % names0
{
if A_index <> %pic_id%
	{
	tmp_name = % names%A_index%
	IfNotInString, tmp_name, id
		{
		;LV_Modify(row_id, Col%A_index%, edit_%A_index%) 无效 请手动执行刷新
		set_string := set_string "[" names%A_index% "]='" edit_%A_index% "',"
		}
	}
}
set_string = %set_string%`n
StringReplace, set_string, set_string, `,`n
sql = % "update " table " set " set_string " where " update_string2 ;查询语句
addmsg(sql)
query := conn.Execute(sql)
sql =
addmsg("修改完成!")
ControlClick, Button1, 上传图片到数据库, , Left
Return

insert:
Gui insert:+OwnDialogs
if row_id > 0
	{
	tmp_y = 0
	IfWinExist,  插入信息
		gui, insert:Destroy
	loop % names0
	{
	if A_index <> %pic_id%
		{
		tmp_name = % names%A_index%
		IfNotInString, tmp_name, id ;排除各种id字段
			{
			Gui,insert:Add,Text,x0 y%tmp_y% w80 h20, % names%A_index% ":"
			Gui,insert:Add,Edit,x70 y%tmp_y% w200 h20 vedit_%A_Index%,
			tmp_y += 20
			}
		}
	}
	Gui,insert:Add,Button,x0 y%tmp_y% w270 h20 gsubinsert, 确定
	Gui,insert:Show, , 插入信息
	gui, insert:+AlwaysOnTop
	}
Else
	MsgBox, 64, 提示, 请先双击一列!
Return

subinsert:
Gui insert:+OwnDialogs
key_string=
value_string=
addmsg("保存新增信息")
gui, insert:Submit
gui, insert:Destroy
loop % names0
{
if A_index <> %pic_id%
	{
	tmp_name = % names%A_index%
	IfNotInString, tmp_name, id
		{
		key_string := key_string "[" names%A_index% "],"
		value_string := value_string "'" edit_%A_index% "',"
		}
	}
}
key_string = %key_string%`n
StringReplace, key_string, key_string, `,`n
value_string = %value_string%`n
StringReplace, value_string, value_string, `,`n
sql = % "insert into " table " (" key_string ")values(" value_string ")" ;查询语句
addmsg(sql)
query := conn.Execute(sql)
sql =
addmsg("插入完成!")
ControlClick, Button1, 上传图片到数据库, , Left
Return

setserver:
Gui,set:Add,Text,x0 y0 w80 h20,服务器地址:
Gui,set:Add,Edit,x70 y0 w200 h20 vhost,
Gui,set:Add,Text,x0 y20 w70 h20,用户名:
Gui,set:Add,Edit,x70 y20 w200 h20 vuser,
Gui,set:Add,Text,x0 y40 w70 h20,密码:
Gui,set:Add,Edit,x70 y40 w200 h20 Password vpass,
Gui,set:Add,Text,x0 y60 w70 h20,数据库:
Gui,set:Add,Edit,x70 y60 w200 h20 vdb,
Gui,set:Add,Button,x0 y80 w270 h20 gsubset, 确定
Gui,set:Show, , 设置数据库信息
gui, set:+AlwaysOnTop
GuiControl, set:, host, %host%
GuiControl, set:, user, %user%
GuiControl, set:, pass, %pass%
GuiControl, set:, db, %db%
Return

pic: ;保存当前图片
FileSelectFile, file, S, , 请选择图片保存路径, 图片文件(*.jpg;*.png;*.gif;*.bmp)
FileCopy, %A_Temp%\show.jpg, %file%, 1
addmsg("另存图片为" file "完成!")
Return

editGuiClose:
gui, edit:Destroy
Return

insertGuiClose:
gui, insert:Destroy
Return

mainGuiClose:
addmsg("退出")
conn.Close()
ExitApp


HEX十六进制与文件互转 字符串简单压缩解压 Autohotkey 4062

作者为 发表

Autohotkey

之前写一个gui,需要嵌入图片到ahk代码,但HEX太长,所以有了这么一个压缩脚本

zip(a){
;自定义设置
size = 2 ;多少字节一取样 比如24为bmp 6字节

;完毕
last =
Loop
{
if a =
	{
	if times > 1
		out = % out "[" times "_" last "]"
	Else
		out = % out last
	Break
	}
StringLeft, tmp_var, a, %size%
StringTrimLeft, a, a, %size%
if tmp_var <> %last%
	{
	if last =
		{
		last := tmp_var
		times = 1
		}
	Else
		{
		if times > 1
			{
			out = % out "[" times "_" last "]"
			last := tmp_var
			times = 1
			}
		Else
			{
			out = % out last
			last := tmp_var
			times = 1
			}
		}
	}
Else
	{
	times += 1
	}
}
return %out%
}

unzip(a){
StringSplit, var, a, ]
Loop % var0-1
{
tmp_var = % var%A_Index%
StringSplit, key, tmp_var, [
StringSplit, xx, key2, _
unzip_var =
Loop % xx1
{
unzip_var = % unzip_var xx2
}
out = % out key1 unzip_var
}
out := out var%var0%
Return out
}

file2hex(file){
tmp_file := FileOpen(file, "r")
while not tmp_file.AtEOF {
    tmp_file.RawRead(Data, 1)
	SetFormat, IntegerFast, hex
	tmp_hex := asc(Data)
	StringReplace, tmp_hex, tmp_hex, 0x, , All
	SetFormat, IntegerFast, d
	if StrLen(tmp_hex) = 1
	tmp_hex = 0%tmp_hex%
	hex = % hex tmp_hex
    }
tmp_file.Close()
Return hex
}

hex2file(hex,file){
tmp_file := FileOpen(file, "w")
StringLen, len, hex
loop % len/2
{
if blob =
	break
StringLeft, tmp_hex, blob, 2
StringTrimLeft, blob, blob, 2
tmp_hex := "0x" tmp_hex
tmp_file.WriteUChar(tmp_hex)
}
tmp_file.Close()
tmp_file =
}


a := file2hex("D:\Desktop\no.bmp")
zip := zip(a)
FileAppend, %zip%, zip.txt
b := unzip(zip)
hex2file(b,"out.txt")


批量结束杀进程 Windows Autohotkey 9243

作者为 发表

Autohotkey

do_not_kill =
(
cmd.exe
conhost.exe
csrss.exe
dwm.exe
explorer.exe
lsass.exe
services.exe
smss.exe
spoolsv.exe
svchost.exe
wininit.exe
winlogon.exe
WmiPrvSE.exe
Autohuotkey.exe
%A_ScriptName%
)
IfExist, settings.conf
    FileRead, do_not_kill, settings.conf
gui, add, text, x0 y0 w200 h20, 白名单
gui, add, Edit, x0 y20 w200 h400 vdo_not_kill, %do_not_kill%
gui, add, button, x0 y420 w200 h20 gkill, 批量杀进程
gui, show, , 批量杀进程
Return

kill:
GuiControlGet, do_not_kill
FileDelete, settings.conf
FileAppend, do_not_kill, settings.conf
killallprocess(do_not_kill)
Return

GuiClose:
FileDelete, settings.conf
FileAppend, do_not_kill, settings.conf
ExitApp


;定义函数
killallprocess(do_not_kill){
RunWait, %ComSpec% /c tasklist >%A_Temp%\tasklist.tmp, , Hide ;CMD 列表进程
Loop
{
FileReadLine, line, %A_Temp%\tasklist.tmp, %A_Index% ;按行读取
if errorlevel
    Break
IfInString, line, .exe ;包含.exe
    {
    StringSplit, var, line, %A_Space%, ;替换空格
    IfNotInString, do_not_kill, %var1%  ;不在列表内
        runwait, %ComSpec% /c taskkill /f /IM %var1%, , Hide ;杀进程
    }
}
}

killallprocess.zip


右键复制图片链接自动下载 Autohotkey 5458

作者为 发表

Autohotkey

主程序 负责监控剪切板并发送下载命令

FileCreateDir, %A_ScriptDir%\down\ ;创建下载目录
Loop
{
Clipboard= ;清空剪切板
ClipWait ;等待有内容
a = %Clipboard% ;赋值
Clipboard= ;清空
;检查匹配后缀 发送下载命令
If a contains .jpg,.jpeg,.gif,.bmp,.png
	{
	run, down.exe %a%
	}
}

下载部分,需要编译成exe

#NoTrayIcon ;无任务栏图标
#SingleInstance off ;开启多进程
if 1 <>
	{
	URLDownloadToFile, %1%, %A_ScriptDir%\down\%A_TickCount%.jpg
	}
ExitApp


File UDF用户自定义函数 Autohotkey 3837

作者为 发表

Autohotkey

;===============================================================================
;
; Description:      返回指定文本文件的行数.
; Syntax:           FileCountLines(sFilePath)
; Parameter(s):     $sFilePath - 路径+文件名
; Requirement(s):   无
; Return Value(s):  成功 - 返回文件的行数
;                   失败 - 返回0 并设置 error = 1
; Author(s):        Tylo <tylo at start dot no> 修正 by thesnow Converted by Thinkai
;
;===============================================================================
FileCountLines(sFilePath){
	global error
	IfNotExist, %sFilePath%
		{
		error = 1
		Return 0
		}
	Else
		{
		FileRead, m, %sFilePath%
		StringSplit, n, m, `n
		if n0 = 0
			Return 1
		Else
			Return n0
		}
}



;======================================================
;
; 函数名称:		EncryptFile(sFilePath)
; 详细信息:		加密文件,NTFS磁盘系统自带的EFS加密
; sFilePath:	sFilePath 为您想加密的文件.
; 返回值 :		Dllcall的Errorlevel
; 作者:			thesnow(rundll32@126.com) Converted by Thinkai
;
;======================================================

EncryptFile(sFilePath){
dllcall("advapi32.dll\EncryptFile","str", sFilePath)
Return Errorlevel
}


;======================================================
;
; 函数名称:		DecryptFile(sFilePath)
; 详细信息:		解密文件,NTFS磁盘系统自带的EFS加密
; sFilePath:	sFilePath 为您想解密的文件.
; 返回值 :		Dllcall的Errorlevel
; 作者:			thesnow(rundll32@126.com) Converted by Thinkai
;
;======================================================

DecryptFile(sFilePath){
dllcall("advapi32.dll\DecryptFile","str", sFilePath,"int",1)
Return Errorlevel
}


;======================================================
;
; 函数名称:		_HideSystemFolder($PathCode,$Hide)
; 详细信息:		隐藏系统特殊文件夹.
; $PathCode:	系统文件夹代码:
;				0,控制面板/1,程序文件夹目录/2,系统所在驱动器/3,windows目录
; $Hide:		隐藏为1,不隐藏为0.
; 返回值 :		成功返回1,失败(文件夹代码错误)返回0,失败(隐藏代码错误),返回0.
; 作者:			thesnow(rundll32@126.com) Converted by Thinkai
;
;======================================================

HideSystemFolder(PathCode:=4,Hide:=1){
If Hide is not integer
	{
	Return 0
	}
Else
	{
	if PathCode = 0
		RegWrite, REG_DWORD, HKCU, Software\Microsoft\Windows\CurrentVersion\Explorer\WebView\BarricadedFolders, shell:ControlPanelFolder, %Hide%
	Else if PathCode = 1
		RegWrite, REG_DWORD, HKCU, Software\Microsoft\Windows\CurrentVersion\Explorer\WebView\BarricadedFolders, shell:ProgramFiles, %Hide%
	Else if PathCode = 2
		RegWrite, REG_DWORD, HKCU, Software\Microsoft\Windows\CurrentVersion\Explorer\WebView\BarricadedFolders, shell:SystemDriveRootFolder, %Hide%
	Else if PathCode = 3
		RegWrite, REG_DWORD, HKCU, Software\Microsoft\Windows\CurrentVersion\Explorer\WebView\BarricadedFolders, shell:Windows, %Hide%
	Else if PathCode = 4
		RegWrite, REG_DWORD, HKCU, Software\Microsoft\Windows\CurrentVersion\Explorer\WebView\BarricadedFolders, shell:Windows, %Hide%
 	Else
		Return 0
	}
Return 1
}


PHPExcel遍历获取excel数据为csv格式 10682

作者为 发表

网站建设

<?php 

//首先导入PHPExcel  
require_once 'PHPExcel.php';  
  
$filePath = "test.xlsx";  
  
//建立reader对象  
$PHPReader = new PHPExcel_Reader_Excel2007();  
if(!$PHPReader->canRead($filePath)){  
    $PHPReader = new PHPExcel_Reader_Excel5();  
    if(!$PHPReader->canRead($filePath)){  
        echo 'no Excel';  
        return ;  
    }  
}  
  
//建立excel对象,此时你即可以通过excel对象读取文件,也可以通过它写入文件  
$PHPExcel = $PHPReader->load($filePath);  
/**获取工作表数量*/  
$sheetCount = $PHPExcel->getSheetCount();
for($sheetid=0;$sheetid<=$sheetCount-1;$sheetid++){
/**读取excel文件中的第N个工作表*/  
$currentSheet = $PHPExcel->getSheet($sheetid);  
//获取sheet名
$currentSheetName = $currentSheet->getTitle();  
/**取得最大的列号*/  
$allColumn = $currentSheet->getHighestColumn();  
/**取得一共有多少行*/  
$allRow = $currentSheet->getHighestRow();  
  
//循环读取每个单元格的内容。注意行从1开始,列从A开始  
for($rowIndex=1;$rowIndex<=$allRow;$rowIndex++){
	$tmpline = NULL;  
    for($colIndex='A';$colIndex<=$allColumn;$colIndex++){  
        $addr = $colIndex.$rowIndex;  
        $cell = $currentSheet->getCell($addr)->getValue();  
        if($cell instanceof PHPExcel_RichText)     //富文本转换字符串  
            $cell = $cell->__toString();  
              $tmpline .= $cell.",";
      
    } 
    $tmpline .= "\n";
    $tmpline=str_replace(",\n","\n",$tmpline);
  echo $currentSheetName.",".$tmpline;
}
}
?>


首先,使用USB网络共享\WIFI等方式使手机和电脑处于同一局域网。然后在手机上安装org.myklos.sendmessage这个App,并开启Server。(群发器已经打包了汉化版)

英文原版org.myklos.sendmessage.zip

打开手机软件上的地址,比如http://192.168.42.129:8080/ 看到内容即可开始使用。

 

在电脑上打开软件,填写上短信服务器地址即可开始使用。

 

 

参数:记录到文件,会把每一条记录写到文件

      慢速发送,1秒一条,推荐手机慢的勾选


接口:

http://[服务器地址]/send/?pass=[密码 可空 ]&number=[号码]&data=[UTF-8 URLEncode的正文]&submit=&id=


php版

<?php
$number = "10001"; //号码
$content = "测试thinkai.net"; //正文
$host = "192.168.42.129:8080"; //服务器地址
$pass = ""; //密码
$data = urlencode($content); //转码
$send = file_get_contents("http://$host/send/?pass=$pass&number=$number&data=$data&submit=&id=");  //调用接口
$result = (explode("\n",$send)); //分割结果
echo str_replace("STATUS: ","",$result[0]); //显示状态
?>


Autohotkey版

#NoTrayIcon
;转码函数
urlencode(string){
clip := ClipboardAll
Clipboard = %string%
Transform, string, Unicode
Clipboard := clip
StringLen, len, string
SetFormat, IntegerFast, hex
Loop
{
if A_Index > %len%
	Break
StringMid, out, string, %A_Index%, 1
hex := Asc(out)
hex := hex * 0x01
StringReplace, hex, hex, 0x, , All
content = %content%`%%hex%
}
SetFormat, IntegerFast, d
Return content
}

number = 10001 ; //号码
content = 测试thinkai.net ; //正文
host = 192.168.42.129:8080 ; //服务器地址
pass =  ; //密码
data := urlencode(content) ; //转码
URLDownloadToFile, http://%host%/send/?pass=%pass%&number=%number%&data=%data%&submit=&id=, %A_Temp%\send.tmp
FileRead, result, %A_Temp%\send.tmp
StringSplit, result, result, `n  ; //分割结果
StringReplace, status, result1, STATUS:%A_Space%, ,
MsgBox, 64, 结果, %status%

群发器源码

#NoTrayIcon ;不显示图标
FileInstall, org.myklos.sendmessage.apk, 网关服务器.apk ;打包文件
;创建界面
Gui, Add, Text, x6 y7 w140 h50 , 短信网关地址`n例192.168.42.129:8080`n一行一个
Gui, Add, Edit, x6 y57 w140 h80 vgate, 192.168.42.129:8080
Gui, Add, CheckBox, x6 y137 w140 h20 vlog, 记录发送记录到文件
Gui, Add, CheckBox, x6 y157 w140 h20 vslow, 慢速发送
Gui, Add, Text, x146 y7 w100 h20 , 发送号码
Gui, Add, Edit, x146 y27 w100 h150 vhm
Gui, Add, Text, x246 y7 w370 h20 , 短信内容
Gui, Add, Edit, x246 y27 w370 h150 vnr
Gui, Add, Text, x6 y177 w240 h60 vshow
Gui, Add, Button, x246 y177 w370 h60 gsend, 开始发送
Gui, Show,h246 w626, 群发短信单体版

;检查是否使用过 加载上次填写的服务器地址
IfExist, gate.ini
	{
	FileRead, gate, gate.ini
	GuiControl, , gate, %gate%
	}


;转码函数
urlencode(string){
clip := ClipboardAll ;剪切板转存
Clipboard = %string%
Transform, string, Unicode ;获取UTF-8
Clipboard := clip
StringLen, len, string
SetFormat, IntegerFast, hex ;运算结果为HEX
Loop
{
if A_Index > %len%
	Break
StringMid, out, string, %A_Index%, 1
hex := Asc(out) ;获取单字节ascii值
hex := hex * 0x01
StringReplace, hex, hex, 0x, , All
content = %content%`%%hex%
}
SetFormat, IntegerFast, d ;运算结果为是静止
Return content
}

Return

Send:
;从界面取回内容
GuiControlGet, hm
GuiControlGet, nr
GuiControlGet, gate
GuiControlGet, log
GuiControlGet, slow
;处理填写内容
IfNotInString, hm, `n
	{
	number0 = 1
	number1 = %hm%
	}
Else
	{
	StringReplace, hm, hm, `r, , All
	hm = %hm%`n
	StringReplace, hm, hm, `n`n, , All
	StringSplit, number, hm, `n
	}
IfNotInString, gate, `n
	{
	gate0 = 1
	gate1 = %gate%
	}
Else
	{
	StringReplace, gate, gate, `r, , All
	gate = %gate%`n
	StringReplace, gate, gate, `n`n, , All
	StringSplit, gate, gate, `n
	}
;初始化
id = 0
success = 0
time = %A_Now%
data := urlencode(nr) ;urlencode
Loop
{
if A_Index > %number0%
	Break
tmpnumber = % number%A_Index%
if tmpnumber <>
	{
	StringReplace, tmpnumber, tmpnumber, -, , All
	b := tmpnumber/1
	IfInString, b, .000000
		{
		id += 1
		if id > %gate0%
			id = 1
		host = % gate%id%
		pass =  ; //密码
		GuiControl, , show, 网关:%host%`n号码:%tmpnumber%`n序号:%A_Index%`n ;显示
		URLDownloadToFile, http://%host%/send/?pass=%pass%&number=%tmpnumber%&data=%data%&submit=&id=, %A_Temp%\send.tmp ;执行并抓回结果
		FileRead, result, %A_Temp%\send.tmp
		StringSplit, result, result, `n  ; //分割结果
		StringReplace, status, result1, STATUS:%A_Space%, ,
		GuiControl, , show, 网关:%host%`n号码:%tmpnumber%`n序号:%A_Index%`n状态:%status%
		if status = STATUS_OK
			success += 1
		if log = 1
			FileAppend, 网关:%host%`,号码:%tmpnumber%`,序号:%A_Index%`,状态:%status%`,时间:%A_Now%`n, %time%.log
		if slow = 1
			sleep, 1000
		;Else
			;sleep, 100
		}
	}
}
GuiControl, , show, 共计发送%number0%条短信,其中成功%success%个!
FileDelete, gate.ini
FileAppend, %gate%, gate.ini
Return

GuiClose:
ExitApp

安卓HTTP短信群发.zip 含汉化版org.myklos.sendmessage.apk


URLEncode/URLDecode函数 Autohotkey Ansi 7065

作者为 发表

Autohotkey

urlencode(string){
string := Ansi2UTF8(string)
StringLen, len, string
Loop % len
{
SetFormat, IntegerFast, hex
StringMid, out, string, %A_Index%, 1
hex := Asc(out)
hex2 := hex
StringReplace, hex, hex, 0x, , All
SetFormat, IntegerFast, d
hex2 := hex2
If (hex2==33 || (hex2>=39 && hex2 <=42) || hex2==45 || hex2 ==46 || (hex2>=48 && hex2<=57) || (hex2>=65 && hex2<=90) || hex2==95 || (hex2>=97 && hex2<=122) || hex2==126)
	content .= out
Else
	content .= "`%" hex
}
Return content
}


urldecode(string){
StringReplace, string, string, +, %A_Space%, All ;去连接符
Loop, Parse, string, `%
{
asc_key := A_LoopField
if A_index = 1
    content = % content asc_key ;直接串接
Else
    {
    if RegExMatch(asc_key,"i)[0-9a-f]{2}")
        {
        StringLeft, part1, asc_key, 2 ;分成两部分 hex 和单字节字符
        StringTrimLeft, part2, asc_key, 2
        asc_var := chr("0x" part1)
        content = % content asc_var part2
        }
    Else
        content = % content asc_key ;直接串接
    }
}
return content
}

Ansi2UTF8(sString)
{
   Ansi2Unicode(sString, wString, 0)
   Unicode2Ansi(wString, zString, 65001)
   Return zString
}
UTF82Ansi(zString)
{
   Ansi2Unicode(zString, wString, 65001)
   Unicode2Ansi(wString, sString, 0)
   Return sString
}
Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
{
     nSize := DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int", -1
      , "Uint", 0
      , "int", 0)
   VarSetCapacity(wString, nSize * 2)
   DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int", -1
      , "Uint", &wString
      , "int", nSize)
}
Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
{
     nSize := DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int", -1
      , "Uint", 0
      , "int", 0
      , "Uint", 0
      , "Uint", 0)
   VarSetCapacity(sString, nSize)
   DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int", -1
      , "str", sString
      , "int", nSize
      , "Uint", 0
      , "Uint", 0)
}


;测试
a := urlencode("Round(Number [, N]): 如果 N 省略或为 0, 则 Number 被取整到最近的整数. 如果 N 为正数, 则 Number 被取整到 N 个小数位. 如果 N 为负数,则 Number 被取整到十进制小数点左边 N 位。例如,Round(345, -1) 的结果为 350 而 Round (345, -2) 的结果为 300。与 Transform Round 不同, 每当 N 省略或小于 1 时结果不带 .000 后缀. 在 v1.0.44.01+,N 值大于零时会准确显示 N 个小数位而不遵循 SetFormat 的设置。要避免这种情况, 需要对 Round() 的返回值再进行一次数学运算; 例如: Round(3.333, 1)+0.")
Clipboard = % a
b := urldecode(a)
FileDelete,  %A_Temp%\a.tmp
FileAppend, %b%, %A_Temp%\a.tmp
FileEncoding, UTF-8
FileRead, b, %A_Temp%\a.tmp
MsgBox, 编码:`n%a%`n解码:`n%b%
str := "%E5%BD%93%E5%89%8D%E4%BD%8D%E7%BD%AE%EF%BC%9A%E7%83%AD%E9%97%A8%E5%B7%A5%E5%85%B7%E5%89%8D20%E5%90%8D"
MsgBox % UTF82Ansi(urldecode(str))


ping函数 数组实际应用 Autohotkey 7067

作者为 发表

Autohotkey

;初始化数组
pinginfo := Object()

;建立函数
ping(pinginfo){
site := pinginfo["site"] ;赋值
RunWait, %ComSpec% /c ping -n 1 %site% >%A_Temp%\ahk_ping.tmp, , Hide ;有cmd ping网址并保存到临时文件夹
FileRead, content, %A_Temp%\ahk_ping.tmp ;读取整个文件到变量
StringReplace, content, content, `r, , All ;去除回车符
StringSplit, var, content, `n ;按换行分割
If content Contains 请求超时,Request timed out
	pinginfo["msg"] = "请求超时" ;返回msg
If content Contains 找不到主机,could not find host
	pinginfo["msg"] = "找不到主机"
Else
	{
	pinginfo["ip"] := RegExReplace(var3, "(来自|Reply from) (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[\s的回复|]*: (字节|bytes)=\d{1,3}\ (时间|time)[=<]\d{1,3}ms TTL=\d{1,3}","$2") ;正则替换
	pinginfo["time"] := RegExReplace(var3, "(来自|Reply from) \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[\s的回复|]*: (字节|bytes)=\d{1,3}\ (时间|time)[=<](\d{1,3})ms TTL=\d{1,3}","$4")
	pinginfo["ttl"] := RegExReplace(var3, "(来自|Reply from) \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[\s的回复|]*: (字节|bytes)=\d{1,3}\ (时间|time)[=<]\d{1,3}ms TTL=(\d{1,3})","$4")
	pinginfo["msg"] = "正常"
	}
Return pinginfo ;返回数组
}

;调用方法
pinginfo["site"] := "www.baidu.com" ;赋值网址
pinginfo := ping(pinginfo) ;调用函数并保存到pinginfo
ip := pinginfo["ip"] ;取出
time := pinginfo["time"]
site := pinginfo["site"]
MsgBox, 网址:%site%(%ip%) 的ping延时为%time%ms ;测试


迷你小说txt阅读器 Win+H随时隐藏 Autohotkey 4858

作者为 发表

Autohotkey

这是原来上计算机课写的一个小说阅读器,老师一来随时隐藏,嘿嘿

阅读界面

章节目录界面

Autohotkey源代码

#MaxMem, 4095 ;最大内存 4G
#NoTrayIcon ;不显示图标
DetectHiddenWindows, On ;检查隐藏窗口
CoordMode, Mouse, Relative ;鼠标坐标相对窗口
;创建章节目录显示窗口
Gui, Add, ListView, x0 y0 w300 h400 glist, idx|章节目录
Gui, Show, , 章节目录
WinHide, 章节目录 ;隐藏窗口
;第一次打开程序
IfNotExist, history.ini
	{
	MsgBox, 4096, 版本说明|What's new, 更新项目:`n1.增加窗口大小调整功能,可以全屏啦!`n2.在Win+H基础上增加Win+Z快速显示隐藏窗口。`n3.优化上一页算法。`n4.增加点击文本上半部分为【上一页】,下半部分为【下一页】的翻页功能。`n`n已知问题:`n调整窗口大小后,当时可能显示错位,翻页后正常。
	FileSelectFile, file, , , 选择一本小说, (*.txt) ;选取文件
	if file =
		Reload
	IniWrite, %file%, history.ini, history, file ;写入ini
	WinShow, 章节目录 ;显示窗口
	FileDelete, mulu.txt
	LV_Delete() ;删除已有信息
	SplashTextOn, 200, 20, 提示, 获取章节中,请稍候! ;悬浮窗口
	FileRead, main, %file% ;读取文件
	StringSplit, line, main, `n ;按行分割
	idx = 0 ;初始变量
	Loop
	{
	idx += 1
	if idx > %line0% ;大于最大行
		Break ;中断循环
	var = % line%idx% ;获取当前行
	if var <>
		{
		StringReplace, var, var, `r, , All ;替换回车
		test := RegExMatch(var, ".*第.*(章|卷|回)\s.{1,40}") ;正则表达式匹配章节
		if test = 1
			{
			LV_Add("",idx,var)
			mulu = %mulu%%idx%,%var%`n ;追加变量
			}
		}
	}
	FileAppend, %mulu%, mulu.txt ;保存目录信息
	SplashTextOff
	}
Else
	{
	IniRead, file, history.ini, history, file ;读取ini中的文件名
	FileRead, main, %file% ;读取文件
	StringSplit, line, main, `n ;按行分割
	MsgBox, 36, 询问, 是否继续阅读【%file%】?
	IfMsgBox, No
		{
		FileDelete, history.ini
		Reload
		}
	Else
		{
		WinShow, 章节目录
		LV_Delete()
		SplashTextOn, 200, 20, 提示, 获取章节中,请稍候!
		FileRead, main, %file% ;读取目录信息
		StringSplit, line, main, `n
		Loop
		{
		FileReadLine, cc, mulu.txt, %A_Index%
		if errorlevel
		Break
		if cc <>
			{
			StringSplit, st, cc, `,,
			idx = %st1%
			var = %st2%
			LV_Add("",idx,var)
			}
		}
		SplashTextOff
		MsgBox, 36, 询问, 是否继续上次阅读位置?
		IfMsgBox, Yes
			{
			FileRead, tail, tail.txt
			IniRead, idx, history.ini, history, idx
			FileRead, dis, dis.txt
			goto, jx
			}
		}
	}

Return

list:
;获取焦点行
FocusedRowNumber := LV_GetNext(0, "F")
if FocusedRowNumber
	{
	LV_GetText(index, FocusedRowNumber, 1) ;获取id
	goto, show
	}
Return

menu:
IfWinExist, 章节目录
	{
	WinHide, 阅读
	WinShow, 章节目录
	}
Return

jx: ;继续阅读
oldidx = %idx%
SplitPath, file, , , , name, 4 ;获取文件名
WinHide, 章节目录
IfWinNotExist, 阅读
	{
	Gui, 2:Add, Text, x0 y10 w270 h180 gtextbody vshow,
	Gui, 2:Add, Text, x20 y190 w40 h20 glast vlast, 上一页
	Gui, 2:Add, Text, x120 y190 w40 h20 gmenu vmenu, 目录
	Gui, 2:Add, Text, x220 y190 w40 h20 gnext vnext, 下一页
	Gui, 2:Add, Text, x0 y210 w270 h20 vbt, %name%
	Gui, 2:Show, , 阅读
	Gui, 2:Default
	Gui, 2:+Resize
	}
Else
	WinShow, 阅读
GuiControl, 2:, show, %dis%
Return

show:
SplitPath, file, , , , name,
WinHide, 章节目录
IfWinNotExist, 阅读
	{
	Gui, 2:Add, Text, x0 y10 w270 h180 gtextbody vshow,
	Gui, 2:Add, Text, x20 y190 w40 h20 glast vlast, 上一页
	Gui, 2:Add, Text, x120 y190 w40 h20 gmenu vmenu, 目录
	Gui, 2:Add, Text, x220 y190 w40 h20 gnext vnext, 下一页
	Gui, 2:Add, Text, x0 y210 w270 h20 vbt, %name%
	Gui, 2:Show, , 阅读
	Gui, 2:Default
	Gui, 2:+Resize
	}
Else
	WinShow, 阅读
add = 0
tail = % line%index%
idx = %index%
goto, display
Return

display:
oldidx = %idx%
dis =
y = 0
Loop
{
if A_Index > %sy%
	{
	GuiControl, 2:, show, %dis%
	Break
	}
if add = 1
	{
	idx += 1
	tail = % line%idx%
	}
test := RegExMatch(tail, ".*第.*(章|卷|回)\s.{1,40}")
if test = 1
	GuiControl, 2:, bt, %name%-%tail%
StringLen, len, tail
if len < %sx% ;单行长度小于最大单行字数
	{
	dis = %dis%%tail%`n
	add = 1
	}
if len >= %sx% ;单行长度大于等于最大单行字数
	{
	stringLeft, cline, tail, %sx% ;截取范围内的
	StringTrimLeft, tail, tail, %sx% ;范围外的
	dis = %dis%%cline%`n
	StringLen, len2, tail
	if len2 < 1
		add = 1
	Else
		add = 0
	}
}
Return


~Left::
~Up::
last:
idx := oldidx-sy/2
StringGetPos, pos, idx, .
StringLeft, idx, idx, %pos%
tail =
goto, display
Return

~Right::
~Down::
next:
goto display
Return


GuiClose: ;主窗口关闭
ExitApp

2GuiClose: ;阅读窗口关闭
FileDelete, tail.txt
FileAppend, %tail%, tail.txt
IniWrite, %idx%, history.ini, history, idx
FileDelete, dis.txt
FileAppend, %dis%, dis.txt
IniWrite, %add%, history.ini, history, add
WinHide, 阅读
WinShow, 章节目录
Return

2GuiSize:
sx := A_GuiWidth/6
StringGetPos, pos, sx, .
StringLeft, sx, sx, %pos%
sx -= 1
sy := A_GuiHeight/12
StringGetPos, pos, sy, .
StringLeft, sy, sy, %pos%
sy -= 4
textw := A_GuiWidth
texth := (sy+1)*12
buttony := texth+10
menux := A_GuiWidth/2-20
nextx := A_GuiWidth-40
titley := texth+30
GuiControl, 2:Move, show, w%textw% h%texth%
GuiControl, 2:Move, last, y%buttony%
GuiControl, 2:Move, menu, x%menux% y%buttony%
GuiControl, 2:Move, next, x%nextx% y%buttony%
GuiControl, 2:Move, bt, y%titley%
Return

textbody:
MouseGetPos, clickx, clicky
updown := clicky/texth
if updown > 0.5
	goto, next
if updown < 0.5
	goto, last
Return

#z:: ;Win+Z快速隐藏
#h:: ;Win+H快速隐藏
IfWinActive, ahk_class AutoHotkeyGUI
	WinHide, ahk_class AutoHotkeyGUI
Else
	WinShow, ahk_class AutoHotkeyGUI
Return

minireader.zip



友情链接:Autohotkey中文论坛Autohotkey中文帮助Autohotkey官网我的B站直播间Autohotkey中文网联系作者免GooglePlay APK下载

 主题设计 • skyfrit.com  Thinkai's Blog | 保留所有权利

43 queries in 1.084 seconds |