Lisp+DWX 之四 Windows API 函数调用示例

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/yxp_xa/article/details/73349587

Lisp 调用 API 函数示例,包括:进程与线程类,控件与消息类、文件及处理类、硬件与系统类、文本和字体类、Windows消息类等。
API 函数随着测试在不断增加中,如有错误,敬请指正。

创建对象和全局变量

(vl-load-com)
(setq *APP (vlax-get-acad-object)
    *DOC (vla-get-ActiveDocument *APP)
    hCAD (vla-get-hwnd *APP)
    hDOC (vla-get-hwnd *DOC)
    wrap (vlax-create-object "DynamicWrapperX"))

1 控件和消息类

;;1.1 获得桌面窗口句柄
(vlax-invoke wrap 'Register "user32" "GetDesktopWindow" "r=m")
(setq hDesk (vlax-invoke wrap 'GetDesktopWindow))


;;1.2 延迟函数,该函数运行时间较长时,主程序会陷入无响应状态,应该用多线程处理一下。
(vlax-invoke wrap 'Register "kernel32" "Sleep" "i=m")
(vlax-invoke wrap 'Sleep 5000)


;;1.3 判断一个窗口句柄是否有效,返回 0 或非 0
(vlax-invoke wrap 'Register "user32" "IsWindow" "i=h" "r=m")
(vlax-invoke wrap 'IsWindow hDOC)


;;1.4 判断一个窗口是否为 Unicode 窗口。这意味着窗口为所有基于文本的消息都接收 Unicode 文字
(vlax-invoke wrap 'Register "user32" "IsWindowUnicode" "i=h" "r=m")
(vlax-invoke wrap 'IsWindowUnicode hDOC)
;;如是 Unicode 窗口则返回非零值,如是 ANSI 窗口则返回零


;;1.5 判断窗口是否可见
(vlax-invoke wrap 'Register "user32" "IsWindowVisible" "i=h" "r=m")
(vlax-invoke wrap 'IsWindowVisible hDOC)


;;1.5 弹出一个消息窗口
(vlax-invoke wrap 'Register "user32" "MessageBoxW" "i=hwwu" "r=m")
(vlax-invoke wrap 'MessageBoxW hCAD "你好, 这是我的第一个API窗口" "啊哈" 1)


;;1.6 在指定的窗口里允许或禁止所有鼠标及键盘输入
(vlax-invoke wrap 'Register "user32" "EnableWindow" "i=hm" "r=m")
(vlax-invoke wrap 'EnableWindow hCAD 1) ;;0为禁止,非0允许


;;1.7 判断窗口是否处于活动状态(可输入)
(vlax-invoke wrap 'Register "user32" "IsWindowEnabled" "i=h" "r=m")
(vlax-invoke wrap 'IsWindowEnabled hCAD) 


;;1.8 最小化指定的窗口
(vlax-invoke wrap 'Register "user32" "CloseWindow" "i=h" "r=m")
(vlax-invoke wrap 'CloseWindow hDOC)


;;1.9 判断窗口是否已最小化
(vlax-invoke wrap 'Register "user32" "IsIconic" "i=h" "r=m")
(vlax-invoke wrap 'IsIconic hDOC)


;;1.10 恢复一个最小化的程序(并不是最大化),并将其激活
(vlax-invoke wrap 'Register "user32" "OpenIcon" "i=h" "r=m")
(vlax-invoke wrap 'OpenIcon hDOC)


;;1.11 判断窗口是否最大化
(vlax-invoke wrap 'Register "user32" "IsZoomed" "i=h" "r=m")
(vlax-invoke wrap 'IsZoomed hDOC)


;;1.12 返回包含了指定点的窗口的句柄。忽略屏蔽、隐藏以及透明窗口
(vlax-invoke wrap 'Register "user32" "WindowFromPoint" "i=mm" "r=m")
(setq hnewWin (vlax-invoke wrap 'WindowFromPoint 200 200))
;;包含了指定点的窗口的句柄。如指定的点处没有窗口存在,则返回零


;;1.13 控制窗口的可见性
(vlax-invoke wrap 'Register "user32" "ShowWindow" "i=hm" "r=m")
(setq hnewWin (vlax-invoke wrap 'ShowWindow hDOC 2))
;参数:
;   1   隐藏窗口,活动状态给令一个窗口
;   2   最小化窗口,并将其激活
;   3   最大化窗口,并将其激活
;   4   用最近的大小和位置显示一个窗口,同时不改变活动窗口
;   5   用当前的大小和位置显示一个窗口,同时令其进入活动状态
;   6   最小化窗口,活动状态给令一个窗口
;   7   最小化一个窗口,同时不改变活动窗口
;   8   用当前的大小和位置显示一个窗口,不改变活动窗口
;   9   用原来的大小和位置显示一个窗口,同时令其进入活动状态


;;1.14 调查窗口标题文字或控件内容的长短
(vlax-invoke wrap 'Register "user32" "GetWindowTextLength" "i=h" "r=m")
(vlax-invoke wrap 'GetWindowTextLength hCAD)


;;1.15 获取窗口的标题文字或控件的内容
(vlax-invoke wrap 'Register "user32" "GetWindowTextW" "i=hpm" "r=m")
(setq ss (vlax-invoke wrap 'Space 256 " "))
(setq pStr (vlax-invoke wrap 'StrPtr ss))
(vlax-invoke wrap 'GetWindowTextW hDOC pStr 256)
(vlax-invoke wrap 'strget pStr)


;;1.16 设置窗口的标题文字或控件的内容
(vlax-invoke wrap 'Register "user32" "SetWindowTextW" "i=hw" "r=m")
(vlax-invoke wrap 'SetWindowTextW hDOC "好大一只兔子")


;;1.17 为指定的窗口取得类名
(vlax-invoke wrap 'Register "user32" "GetClassNameW" "i=hpm" "r=m")
(setq ss (vlax-invoke wrap 'Space 256 " ")
    pStr (vlax-invoke wrap 'StrPtr ss))
(vlax-invoke wrap 'GetClassNameW hDOC pStr 256)
(vlax-invoke wrap 'strget pStr)


;;1.18 获取一个记事本窗口的句柄
(startapp "notepad.exe")
(vlax-invoke wrap 'Register "user32" "FindWindowExW" "i=hhhw" "r=m")
(setq Jsb (vlax-invoke wrap 'FindWindowExW 0 hCAD 0 "无标题 - 记事本"))


;;1.19 闪烁显示指定窗口,引起用户注意(例如,记事本窗口)
(vlax-invoke wrap 'Register "user32" "FlashWindow" "i=hm" "r=m")
(vlax-invoke wrap 'FlashWindow Jsb 1)
;; 1 闪烁窗口标题和任务栏图标, 0 仅闪烁任务栏图标


;;1.20 让窗口总在最前(例如,记事本窗口)
(vlax-invoke wrap 'Register "user32" "SetWindowPos" "i=hmmmmmm" "r=m")
(vlax-invoke wrap 'SetWindowPos Jsb -1 0 0 0 0 3)
;;参数 2:
;;      1   将窗口置于窗口列表底部
;;      0   将窗口置于Z序列的顶部;Z序列代表在分级结构中,窗口针对一个给定级别的窗口显示的顺序
;;      -1  将窗口置于列表顶部,并位于任何最顶部窗口的前面(类似 QQ 界面)
;;      -2  将窗口置于列表顶部,并位于任何最顶部窗口的后面(正常)
;;参数 34: 窗口坐标 x y
;;参数 56: 窗口大小 w h
;;参数 7: 
;       1 保持当前大小
;       2 保持当前位置
;       4 保持窗口在列表的当前位置
;       8 窗口不自动重画
;       16 不激活窗口
;       32 围绕窗口画一个框
;       64 显示窗口

2 硬件与系统类

;;2.1 判断系统存在哪些驱动器
(vlax-invoke DWX 'Register "kernel32" "GetLogicalDrives" "r=l")
(vlax-invoke DWX 'GetLogicalDrives)
;;位 0 表示 A:  如果只存在 C、D 驱动器,则应该返回 12 = 1100(2)


;;2.2 用于生成简单的声音,参数为频率(37-32767)和持续时间(毫秒)
(vlax-invoke DWX 'Register "kernel32" "Beep" "i=mm" "r=m")
(vlax-invoke DWX 'Beep 800 1000)


;;2.3 获取自windows启动以来经历的时间长度(毫秒)
(vlax-invoke DWX 'Register "kernel32" "GetTickCount" "r=m")
(vlax-invoke DWX 'GetTickCount)


;;2.4 取得当前线程的地方ID
(vlax-invoke DWX 'Register "kernel32" "GetThreadLocale" "r=m")
(vlax-invoke DWX 'GetThreadLocale)


;;2.5 判断插入符光标的闪烁频率
(vlax-invoke DWX 'Register "user32" "GetCaretBlinkTime" "r=m")
(vlax-invoke DWX 'GetCaretBlinkTime)


;;2.6 取得这台计算机的名称
(vlax-invoke DWX 'Register "kernel32" "GetComputerNameEx" "i=pm" "r=m")
(setq ss (vlax-invoke DWX 'Space 32 " ")
    pStr (vlax-invoke DWX 'StrPtr ss))
(vlax-invoke DWX 'GetComputerNameEx pStr 32) ;;返回 0
(vlax-invoke DWX 'strget pStr)


;;2.7 得到鼠标坐标
;;API声明,一个 "m" 占 8 个字节,用来接收 xy 坐标,宽度应该够了
(vlax-invoke DWX 'Register "user32" "GetCursorPos" "i=m" "r=m") 
(setq pt (vlax-invoke DWX 'MemAlloc 16 1)) 
(vlax-invoke DWX 'GetCursorPos pt) 
(setq x (vlax-invoke DWX 'NumGet pt 0 "l")) 
(setq y (vlax-invoke DWX 'NumGet pt 4 "l")) 
(vlax-invoke DWX 'MemFree pt) ;;释放内存


;;2.8 模拟按键
(vlax-invoke DWX 'Register "user32" "keybd_event" "i=llll" "r=m")
(vlax-invoke DWX 'SetWindowPos Jsb -1 10 10 500 400 64)
(vlax-invoke DWX 'keybd_event 65 0 0 0) ;;"A"
(vlax-invoke DWX 'keybd_event 13 0 0 0) ;;回车

;;2.9 模拟按下 Ctrl + V
(vlax-invoke DWX 'keybd_event 17 0 0 0)
(vlax-invoke DWX 'keybd_event 86 0 0 0)
(vlax-invoke DWX 'keybd_event 8 0 2 0)
(vlax-invoke DWX 'keybd_event 17 0 2 0)

3 设备与场景类

;;3.1 创建一个由点X1,Y1和X2,Y2描述的矩形区域
(vlax-invoke DWX 'Register "gdi32" "CreateRectRgn" "i=mmmm" "r=m")
(setq hREC (vlax-invoke DWX 'CreateRectRgn 10 10 200 200))


;;3.2 创建一个刷子
(vlax-invoke DWX 'Register "gdi32" "CreateSolidBrush" "i=m" "r=m")
(setq hBuh (vlax-invoke DWX 'CreateSolidBrush 800))


;;3.3 用指定的刷子填充一个矩形
(vlax-invoke DWX 'Register "user32" "FillRect" "i=hhh" "r=m")
(setq hFlr (vlax-invoke DWX 'FillRect hCAD hREC hBuh))


;;3.4 为专门设备创建设备场景
(vlax-invoke DWX 'Register "gdi32:CreateDCA" "CreateDCBynum" "i=sssm" "r=m")
(setq hDsy (vlax-invoke DWX 'CreateDCBynum "DISPLAY" "" "" 0))


;;3.5 靠近屏幕左上角画一个矩形
(vlax-invoke DWX 'Register "gdi32" "Rectangle" "i=hmmmm" "r=m")
(setq hRct (vlax-invoke DWX 'Rectangle hDsy 5 5 200 200))

4 文件操作类

;;4.1 打开一个文件,返回文件的指针
(vlax-invoke DWX 'Register "kernel32" "CreateFileW" "i=wllplll" "r=l")
(setq fileName "d:\\aa.bin")
(setq FileID (vlax-invoke DWX 'CreateFileW fileName 1 1 0 3 128 0))


;;4.2 根据文件的指针,将文件读入内存
(vlax-invoke DWX 'Register "kernel32" "ReadFile" "i=pplpl" "r=l")
(setq FileSize (vl-file-size fileName))
(setq FileBuff (vlax-invoke DWX 'MemAlloc FileSize 1)) ;;分配一块内存,存储文件内容
(setq FineNumber (vlax-invoke DWX 'MemAlloc 4 1))  ;;返回一个长整型数字的指针,获取实际读入的大小
(vlax-invoke DWX 'ReadFile FileID FileBuff FileSize FineNumber 0) ;;读入文件到 FileBuff
(setq RealSize (vlax-invoke DWX 'NumGet FineNumber))  ;;文件读入的实际大小
(vlax-invoke DWX 'MemRead FileBuff RealSize)  ;;从内存读入文件内容
(vlax-invoke DWX 'MemFree FileBuff)  ;;记得释放内存


;;4.3 将内存数据写入一个文件
;;参数 文件指针,内存指针,写入字节数,实际写入字节(接收),
(vlax-invoke DWX 'Register "kernel32" "WriteFile" "i=pplpl" "r=l")
;;将指针指向的二进制保存到文件,参数为:文件全路径,指针,文件的长度(字节)
;;(save_mem_hex "d:\\abc.bin" Pn Ln)
(defun save_mem_hex(file p n / FileID tf FileSize FineNumber)
    (vlax-invoke DWX 'Register "kernel32" "CreateFileW" "i=wllplll" "r=l")
    (vlax-invoke DWX 'Register "kernel32" "WriteFile" "i=pplpl" "r=l")
    (vlax-invoke DWX 'Register "kernel32" "CloseHandle" "i=p" "r=l")
    (setq FileID (vlax-invoke DWX 'CreateFileW file 1073741824 1 0 4 128 0))
    (setq FineNumber (vlax-invoke DWX 'MemAlloc 4 1))
    (vlax-invoke DWX 'WriteFile FileID p n FineNumber 0)
    (vlax-invoke DWX 'CloseHandle FileID)
    (vlax-invoke DWX 'NumGet FineNumber)
)


;;4.4 关闭文件
(vlax-invoke DWX 'Register "kernel32" "CloseHandle" "i=p" "r=l")
(vlax-invoke DWX 'CloseHandle FileID)


;;4.5 以二进制读入一个文件到 txt,再将 txt 写入新文件
(defun test()
(setq DWX (vlax-create-object "DynamicWrapperX"))
(vlax-invoke DWX 'Register "kernel32" "CreateFileW" "i=wllplll" "r=l")
(vlax-invoke DWX 'Register "kernel32" "ReadFile" "i=pplpl" "r=l")
(vlax-invoke DWX 'Register "kernel32" "WriteFile" "i=pplpl" "r=l")
(vlax-invoke DWX 'Register "kernel32" "CloseHandle" "i=p" "r=l")
(setq fileName "d:\\aa.bin")
(setq FileID (vlax-invoke DWX 'CreateFileW fileName 1 1 0 3 128 0))
(setq FileSize (vl-file-size fileName))
(setq FileBuff (vlax-invoke DWX 'MemAlloc FileSize 1))
(setq FineNumber (vlax-invoke DWX 'MemAlloc 4 1))
(vlax-invoke DWX 'ReadFile FileID FileBuff FileSize FineNumber 0)
(vlax-invoke DWX 'CloseHandle FileID)
(setq RealSize (vlax-invoke DWX 'NumGet FineNumber))
(setq txt (vlax-invoke DWX 'MemRead FileBuff RealSize))
;;保存文件
(setq NewFileID (vlax-invoke DWX 'CreateFileW "d:\\ab.bin" 1073741824 1 0 4 128 0))
(setq Prtxt (vlax-invoke DWX 'StrPtr txt "s"))
(setq savetxt (vlax-invoke DWX 'WriteFile NewFileID Prtxt RealSize FineNumber 0))
(vlax-invoke DWX 'CloseHandle NewFileID)
(vlax-invoke DWX 'MemFree FileBuff)
(vlax-release-object DWX)
savetxt
)


;;4.6 以二进制模式打开一个文件(该函数只接受 ANSI 编码文件名,不支持中文)
(vlax-invoke DWX 'Register "kernel32" "_lopen" "i=sl" "r=l")
(setq fileName "d:\\aa.bin")
(setq FileIDs (vlax-invoke DWX '_lopen fileName 0))


;;4.7 根据文件的指针,将文件读入内存,返回实际读入的文件大小
(vlax-invoke DWX 'Register "kernel32" "_lread" "i=ppl" "r=l")
(setq FileSize (vl-file-size fileName))
(setq FileBuffs (vlax-invoke DWX 'MemAlloc FileSize 1)) ;;分配一块内存
(setq FRSize (vlax-invoke DWX '_lread FileIDs FileBuffs FileSize))  ;;读文件到内存
(vlax-invoke DWX 'MemRead FileBuffs FRSize)  ;;读内存
(vlax-invoke DWX '_lclose FileIDs)


;;4.8 创建一个文件,用于读写
;; 0——文件能够读写; 1——创建只读文件; 2——创建隐藏文件; 3——创建系统文件
(vlax-invoke DWX 'Register "kernel32" "_lcreat" "i=sl" "r=l")
(setq Fp (vlax-invoke DWX '_lcreat "d:\\ab.bin" 0))


;;4.9 内存块写入文件, 参数1-文件指针,参数2-内存块指针,参数3-要写入的字节数
(vlax-invoke DWX 'Register "kernel32" "_lwrite" "i=ppl" "r=l")
(setq txt "Hello DWX!"
    Pstr (vlax-invoke DWX 'StrPtr txt "s")) ;;纯英文用 s
(vlax-invoke DWX '_lwrite Fp Pstr 10)


;;4.10 关闭文件
(vlax-invoke DWX 'Register "kernel32" "_lclose" "i=p" "r=l")
(vlax-invoke DWX '_lclose Fp)

5 窗口与菜单类

;;5.1 创建一个窗口顶级菜单
(vlax-invoke DWX 'Register "user32" "CreateMenu" "r=l")
(setq PtMenu (vlax-invoke DWX 'CreateMenu))


;;5.2 获取一个窗口的菜单句柄
(vlax-invoke DWX 'Register "user32" "GetMenu" "i=p" "r=m")
(setq PtCad (vlax-invoke DWX 'GetMenu hCAD))


;;5.3 取得指定窗口的系统菜单的句柄
(vlax-invoke DWX 'Register "user32" "GetSystemMenu" "i=pl" "r=m")
(setq Pcadsys (vlax-invoke DWX 'GetSystemMenu hCAD 0))


;;5.4 判断指定的句柄是否为一个菜单的句柄, 返回值: 1=是 0=否
(vlax-invoke DWX 'Register "user32" "IsMenu" "i=p" "r=l")
(vlax-invoke DWX 'IsMenu PtCad)


;;5.5 返回位于菜单中指定位置处的条目的菜单ID
;;如条目属于一个弹出式菜单,就返回-1;如指定的条目属于一个分隔符则返回0
(vlax-invoke DWX 'Register "user32" "GetMenuItemID" "i=pl" "r=l")
(setq PtId (vlax-invoke DWX 'GetMenuItemID PtCad 1))


;;5.6 返回菜单中条目(菜单项)的数量
(vlax-invoke DWX 'Register "user32" "GetMenuItemCount" "i=p" "r=l")
(vlax-invoke DWX 'GetMenuItemCount PtCad)
(vlax-invoke DWX 'GetMenuItemCount Pcadsys)


;;5.7 获得指定菜单条目的字符串
(vlax-invoke DWX 'Register "user32" "GetMenuStringW" "i=plpll" "r=l")
(setq Ptxt (vlax-invoke DWX 'MemAlloc 20 1))
;(setq nPtxt (vlax-invoke DWX 'MemAlloc 20 1))
;(vlax-invoke DWX 'NumPut 0 Ptxt 0 "l")
(setq PtTn (vlax-invoke DWX 'GetMenuStringW PtCad 1 Ptxt 20 1024))
(vlax-invoke DWX 'MemRead Ptxt PtTn) ;;返回 16 进制字符
(vlax-invoke DWX 'StrGet Ptxt "s")   ;;返回 ANSI 字符(如果是中文则乱码)
(vlax-invoke DWX 'StrGet Ptxt "w")   ;;返回 Unicode 字符
(setq PtTn (vlax-invoke DWX 'GetMenuStringW Pcadsys 1 Ptxt 20 1024));;窗口最小化/最大化菜单



;;5.8 在指定的菜单里添加一个菜单项
(vlax-invoke DWX 'Register "user32" "AppendMenuW" "i=pllw" "r=l")
(setq numb (vlax-invoke DWX 'NumPut 0 "l"))
(vlax-invoke DWX 'AppendMenuW PtCad 0 numb "装B专用版本")
(vlax-invoke DWX 'NumGet numb1 0 "l")


;;5.9 以下代码示例了在 CAD 菜单中插入一个下拉式菜单
;;测试版本 AutoCAD 2012
(defun test()
    (vlax-invoke DWX 'Register "user32" "CreateMenu" "r=l")
    (vlax-invoke DWX 'Register "user32" "AppendMenuW" "i=plpw" "r=l")
    (vlax-invoke DWX 'Register "user32" "GetMenu" "i=p" "r=p")
    (setq PtCad (vlax-invoke DWX 'GetMenu hCAD))
    (setq PtMenu (vlax-invoke DWX 'CreateMenu))
    (setq nP1 (vlax-invoke dwx 'MemAlloc 4 1))
    (setq nP2 (vlax-invoke dwx 'MemAlloc 4 1))
    (vlax-invoke DWX 'AppendMenuW PtMenu 0 nP1 "菜单一") ;;0 表示新建
    (vlax-invoke DWX 'AppendMenuW PtMenu 0 nP2 "菜单二")
    (vlax-invoke DWX 'AppendMenuW PtCad 16 PtMenu "装B专用版本") ;;16 表示添加pup
    (vlax-invoke dwx 'NumGet nP1 0 "l")
)

6 Windows 进程类

;;6.1 获取当前进程的 PID
(vlax-invoke DWX 'Register "Kernel32" "GetCurrentProcessId" "r=l")
(vlax-invoke dwx 'GetCurrentProcessId)


;;6.2 获取当前进程的全路径
(vlax-invoke DWX 'Register "Kernel32" "GetModuleFileName" "i=lll" "r=l")
(setq Pat (vlax-invoke dwx 'MemAlloc 256 1)) ;;进程名
(vlax-invoke dwx 'GetModuleFileName 0 Pat 260)
(vlax-invoke dwx 'StrGet Pat "s")


;;6.3 获取 windows 正在运行的进程 PID 表
(vlax-invoke DWX 'Register "PSAPI.DLL" "EnumProcesses" "i=mll" "r=l")
(setq P1 (vlax-invoke dwx 'MemAlloc 20000 1)) ;;接收 PID 数组
(setq P2 (vlax-invoke dwx 'MemAlloc 4 1))     ;;接收到的字节
(vlax-invoke DWX 'EnumProcesses P1 5000 P2)
(setq m (vlax-invoke dwx 'NumGet P2 0 "l"))
(setq n 0 Lpid nil)  ;;提取 PID 表
(repeat (/ m 4)
    (setq Lpid (cons (vlax-invoke dwx 'NumGet P1 n "l") Lpid)
        n (+ n 4))
)
(reverse Lpid)

猜你喜欢

转载自blog.csdn.net/yxp_xa/article/details/73349587