gpt4 book ai didi

windows - WM_GETICON 有时不返回图标句柄

转载 作者:可可西里 更新时间:2023-11-01 09:26:17 25 4
gpt4 key购买 nike

我正在尝试显示所有窗口标题,包括相应的图标,就像 Windows 任务管理器所做的那样。这仅在一定程度上有效 - 虽然我能够获得窗口的标题栏文本,但该图标并不总是可用。

为了获取图标,我将 WM_GETICON 消息传递给 SendMessage ( source ):

Public Const WM_GETICON As UInteger = &H7F
Public Function GetWindowIcon(ByVal WindowHandle As IntPtr) As Icon
Dim IconHandle As IntPtr = SendMessage(WindowHandle, WM_GETICON, 0, 0)
If Not IconHandle = IntPtr.Zero Then
Return Icon.FromHandle(IconHandle)
Else
Return Nothing
End If
End Function

对于某些窗口,这只会返回正确的图标。对于其他人,它返回 Nothing,因为 IconHandle 等于 0。在 Windows 任务管理器和任务栏中,它们显示得很好。

这可能是什么原因造成的,我应该如何解决这个问题?

最佳答案

使用一些复制粘贴和乱搞,我最终得到了以下代码......但它现在适用于所有窗口。

基本上,它会尝试 WM_GETICON 来获得一个大图标。如果失败,它会调用 GetClassLong,有时会包含图标。否则,WM_GETICON 用于获取小图标。在前两种情况下,我必须将其转换为 Bitmap,将其调整为 16x16(我需要该大小),然后再将其转换回 Icon

Public Function GetClassLongPtr(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As IntPtr
If IntPtr.Size > 4 Then
Return GetClassLongPtr64(hWnd, nIndex)
Else
Return New IntPtr(GetClassLongPtr32(hWnd, nIndex))
End If
End Function

<DllImport("user32.dll", EntryPoint:="GetClassLong")> _
Public Function GetClassLongPtr32(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As UInteger
End Function

<DllImport("user32.dll", EntryPoint:="GetClassLongPtr")> _
Public Function GetClassLongPtr64(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As IntPtr
End Function

<DllImport("user32.dll")> _
Public Function SendMessage(ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Boolean, ByVal lParam As Int32) As Integer
End Function


Public Const WM_GETICON As UInteger = &H7F
Public Function GetWindowIcon(ByVal WindowHandle As IntPtr) As Icon
Dim IconHandle As IntPtr = SendMessage(WindowHandle, WM_GETICON, 1, 0)
If Not IconHandle = IntPtr.Zero Then
Dim _icon = Icon.FromHandle(IconHandle)
Dim bmp = _icon.ToBitmap
Dim scale_factor As Single = 16 / _icon.Size.Width

' Make a bitmap for the result.
Dim bm_dest As New Bitmap( _
CInt(bmp.Width * scale_factor), _
CInt(bmp.Height * scale_factor))

' Make a Graphics object for the result Bitmap.
Dim gr_dest As Graphics = Graphics.FromImage(bm_dest)

' Copy the source image into the destination bitmap.
gr_dest.DrawImage(bmp, 0, 0, _
bm_dest.Width + 1, _
bm_dest.Height + 1)

Return MakeIcon(bm_dest, 16, False)
'Return Icon.FromHandle(IconHandle)
Else
IconHandle = GetClassLongPtr(WindowHandle, -34)
If Not IconHandle = IntPtr.Zero Then
Dim _icon = Icon.FromHandle(IconHandle)

Dim bmp = _icon.ToBitmap
Dim scale_factor As Single = 16 / _icon.Size.Width

' Make a bitmap for the result.
Dim bm_dest As New Bitmap( _
CInt(bmp.Width * scale_factor), _
CInt(bmp.Height * scale_factor))

' Make a Graphics object for the result Bitmap.
Dim gr_dest As Graphics = Graphics.FromImage(bm_dest)

' Copy the source image into the destination bitmap.
gr_dest.DrawImage(bmp, 0, 0, _
bm_dest.Width + 1, _
bm_dest.Height + 1)

Return MakeIcon(bm_dest, 16, False)
Else
IconHandle = SendMessage(WindowHandle, WM_GETICON, 1, 0)
If Not IconHandle = IntPtr.Zero Then
Dim _icon = Icon.FromHandle(IconHandle)
Dim bmp = _icon.ToBitmap
Dim scale_factor As Single = 16 / _icon.Size.Width

' Make a bitmap for the result.
Dim bm_dest As New Bitmap( _
CInt(bmp.Width * scale_factor), _
CInt(bmp.Height * scale_factor))

' Make a Graphics object for the result Bitmap.
Dim gr_dest As Graphics = Graphics.FromImage(bm_dest)

' Copy the source image into the destination bitmap.
gr_dest.DrawImage(bmp, 0, 0, _
bm_dest.Width + 1, _
bm_dest.Height + 1)

Return MakeIcon(bm_dest, 16, False)
Else
Return Nothing
End If
End If
End If
End Function



''' <summary>
''' Converts an image into an icon.
''' </summary>
''' <param name="img">The image that shall become an icon</param>
''' <param name="size">The width and height of the icon. Standard
''' sizes are 16x16, 32x32, 48x48, 64x64.</param>
''' <param name="keepAspectRatio">Whether the image should be squashed into a
''' square or whether whitespace should be put around it.</param>
''' <returns>An icon!!</returns>
Private Function MakeIcon(ByVal img As Image, ByVal size As Integer, ByVal keepAspectRatio As Boolean) As Icon
Dim square As New Bitmap(size, size)
' create new bitmap
Dim g As Graphics = Graphics.FromImage(square)
' allow drawing to it
Dim x As Integer, y As Integer, w As Integer, h As Integer
' dimensions for new image
If Not keepAspectRatio OrElse img.Height = img.Width Then
' just fill the square
x = 0
y = 0
' set x and y to 0
' set width and height to size
w = size
h = size
Else
' work out the aspect ratio
Dim r As Single = CSng(img.Width) / CSng(img.Height)

' set dimensions accordingly to fit inside size^2 square
If r > 1 Then
' w is bigger, so divide h by r
w = size
h = CInt(Math.Truncate(CSng(size) / r))
x = 0
' center the image
y = (size - h) \ 2
Else
' h is bigger, so multiply w by r
w = CInt(Math.Truncate(CSng(size) * r))
h = size
y = 0
' center the image
x = (size - w) \ 2
End If
End If

' make the image shrink nicely by using HighQualityBicubic mode
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default
g.DrawImage(img, x, y, w, h)
' draw image with specified dimensions
'g.Flush()
' make sure all drawing operations complete before we get the icon
' following line would work directly on any image, but then
' it wouldn't look as nice.
Return Icon.FromHandle(square.GetHicon())
End Function

关于windows - WM_GETICON 有时不返回图标句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5542423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com