2017-08-04 30 views
0

我想知道是否可以從加載光標SetSystemCursor帶光標資源的SetSystemCursor

我的代碼:

Private Declare Function SetSystemCursor Lib "user32.dll" (ByVal hCursor As IntPtr, ByVal id As Integer) As Boolean 
Private Declare Function LoadCursorFromFile Lib "user32.dll" Alias "LoadCursorFromFileA" (ByVal lpFileName As String) As IntPtr 
Private Const IDC_ARROW As UInt32 = 32512 
Dim SavedCursor As Icon 

... 

SetSystemCursor(My.Ressources.CustomCursor, IDC_ARROW) 
+0

你試過你的代碼?錯誤?結果? –

回答

0

所有我只是想指出的SetSystemCursor()第二個參數應該是一個UInteger,不Integer首先:

Private Declare Function SetSystemCursor Lib "user32.dll" (ByVal hCursor As IntPtr, ByVal id As UInteger) As Boolean 

但是這幾天你應該聲明P /調用DllImport attribute

<DllImport("user32.dll")> 
Private Shared Function SetSystemCursor(ByVal hCursor As IntPtr, ByVal id As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

編輯:

我偶然發現this blog post從字節數組提供加載32位深度的遊標的一個非常簡潔的方式。

我已經將它轉換爲VB.NET並修復了一些非託管函數的數據類型,它看起來很完美!它可以在沒有問題的情況下加載32位遊標,您可以像使用其他遊標一樣使用它們。

我將該類重命名爲CursorHelper,因爲它具有更通用的名稱,因爲我實現了其中一些類中的一些方法。

貸記Jerome Viveiros爲原始代碼!

'+--------------------------------------------+' 
'|           |' 
'|    == CursorHelper ==    |' 
'|           |' 
'| Original name:  CursorResourceLoader |' 
'| Original creator: Jerome Viveiros  |' 
'|           |' 
'| VB.NET conversion: Visual Vincent  |' 
'| Misc. additions:  Visual Vincent  |' 
'|           |' 
'+--------------------------------------------+' 

'Original code from: 
'https://psycodedeveloper.wordpress.com/2013/05/26/how-to-load-an-embedded-cursor-from-resources-in-c-windows-forms/ 

Imports System.IO 
Imports System.Runtime.InteropServices 

Public NotInheritable Class CursorHelper 
    Private Sub New() 
    End Sub 

#Region "Methods" 
    ''' <summary> 
    ''' Creates a cursor from an array of bytes. 
    ''' </summary> 
    ''' <param name="cursorResource">The byte array to create the cursor from (must be data in a cursor format!).</param> 
    ''' <param name="ImageIndex">The index of the image to use as a cursor (usually cursors only have one image, so leave this at 0).</param> 
    ''' <remarks></remarks> 
    Public Shared Function LoadEmbeddedCursor(ByVal cursorResource As Byte(), Optional ByVal ImageIndex As Integer = 0) As Cursor 
     Dim ResourceHandle As GCHandle = GCHandle.Alloc(cursorResource, GCHandleType.Pinned) 
     Dim IconImage As IntPtr = IntPtr.Zero 
     Dim CursorHandle As IntPtr = IntPtr.Zero 

     Try 
      Dim Header As IconHeader = CType(Marshal.PtrToStructure(ResourceHandle.AddrOfPinnedObject(), GetType(IconHeader)), IconHeader) 

      If ImageIndex >= Header.count Then 
       Throw New ArgumentOutOfRangeException(ImageIndex) 
      End If 

      Dim IconInfoPtr As IntPtr = ResourceHandle.AddrOfPinnedObject() + Marshal.SizeOf(GetType(IconHeader)) + ImageIndex * Marshal.SizeOf(GetType(IconInfo)) 
      Dim Info As IconInfo = CType(Marshal.PtrToStructure(IconInfoPtr, GetType(IconInfo)), IconInfo) 

      IconImage = Marshal.AllocHGlobal(Info.size + 4) 
      Marshal.WriteInt16(IconImage + 0, Info.hotspot_x) 
      Marshal.WriteInt16(IconImage + 2, Info.hotspot_y) 
      Marshal.Copy(cursorResource, Info.offset, IconImage + 4, Info.size) 

      CursorHandle = NativeMethods.CreateIconFromResource(IconImage, Info.size + 4, False, &H30000) 
      Return New Cursor(CursorHandle) 

     Finally 
      If CursorHandle <> IntPtr.Zero Then 
       NativeMethods.DestroyIcon(CursorHandle) 
      End If 

      If IconImage <> IntPtr.Zero Then 
       Marshal.FreeHGlobal(IconImage) 
      End If 

      If ResourceHandle.IsAllocated Then 
       ResourceHandle.Free() 
      End If 
     End Try 
    End Function 

    ''' <summary> 
    ''' Creates a cursor from an array of bytes and sets it to be the specified system cursor. 
    ''' </summary> 
    ''' <param name="Bytes">The array of bytes to create the cursor from.</param> 
    ''' <param name="Type">The system cursor to assign the new cursor to.</param> 
    ''' <remarks></remarks> 
    Public Shared Function SetSystemCursor(ByVal Bytes As Byte(), ByVal Type As SystemCursor) As Boolean 
     Using Cursor As Cursor = CursorHelper.LoadEmbeddedCursor(Bytes) 
      Return CursorHelper.SetSystemCursor(Cursor, Type) 
     End Using 
    End Function 

    ''' <summary> 
    ''' Sets a cursor to be the specified system cursor. 
    ''' </summary> 
    ''' <param name="Handle">The handle of the new cursor.</param> 
    ''' <param name="Type">The system cursor to assign the new cursor to.</param> 
    ''' <remarks></remarks> 
    Public Shared Function SetSystemCursor(ByVal Handle As IntPtr, ByVal Type As SystemCursor) As Boolean 
     Return NativeMethods.SetSystemCursor(Handle, CType(Type, UInteger)) 
    End Function 

    ''' <summary> 
    ''' Sets a cursor to be the specified system cursor. 
    ''' </summary> 
    ''' <param name="Cursor">The new cursor.</param> 
    ''' <param name="Type">The system cursor to assign the new cursor to.</param> 
    ''' <remarks></remarks> 
    Public Shared Function SetSystemCursor(ByVal Cursor As Cursor, ByVal Type As SystemCursor) As Boolean 
     Return NativeMethods.SetSystemCursor(Cursor.Handle, CType(Type, UInteger)) 
    End Function 
#End Region 

#Region "Enumerations" 
    Public Enum SystemCursor As UInteger 
     ''' <summary> 
     ''' Standard arrow and small hourglass 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_APPSTARTING = 32650 

     ''' <summary> 
     ''' Standard arrow 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_NORMAL = 32512 

     ''' <summary> 
     ''' Crosshair 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_CROSS = 32515 

     ''' <summary> 
     ''' Hand 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_HAND = 32649 

     ''' <summary> 
     ''' Arrow and question mark 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_HELP = 32651 

     ''' <summary> 
     ''' I-beam 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_IBEAM = 32513 

     ''' <summary> 
     ''' Slashed circle 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_NO = 32648 

     ''' <summary> 
     ''' Four-pointed arrow pointing north, south, east, and west 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_SIZEALL = 32646 

     ''' <summary> 
     ''' Double-pointed arrow pointing northeast and southwest 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_SIZENESW = 32643 

     ''' <summary> 
     ''' Double-pointed arrow pointing north and south 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_SIZENS = 32645 

     ''' <summary> 
     ''' Double-pointed arrow pointing northwest and southeast 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_SIZENWSE = 32642 

     ''' <summary> 
     ''' Double-pointed arrow pointing west and east 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_SIZEWE = 32644 

     ''' <summary> 
     ''' Vertical arrow 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_UP = 32516 

     ''' <summary> 
     ''' Hourglass 
     ''' </summary> 
     ''' <remarks></remarks> 
     OCR_WAIT = 32514 
    End Enum 
#End Region 

#Region "Native Methods" 
    Private NotInheritable Class NativeMethods 
     Private Sub New() 
     End Sub 

     <DllImport("user32.dll", SetLastError:=True)> _ 
     Public Shared Function DestroyIcon(ByVal hIcon As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean 
     End Function 

     <DllImport("user32.dll", SetLastError:=True)> _ 
     Public Shared Function CreateIconFromResource(ByVal presbits As IntPtr, ByVal dwResSize As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal fIcon As Boolean, ByVal dwVer As UInteger) As IntPtr 
     End Function 

     <DllImport("user32.dll")> _ 
     Public Shared Function SetSystemCursor(ByVal hCursor As IntPtr, ByVal id As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean 
     End Function 
    End Class 
#End Region 

#Region "Native Structures" 
    <StructLayout(LayoutKind.Explicit, Pack:=1)> _ 
    Private Structure IconHeader 
     <FieldOffset(0)> _ 
     Public reserved As Short 

     <FieldOffset(2)> _ 
     Public type As Short 

     <FieldOffset(4)> _ 
     Public count As Short 
    End Structure 

    <StructLayout(LayoutKind.Explicit, Pack:=1)> _ 
    Private Structure IconInfo 
     <FieldOffset(0)> _ 
     Public width As Byte 

     <FieldOffset(1)> _ 
     Public height As Byte 

     <FieldOffset(2)> _ 
     Public colors As Byte 

     <FieldOffset(3)> _ 
     Public reserved As Byte 

     <FieldOffset(4)> _ 
     Public planes As Short 

     <FieldOffset(6)> _ 
     Public bpp As Short 

     <FieldOffset(4)> _ 
     Public hotspot_x As Short 

     <FieldOffset(6)> _ 
     Public hotspot_y As Short 

     <FieldOffset(8)> _ 
     Public size As Integer 

     <FieldOffset(12)> _ 
     Public offset As Integer 
    End Structure 

#End Region 

End Class 

用法示例:

CursorHelper.SetSystemCursor(My.Resources.CustomCursor, CursorHelper.SystemCursor.OCR_NORMAL) 
+0

我有一個小問題,光標變成全黑。但是,如果我把它放在窗口中,它不是全黑的,否則它會工作。 – Jni

+0

@Jni:如果使用'LoadCursorFromFile()'從文件加載遊標,會發生同樣的事情嗎? –

+0

我不知道它不與LoadCursorFile一起工作,如果你不知道它沒有問題,我只是想知道你是否有想法。 – Jni