NirSoft GDIView can retrieve GDI handles for all open processes. I used it to get the hFont for the title bar, and then used WM_SETFONT to set the Edit control in Notepad to have the same font as the title bar.
This could be useful if you want to easily apply a font of your choice to a control. You just need to set the title bar font for all programs, and a large number of control types support WM_SETFONT.
[Note: NirSoft GDIView does not need to be run in Admin mode.]
GDIView - View GDI handles/resources list and detect GDI leaks
http://www.nirsoft.net/utils/gdi_handles.html
Basically, I've started trying to convert the code below into AutoHotkey, and will continue when I have the chance.
The following code appears to be able to enumerate GDI handles:
c++ - How to get list of GDI handles - Stack Overflow
http://stackoverflow.com/questions/1390 ... di-handles
Thanks for reading.
get a process's GDI handles (e.g. get/set title bar font and apply WM_SETFONT to a control) Topic is solved
get a process's GDI handles (e.g. get/set title bar font and apply WM_SETFONT to a control)
Last edited by jeeswg on 25 May 2017, 01:32, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: get a process's GDI handles (e.g. get/set title bar font and apply WM_SETFONT to a control)
Things that are required: set title bar font, get GDI handles, get hFont information.
Here is code to set the title bar font and get hFont information:
Here is code to set the title bar font and get hFont information:
Code: Select all
q:: ;get font information
SendMessage, 0x31, 0, 0, Edit1, ahk_class Notepad ;WM_GETFONT
hFont := ErrorLevel
oFontInfo := JEE_FontGetInfo(hFont)
MsgBox, % oFontInfo.Summary
oFontInfo := ""
return
;==================================================
JEE_FontGetInfo(hFont)
{
vSize := DllCall("gdi32\GetObject", Ptr,hFont, Int,0, Ptr,0)
VarSetCapacity(LOGFONT, vSize) ;LOGFONT Unicode
DllCall("Gdi32\GetObject", Ptr,hFont, Int,vSize, Ptr,&LOGFONT)
oFontInfo := {}
oFontInfo.Height := NumGet(LOGFONT, 0, "Int") ;lfHeight
oFontInfo.Width := NumGet(LOGFONT, 4, "Int") ;lfWidth
oFontInfo.Escapement := NumGet(LOGFONT, 8, "Int") ;lfEscapement
oFontInfo.Orientation := NumGet(LOGFONT, 12, "Int") ;lfOrientation
oFontInfo.Weight := NumGet(LOGFONT, 16, "Int") ;lfWeight
oFontInfo.Italic := NumGet(LOGFONT, 20, "UChar") ;lfItalic
oFontInfo.Underline := NumGet(LOGFONT, 21, "UChar") ;lfUnderline
oFontInfo.StrikeOut := NumGet(LOGFONT, 22, "UChar") ;lfStrikeOut
oFontInfo.CharSet := NumGet(LOGFONT, 23, "UChar") ;lfCharSet
oFontInfo.OutPrecision := NumGet(LOGFONT, 24, "UChar") ;lfOutPrecision ;(CreateFont: fdwOutputPrecision)
oFontInfo.ClipPrecision := NumGet(LOGFONT, 25, "UChar") ;lfClipPrecision
oFontInfo.Quality := NumGet(LOGFONT, 26, "UChar") ;lfQuality
oFontInfo.PitchAndFamily := NumGet(LOGFONT, 27, "UChar") ;lfPitchAndFamily
oFontInfo.FaceName := StrGet(&LOGFONT + 28, 32) ;lfFaceName[LOGFONT_FACESIZE] ;(CreateFont: lpszFace)
vScreenDPI := A_ScreenDPI
if (vScreenDPI = "")
RegRead, vScreenDPI, HKEY_LOCAL_MACHINE, SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontDPI, LogPixels
oFontInfo.Size := DllCall("kernel32\MulDiv", Int,-oFontInfo.Height, Int,72, Int,vScreenDPI)
vList := "Height,Width,Escapement,Orientation,Weight,Italic,Underline,StrikeOut,CharSet,OutPrecision,ClipPrecision,Quality,PitchAndFamily,FaceName"
Loop, Parse, vList, % ","
oFontInfo.Summary .= oFontInfo[A_LoopField] " "
oFontInfo.Summary .= "[" oFontInfo.Size "]"
return oFontInfo
}
;==================================================
Code: Select all
q:: ;set title bar font
JEE_SystemSetFont("Caption", "Arial", 18, 700)
return
;==================================================
;e.g.
;JEE_SystemSetFont("Message", "Arial", 18, 700)
;JEE_SetSystemFont
;JEE_SystemFontSet
JEE_SystemSetFont(vType:="", vName:="", vSize:=0, vWeight:=0, vIsItalic:=-1)
{
;SPI_GETICONTITLELOGFONT := 0x1F
;SPI_SETICONTITLELOGFONT := 0x22
;SPI_GETNONCLIENTMETRICS := 0x29
;SPI_SETNONCLIENTMETRICS := 0x2A
;SPIF_UPDATEINIFILE := 0x1
;SPIF_SENDCHANGE := 0x2
static vSizeLF := A_IsUnicode ? 92 : 60
static vSizeNCM := 40 + 5*vSizeLF
if (vType = "Icon")
{
VarSetCapacity(LOGFONT, vSizeLF, 0)
if !DllCall("SystemParametersInfo", UInt,0x1F, UInt,vSizeLF, Ptr,&LOGFONT, UInt,0)
return 0
vAddress := &LOGFONT
vMode := "Icon"
}
else
{
vOffset := ""
(vType = "Caption") ? (vOffset := 24) : ""
(vType = "SmCaption") ? (vOffset := 32 + vSizeLF) : ""
(vType = "Menu") ? (vOffset := 40 + 2*vSizeLF) : ""
(vType = "Status") ? (vOffset := 40 + 3*vSizeLF) : ""
(vType = "Message") ? (vOffset := 40 + 4*vSizeLF) : ""
if (vOffset = "")
return
VarSetCapacity(NONCLIENTMETRICS, vSizeNCM, 0)
NumPut(vSizeNCM, &NONCLIENTMETRICS, 0, "UInt")
if !DllCall("SystemParametersInfo", UInt,0x29, UInt,vSizeNCM, Ptr,&NONCLIENTMETRICS, UInt,0)
return 0
vAddress := &NONCLIENTMETRICS + vOffset
}
if vName
StrPut(vName, vAddress+28, 32)
if vSize
{
vHeight := -DllCall("MulDiv", Int,vSize, Int,A_ScreenDPI, Int,72)
NumPut(vHeight, vAddress+0, "Int")
}
if Weight
NumPut(vWeight, vAddress+16, "Int")
if (vIsItalic = 1) || (vIsItalic = 0)
NumPut(vIsItalic, &vAddress+20, "UChar")
if (vMode = "Icon")
vRet := DllCall("SystemParametersInfo", UInt,0x22, UInt,vSizeLF, Ptr,&LOGFONT, UInt,0x3)
else
vRet := DllCall("SystemParametersInfo", UInt,0x2A, UInt,vSizeNCM, Ptr,&NONCLIENTMETRICS, UInt,0x3)
return !!vRet
}
;==================================================
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: get a process's GDI handles (e.g. get/set title bar font and apply WM_SETFONT to a control) Topic is solved
OK, I managed to get everything to work now. It uses the JEE_FontGetInfo function from above. I basically had to learn C++ from scratch to get it all working.
Code: Select all
q:: ;process - get gdi handles
DetectHiddenWindows, On
WinGet, hWnd, ID, A
WinGet, vPID, PID, % "ahk_id " hWnd
WinGetTitle, vWinTitle, % "ahk_id " hWnd
WinGetClass, vWinClass, % "ahk_id " hWnd
vListAll := JEE_ProcessGetGDIHandles(vPID)
;Clipboard := vListAll
MsgBox, % vListAll
vListFont := JEE_ProcessGetGDIHandles(vPID, "`n", 10, 0)
;Clipboard := vListFont
MsgBox, % vListFont
vOutput := vPID "`t" vWinTitle "`t" vWinClass "`r`n"
Loop, Parse, vListFont, `n, `r
{
hFont := A_LoopField
vOutput .= hFont "`t" JEE_FontGetInfo(hFont).Summary "`r`n"
}
MsgBox, % SubStr(vOutput, 1, -2)
return
;==================================================
;DetectHiddenWindows, On
;WinGet, hWnd, ID, A
;WinGet, vPID, PID, % "ahk_id " hWnd
;MsgBox, % JEE_ProcessGetGDIHandles(vPID) ;list all (with labels)
;MsgBox, % JEE_ProcessGetGDIHandles(vPID, "`n", 10, 0) ;list hFonts only (no labels)
;return
;based on:
;c++ - How to get list of GDI handles - Stack Overflow
;https://stackoverflow.com/questions/13905661/how-to-get-list-of-gdi-handles
;see also:
;GDIView - View GDI handles/resources list and detect GDI leaks
;http://www.nirsoft.net/utils/gdi_handles.html
JEE_ProcessGetGDIHandles(vPID, vSep:="`n", vKeepType:=-1, vIncLabel:=1)
{
;PROCESS_QUERY_INFORMATION := 0x400 ;PROCESS_VM_READ := 0x10
if !hProc := DllCall("kernel32\OpenProcess", UInt,0x410, Int,0, UInt,vPID, Ptr)
return
vGdiSharedHandleTableOffset := A_Is64bitOS ? 0xF8 : 0x94
vCountTable := 16384
vSizePEB := vGdiSharedHandleTableOffset+8
VarSetCapacity(PEB, vSizePEB, 0)
vSizePBI := A_Is64bitOS?48:24
;ProcessBasicInformation := 0
VarSetCapacity(PROCESS_BASIC_INFORMATION, vSizePBI, 0)
if A_Is64bitOS && (A_PtrSize = 4)
{
vNtQueryInformationProcess := "ntdll\NtWow64QueryInformationProcess64"
vNtReadVirtualMemory := "ntdll\NtWow64ReadVirtualMemory64"
}
else
{
vNtQueryInformationProcess := "ntdll\NtQueryInformationProcess"
vNtReadVirtualMemory := "ntdll\NtReadVirtualMemory"
}
if DllCall(vNtQueryInformationProcess, Ptr,hProc, UInt,0, Ptr,&PROCESS_BASIC_INFORMATION, UInt,vSizePBI, Ptr,0)
{
DllCall("kernel32\CloseHandle", Ptr,hProc)
return
}
vPebBaseAddress := NumGet(PROCESS_BASIC_INFORMATION, 8, "Int64") ;PebBaseAddress
if DllCall(vNtReadVirtualMemory, Ptr,hProc, Int64,vPebBaseAddress, Ptr,&PEB, UInt,vSizePEB, Ptr,0)
{
DllCall("kernel32\CloseHandle", Ptr,hProc)
return
}
pGdiTable := NumGet(PEB, vGdiSharedHandleTableOffset, "Int64")
vSizeCell := A_Is64bitOS?24:16
vSizeTable := vSizeCell * vCountTable
VarSetCapacity(ArrayGDICELL, vSizeTable, 0)
if DllCall(vNtReadVirtualMemory, Ptr,hProc, Int64,pGdiTable, Ptr,&ArrayGDICELL, UInt, vSizeTable, Ptr,0)
{
DllCall("kernel32\CloseHandle", Ptr,hProc)
return
}
DllCall("kernel32\CloseHandle", Ptr,hProc)
vOutput := ""
VarSetCapacity(vOutput, 100000*2)
vOffset := &ArrayGDICELL-vSizeCell
oType := {0:"Unknown type",1:"DC",4:"Region",5:"Bitmap",8:"Palette",10:"Font",16:"Brush",48:"Pen"}
Loop, % vCountTable
{
vOffset += vSizeCell
vPID2 := NumGet(vOffset+0, A_Is64bitOS?8:4, "UShort") ;wProcessId
vUpper := NumGet(vOffset+0, A_Is64bitOS?12:8, "UShort") ;wUpper
vType := NumGet(vOffset+0, A_Is64bitOS?14:10, "UShort") ;wType
if !(vPID2 = vPID)
continue
vGdiHandle := (vUpper << 16) + A_Index - 1
vType &= 0x7F
if (vKeepType >= 0) && !(vKeepType = vType)
continue
if !oType.HasKey(vType)
vType := 0
if vIncLabel
vOutput .= oType[vType] " handle:" Format("0x{:08X}", vGdiHandle) vSep
else
vOutput .= Format("0x{:08X}", vGdiHandle) vSep
}
return SubStr(vOutput, 1, -StrLen(vSep))
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Who is online
Users browsing this forum: FanaticGuru, filipemb, Google [Bot], LRRUNB and 230 guests