document updated 16 years ago, on May 7, 2008
; =================================================================================================
; Some controls don't allow themselves to be Ctrl+C copied, but their text can still be read by
; other applications.
;
; This allows you to copy those "uncopyable" controls.
; =================================================================================================
title := "Copy text from controls that don't allow Ctrl+C."
MsgBox,,%title%,Instructions: After pressing okay:`n1. Move your mouse over the desired control.`n2. Press the Left Shift key.`n`nDesired text will be placed in the clipboard.
;DetectHiddenText,On
CoordMode, Mouse, Screen
Loop {
;MouseGetPos,,,hwnd,2
MouseGetPos, m_x, m_y
hwnd := DllCall( "WindowFromPoint", "int", m_x, "int", m_y )
if (!hwnd)
ToolTip,No window found. (%m_x%`, %m_y%)
else {
; at this point, some or all of the following may be warranted, to narrow down the hWnd:
; ChildWindowFromPoint()
; ChildWindowFromPointEx()
; RealChildWindowFromPoint()
; find the lowest-level child window that contains any text
; Loop {
; hwnd := DllCall( "ChildWindowFromPoint", "int", hwnd, "int", m_x, "int", m_y )
;
; if (hwnd == 0)
; Break
;
; ct := GetText(hwnd)
; if (StrLen(ct) > 0)
; ctext := ct
; }
ctext := GetText(hwnd)
if (StrLen(ctext) <= 0)
ToolTip,<NO TEXT FOUND>
else if (StrLen(ctext) > 20) {
tt := SubStr(ctext,1,15) . "... (" . StrLen(ctext) . " chars)"
;tt := SubStr(ctext,1,15) . "... (" . StrLen(ctext) . " chars) (hwnd " . hwnd . ") (class " . GetClassName(hwnd) . ")"
ToolTip,%tt%
}
else
ToolTip,%ctext%
}
if (GetKeyState("Shift", "P")) {
Clipboard := ctext
notice := StrLen(ctext) . " characters copied to the clipboard"
MsgBox,,%title%,%notice%
ExitApp
}
if (GetKeyState("Escape", "P")) {
SplashTextOn,200,70,%title%,`nExiting
Sleep,500
SplashTextOff
ExitApp
}
;Sleep,200
}
ExitApp
GetText(hwnd) {
; we could use ControlGetText or WinGetText... but I'm more confident in the below code instead
VarSetCapacity(contents, maxlen := 8192)
SendMessage, WM_GETTEXT:=13, maxlen, &contents, , ahk_id %hwnd%
VarSetCapacity(title, maxlen := 8192)
DllCall("GetWindowText"
,"UInt",hwnd
,"Str", title
,"UInt",maxlen)
if (contents == title)
return contents
else if (StrLen(contents)>0 && StrLen(title)>0)
return title . "`n" . contents
else
return title . contents
}
GetClassName(hwnd) {
VarSetCapacity(classname, 256) ; the most a classname can *ever* be is 256 chars
DllCall("GetClassName", "UInt", hwnd, "Str", classname, "UInt", 256)
return classname
}