- Offizieller Beitrag
Ich wollte mal ein kleines Programm mit Nim schreiben und so ist "Nim-WindowInfo" rausgekommen.
Das Programm öffnet ein Fenster im Vordergrund (bleibt OnTop) und zeigt verschiedene Informationen zu dem Fenster an, dass gerade aktiv ist (Nein, nicht so ausführlich wie Au3Info).
Edit: Neue Version! CopyToClipboard funktioniert nun. Danke, BugFix!
Edit 23.06.20: Neue Version!
- Hotkey geändert! <CTRL> & <C> war suboptimal, weil das ja ein globaler Hotkey ist und man somit die Zwischenablage nicht mehr normal benutzen konnte. Der Hotkey ist jetzt <ALT> & <C>.
- Es werden jetzt auch Informationen zu den Control-Elementen angezeigt. Das funktioniert noch nicht perfekt. Bei manchen Programmen werden da "falsche" Daten angezeigt.
import wNim
import os
import strutils
import times
include winim/[inc\winuser]
const sTitle = "Nim-WindowInfo"
const sVersion = "0.3.0.0"
const sDate = "23.06.2020"
const sAuthor = "Oscar (www.autoit.de)"
proc copyTextToClip(sText: string): bool {.discardable.} =
let data = newWideCString(sText)
let pData = cast[LPWSTR](data[0].addr)
let iLen = data.len * 2 + 2
let hMem = GlobalAlloc(GMEM_MOVEABLE, cast[SIZE_T](iLen))
if hMem == 0: return false
let pMem = GlobalLock(hMem)
if pMem == NULL: return false
copyMem(pMem, pData, iLen)
GlobalUnlock(hMem)
OpenClipboard(0)
if SetClipboardData(CF_UNICODETEXT, hMem) == 0:
GlobalFree(hMem)
CloseClipboard()
return false
return CloseClipboard() != 0
let appSize: wSize = (600, 720)
let app = App()
let frame = Frame(title=sTitle & " v" & sVersion[0..2], size=appSize, style=(wDefaultFrameStyle or wStayOnTop))
frame.registerHotKey(1, wModAlt, wKey_C) # <ALT> & <C> registrieren, zum speichern der Infos (siehe unten)
let panel = Panel(frame)
panel.setBackgroundColor(0x00F0F0F0)
const aCtrlTitle = [
"Window-Title", "Window-Handle", "Window-Classname", "Window-Position", "Window-Size",
"Control-Handle", "Control-Classname", "Control-Position", "Control-Size"
]
var aidCtrl: array[9, wStaticText]
for i in 0..8:
StaticBox(panel, label=aCtrlTitle[i], pos=(10, 10 + i * 70), size=(560, 60))
aidCtrl[i] = StaticText(panel, pos=(20, 35 + i * 70), size=(520, 30), style=wAlignLeftNoWordWrap)
aidCtrl[i].font = Font(14, faceName="Arial", weight=wFontWeightNormal)
let idStatus = StatusBar(frame)
idStatus.setFieldsCount(3)
frame.dpiAutoScale:
frame.minSize = appSize
frame.maxSize = appSize
var
sWinInfo: string # String zum speichern der Infos (fuer die Zwischenablage)
iTime: int = 0 # zum zaehlen der Zehntelsekunden (Anzeige "gespeichert" in der Statuszeile)
wi: WINDOWINFO # WINDOWINFO-Struktur erstellen
pWi: PWINDOWINFO = wi.addr # Pointer auf die Struktur
wi.cbSize = cast[DWORD](sizeof(wi)) # die Groesse der WINDOWINFO-Struktur eintragen
var
classBuf = newWideCString("", 256) # Buffer fuer die Class erstellen
pClass = cast[LPWSTR](classBuf[0].addr) # Pointer auf den Buffer
frame.startTimer(0.1) # starte den Timer (Zeit in Sekunden als Float)
frame.wEvent_Timer do (event: wEvent): # hier wird das Timer-Event ausgewertet
var
pt: POINT # POINT-Struktur erstellen
pPt: LPPOINT = pt.addr # Pointer auf die Struktur
GetCursorPos(pPt) # Mauskoordinaten holen (POINT)
sWinInfo = "Window\r\n" # Infostring leeren
let sPos = "X: " & $pt.x & "\tY: " & $pt.y # Mauskoordinaten holen
idStatus.setStatusText(sPos) # und in die Statuszeile schreiben
var hRoot = WindowFromPoint(pt)
hRoot = GetAncestor(hRoot, GA_ROOTOWNER)
let iTitleLen = GetWindowTextLengthW(hRoot) + 1 # Titellaenger ermitteln
var
titleBuf = newWideCString("", iTitleLen) # Buffer fuer den Titel erstellen
pTitle: LPWSTR = cast[LPWSTR](titleBuf[0].addr) # Pointer auf den Buffer
GetWindowTextW(hRoot, pTitle, iTitleLen) # den Window-Titel holen
let sWinTitle = $(cast[WideCString](pTitle)) # in einen String umwandeln
sWinInfo &= "Title: \"" & sWinTitle & "\"\r\n"
aidCtrl[0].label = sWinTitle # ins Label schreiben
let sHandle = "0x" & $(hRoot.toHex) # das Handle als Hex in einen String umwandeln
aidCtrl[1].label = sHandle
sWinInfo &= "Handle: " & sHandle & "\r\n"
var sClassname = "no class name"
if GetClassNameW(hRoot, pClass, 255) > 0: # Classnamen holen
sClassname = $(cast[WideCString](pClass))
aidCtrl[2].label = sClassname
sWinInfo &= "Classname: \"" & sClassname & "\"\r\n"
GetWindowInfo(hRoot, pWi) # WINDOWINFO vom aktiven Fenster holen
let sWinPos = "X: " & $wi.rcWindow.left & "\t Y: " & $wi.rcWindow.top
sWinInfo &= "Position: " & sWinPos & "\r\n"
aidCtrl[3].label = sWinPos
let sWinSize = "W: " & $(wi.rcWindow.right - wi.rcWindow.left) & "\t H: " & $(wi.rcWindow.bottom - wi.rcWindow.top)
sWinInfo &= "Size: " & sWinSize & "\r\n"
aidCtrl[4].label = sWinSize
let hDc = GetWindowDC(0) # Desktop-DC holen
let iColor = GetPixel(hDc, pt.x, pt.y) # Farbe unter dem Mauszeiger
let sColor = "Color: 0x" & iColor.toHex
idStatus.setStatusText(sColor, 1) # in die Statuszeile schreiben
ReleaseDC(GetDesktopWindow(), hDc) # DC freigeben
var hParent = WindowFromPoint(pt) # ab hier werden die Daten des Control-Elements ermittelt
ScreenToClient(hParent, pPt)
var hChild = ChildWindowFromPointEx(hParent, pt, 0)
if hChild == hParent: hParent = GetParent(hParent)
let sCtrlHandle = "0x" & $(hChild.toHex)
sWinInfo &= "\r\nControl\r\nHandle: " & sCtrlHandle & "\r\n"
aidCtrl[5].label = sCtrlHandle
sClassname = "no class name"
if GetClassNameW(hChild, pClass, 255) > 0: # Classnamen holen
sClassname = $(cast[WideCString](pClass))
var
iInstance: int = 0
hCheck: HWND = FindWindowExW(hParent, 0, pClass, NULL)
while hCheck != 0:
inc(iInstance)
if hCheck == hChild: break
hCheck = FindWindowExW(hParent, hCheck, pClass, NULL)
sClassname &= $iInstance
sWinInfo &= "Classname: " & sClassname & "\r\n"
aidCtrl[6].label = sClassname
var
rCh: RECT # RECT-Struktur erstellen (Control)
sCtrlPos = "X: , Y: "
sClSize = "W: , H: "
if GetWindowRect(hChild, rCh.addr) == TRUE:
pt.x = rCh.left
pt.y = rCh.top
ScreenToClient(hRoot, pPt)
sCtrlPos = "X: " & $pt.x & ", Y: " & $pt.y
sClSize = "W: " & $(rCh.right - rCh.left) & ", H: " & $(rCh.bottom - rCh.top)
sWinInfo &= "Position: " & sCtrlPos & "\r\n"
aidCtrl[7].label = sCtrlPos
sWinInfo &= "Size: " & sClSize & "\r\n"
aidCtrl[8].label = sClSize
sWinInfo &= "\r\nMouse\r\nPosition: " & sPos & "\r\n"
sWinInfo &= sColor & "\r\n"
if iTime > -1: dec(iTime)
if iTime == 0: # ist die Zeit fuer die "gespeichert"-Anzeige abgelaufen?
idStatus.setStatusText("", 2)
frame.wEvent_HotKey do (event: wEvent): # Hotkey-Event-Funktion
if copyTextToClip(sWinInfo):
idStatus.setStatusText("Copy to clipboard.", 2)
iTime = 30 # Zeit (in Zehntelsekunden), fuer die "gespeichert"-Anzeige
frame.center()
frame.show()
app.mainLoop()
Alles anzeigen
Im ZIP-Archiv (Anhang) befindet sich der obige Programmcode zum herunterladen.