#c:: GetClip: ClipSave := ClipboardAll Send, {PrintScreen} Sleep, 200 Clip := ClipboardAll Clipboard := ClipSave a := fileopen("clip.tmp","w") a.RawWrite(Clip,StrLen(Clip)) a.Close() Return #v:: ReadClip: ClipSave := ClipboardAll ;读取文件到剪切板 FileRead, Clipboard, *c clip.tmp Send, ^v Sleep, 200 Clipboard := ClipSave Return
;写 a := fileopen("test.txt","w") ;写入方式打开 b := ClipboardAll ;赋值从剪切板 u := A_IsUnicode ? 2 : 1 ;Unicode版长度为2 a.RawWrite(b,StrLen(b)*u) ;长度为变量的长度 a.Close() ;读 a := fileopen("test.txt","r") c = 0 a.Rawread(c,a.Length) ListVars Pause
;调用测试示例 a := ClipboardAll ;赋值 ;两种方法测试耗时 oldtime := A_TickCount test1 := HexOut(a) ;方法1 time1 := A_TickCount-oldtime oldtime := A_TickCount test2 := HexOut2(a) ;方法2 time2 := A_TickCount-oldtime ;MsgBox, 64, 提示, 方法1:%test1%`n耗时:%time1%ms`n`n方法2:%test2%`n耗时:%time2%ms MsgBox, 64, 提示, 方法1耗时:%time1%ms`n`n方法2耗时:%time2%ms HexOut(var,h:=0){ u := A_IsUnicode ? 2 : 1 ;Unicode版ahk字符长度是2 hex := {0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,10:"A",11:"B",12:"C",13:"D",14:"E",15:"F"} ;预置0-F的十六进制值 Loop % StrLen(var) ;循环变量的长度/次 { char := NumGet(var, (A_index-1)*u, "UChar") ;内存读取无格式单字节Asc值 ;串接 out .= hex[Floor(char/16)] hex[mod(char,16)] ;十进制转十六进制 Floor向下取整第二位 mod取余数第一位 并分别十六进制 } if h = 1 Return "0x" out ;返回0xFF格式 Else Return out ;返回FF格式 } HexOut2(var,h:=0){ u := A_IsUnicode ? 2 : 1 Loop % StrLen(var) ;循环变量的长度/次 { char := NumGet(&var, (A_index-1)*u, "UChar") ;内存读取无格式单字节Asc值 ;串接十六进制 SetFormat, IntegerFast, hex StringReplace, char, char, 0x, , All SetFormat, IntegerFast, d out .= StrLen(char)=2 ? char : "0" char } if h = 1 Return "0x" out ;返回0xFF格式 Else Return out ;返回FF格式 }
在ahk中可能会有以下几种情况会用到URL:
需要打开某网站,并且会模拟登陆什么的。这种情况可以分3种:
(1)打开网址,通过ImageSearch等方式找到位置点击并登陆。
常用命令:
Run, ;打开百度 Run, D:\Program Files (x86)\sogouexplorer\SogouExplorer.exe http://thinkai.net ;指定浏览器打开 Run, iexplore.exe http://ahk8.com, , hide ;隐藏打开 一定程度不起作用 Loop { ImageSearch, out_x, out_y, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, d:\test.bmp ;全屏找BMP图片 找到退出循环 If !errorlevel { MsgBox, 找到该BMP,左上角坐标是%out_x%`,%out_y% } }
(2)IE打开,通过COM打开网址并进行一系列静默操作(类似ControlSend)。可以参考星雨朝霞写的AHKinfo 窗口信息工具 和 一键登录AHK中文论坛[网页操作]
(3)后台静默打开。这时就可能要用到WGET UrlDownloadToFile UrlDownloadToVar WinHttp.WinHttpRequest.5.1这四个函数了。
WGET wget是一个从网络上自动下载文件的自由工具,支持通过HTTP、HTTPS、FTP三个最常见的TCP/IP协议下载,并可以使用HTTP代理.Windows版:wget.zip 功能比较全,建议用此命令来模拟登陆,支持post数据,支持cookie,支持改user-agent。下面是程序的参数:
GNU Wget 1.11.4, a non-interactive network retriever. Usage: wget [OPTION]... [URL]... Mandatory arguments to long options are mandatory for short options too. Startup: -V, --version display the version of Wget and exit. -h, --help print this help. -b, --background go to background after startup. -e, --execute=COMMAND execute a `.wgetrc'-style command. Logging and input file: -o, --output-file=FILE log messages to FILE. -a, --append-output=FILE append messages to FILE. -d, --debug print lots of debugging information. -q, --quiet quiet (no output). -v, --verbose be verbose (this is the default). -nv, --no-verbose turn off verboseness, without being quiet. -i, --input-file=FILE download URLs found in FILE. -F, --force-html treat input file as HTML. -B, --base=URL prepends URL to relative links in -F -i file. Download: -t, --tries=NUMBER set number of retries to NUMBER (0 unlimits). --retry-connrefused retry even if connection is refused. -O, --output-document=FILE write documents to FILE. -nc, --no-clobber skip downloads that would download to existing files. -c, --continue resume getting a partially-downloaded file. --progress=TYPE select progress gauge type. -N, --timestamping don't re-retrieve files unless newer than local. -S, --server-response print server response. --spider don't download anything. -T, --timeout=SECONDS set all timeout values to SECONDS. --dns-timeout=SECS set the DNS lookup timeout to SECS. --connect-timeout=SECS set the connect timeout to SECS. --read-timeout=SECS set the read timeout to SECS. -w, --wait=SECONDS wait SECONDS between retrievals. --waitretry=SECONDS wait 1..SECONDS between retries of a retrieval. --random-wait wait from 0...2*WAIT secs between retrievals. --no-proxy explicitly turn off proxy. -Q, --quota=NUMBER set retrieval quota to NUMBER. --bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host. --limit-rate=RATE limit download rate to RATE. --no-dns-cache disable caching DNS lookups. --restrict-file-names=OS restrict chars in file names to ones OS allows. --ignore-case ignore case when matching files/directories. --user=USER set both ftp and http user to USER. --password=PASS set both ftp and http password to PASS. Directories: -nd, --no-directories don't create directories. -x, --force-directories force creation of directories. -nH, --no-host-directories don't create host directories. --protocol-directories use protocol name in directories. -P, --directory-prefix=PREFIX save files to PREFIX/... --cut-dirs=NUMBER ignore NUMBER remote directory components. HTTP options: --http-user=USER set http user to USER. --http-password=PASS set http password to PASS. --no-cache disallow server-cached data. -E, --html-extension save HTML documents with `.html' extension. --ignore-length ignore `Content-Length' header field. --header=STRING insert STRING among the headers. --max-redirect maximum redirections allowed per page. --proxy-user=USER set USER as proxy username. --proxy-password=PASS set PASS as proxy password. --referer=URL include `Referer: URL' header in HTTP request. --save-headers save the HTTP headers to file. -U, --user-agent=AGENT identify as AGENT instead of Wget/VERSION. --no-http-keep-alive disable HTTP keep-alive (persistent connections). --no-cookies don't use cookies. --load-cookies=FILE load cookies from FILE before session. --save-cookies=FILE save cookies to FILE after session. --keep-session-cookies load and save session (non-permanent) cookies. --post-data=STRING use the POST method; send STRING as the data. --post-file=FILE use the POST method; send contents of FILE. --content-disposition honor the Content-Disposition header when choosing local file names (EXPERIMENTAL). --auth-no-challenge Send Basic HTTP authentication information without first waiting for the server's challenge. HTTPS (SSL/TLS) options: --secure-protocol=PR choose secure protocol, one of auto, SSLv2, SSLv3, and TLSv1. --no-check-certificate don't validate the server's certificate. --certificate=FILE client certificate file. --certificate-type=TYPE client certificate type, PEM or DER. --private-key=FILE private key file. --private-key-type=TYPE private key type, PEM or DER. --ca-certificate=FILE file with the bundle of CA's. --ca-directory=DIR directory where hash list of CA's is stored. --random-file=FILE file with random data for seeding the SSL PRNG. --egd-file=FILE file naming the EGD socket with random data. FTP options: --ftp-user=USER set ftp user to USER. --ftp-password=PASS set ftp password to PASS. --no-remove-listing don't remove `.listing' files. --no-glob turn off FTP file name globbing. --no-passive-ftp disable the "passive" transfer mode. --retr-symlinks when recursing, get linked-to files (not dir). --preserve-permissions preserve remote file permissions. Recursive download: -r, --recursive specify recursive download. -l, --level=NUMBER maximum recursion depth (inf or 0 for infinite). --delete-after delete files locally after downloading them. -k, --convert-links make links in downloaded HTML point to local files. -K, --backup-converted before converting file X, back up as X.orig. -m, --mirror shortcut for -N -r -l inf --no-remove-listing. -p, --page-requisites get all images, etc. needed to display HTML page. --strict-comments turn on strict (SGML) handling of HTML comments. Recursive accept/reject: -A, --accept=LIST comma-separated list of accepted extensions. -R, --reject=LIST comma-separated list of rejected extensions. -D, --domains=LIST comma-separated list of accepted domains. --exclude-domains=LIST comma-separated list of rejected domains. --follow-ftp follow FTP links from HTML documents. --follow-tags=LIST comma-separated list of followed HTML tags. --ignore-tags=LIST comma-separated list of ignored HTML tags. -H, --span-hosts go to foreign hosts when recursive. -L, --relative follow relative links only. -I, --include-directories=LIST list of allowed directories. -X, --exclude-directories=LIST list of excluded directories. -np, --no-parent don't ascend to the parent directory. Mail bug reports and suggestions to <bug-wget@gnu.org>.
UrlDownloadToFile 是AHK自带的一个命令。支持http和ftp,但不能提交数据等,但是速度很快。注意如果通过此命令执行网页代码比如php时间过长的话会自己断掉。所以可以使用WGET等。
UrlDownloadToVar 这是官方论坛上的一个函数,主要通过Dllcall下载数据到变量,不产生文件,缺点是较慢。下面是它的代码:
msgbox % UrlDownloadToVar(" ;调用演示 UrlDownloadToVar(URL, Proxy="", ProxyBypass="") { AutoTrim, Off hModule := DllCall("LoadLibrary", "str", "wininet.dll") If (Proxy != "") AccessType=3 Else AccessType=1 ;INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration ;INTERNET_OPEN_TYPE_DIRECT 1 // direct to net ;INTERNET_OPEN_TYPE_PROXY 3 // via named proxy ;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS io_hInternet := DllCall("wininet\InternetOpenA" , "str", "" ;lpszAgent , "uint", AccessType , "str", Proxy , "str", ProxyBypass , "uint", 0) ;dwFlags iou := DllCall("wininet\InternetOpenUrlA" , "uint", io_hInternet , "str", url , "str", "" ;lpszHeaders , "uint", 0 ;dwHeadersLength , "uint", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item , "uint", 0) ;dwContext If (ErrorLevel != 0 or iou = 0) { DllCall("FreeLibrary", "uint", hModule) return 0 } VarSetCapacity(buffer, 512, 0) VarSetCapacity(NumberOfBytesRead, 4, 0) Loop { irf := DllCall("wininet\InternetReadFile", "uint", iou, "uint", &buffer, "uint", 512, "uint", &NumberOfBytesRead) NOBR = 0 Loop 4 ; Build the integer by adding up its bytes. - ExtractInteger NOBR += *(&NumberOfBytesRead + A_Index-1) << 8*(A_Index-1) IfEqual, NOBR, 0, break ;BytesReadTotal += NOBR DllCall("lstrcpy", "str", buffer, "uint", &buffer) res = %res%%buffer% } StringTrimRight, res, res, 2 DllCall("wininet\InternetCloseHandle", "uint", iou) DllCall("wininet\InternetCloseHandle", "uint", io_hInternet) DllCall("FreeLibrary", "uint", hModule) AutoTrim, on return, res }
WinHttp.WinHttpRequest.5.1 是官方手册里面一个示例,通过COM下载数据到变量。
热键定义
亲,你了解热键吗?热键,又叫快速键或快捷键,指通过某些特定的按键、按键顺序或按键组合来完成一个操作,很多快捷键往往与如 Ctrl 键、Shift 键、Alt 键、Fn 键以及 Windows 平台下的 Windows 键和 Mac 机上的 Meta 键等配合使用。在Autohotkey中热键涵盖了键盘、鼠标、游戏手柄、遥控器以及特殊按键。不了解的同学可以在帮助页面内查看。
2. 使用方式
(1)可以通过“热键::”的方式,在脚本中直接定义,但是缺点是不可以灵活设置。例:
^!z:: Msgbox, 你按了Ctrl+Alt+z! Return
(2)可以用hotkey命令,Hotkey, 热键, 标签, 选项(开On/关Off/其他)。其中,热键和标签都可以是变量。例:
#Persistent ;一直运行 Hotkey, ^!z, my_label, On Return my_label: MsgBox, 你按了%A_ThisHotkey%! return
(3)可以发送到默认窗口或者指定窗口或控件。参见Send / SendRaw / SendInput / SendPlay / SendEvent ControlSend / ControlSendRaw
3. 热键组合方式
组合模式为【修饰符】+【按键修饰符】+【键】或者【键】&【键】。
修饰符:
~:激发热键时,不会屏蔽(被操作系统隐藏)热键中按键原有的功能。
$:通常只在脚本使用 Send 命令发送包含了热键自身的按键时才需要使用此符号, 此时可以避免触发它自己。
按键修饰符:
#(Win 徽标键) !(Alt) ^(Ctrl) +(Shift) <>(左右区域) <^>!(AltGr) UP(抬起)
示例:
;挂上键盘钩子 便于查看所有按下的键 #UseHook #InstallKeybdHook #InstallKeybdHook a:: /:: `:: F1:: ;辅助键 ~x:: ;Ctrl+x #q:: ;Win+q ^!+m:: ;Ctrl+Alt+Shift+m ^LButton:: ;Ctrl+鼠标左键 ^RButton:: ;Ctrl+鼠标右键 ^MButton:: ;Ctrl+鼠标中键 ^WheelDown:: ;Ctrl+鼠标滚轮下滑 ^WheelUp:: ;Ctrl+鼠标滚轮上滑 ^SC20:: ;Ctrl+d ^VK53:: ;Ctrl+s $#z:: ;Win+z 屏蔽send发送的此热键触发 a & b:: ;a+b MsgBox, 你按下了%A_ThisHotkey%! Return
提示,要监控所有按键操作的话,可以在脚本头加上:
#UseHook #InstallKeybdHook #InstallKeybdHook
然后双击autohotkey图标,按照下图或者Ctrl+K查看所有按键,还会有VK、SC值以及作用窗口:
本人写来单位自用的一个呼叫中心外呼的一个提取/提交数据工具,po出来仅供交流学习之用。
php接口(UTF-8):
<?php $c = new PDO( "sqlsrv:server=(local); Database = ", "username", "password", array(PDO::SQLSRV_ATTR_DIRECT_QUERY => true)); if (isset($_GET['str'])){ $str_obj = explode(";",urldecode($_GET['str'])); $str = $str_obj[0]; $token = substr($str,(strlen($str)-12),12); if ($token=="))))"){ if (isset($_GET['o'])){ if ($_GET['o']==1){ echo qt((substr($str,0,(strlen($str)-12)))); }else if ($_GET['o']==2){ echo get_rowcount((substr($str,0,(strlen($str)-12)))); } }else{ echo query((substr($str,0,(strlen($str)-12)))); } }else{ echo "Error token!"; } } function get_rowcount($query){ global $c; $stmt = $c->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); $stmt->execute(); global $rowcount; $rowcount=NULL; $rowcount = $stmt->rowCount(); return $rowcount; } function query($query){ global $c; $stmt = $c->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); $stmt->execute(); global $rowcount; $rowcount=NULL; $rowcount = $stmt->rowCount(); if(stripos($query, 'update') !== false){ return "UP".$rowcount; }elseif(stripos($query, 'delete') !== false){ return "DE".$rowcount; }elseif(stripos($query, 'insert') !== false){ return "IN".$rowcount; }else{ $content=NULL; if( $stmt->rowCount() == 0){ return ""; }else{ while ( $row = $stmt->fetch( PDO::FETCH_NUM ) ){ for($i = 0; $i < $stmt->columnCount(); $i++) { $type=gettype($row[$i]); if ($type=="object"){ $var=$row[$i]; $time=str_replace("T"," ",$var->format(DateTime::ISO8601)); $time=substr($time,0,19); $time=$time.".000"; $content=$content.$time.","; }else{ $ctmp=str_replace(",",",",$row[$i]); $content=$content.$ctmp.","; } } $content=$content."\n"; } $content=str_replace(",\n","\n",$content); return $content; } } } function qt($query){ global $c; $stmt = $c->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); $stmt->execute(); global $rowcount; $rowcount=NULL; $rowcount = $stmt->rowCount(); if(stripos($query, 'update') !== false){ return "UP".$rowcount; }elseif(stripos($query, 'delete') !== false){ return "DE".$rowcount; }elseif(stripos($query, 'insert') !== false){ return "IN".$rowcount; }else{ $content=NULL; if( $stmt->rowCount() == 0){ return "NO"; }else{ $a = $stmt->fetch( PDO::FETCH_ASSOC); $Fields = array_keys($a); global $titles; $titles=NULL; for($i = 0; $i < $stmt->columnCount(); $i++) { $name=iconv('GB2312','UTF-8',$Fields[$i]); $titles=$titles."$name,"; } $titles=$titles."\r\n"; $titles=str_replace(",\r\n","",$titles); $content = $titles."\r\n"; $stmt->execute(); while ( $row = $stmt->fetch( PDO::FETCH_NUM ) ){ for($i = 0; $i < $stmt->columnCount(); $i++) { $type=gettype($row[$i]); if ($type=="object"){ $var=$row[$i]; $time=str_replace("T"," ",$var->format(DateTime::ISO8601)); $time=substr($time,0,19); $time=$time.".000"; $content=$content.$time.","; }else{ $ctmp=str_replace(",",",",$row[$i]); $content=$content.$ctmp.","; } } $content=$content."\r\n"; } $content=str_replace(",\r\n","\r\n",$content); return $content; } } } ?>
数据库结构(三张表):
USE [Database1] GO DROP TABLE [dbo].[增值业务目标客户] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[增值业务目标客户]( [地区] [nvarchar](50) NOT NULL, [手机号码] [nvarchar](11) NOT NULL, [外呼业务] [nvarchar](50) NOT NULL, [语种] [nvarchar](50) NULL, [导入日期] [date] NULL, [ID] [int] IDENTITY(1,1) NOT NULL, [SID] [int] NULL, [工号] [nvarchar](50) NULL, CONSTRAINT [PK_增值业务] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO DROP TABLE [dbo].[增值业务目标任务] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[增值业务目标任务]( [地区] [nvarchar](50) NOT NULL, [外呼业务] [nvarchar](50) NOT NULL, [语种] [nvarchar](50) NOT NULL, [导入日期] [date] NOT NULL, [locked] [int] NULL, [id] [int] IDENTITY(1,1) NOT NULL ) ON [PRIMARY] GO ALTER TABLE [dbo].[增值业务数据提交] DROP CONSTRAINT [DF_增值业务数据提交_导入时间] GO ALTER TABLE [dbo].[增值业务数据提交] DROP CONSTRAINT [DF_增值业务数据提交_提交日期] GO ALTER TABLE [dbo].[增值业务数据提交] DROP CONSTRAINT [DF_增值业务数据提交_提交单位] GO DROP TABLE [dbo].[增值业务数据提交] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[增值业务数据提交]( [工号] [nvarchar](50) NULL, [姓名] [nvarchar](50) NULL, [外呼日期] [nvarchar](50) NULL, [业务类型] [nvarchar](50) NULL, [地州] [nvarchar](50) NULL, [语种] [nvarchar](50) NULL, [用户号码] [nvarchar](50) NULL, [接通情况] [nvarchar](50) NULL, [备注] [nvarchar](255) NULL, [质检结果] [nvarchar](50) NULL, [质检备注] [nvarchar](50) NULL, [质检人] [nvarchar](50) NULL, [质检时间] [datetime] NULL, [提交单位] [nvarchar](50) NULL, [提交日期] [date] NULL, [ID] [int] IDENTITY(1,1) NOT NULL, [LID] [int] NULL, [导入时间] [datetime] NULL ) ON [PRIMARY] GO ALTER TABLE [dbo].[增值业务数据提交] ADD CONSTRAINT [DF_增值业务数据提交_提交单位] DEFAULT (N'呼叫中心') FOR [提交单位] GO ALTER TABLE [dbo].[增值业务数据提交] ADD CONSTRAINT [DF_增值业务数据提交_提交日期] DEFAULT (CONVERT([date],getdate())) FOR [提交日期] GO ALTER TABLE [dbo].[增值业务数据提交] ADD CONSTRAINT [DF_增值业务数据提交_导入时间] DEFAULT (getdate()) FOR [导入时间] GO
Autohotkey代码(ANSI32):
#SingleInstance force ;单线程 FileEncoding, UTF-8 ;php pdo是utf-8的 FileInstall, 1.bmp, 1.bmp ;打电话的图标 FileInstall, 2.bmp, 2.bmp ;数据库配置信息 host = 135.230.71.1 api = http://%host%/sqlapi.php ;接口url oldtime = %A_TickCount% ;上次点击时间 ;检查连通性 if Not InStr(ping_info := ping(host),"正常") { MsgBox, 4112, 网络错误, % ping_info ExitApp } ;登陆界面 gui, login:add, text, x0 y0 w60 h20, 工号: gui, login:add, edit, x60 y0 w200 h20 vuser_id, gui, login:add, text, x0 y20 w60 h20, 姓名: gui, login:add, edit, x60 y20 w200 h20 vuser_name, gui, login:add, text, x0 y40 w60 h20, 语种: gui, login:add, DropDownList, x60 y40 w200 h60 vuser_lang, 汉语|英语 gui, login:add, button, x0 y60 w260 h20 glogin, 登陆 gui, login:show, , 坐席登陆 gui, login:+AlwaysOnTop Return login: Gui, login:Submit, NoHide if user_lang= { MsgBox, 4112, 错误, 未选择语种! Return } user_id := StrLen(user_id)=3 ? user_id : SubStr(user_id,1,3) ;只保留前三位 user_id := user_id "#" ;添加# ;检查工号是否在数据库内 if (get_1_result("SELECT count(*) FROM [Database1].[dbo].[用户表] where 工号='" user_id "'")>0) { gui, login:Destroy goto, show } Else { MsgBox, 4112, 错误, 没有此工号! } Return show: ;创建界面 Gui,main:Add,Text,x0 y3 w60 h12,当前任务: Gui,main:Font,Normal s8 c0x0 Bold,Verdana Gui,main:Add,Text,x60 y3 w260 h15 vtask_name, Gui,main:Font Gui,main:Add,Button,x320 y0 w40 h20 gchoose, 选择 Gui,main:Add,Text,x360 y3 w60 h12,任务信息: Gui,main:Font,Normal s8 Bold,Verdana Gui,main:Add,Text,x420 y3 w230 h15 vtask_info, Gui,main:Font Gui,main:Add,Text,x0 y23 w60 h12,联系电话: Gui,main:Font,Normal s9 c0x0 Bold,Verdana Gui,main:Add,Edit,x60 y20 w120 h20 ReadOnly 1 Border vphone, Gui,main:Font Gui,main:Add,Button,x180 y20 w50 h20 gcall,外呼 Gui,main:Add,Text,x230 y23 w60 h12,接通情况: Gui,main:Add,DropDownList,x290 y20 w200 vcalling_result, 通后挂断|无人接听|成功|关机|无法接通|少数民族|停机|用户考虑|空号|拒绝使用|老人小孩|不是机主 Gui,main:Add,Text,x0 y43 w60 h12,备注: Gui,main:Add,Edit,x60 y40 w430 h20 vnote, Gui,main:Add,ListView,x0 y60 w650 h108, 工号|姓名|外呼日期|业务类型|地州|语种|用户号码|接通情况|备注|质检结果|质检备注|质检人|质检时间|提交单位|提交日期|ID|LID|导入时间 Gui,main:Add,Button,x490 y20 w80 h40 gsubmit, 提交 Gui,main:Add,Button,x570 y20 w80 h40 gupdate, 修改 Gui,main:Show,w650 h170 , xx呼叫中心增值业务 Gui,main:+AlwaysOnTop Gui,main:Default Gosub, show_lv ;显示当日已拨打电话 Return submit: ;检查是否频繁提交 if newtime<> oldtime = %newtime% newtime = %A_TickCount% timediff := newtime-oldtime if timediff < 6000 { MsgBox, 4144, 提示, 请勿频繁提交,稍后再试! Return } ;获取表单 gui, main:submit, NoHide GuiControl, main:Choose, calling_result, 0 GuiControl, main:, note, calldate = %A_YYYY%-%A_MM%-%A_DD% ;插入 effect_row := get_rowcount("INSERT INTO [Database1].[dbo].[增值业务数据提交] ([工号],[姓名],[外呼日期],[业务类型],[语种],[地州],[用户号码],[接通情况],[备注],[LID])Values('" user_id "','" user_name "','" calldate "','" business "','" user_lang "','" area "','" phone "','" calling_result "','" note "','" id "')") ;获取刚才插入的id sid := get_1_result("select top 1 id from [Database1].[dbo].[增值业务数据提交] where 工号='" user_id "' and 外呼日期='" calldate "' and 用户号码='" phone "' order by id desc") ;在目标客户表里添加sid 即提交表里的id effect_row := get_rowcount("update [Database1].[dbo].[增值业务目标客户] set sid='" sid "' where id='" id "'") Gosub, show_lv goto, get_task Return update: ;获取单击点中的行 FocusedRowNumber := LV_GetNext(0, "F") if not FocusedRowNumber { MsgBox, 4144, 提示, 您未选择任何当已提交数据! Return } LV_GetText(e_id, FocusedRowNumber, 16) WinGetPos, x, y, , , xx呼叫中心增值业务 gui, main:Hide WinHide, xx呼叫中心增值业务 gui, 3:Destroy gui, 3:add, DropDownList, x0 y0 w200 h600 ve_calling_result, 通后挂断|无人接听|成功|关机|无法接通|少数民族|停机|用户考虑|空号|拒绝使用|老人小孩|不是机主 gui, 3:add, Button, x200 y0 w40 h20 gsubupdate,确定 gui, 3:show, x%x% y%y% , 修改接通情况 Return subupdate: GuiControlGet, e_calling_result ;排除没有选择的情况 if e_calling_result <> { gui, 3:Destroy gui, main:show ;更新 effect_row := get_rowcount("update [Database1].[dbo].[增值业务数据提交] set 接通情况='" e_calling_result "' where id='" e_id "'") } Return call: ;在拨打界面网页内直接输入号码并点击拨打 Clipboard = %phone% WinWait, 客服中心拨打界面 WinActivate, 客服中心拨打界面 error = 1 Loop, 1000 { ImageSearch, x, y, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, 1.bmp if !Errorlevel { x+=30 y+=5 MouseClick, Left, %x%, %y% loop, 20 { Send, {Delete}{BackSpace} } send, ^v error = 0 Break } Sleep, 50 } if error = 0 { Loop, 1000 { ImageSearch, x, y, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, 2.bmp if !Errorlevel { x+=10 y+=5 MouseClick, Left, %x%, %y% Break } Sleep, 50 } } Return show_lv: ;删除现有 LV_Delete() ;获取当日该工号外呼提交数据倒序前20项 result := get_result("select top 20 * from [Database1].[dbo].[增值业务数据提交] where 工号='" user_id "' and 外呼日期=cast(cast(getdate() as date) as nvarchar) and 接通情况 is not null order by id desc") ;按行分割 StringSplit, line, result, `n loop % line0 { ;赋值临时行 tmp_line = % line%A_index% if tmp_line<> ;不为空 { StringSplit, var, tmp_line, `, LV_Add("",var1,var2,var3,var4,var5,var6,var7,var8,var9,var10,var11,var12,var13,var14,var15,var16,var17,var18) } } ;自动调整列宽 LV_ModifyCol() Return choose: WinGetPos, x, y, , , xx呼叫中心增值业务 gui, main:Hide WinHide, xx呼叫中心增值业务 ;查询目标任务表中放行的目标客户表中的数据 result := get_result("SELECT [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar) FROM [Database1].[dbo].[增值业务目标客户] where [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar) in (SELECT [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar) FROM [Database1].[dbo].[增值业务目标任务] where locked=0 and [语种]='" user_lang "') group by [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar)") gui, 2:Destroy StringReplace, tasks, result, `n, |, All gui, 2:add, DropDownList, x0 y0 w300 h600 vctask, %tasks% gui, 2:add, Button, x300 y0 w40 h20 gsubchoose,确定 gui, 2:show, x%x% y%y% , 选择任务 Return subchoose: GuiControlGet, ctask gui, 2:Destroy gui, main:show GuiControl, main:, task_name, %ctask% ;显示任务信息,15间隔重复 SetTimer, show_task_info, 15000 oldtime = %A_TickCount% goto, get_task Return get_task: ;检查是否有该工号占有但是没有提交的数据 提交的数据会有sid if (get_1_result("SELECT count(*) FROM [Database1].[dbo].[增值业务目标客户] where [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar)='" ctask "' and 工号='" user_id "' and sid is null")<1) { ;占有一个 effect_row := get_rowcount("update [Database1].[dbo].[增值业务目标客户] set 工号='" user_id "' where id=(SELECT TOP 1 id FROM [Database1].[dbo].[增值业务目标客户] where [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar)='" ctask "' and 工号 is null)") } ;获取已占有数据量 tmp_rows := get_1_result("SELECT count(*) FROM [Database1].[dbo].[增值业务目标客户] where [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar)='" ctask "' and 工号='" user_id "' and sid is null") if tmp_rows > 0 { ;获取已占有数据 tmp_row := get_1_result("SELECT TOP 1 * FROM [Database1].[dbo].[增值业务目标客户] where [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar)='" ctask "' and 工号='" user_id "' and sid is null") ;分割数据 StringSplit, tmp_var, tmp_row, `, area := tmp_var1 phone := tmp_var2 business := tmp_var3 id := tmp_var6 GuiControl, main:, phone, %phone% } Else { MsgBox, 4112, 提示, 当前任务已空! } Return show_task_info: GuiControl, main:, task_info, % "当前任务总量:" get_1_result("SELECT count(*) FROM [Database1].[dbo].[增值业务目标客户] where [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar)='" ctask "'") Sleep, 2800 GuiControl, main:, task_info, % "当前任务剩余量:" get_1_result("SELECT count(*) FROM [Database1].[dbo].[增值业务目标客户] where [地区]+[外呼业务]+[语种]+cast([导入日期] as nvarchar)='" ctask "' and [工号] is null") Sleep, 2800 GuiControl, main:, task_info, % "您当日的外呼量:" get_1_result("select count(*) from [Database1].[dbo].[增值业务数据提交] where 工号='" user_id "' and 外呼日期=cast(getdate() as date) and 接通情况 is not null") Sleep, 2800 GuiControl, main:, task_info, % "您当日的外呼成功量:" get_1_result("select count(*) from [Database1].[dbo].[增值业务数据提交] where 工号='" user_id "' and 外呼日期=cast(getdate() as date) and 接通情况='成功' and (质检结果 is null or 质检结果='合格')") Sleep, 2800 GuiControl, main:, task_info, % "您当日的质检不合格量:" get_1_result("select count(*) from [Database1].[dbo].[增值业务数据提交] where 工号='" user_id "' and 外呼日期=cast(getdate() as date) and 接通情况='成功' and 质检结果='不合格'") Return ;ping检查网络函数 ping(ip){ RunWait, %ComSpec% /c ping -n 1 %ip% >%A_Temp%\ahk_ping.tmp, , Hide FileRead, content, %A_Temp%\ahk_ping.tmp StringReplace, content, content, `r, , All StringSplit, var, content, `n If content Contains 请求超时,Request timed out Return "请求超时" If content Contains 找不到主机,could not find host Return "找不到主机" If content Contains 无法访问目标主机,Destination host unreachable Return "无法访问目标主机" Else { 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") Return "正常 time:" time "ms" } } ;转码函数 urlencode(string,utf8:=1){ if (utf8=1 && A_IsUnicode<>1) { clip := ClipboardAll Clipboard = %string% Transform, string, Unicode Clipboard := clip } 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 } ;执行SQL并返回带标题的csv逗号分隔格式的结果的函数 get_result_with_colname(sql){ global api ;全局变量 URLDownloadToFile, % api "?str=" urlencode(sql "))))") "&o=1", %A_Temp%\res_with_colname.tmp FileRead, result, %A_Temp%\res_with_colname.tmp Return result } ;执行SQL并返回不带标题的csv逗号分隔格式的结果的函数 get_result(sql){ global api URLDownloadToFile, % api "?str=" urlencode(sql "))))"), %A_Temp%\res.tmp FileRead, result, %A_Temp%\res.tmp Return result } ;执行SQL并返回不带标题的csv逗号分隔格式的第一项结果的函数 get_1_result(sql){ global api URLDownloadToFile, % api "?str=" urlencode(sql "))))"), %A_Temp%\1res.tmp FileReadLine, result, %A_Temp%\1res.tmp, 1 Return result } ;执行SQL并返回影响结果数量的函数 get_rowcount(sql){ global api URLDownloadToFile, % api "?str=" urlencode(sql "))))") "&o=2", %A_Temp%\rowcount FileReadLine, result, %A_Temp%\rowcount.tmp, 1 Return result } loginGuiclose: mainGuiClose: ExitApp
ahk+php+sqlserver呼叫中心外呼数据提交工具案例.zip
应网友jem需求编写。
2014-09-23更新:
;多级字符输入菜单 by Thinkai @2014-09-23 ;EscapeChar = | ;菜单分隔符。不建议用中文字符,可能会导致显示错误。默认为“,” ;加载文件到数组 e := file_menu_2_obj("e.csv") Return ;写你的热键并调用函数 ::c:: #e:: create_menu(e) return file_menu_2_obj(file){ ;加载菜单文件到数组 if !file { MsgBox, 4112, 错误, 文件%file%不存在! return "Error:No file" } Else { FileRead, content, %file% Return csv2obj(content) } } csv2obj(string){ ;csv分隔符格式文本转object函数 obj := Object() ;初始化 StringReplace, string, string, `r, , All ;去回车 StringSplit, var, string, `n ;按行分割 Loop % var0 ;循环读取 { tmp_line := var%A_Index% ;赋值临时行 if tmp_line <> { tmp_obj := string_2_obj(tmp_line) ;文本转object函数 obj := combine_obj(tmp_obj,obj) ;合并数组 } } return obj } ;文本转object函数 string_2_obj(string){ ;全局分隔符 global EscapeChar if (!EscapeChar) EscapeChar = , obj := object() ;初始化 StringSplit, var, string, %EscapeChar% ;按分隔符分割 if var0 > 1 { ;下级成为上级的一个key Loop % var0-1 { index := var0-A_index index2 := index+1 obj%index% := object() obj%index%[var%index2%] := 0 } ;下级数组成为上级数组的一个key Loop % var0-2 { index := var0-A_index-1 index2 := index+1 obj%index%[var%index2%] := obj%index2% } ;定义根数组 obj[var1] := obj1 return obj } Else { ;只有一个值 obj[var1] := 0 return obj } } combine_obj(obj1,obj2){ ;联合数组函数 for k,v in obj1 { if (inobj(obj2,k)) ;两个数组有相同键 { if (isobject(obj1[k]) && isobject(obj2[k])) ;都是数组 合并 obj2[k] := combine_obj(obj1[k],obj2[k]) Else if (isobject(obj1[k]) && !isobject(obj2[k])) ; 数组2的相应键不是数组 赋值为数组1的对应键 obj2[k] := obj1[k] } Else { obj2[k] := v ;数组2没有该键 添加 } } Return obj2 } create_menu(obj,menu_name:="main",index:=1){ ;创建并显示菜单函数 keys := ["",1,2,3,4,5,6,7,8,9,0,"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"] ;创建主菜单 Menu, % menu_name, add, Menu, % menu_name, DeleteAll ;枚举数组 for k,v in obj { index += 1 ;如果该项是数组 if (IsObject(v)) { submenu_name = %menu_name%_%k% ;定义子菜单菜单名 ;预创建子菜单 不然报错 Menu, % submenu_name, add, Menu, % submenu_name, DeleteAll ;添加子菜单 Menu, % menu_name, add, % k ? "(&" keys[index] ") " k : "", :%submenu_name% create_menu(v,submenu_name) } Else { ;单独项 Menu, % menu_name, add, % k ? "(&" keys[index] ") " k : "", MenuHandler } } ;如果是根菜单,显示它 if menu_name = main menu,% menu_name, show } inobj(obj,key){ ;判断数组内是否有指定字符的键值或变量 for k,v in obj { if k = %key% return 1 } } MenuHandler: ;点击菜单句柄 ;转存剪切板 直接粘贴 支持中文 clip := ClipboardAll ;发送括号后面的内容 ;应jem要求加入父级 StringSplit, father, A_ThisMenu, _ father = % father%father0% current := RegExReplace(A_ThisMenuItem,"\(.*\)\s*(.*)","$1") result := father="main" ? current : father "/" current StringReplace, result, result, `r, , All Clipboard := result Send, ^v ;加等待时间 以防部分程序反应慢获取到原剪切板数据 Sleep,200 Clipboard := clip return
;七级字符输入菜单 by Thinkai @2014-09-13 EscapeChar = | ;菜单分隔符。不建议用中文字符,可能会导致显示错误。默认为“,” ;加载文件到数组 ;q := file_menu_2_obj("q.txt") ;w := file_menu_2_obj("w.txt") ;无文件情况的演示 example = ( 男|高|娘 男|高|娘|搞基 男|高|娘|异性恋 男|高|娘|双性恋 男|高|猛 男|高|猪肝 男|富|帅|就|是|拽 男|帅 男|矮 男|矬 男|穷 女|白|富|美|就|是|拽 女|富 女|美 女|黑 女|穷 女|丑 人妖 畜生 禽类 微生物 ) IfNotExist, e.txt { FileAppend, %example%, e.txt } ;演示段落完毕 e := file_menu_2_obj("e.txt") Return ;写你的热键并调用函数 ;::a:: ;#q:: ;调用函数 ;create_menu(q) ;return ;::b:: ;#w:: ;create_menu(w) ;return ::c:: #e:: create_menu(e) return file_menu_2_obj(file){ ;加载菜单文件到数组 if !file { MsgBox, 4112, 错误, 文件%file%不存在! return "Error:No file" } Else { FileRead, content, %file% Return menu_string_2_obj(content) } } menu_string_2_obj(string){ ;文本菜单项转为多维数组,请请定义好EscapeChar菜单分隔符 global EscapeChar if (!EscapeChar) EscapeChar = , out := Object() StringSplit, var, string, `n Loop % var0 { if (var%A_Index%) StringSplit, tmp, var%A_Index%, %EscapeChar% if (tmp%tmp0%) { if tmp0 = 1 { if (!inobj(out,var%A_index%)) out[var%A_index%] := "0" } Else if tmp0 = 2 { if (!IsObject(out[tmp1])) { out[tmp1] := Object() } if (!inobj(out[tmp1],tmp2)) out[tmp1][tmp2] := "0" } Else if tmp0 = 3 { if (!IsObject(out[tmp1])) { out[tmp1] := Object() } if (!IsObject(out[tmp1][tmp2])) { out[tmp1][tmp2] := Object() } if (!inobj(out[tmp1][tmp2],tmp3)) out[tmp1][tmp2][tmp3] := "0" } Else if tmp0 = 4 { if (!IsObject(out[tmp1])) { out[tmp1] := Object() } if (!IsObject(out[tmp1][tmp2])) { out[tmp1][tmp2] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3])) { out[tmp1][tmp2][tmp3] := Object() } if (!inobj(out[tmp1][tmp2][tmp3],tmp4)) out[tmp1][tmp2][tmp3][tmp4] := "0" } Else if tmp0 = 5 { if (!IsObject(out[tmp1])) { out[tmp1] := Object() } if (!IsObject(out[tmp1][tmp2])) { out[tmp1][tmp2] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3])) { out[tmp1][tmp2][tmp3] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3][tmp4])) { out[tmp1][tmp2][tmp3][tmp4] := Object() } if (!inobj(out[tmp1][tmp2][tmp3][tmp4],tmp5)) out[tmp1][tmp2][tmp3][tmp4][tmp5] := "0" } Else if tmp0 = 6 { if (!IsObject(out[tmp1])) { out[tmp1] := Object() } if (!IsObject(out[tmp1][tmp2])) { out[tmp1][tmp2] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3])) { out[tmp1][tmp2][tmp3] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3][tmp4])) { out[tmp1][tmp2][tmp3][tmp4] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3][tmp4][tmp5])) { out[tmp1][tmp2][tmp3][tmp4][tmp5] := Object() } if (!inobj(out[tmp1][tmp2][tmp3][tmp4][tmp5],tmp6)) out[tmp1][tmp2][tmp3][tmp4][tmp5][tmp6] := "0" } Else if tmp0 = 7 { if (!IsObject(out[tmp1])) { out[tmp1] := Object() } if (!IsObject(out[tmp1][tmp2])) { out[tmp1][tmp2] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3])) { out[tmp1][tmp2][tmp3] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3][tmp4])) { out[tmp1][tmp2][tmp3][tmp4] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3][tmp4][tmp5])) { out[tmp1][tmp2][tmp3][tmp4][tmp5] := Object() } if (!IsObject(out[tmp1][tmp2][tmp3][tmp4][tmp5][tmp6])) { out[tmp1][tmp2][tmp3][tmp4][tmp5][tmp6] := Object() } if (!inobj(out[tmp1][tmp2][tmp3][tmp4][tmp5][tmp6],tmp7)) out[tmp1][tmp2][tmp3][tmp4][tmp5][tmp6][tmp7] := "0" } } } Return out } MsgBox % A_IsUnicode create_menu(out){ ;创建并显示菜单函数,传入菜单数组,菜单点击到MenuHandler标签 keys := ["",1,2,3,4,5,6,7,8,9,0,"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"] Menu, main, add, Menu, main,DeleteAll index1 = 1 for k,v in out { index1 += 1 if (IsObject(v)) { Menu, main_%k%, add, Menu, main_%k%, DeleteAll Menu, main, add, % k ? "(&" keys[index1] ") " k : "", :main_%k% subkey1 := k index2 = 1 for k,v in out[subkey1] { index2 += 1 if (IsObject(v)) { Menu, main_%subkey1%_%k%, add, Menu, main_%subkey1%_%k%, DeleteAll Menu, main_%subkey1%, add, % k ? "(&" keys[index2] ") " k : "", :main_%subkey1%_%k% subkey2 := k index3 = 1 for k,v in out[subkey1][subkey2] { index3 += 1 if (IsObject(v)) { Menu, main_%subkey1%_%subkey2%_%k%, add, Menu, main_%subkey1%_%subkey2%_%k%, DeleteAll Menu, main_%subkey1%_%subkey2%, add, % k ? "(&" keys[index3] ") " k : "", :main_%subkey1%_%subkey2%_%k% subkey3 := k index4 = 1 for k,v in out[subkey1][subkey2][subkey3] { index4 += 1 if (IsObject(v)) { Menu, main_%subkey1%_%subkey2%_%subkey3%_%k%, add, Menu, main_%subkey1%_%subkey2%_%subkey3%_%k%, DeleteAll Menu, main_%subkey1%_%subkey2%_%subkey3%, add, % k ? "(&" keys[index4] ") " k : "", :main_%subkey1%_%subkey2%_%subkey3%_%k% subkey4 := k index5 = 1 for k,v in out[subkey1][subkey2][subkey3][subkey4] { index5 += 1 if (IsObject(v)) { Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%k%, add, Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%k%, DeleteAll Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%, add, % k ? "(&" keys[index5] ") " k : "", :main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%k% subkey5 := k index6 = 1 for k,v in out[subkey1][subkey2][subkey3][subkey4][subkey5] { index6 += 1 if (IsObject(v)) { Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%subkey5%_%k%, add, Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%subkey5%_%k%, DeleteAll Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%subkey5%, add, % k ? "(&" keys[index6] ") " k : "", :main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%subkey5%_%k% subkey6 := k index7 = 1 for k,v in out[subkey1][subkey2][subkey3][subkey4][subkey5][subkey6] { index7 += 1 Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%subkey5%_%subkey6%, add, % k ? "(&" keys[index7] ") " k : "", MenuHandler } } Else { Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%_%subkey5%, add, % k ? "(&" keys[index6] ") " k : "", MenuHandler } } } Else { Menu, main_%subkey1%_%subkey2%_%subkey3%_%subkey4%, add, % k ? "(&" keys[index5] ") " k : "", MenuHandler } } } Else { Menu, main_%subkey1%_%subkey2%_%subkey3%, add, % k ? "(&" keys[index4] ") " k : "", MenuHandler } } } Else { Menu, main_%subkey1%_%subkey2%, add, % k ? "(&" keys[index3] ") " k : "", MenuHandler } } } Else { Menu, main_%subkey1%, add, % k ? "(&" keys[index2] ") " k : "", MenuHandler } } } Else { Menu, main, add, % k ? "(&" keys[index1] ") " k : "", MenuHandler } } menu, main, show } inobj(obj,key){ ;判断数组内是否有指定字符的键值或变量 var = 0 for k,v in obj { if if (k=key and v=key) var = 3 Else if (k=key) var := var>1 ? var : 1 Else if (v=key) var := var>2 ? var : 2 } Return var } MenuHandler: ;转存剪切板 直接粘贴 支持中文 clip := ClipboardAll ;发送括号后面的内容 Clipboard := RegExReplace(A_ThisMenuItem,"\(.*\)\s*(.*)","$1") Send, ^v Sleep,200 Clipboard := clip return
应网友小古要求写的,这里仅贴出最终版
功能:
1、可以按照自己的查询语句执行
2、自适应显示内容和上传图片
3、可以编辑可插入内容(屏蔽包含“id”字段)
4、点击图片保存图片
5、保存数据库信息方便下次使用
6、兼容SQL SERVER 2000/2005/2008/2012/2014各版本 采用ADO连接方式
程序下载:
;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
之前写一个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")
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 ;杀进程 } } }
49 queries in 1.630 seconds |