函数,类库收藏
调整显示器亮度
原文链接:https://www.autohotkey.com/board/topic/19754-get-info-from-context-menu/
; ===============================================================================================================================
; AutoHotkey wrapper for Monitor Configuration API Functions
;
; Author ....: jNizM
; Released ..: 2015-05-26
; Modified ..: 2020-07-29
; Github ....: https://github.com/jNizM/Class_Monitor
; Forum .....: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62955
; ===============================================================================================================================
class Monitor
{
; ===== PUBLIC METHODS ======================================================================================================
GetBrightness(Display := "")
{
if (hMonitor := this.GetMonitorHandle(Display))
{
PhysicalMonitors := this.GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor)
hPhysicalMonitor := this.GetPhysicalMonitorsFromHMONITOR(hMonitor, PhysicalMonitors, PHYSICAL_MONITOR)
Brightness := this.GetMonitorBrightness(hPhysicalMonitor)
this.DestroyPhysicalMonitors(PhysicalMonitors, PHYSICAL_MONITOR)
return Brightness
}
return false
}
GetContrast(Display := "")
{
if (hMonitor := this.GetMonitorHandle(Display))
{
PhysicalMonitors := this.GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor)
hPhysicalMonitor := this.GetPhysicalMonitorsFromHMONITOR(hMonitor, PhysicalMonitors, PHYSICAL_MONITOR)
Contrast := this.GetMonitorContrast(hPhysicalMonitor)
this.DestroyPhysicalMonitors(PhysicalMonitors, PHYSICAL_MONITOR)
return Contrast
}
return false
}
GetGammaRamp(Display := "")
{
if (DisplayName := this.GetDisplayName(Display))
{
if (hDC := this.CreateDC(DisplayName))
{
GammaRamp := this.GetDeviceGammaRamp(hDC)
this.DeleteDC(hDC)
return GammaRamp
}
this.DeleteDC(hDC)
}
return false
}
RestoreFactoryDefault(Display := "")
{
if (hMonitor := this.GetMonitorHandle(Display))
{
PhysicalMonitors := this.GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor)
hPhysicalMonitor := this.GetPhysicalMonitorsFromHMONITOR(hMonitor, PhysicalMonitors, PHYSICAL_MONITOR)
this.RestoreMonitorFactoryDefaults(hPhysicalMonitor)
this.DestroyPhysicalMonitors(PhysicalMonitors, PHYSICAL_MONITOR)
return true
}
return false
}
SetBrightness(Brightness, Display := "")
{
if (hMonitor := this.GetMonitorHandle(Display))
{
PhysicalMonitors := this.GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor)
hPhysicalMonitor := this.GetPhysicalMonitorsFromHMONITOR(hMonitor, PhysicalMonitors, PHYSICAL_MONITOR)
GetBrightness := this.GetMonitorBrightness(hPhysicalMonitor)
Brightness := (Brightness < GetBrightness["Minimum"]) ? GetBrightness["Minimum"]
: (Brightness > GetBrightness["Maximum"]) ? GetBrightness["Maximum"]
: (Brightness)
this.SetMonitorBrightness(hPhysicalMonitor, Brightness)
this.DestroyPhysicalMonitors(PhysicalMonitors, PHYSICAL_MONITOR)
return Brightness
}
return false
}
SetContrast(Contrast, Display := "")
{
if (hMonitor := this.GetMonitorHandle(Display))
{
PhysicalMonitors := this.GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor)
hPhysicalMonitor := this.GetPhysicalMonitorsFromHMONITOR(hMonitor, PhysicalMonitors, PHYSICAL_MONITOR)
GetContrast := this.GetMonitorContrast(hPhysicalMonitor)
Contrast := (Contrast < GetContrast["Minimum"]) ? GetContrast["Minimum"]
: (Contrast > GetContrast["Maximum"]) ? GetContrast["Maximum"]
: (Contrast)
this.SetMonitorContrast(hPhysicalMonitor, Contrast)
this.DestroyPhysicalMonitors(PhysicalMonitors, PHYSICAL_MONITOR)
return Contrast
}
return false
}
SetGammaRamp(Red, Green, Blue, Display := "")
{
if (DisplayName := this.GetDisplayName(Display))
{
if (hDC := this.CreateDC(DisplayName))
{
this.SetDeviceGammaRamp(hDC, Red, Green, Blue)
this.DeleteDC(hDC)
return true
}
this.DeleteDC(hDC)
}
return false
}
; ===== PRIVATE METHODS =====================================================================================================
CreateDC(DisplayName)
{
if (hDC := DllCall("gdi32\CreateDC", "str", DisplayName, "ptr", 0, "ptr", 0, "ptr", 0, "ptr"))
return hDC
return false
}
DeleteDC(hDC)
{
if (DllCall("gdi32\DeleteDC", "ptr", hDC))
return true
return false
}
DestroyPhysicalMonitors(PhysicalMonitorArraySize, PHYSICAL_MONITOR)
{
if (DllCall("dxva2\DestroyPhysicalMonitors", "uint", PhysicalMonitorArraySize, "ptr", &PHYSICAL_MONITOR))
return true
return false
}
EnumDisplayMonitors(hMonitor := "")
{
static EnumProc := RegisterCallback(Monitor.EnumProc)
static DisplayMonitors := {}
if (MonitorNumber = "")
DisplayMonitors := {}
if (DisplayMonitors.MaxIndex() = "")
if (DllCall("user32\EnumDisplayMonitors", "ptr", 0, "ptr", 0, "ptr", EnumProc, "ptr", &DisplayMonitors, "uint"))
return (MonitorNumber = "") ? DisplayMonitors : DisplayMonitors.HasKey(MonitorNumber) ? DisplayMonitors[MonitorNumber] : false
return false
}
EnumProc(hDC, RECT, ObjectAddr)
{
DisplayMonitors := Object(ObjectAddr)
MonitorInfo := Monitor.GetMonitorInfo(this)
DisplayMonitors.Push(MonitorInfo)
return true
}
GetDeviceGammaRamp(hMonitor)
{
VarSetCapacity(GAMMA_RAMP, 1536, 0)
if (DllCall("gdi32\GetDeviceGammaRamp", "ptr", hMonitor, "ptr", &GAMMA_RAMP))
{
GammaRamp := []
GammaRamp["Red"] := NumGet(GAMMA_RAMP, 2, "ushort") - 128
GammaRamp["Green"] := NumGet(GAMMA_RAMP, 512 + 2, "ushort") - 128
GammaRamp["Blue"] := NumGet(GAMMA_RAMP, 1024 + 2, "ushort") - 128
return GammaRamp
}
return false
}
GetDisplayName(Display := "")
{
DisplayName := ""
if (Enum := this.EnumDisplayMonitors()) && (Display != "")
{
for k, Mon in Enum
if (InStr(Mon["Name"], Display))
DisplayName := Mon["Name"]
}
if (DisplayName = "")
if (hMonitor := this.MonitorFromWindow())
DisplayName := this.GetMonitorInfo(hMonitor)["Name"]
return DisplayName
}
GetMonitorBrightness(hMonitor)
{
if (DllCall("dxva2\GetMonitorBrightness", "ptr", hMonitor, "uint*", Minimum, "uint*", Current, "uint*", Maximum))
return { "Minimum": Minimum, "Current": Current, "Maximum": Maximum }
return false
}
GetMonitorContrast(hMonitor)
{
if (DllCall("dxva2\GetMonitorContrast", "ptr", hMonitor, "uint*", Minimum, "uint*", Current, "uint*", Maximum))
return { "Minimum": Minimum, "Current": Current, "Maximum": Maximum }
return false
}
GetMonitorHandle(Display := "")
{
hMonitor := 0
if (Enum := this.EnumDisplayMonitors()) && (Display != "")
{
for k, Mon in Enum
if (InStr(Mon["Name"], Display))
hMonitor := Mon["Handle"]
}
if !(hMonitor)
hMonitor := this.MonitorFromWindow()
return hMonitor
}
GetMonitorInfo(hMonitor)
{
NumPut(VarSetCapacity(MONITORINFOEX, 40 + (32 << !!A_IsUnicode)), MONITORINFOEX, 0, "uint")
if (DllCall("user32\GetMonitorInfo", "ptr", hMonitor, "ptr", &MONITORINFOEX))
{
MONITORINFO := []
MONITORINFO["Handle"] := hMonitor
MONITORINFO["Name"] := Name := StrGet(&MONITORINFOEX + 40, 32)
MONITORINFO["Number"] := RegExReplace(Name, ".*(\d+)$", "$1")
MONITORINFO["Left"] := NumGet(MONITORINFOEX, 4, "int")
MONITORINFO["Top"] := NumGet(MONITORINFOEX, 8, "int")
MONITORINFO["Right"] := NumGet(MONITORINFOEX, 12, "int")
MONITORINFO["Bottom"] := NumGet(MONITORINFOEX, 16, "int")
MONITORINFO["WALeft"] := NumGet(MONITORINFOEX, 20, "int")
MONITORINFO["WATop"] := NumGet(MONITORINFOEX, 24, "int")
MONITORINFO["WARight"] := NumGet(MONITORINFOEX, 28, "int")
MONITORINFO["WABottom"] := NumGet(MONITORINFOEX, 32, "int")
MONITORINFO["Primary"] := NumGet(MONITORINFOEX, 36, "uint")
return MONITORINFO
}
return false
}
GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor)
{
if (DllCall("dxva2\GetNumberOfPhysicalMonitorsFromHMONITOR", "ptr", hMonitor, "uint*", NumberOfPhysicalMonitors))
return NumberOfPhysicalMonitors
return false
}
GetPhysicalMonitorsFromHMONITOR(hMonitor, PhysicalMonitorArraySize, ByRef PHYSICAL_MONITOR)
{
VarSetCapacity(PHYSICAL_MONITOR, (A_PtrSize + 256) * PhysicalMonitorArraySize, 0)
if (DllCall("dxva2\GetPhysicalMonitorsFromHMONITOR", "ptr", hMonitor, "uint", PhysicalMonitorArraySize, "ptr", &PHYSICAL_MONITOR))
return NumGet(PHYSICAL_MONITOR, 0, "ptr")
return false
}
MonitorFromWindow(hWindow := 0)
{
static MONITOR_DEFAULTTOPRIMARY := 0x00000001
if (hMonitor := DllCall("user32\MonitorFromWindow", "ptr", hWindow, "uint", MONITOR_DEFAULTTOPRIMARY))
return hMonitor
return false
}
RestoreMonitorFactoryDefaults(hMonitor)
{
if (DllCall("dxva2\RestoreMonitorFactoryDefaults", "ptr", hMonitor))
return false
return true
}
SetDeviceGammaRamp(hMonitor, Red, Green, Blue)
{
loop % VarSetCapacity(GAMMA_RAMP, 1536, 0) / 6
{
NumPut((r := (red + 128) * (A_Index - 1)) > 65535 ? 65535 : r, GAMMA_RAMP, 2 * (A_Index - 1), "ushort")
NumPut((g := (green + 128) * (A_Index - 1)) > 65535 ? 65535 : g, GAMMA_RAMP, 512 + 2 * (A_Index - 1), "ushort")
NumPut((b := (blue + 128) * (A_Index - 1)) > 65535 ? 65535 : b, GAMMA_RAMP, 1024 + 2 * (A_Index - 1), "ushort")
}
if (DllCall("gdi32\SetDeviceGammaRamp", "ptr", hMonitor, "ptr", &GAMMA_RAMP))
return true
return false
}
SetMonitorBrightness(hMonitor, Brightness)
{
if (DllCall("dxva2\SetMonitorBrightness", "ptr", hMonitor, "uint", Brightness))
return true
return false
}
SetMonitorContrast(hMonitor, Contrast)
{
if (DllCall("dxva2\SetMonitorContrast", "ptr", hMonitor, "uint", Contrast))
return true
return false
}
}
; ===============================================================================================================================
使用方法,台式机也能用,笔记本用setgammaramp调整亮度。
检索(特定)监视器的最小、最大和当前亮度设置。
for k, v in Monitor.GetBrightness("\\.\DISPLAY2") ; or just "2"
MsgBox % k ": " v
检索默认(主)显示器的最小、最大和当前亮度设置。
for k, v in Monitor.GetBrightness() ; empty parameter
MsgBox % k ": " v
检索(特定)监视器的最小、最大和当前对比度设置。
for k, v in Monitor.GetContrast("\\.\DISPLAY2") ; or just "2"
MsgBox % k ": " v
检索默认(主)监视器的最小、最大和当前对比度设置。
for k, v in Monitor.GetContrast() ; empty parameter
MsgBox % k ": " v
检索(特定)监视器的红色、绿色和蓝色伽马渐变设置。
for k, v in Monitor.GetGammaRamp("\\.\DISPLAY2") ; or just "2"
MsgBox % k ": " v
检索默认(主要)监视器的红色、绿色和蓝色伽马渐变设置。
for k, v in Monitor.GetGammaRamp() ; empty parameter
MsgBox % k ": " v
设置(特定)监视器的亮度值。
Monitor.SetBrightness(50, "\\.\DISPLAY2") ; or just "2"
设置默认(主)显示器的亮度值。
Monitor.SetBrightness(50) ; empty parameter
设置(特定)监视器的对比度值。
Monitor.SetContrast(50, "\\.\DISPLAY2") ; or just "2"
设置默认(主要)监视器的对比度值。
Monitor.SetContrast(50) ; empty parameter
设置(特定)监视器的红色、绿色和蓝色伽马渐变值。
Monitor.SetGammaRamp(100, 100, 80, "\\.\DISPLAY2") ; or just "2"
设置默认(主要)监视器的红色、绿色和蓝色伽马渐变值。
Monitor.SetGammaRamp(100, 100, 80) ; empty parameter
将(特定)显示器的设置恢复为出厂默认设置(亮度和对比度)。
Monitor.RestoreFactoryDefault(\\.\DISPLAY2") ; or just "2"
将默认(主)显示器的设置恢复为出厂默认设置(亮度和对比度)。
Monitor.RestoreFactoryDefault() ; empty parameter
快速获取 WM_COMMAND ID
;AHK v1.1 x64/x32 compatible update by jeeswg of:
;Get Info from Context Menu - Scripts and Functions - AutoHotkey Community
;https://autohotkey.com/board/topic/19754-get-info-from-context-menu/
;
; AutoHotkey Version: 1.x
; Language: English
; Platform: Win9x/NT
; Author: micha
;
; Script Function:
; Demonstrates how to retrieve infos from a context/ popup menu
;
/*
This is the struct we are using.
typedef struct tagMENUITEMINFO {
UINT cbSize;
UINT fMask;
UINT fType;
UINT fState;
UINT wID;
HMENU hSubMenu;
HBITMAP hbmpChecked;
HBITMAP hbmpUnchecked;
ULONG_PTR dwItemData;
LPTSTR dwTypeData;
UINT cch;
HBITMAP hbmpItem;
} MENUITEMINFO, *LPMENUITEMINFO;
*/
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
#Persistent
SetTimer, Demo, 500
return
Demo:
;constants
MFS_ENABLED = 0
MFS_CHECKED = 8
MFS_DEFAULT = 0x1000
MFS_DISABLED = 2
MFS_GRAYED = 1
MFS_HILITE = 0x80
;MFS_UNCHECKED = 0
;MFS_UNHILITE = 0
;Get mouse position and handle to wnd under the mouse cursor
MouseGetPos, MouseScreenX, MouseScreenY, MouseWindowUID, MouseControlID
WinGet,ControlHwnd, ID,ahk_id %MouseWindowUID%
;Get count of menu items
ContextMenCnt := GetContextMenuCount(ControlHwnd)
if ContextMenCnt < 1
{
Tooltip,
return
}
TooltipText =
;Read info for each menu item
loop, %ContextMenCnt%
{
IsEnabled := GetContextMenuState(ControlHwnd, a_index-1)
{
CurrentText =
if IsEnabled = 0
CurrentText = %CurrentText% Enabled
if (IsEnabled & MFS_CHECKED)
CurrentText = %CurrentText% Checked
if (IsEnabled & MFS_DEFAULT)
CurrentText = %CurrentText% Default
if (IsEnabled & MFS_DISABLED)
CurrentText = %CurrentText% Disabled
if (IsEnabled & MFS_GRAYED)
CurrentText = %CurrentText% Grayed
if (IsEnabled & MFS_HILITE)
CurrentText = %CurrentText% Highlight
TooltipText = %TooltipText%%a_index%:%CurrentText%`n
}
}
TextText =
loop, %ContextMenCnt%
{
StrSize := GetContextMenuText(ControlHwnd, a_index-1)
nID := GetContextMenuID(ControlHwnd, a_index-1)
TextText = %TextText%%a_index%:%StrSize%-ID=%nID%`n
}
CoordMode, Tooltip, Screen
Tooltip, %TooltipText%---`n%TextText%, 0, 0
return
/***************************************************************
* returns the count of menu items
***************************************************************
*/
GetContextMenuCount(hWnd)
{
WinGetClass, WindowClass, ahk_id %hWnd%
;All popups should have the window class #32768
if WindowClass <> #32768
{
return 0
}
;Retrieve menu handle from window
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
menuitemcount:=DllCall("GetMenuItemCount", Ptr,hMenu)
Return, menuitemcount
}
/***************************************************************
* returns the state of a menu entry
***************************************************************
*/
GetContextMenuState(hWnd, Position)
{
WinGetClass, WindowClass, ahk_id %hWnd%
if WindowClass <> #32768
{
return -1
}
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
;We need to allocate a struct
VarSetCapacity(MenuItemInfo, 60, 0)
;Set Size of Struct to the first member
NumPut(A_PtrSize=8?80:48, MenuItemInfo, 0, "UInt")
;Get only Flags from dllcall GetMenuItemInfo MIIM_TYPE = 1
NumPut(1, MenuItemInfo, 4, "UInt")
;GetMenuItemInfo: Handle to Menu, Index of Position, 0=Menu identifier / 1=Index
InfoRes := DllCall("user32.dll\GetMenuItemInfo", Ptr,hMenu, UInt,Position, Int,1, Ptr,&MenuItemInfo)
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes != 0
return -1
;Get Flag from struct
GetMenuItemInfoRes := NumGet(MenuItemInfo, 12, "UInt")
/*
IsEnabled = 1
if GetMenuItemInfoRes > 0
IsEnabled = 0
return IsEnabled
*/
return GetMenuItemInfoRes
}
/***************************************************************
* returns the ID of a menu entry
***************************************************************
*/
GetContextMenuID(hWnd, Position)
{
WinGetClass, WindowClass, ahk_id %hWnd%
if WindowClass <> #32768
{
return -1
}
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
;UINT GetMenuItemID( HMENU hMenu, int nPos);
InfoRes := DllCall("user32.dll\GetMenuItemID", Ptr,hMenu, Int,Position, UInt)
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes != 0
return -1
return InfoRes
}
/***************************************************************
* returns the text of a menu entry (standard windows context menus only!!!)
***************************************************************
*/
GetContextMenuText(hWnd, Position)
{
WinGetClass, WindowClass, ahk_id %hWnd%
if WindowClass <> #32768
{
return -1
}
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
;We need to allocate a struct
VarSetCapacity(MenuItemInfo, 200, 0)
;Set Size of Struct (48) to the first member
NumPut(A_PtrSize=8?80:48, MenuItemInfo, 0, "UInt")
;Retrieve string MIIM_STRING = 0x40 = 64 (/ MIIM_TYPE = 0x10 = 16)
NumPut(64, MenuItemInfo, 4, "UInt")
;Set type - Get only size of string we need to allocate
;NumPut(0, MenuItemInfo, 8, "UInt")
;GetMenuItemInfo: Handle to Menu, Index of Position, 0=Menu identifier / 1=Index
InfoRes := DllCall("user32.dll\GetMenuItemInfo", Ptr,hMenu, UInt,Position, Int,1, Ptr,&MenuItemInfo)
if InfoRes = 0
return -1
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes <> 0
return -1
;Get size of string from struct
GetMenuItemInfoRes := NumGet(MenuItemInfo, A_PtrSize=8?64:40, "UInt")
;If menu is empty return
If GetMenuItemInfoRes = 0
return "{Empty String}"
;+1 should be enough, we'll use 2
GetMenuItemInfoRes += 2
;Set capacity of string that will be filled by windows
VarSetCapacity(PopupText, GetMenuItemInfoRes, 0)
;Set Size plus 0 terminator + security ;-)
NumPut(GetMenuItemInfoRes, MenuItemInfo, A_PtrSize=8?64:40, "UInt")
NumPut(&PopupText, MenuItemInfo, A_PtrSize=8?56:36, "Ptr")
InfoRes := DllCall("user32.dll\GetMenuItemInfo", Ptr,hMenu, UInt,Position, Int,1, Ptr,&MenuItemInfo)
if InfoRes = 0
return -1
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes <> 0
return -1
return PopupText
}
;PrintScreen::reload
直接运行,鼠标移动到控件自动在屏幕左上角显示相关信息。
监控窗口闪烁
AHK V2 by Tebayaki
Persistent
; 监控窗口闪烁 by Tebayaki
;DllCall("FlashWindow", "ptr", WinExist("窗口标题"), "int", true)
hook := ShellHook((wParam, lParam, *) => wParam == 32774 && WinExist("窗口标 题 ") ? WinActivate('窗口标题') : 0)
class ShellHook {
static Message := DllCall("RegisterWindowMessage", "str", "ShellHook")
static RefCount := 0
__New(function) {
!ShellHook.RefCount++ ? DllCall("RegisterShellHookWindow", "ptr",
A_ScriptHwnd) : ""
OnMessage(ShellHook.Message, this.function := function)
}
__Delete() {
!-- ShellHook.RefCount ? DllCall("DeregisterShellHookWindow", "ptr",
A_ScriptHwnd) : ""
OnMessage(ShellHook.Message, this.function, 0)
}
}
更改窗口标题使用,比如qq有消息时自动弹出聊天窗口。
边框高亮线
AHK V1 by dbgba
; ====================== 边框高亮线 ====================== by dbgba
class HighlightOutline {
__New(color="red", Transparent=255){
Loop 4 {
Gui New, -Caption +AlwaysOnTop +ToolWindow HWNDhwnd -DPIScale +E0x20 +E0x00080000
Gui Color, %color%
DllCall("SetLayeredWindowAttributes", "Ptr", this[A_Index] := hwnd, "Uint", 0, "Uchar", Transparent, "int", 2)
}
this.top := this[1]
, this.right := this[2]
, this.bottom := this[3]
, this.left := this[4]
Gui % "Gui_Cheek_Number" A_DefaultGui ": Default"
}
Show(x1, y1, x2, y2, b=3) {
Try {
Gui % this.1 ":Show", % "NA x" x1-b " y" y1-b " w" x2-x1+b*2 " h" b
Gui % this.2 ":Show", % "NA x" x2 " y" y1 " w" b " h" y2-y1
Gui % this.3 ":Show", % "NA x" x1-b " y" y2 " w" x2-x1+2*b " h" b
Gui % this.4 ":Show", % "NA x" x1-b " y" y1 " w" b " h" y2-y1
}
}
Hide() {
Loop 4
Try Gui % this[A_Index] ": Hide"
}
Destroy() {
Loop 4
Try Gui % this[A_Index] ": Destroy"
}
}
调用示例
Loop 7
演示1%A_Index% := new HighlightOutline(), 演示1%A_Index%.Show(A_Index*100, A_Index*100, 250+(A_Index*100), 350+(A_Index*100))
演示2 := new HighlightOutline("Blue", 128) ; 第二项128是高亮线的透明度
演示2.Show(55, 55, 900, 600)
Return
F1::演示2.Hide()
F2::演示2.Show(33, 33, 555, 777)
AHK V2
; by zzZ…
class HighlightOutline
{
gui := []
__New(x1, y1, x2, y2, b := 3,color := "red", Transparent := 255, time_out := unset)
{
this.gui.Length := 4
Loop 4 {
this.gui[A_index] := Gui("-Caption +AlwaysOnTop +ToolWindow -DPIScale +E0x20 +E0x00080000")
this.gui[A_index].BackColor := color
DllCall("SetLayeredWindowAttributes", "Ptr", this.gui[A_index].hwnd, "Uint", 0, "Uchar", Transparent, "int", 2)
}
if(IsSet(time_out))
{
this.timer := ObjBindMethod(this, "Destroy")
this.Show(x1, y1, x2, y2)
SetTimer(this.timer, -time_out)
}
}
Show(x1, y1, x2, y2, b := 3)
{
Try
{
this.gui[1].Show("NA x" x1-b " y" y1-b " w" x2-x1+b*2 " h" b)
this.gui[2].show("NA x" x2 " y" y1 " w" b " h" y2-y1)
this.gui[3].Show("NA x" x1-b " y" y2 " w" x2-x1+2*b " h" b)
this.gui[4].Show("NA x" x1-b " y" y1 " w" b " h" y2-y1)
}
}
Hide()
{
Loop(4)
{
try
{
this.gui[A_Index].Hide()
}
}
}
Destroy()
{
this.timer := 0
Loop(4)
{
try
{
this.gui[A_Index].Destroy()
}
}
}
}
调用示例
t1 := HighlightOutline(0, 0, 200, 200,,"d21d83", 128)
t1.Show(0, 0, 200, 200)
HighlightOutline(200, 0, 400, 200,,"328ad6", 255, 3000)
loop(3)
{
Sleep(1000)
t1.Hide()
Sleep(1000)
t1.Show(0, 0, 200, 200)
}
t1.Destroy()
PostMessage和SendMessage用法整理
AHK V1
WM_SETTEXT := 0x0C
向记事本发送文本
Run Notepad
Sleep 1000
SendMessage, 0x0C, 0, "New Notepad Title", Edit1, ahk_class Notepad
;=================================================================================
WM_GETTEXT := 0x0D
从记事本获取文本
len := 30
buf := VarSetCapacity(buf, (len + 10) * 2)
SendMessage, 0x0D, len, &buf, Edit1, ahk_class Notepad
MsgBox, % buf
;=================================================================================
AHK V2
WM_GETTEXT := 0x0D
从记事本获取文本 By Tebayak
len := 30
buf := Buffer((len + 10) * 2)
SendMessage(WM_GETTEXT := 0x000D, len, buf.Ptr, "Edit1", "ahk_class Notepad")
MsgBox StrGet(buf, len)
;==================================================================================
运行CMD命令的函数
AHK V1
;by Zzz...
RunCmd(CmdLine, WorkingDir:="", Cp:="CP0") { ; Thanks Sean! SKAN on D34E @ tiny.cc/runcmd
Local P8 := (A_PtrSize=8), pWorkingDir := (WorkingDir ? &WorkingDir : 0)
Local SI, PI, hPipeR:=0, hPipeW:=0, Buff, sOutput:="", ExitCode:=0, hProcess, hThread
DllCall("CreatePipe", "PtrP",hPipeR, "PtrP",hPipeW, "Ptr",0, "UInt",0)
, DllCall("SetHandleInformation", "Ptr",hPipeW, "UInt",1, "UInt",1)
VarSetCapacity(SI, P8? 104:68,0), NumPut(P8? 104:68, SI)
, NumPut(0x100, SI, P8? 60:44,"UInt"), NumPut(hPipeW, SI, P8? 88:60)
, NumPut(hPipeW, SI, P8? 96:64)
, VarSetCapacity(PI, P8? 24:16)
If not DllCall("CreateProcess", "Ptr",0, "Str",CmdLine, "Ptr",0, "UInt",0, "UInt",True
, "UInt",0x08000000 | DllCall("GetPriorityClass", "Ptr",-1,"UInt"), "UInt",0
, "Ptr",pWorkingDir, "Ptr",&SI, "Ptr",&PI )
Return Format( "{1:}", ""
, DllCall("CloseHandle", "Ptr",hPipeW)
, DllCall("CloseHandle", "Ptr",hPipeR)
, ErrorLevel := -1 )
DllCall( "CloseHandle", "Ptr",hPipeW)
, VarSetCapacity(Buff, 4096, 0), nSz:=0
While DllCall("ReadFile", "Ptr",hPipeR, "Ptr",&Buff, "UInt",4094, "PtrP",nSz, "UInt",0)
sOutput .= StrGet(&Buff, nSz, Cp)
hProcess := NumGet(PI, 0), hThread := NumGet(PI,4)
, DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode)
, DllCall("CloseHandle", "Ptr",hProcess), DllCall("CloseHandle", "Ptr",hThread)
, DllCall("CloseHandle", "Ptr",hPipeR), ErrorLevel := ExitCode
Return sOutput
}
使用方法
Msgbox % RunCmd("ipconfig")
运行多行CMD
RunWaitMany(commands) {
shell := ComObjCreate("WScript.Shell")
; 打开 cmd.exe 禁用命令显示
exec := shell.Exec(ComSpec " /Q /K echo off")
; 发送并执行命令,使用新行分隔
exec.StdIn.WriteLine(commands "`nexit") ; 保证执行完毕后退出!
; 读取并返回所有命令的输出
return exec.StdOut.ReadAll()
}
使用方法
; ...或一次执行多条命令并获取其输出:
MsgBox % RunWaitMany("
(
echo 在这填入命令,
echo 会执行所有命令,
echo 并获取输出.
)")
AHK V2
;by Tebayaki
ReadProcessStdOut(cmd, encoding := "cp0") {
sa := Buffer(24)
NumPut("uint", sa.Size, sa)
NumPut("ptr", 0, "uint", 1, sa, 8)
if !DllCall("CreatePipe", "ptr*", &hReadPipe := 0, "ptr*", &hWritePipe := 0, "ptr", sa, "uint", 0)
throw OSError()
DllCall("SetHandleInformation", "ptr", hReadPipe, "uint", 1, "uint", 0)
si := Buffer(104, 0)
NumPut("uint", si.Size, si)
NumPut("uint", 0x101, si, 60)
NumPut("ptr", hWritePipe, si, 88)
if !DllCall("CreateProcessW", "ptr", 0, "str", cmd, "ptr", 0, "ptr", 0, "int", true, "uint", 0, "ptr", 0, "ptr", 0, "ptr", si, "ptr", pi := Buffer(24)) {
DllCall("CloseHandle", "ptr", hWritePipe)
DllCall("CloseHandle", "ptr", hReadPipe)
throw OSError()
}
DllCall("CloseHandle", "ptr", NumGet(pi, "ptr"))
DllCall("CloseHandle", "ptr", NumGet(pi, 8, "ptr"))
DllCall("CloseHandle", "ptr", hWritePipe)
stdout := ""
while DllCall("ReadFile", "ptr", hReadPipe, "ptr", buf := Buffer(4096), "uint", buf.Size, "uint*", &lpNumberOfBytesRead := 0, "ptr", 0) && lpNumberOfBytesRead
stdout .= StrGet(buf, lpNumberOfBytesRead, encoding)
DllCall("CloseHandle", "ptr", hReadPipe)
return stdout
}
使用方法
Msgbox(ReadProcessStdOut("net localgroup Administrators"))
脚本提权
原文链接:https://www.autoahk.com/archives/35533
;by 空
; 强制自身进程以 管理员权限 或 普通权限 或 ANSI 或 U32 或 U64 版本运行。
; 例1: runwith("admin","u32") 强制自身以 u32 + 管理员权限 运行。
; 例2: runwith("","ansi") 强制自身以 ansi 版本运行(权限不变)。
; 例3: runwith("normal") 强制自身以 普通权限 运行(版本不变)。
RunWith(RunAsAdmin:="Default", ANSI_U32_U64:="Default")
{
; 格式化预期的模式
switch, RunAsAdmin
{
case "Normal","Standard","No","0": RunAsAdmin:=0
case "Admin","Yes","1": RunAsAdmin:=1
case "Default": RunAsAdmin:=A_IsAdmin
default: RunAsAdmin:=A_IsAdmin
}
switch, ANSI_U32_U64
{
case "A32","ANSI","A": ANSI_U32_U64:="AutoHotkeyA32.exe"
case "U32","X32","32": ANSI_U32_U64:="AutoHotkeyU32.exe"
case "U64","X64","64": ANSI_U32_U64:="AutoHotkeyU64.exe"
case "Default": ANSI_U32_U64:="AutoHotkey.exe"
default: ANSI_U32_U64:="AutoHotkey.exe"
}
; 获取传递给 “.ahk” 的用户参数(不是 /restart 之类传递给 “.exe” 的开关参数)
for k, v in A_Args
{
if (RunAsAdmin=1)
{
; 转义所有的引号与转义符号
v:=StrReplace(v, "\", "\\")
v:=StrReplace(v, """", "\""")
; 无论参数中是否有空格,都给参数两边加上引号
; Run 的内引号是 "
ScriptParameters .= (ScriptParameters="") ? """" v """" : A_Space """" v """"
}
else
{
; 转义所有的引号与转义符号
; 注意要转义两次 Run 和 RunAs.exe
v:=StrReplace(v, "\", "\\")
v:=StrReplace(v, """", "\""")
v:=StrReplace(v, "\", "\\")
v:=StrReplace(v, """", "\""")
; 无论参数中是否有空格,都给参数两边加上引号
; RunAs.exe 的内引号是 \"
ScriptParameters .= (ScriptParameters="") ? "\""" v "\""" : A_Space "\""" v "\"""
}
}
; 判断当前 exe 是什么版本
if (!A_IsUnicode)
RunningEXE:="AutoHotkeyA32.exe"
else if (A_PtrSize=4)
RunningEXE:="AutoHotkeyU32.exe"
else if (A_PtrSize=8)
RunningEXE:="AutoHotkeyU64.exe"
; 运行模式与预期相同,则直接返回。 ANSI_U32_U64="AutoHotkey.exe" 代表不对 ahk 版本做要求。
if (A_IsAdmin=RunAsAdmin and (ANSI_U32_U64="AutoHotkey.exe" or ANSI_U32_U64=RunningEXE))
return
; 如果当前已经是使用 /restart 参数重启的进程,则报错避免反复重启导致死循环。
else if (RegExMatch(DllCall("GetCommandLine", "str"), " /restart(?!\S)"))
{
预期权限:=(RunAsAdmin=1) ? "管理员权限" : "普通权限"
当前权限:=(A_IsAdmin=1) ? "管理员权限" : "普通权限"
ErrorMessage=
(LTrim
预期使用: %ANSI_U32_U64%
当前使用: %RunningEXE%
预期权限: %预期权限%
当前权限: %当前权限%
程序即将退出。
)
MsgBox 0x40030, 运行状态与预期不一致, %ErrorMessage%
ExitApp
}
else
{
; 获取 AutoHotkey.exe 的路径
SplitPath, A_AhkPath, , Dir
if (RunAsAdmin=0)
{
; 强制普通权限运行
switch, A_IsCompiled
{
; %A_ScriptFullPath% 必须加引号,否则含空格的路径会被截断。%ScriptParameters% 必须不加引号,因为构造时已经加了。
; 工作目录不用单独指定,默认使用 A_WorkingDir 。
case, "1": Run, RunAs.exe /trustlevel:0x20000 "\"%A_ScriptFullPath%\" /restart %ScriptParameters%",, Hide
default: Run, RunAs.exe /trustlevel:0x20000 "\"%Dir%\%ANSI_U32_U64%\" /restart \"%A_ScriptFullPath%\" %ScriptParameters%",, Hide
}
}
else
{
; 强制管理员权限运行
switch, A_IsCompiled
{
; %A_ScriptFullPath% 必须加引号,否则含空格的路径会被截断。%ScriptParameters% 必须不加引号,因为构造时已经加了。
; 工作目录不用单独指定,默认使用 A_WorkingDir 。
case, "1": Run, *RunAs "%A_ScriptFullPath%" /restart %ScriptParameters%
default: Run, *RunAs "%Dir%\%ANSI_U32_U64%" /restart "%A_ScriptFullPath%" %ScriptParameters%
}
}
ExitApp
}
}
使用方法
RunWith("admin",32)
当前AHK版本 := (!A_IsUnicode) ? "ANSI" : (A_PtrSize=4) ? "Unicode 32" : "Unicode 64"
当前权限 := (A_IsAdmin=1) ? "管理员权限" : "普通权限"
MsgBox, % "当前AHK版本: " 当前AHK版本 "`n`n当前权限: " 当前权限