Page 1 of 2 12 LastLast
Results 1 to 40 of 56

Thread: Create and load Cursor from byte array.

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Create and load Cursor from byte array.

    Hi all,

    Below is a byte dump of .cur file .

    I want to store those dump bytes in an array and from the bytes, re-create the cursor and get its handle so I can pass the handle to the SetCursor API.

    I know I can get the cursor handle if I use the LoadCursorfromFile API but I don't want to use a file .. I want to load the cursor from the byte array in memory.

    Regards.

    Cursor file dump.
    Code:
    00 00 02 00 01 00 20 20 10 00 0c 00 01 00 e8 02
    00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00
    00 00 01 00 04 00 00 00 00 00 80 02 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00
    00 00 80 00 80 00 80 80 00 00 80 80 80 00 c0 c0
    c0 00 00 00 ff 00 00 ff 00 00 00 ff ff 00 ff 00
    00 00 ff 00 ff 00 ff ff 00 00 ff ff ff 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 0f ff ff f8 00 00 00 00 00 00 00 00
    00 00 00 00 ff ff ff ff 80 00 00 00 00 00 00 00
    00 00 00 0f ff ff ff ff 80 00 00 00 00 00 00 00
    00 00 00 ff ff ff ff ff f8 00 00 00 00 00 00 00
    00 00 00 ff ff ff ff ff f8 00 00 00 00 00 00 00
    00 00 0f ff ff ff ff ff f8 00 00 00 00 00 00 00
    00 00 0f ff ff ff ff ff ff 80 00 00 00 00 00 00
    00 00 ff ff ff ff ff ff ff 80 00 00 00 00 00 00
    00 00 ff 88 ff ff ff ff ff 80 00 00 00 00 00 00
    00 0f f8 00 ff ff ff ff ff 80 00 00 00 00 00 00
    00 0f 80 00 ff ff ff ff 7f 80 00 00 00 00 00 00
    00 f8 00 00 ff 7f f7 f8 0f 80 00 00 00 00 00 00
    00 00 00 00 f8 0f 80 f8 0f 80 00 00 00 00 00 00
    00 00 00 00 f8 0f 80 f8 00 00 00 00 00 00 00 00
    00 00 00 00 f8 0f 80 f8 00 00 00 00 00 00 00 00
    00 00 00 00 f8 0f 80 00 00 00 00 00 00 00 00 00
    00 00 00 00 f8 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 f8 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 f8 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 f8 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 f8 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff f8
    07 ff ff f0 07 ff ff e0 03 ff ff c0 03 ff ff 80
    01 ff ff 80 01 ff ff 00 01 ff ff 00 00 ff fe 00
    00 ff fe 00 00 ff fc 00 00 ff fc 20 00 ff f8 60
    00 ff fc e0 00 ff ff e0 01 ff ff e0 07 ff ff e0
    0f ff ff e0 7f ff ff e1 ff ff ff e1 ff ff ff e1
    ff ff ff e1 ff ff ff f3 ff ff ff ff ff ff

  2. #2

  3. #3
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Create and load Cursor from byte array.

    Sorry to interrupt this thread but is it possible to create a mouse pointer image from any bitmap I have and at the size of the bitmap.

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Thanks The trick.

    I never knew about this handy CreateIconFromResourceEx API function.

    However, this seems to works only for PNG files not for .ICO or .CUR files

    Also, as opposed to what the documentation says, it doesn't seem to return a propper handle to the cursor or icon which you can then pass to the SetCursor API

    Below is a code that uses the CreateIconFromResourceEx API to create a handle from a PNG file (hand.png) which I downloaded from the internet.

    The LoadPNGtoICO function sucessfully returns a IPicture object and it also can be passed to the DrawIcon API to draw the icon onto the DC BUT the following doesn't work :

    Code:
    SetCursor hIcon
    I need to use the SetCursor API in the Form's mouse move event dynamically.


    This code works fine for creating a IPicture Object and for using the DrawIcon API BUT doesn't work work for the SetCursor API
    Code:
    Option Explicit
    
    Private Type uPicDesc
        Size As Long
        Type As Long
        hPic As Long
        hPal As Long
    End Type
    
    Private Type GUID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(0 To 7) As Byte
    End Type
    
    
    Private Declare Function CreateIconFromResourceEx Lib "user32.dll" (ByRef presbits As Any, ByVal dwResSize As Long, ByVal fIcon As Long, ByVal dwVer As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal Flags As Long) As Long
    Private Declare Function OleCreatePictureIndirect Lib "OleAut32.dll" (lpPictDesc As Any, riid As Any, ByVal fPictureOwnsHandle As Long, ipic As IPicture) As Long
    Private Declare Function CopyImage Lib "user32" (ByVal handle As Long, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
    Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long
    Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Long
    Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
    
    Private Const vbPicTypeIcon As Long = 3
    Private hIcon As Long, hCopy As Long
    
     
        
    Private Sub Command1_Click()
        
        Dim tPicture As StdPicture
        Dim imgData() As Byte, fnr As Integer, lSize As Long
        Dim hdc As Long
        
        
        fnr = FreeFile()
        On Error Resume Next
        
        Open app.Path & "\hand.png" For Binary As #fnr
        
        If Err Then
            MsgBox Err.Description
            Exit Sub
        End If
        On Error GoTo 0
        lSize = LOF(fnr)
        If lSize = 0& Then
            MsgBox "File does not exist", vbExclamation + vbOKOnly
            Close #fnr
            Exit Sub
        End If
        ReDim imgData(0 To lSize - 1&)
        Get #fnr, 1, imgData()
        Close #fnr
        
        Set tPicture = LoadPNGtoICO(imgData())
        Set Me.Picture = tPicture
        
        If tPicture Is Nothing Then
        MsgBox "Failed to load the file. May not be valid PNG format or pre-Vista operating system.", vbExclamation + vbOKOnly
        Else
        'DrawIcon ALSO WORKS !!!
        DrawIcon Me.hdc, 0, 0, hIcon
        End If
        
        DestroyIcon hIcon
        DestroyIcon hCopy
        
    End Sub
        
        
    
    Function LoadPNGtoICO(pngData() As Byte) As IPicture
        
        Const IMAGE_CURSOR = 2
        Const IMAGE_ICON = 1
        Const LR_COPYRETURNORG = &H4
        
        Dim IID_IDispatch As GUID, uPicinfo As uPicDesc
        
        
        hIcon = CreateIconFromResourceEx(pngData(0), UBound(pngData) + 1&, 1&, &H30000, 0&, 0&, 0&)
         hCopy = CopyImage(hIcon, IMAGE_CURSOR, 0, 0, LR_COPYRETURNORG)
        
        If hCopy Then
            With uPicinfo
                .Size = Len(uPicinfo)
                .Type = vbPicTypeIcon
                .hPic = hCopy
                .hPal = 0
            End With
            
            With IID_IDispatch
                .Data1 = &H20400
                .Data4(0) = &HC0
                .Data4(7) = &H46
            End With
            
            Call OleCreatePictureIndirect(uPicinfo, IID_IDispatch, True, LoadPNGtoICO)
        
        End If
        
    End Function

    Regards.
    Last edited by JAAFAR; Jun 10th, 2019 at 04:41 PM.

  5. #5
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    CreateIconFromResourceEx works for icons & cursors also, but for cursors, you need to prefix the bits with 4 bytes: Cursor HotSpot
    1st 2 bytes is HotSpotX
    2nd 2 bytes is HotSpotY
    remaining bytes is the pixel data in proper format, i.e., BitmapInfoHeader followed by mask/and bits
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by Code Dummy View Post
    Sorry to interrupt this thread but is it possible to create a mouse pointer image from any bitmap I have and at the size of the bitmap.
    An old MS KB article said:

    Cursor sizes

    Although cursors can, in theory, be any size, the system imposes a standard size that is exposed by means of the SM_CXCURSOR and SM_CYCURSOR values. These metrics are read-only. On standard, low-DPI systems, these metrics are set to 32x32 pixels (32 bytes/row). When the system loads cursors by means of the standard LoadCursor function, the cursor is stretched to this dimension.

    Most system cursors appear smaller than 32x32 and do not use some of the space around the cursor. The cursors in the extra-large schemes use more of the available 32x32 area. Windows XP does not include any system cursors that are larger than 32x32. (If larger cursors were included, they would be stretched down to 32x32 when the standard APIs load the cursors.)

    For high-DPI systems, Windows XP has adjusted the SM_CXCURSOR and SM_CYCURSOR values to be 64x64 pixels. This size adjustment is to prevent the mouse pointer from virtually disappearing because it is too small to be effectively used. Although the other aspects of the system scale with DPI, the mouse pointer does not scale. Microsoft does not try to enforce a DPI-independent size for the mouse pointer.

    The system also provides the SetSystemCursor API function that you can use to change the system cursor for specific categories. You can use this function to set a cursor of any size. However, you must call the function programmatically, and you can only use it to set a cursor for a specific category. You cannot use it to make all cursors on the system the same size.

    For cursor sets that you want to use on high-DPI systems, Microsoft recommends that you author them with both 32x32 and 64x64 candidates. The system will select the appropriate candidate during loading, depending on the DPI of the system.
    That is supposed to be Q307213 but I can't find it online.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    CreateIconFromResourceEx works for icons & cursors also, but for cursors, you need to prefix the bits with 4 bytes: Cursor HotSpot
    1st 2 bytes is HotSpotX
    2nd 2 bytes is HotSpotY
    remaining bytes is the pixel data in proper format, i.e., BitmapInfoHeader followed by mask/and bits
    This is new territory to me.

    Is the CreateDIBSection API the right way to create the bitmap ?

    And if so, I don't know how to determine the correct Width and Height in the bitmap header based on the hex dump .

    Regards.

  8. #8
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by JAAFAR View Post
    This is new territory to me.

    Is the CreateDIBSection API the right way to create the bitmap ?

    And if so, I don't know how to determine the correct Width and Height in the bitmap header based on the hex dump .

    Regards.
    You can assume the dimensions are square, but that wouldn't be fool-proof. Based on that idea, if you have a hex dump of 256 pixels, then your icon/cursor is 16x16: Sqr(256). And if a cursor, you can assume the hotspot is dead center or top left, but that would not be a good assumption. A lot of assumptions....

    Regarding CreateDibSection... no, the CreateIconFromResourceEx just requires a byte array. But you'll need to know how to write all the info to that byte array. That requires knowledge of the binary format of a cursor/icon
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by JAAFAR View Post
    This is new territory to me.
    I was curious and looked at your dump closer. That dump is a complete cursor resource. Sending it to the API just needs a little tweak...

    Explaining your hex dump
    1st 6 bytes is the ICONDIR. In that structure, is the number of images in the entire file
    next 16 bytes is the ICONDIRENTRY. One of these for each image in the file
    after the last ICONDIRENTRY are the icon/cursor data of each image, stacked
    Code:
    -------- the 1st 22 bytes  below are a standard icon/cursor header for 1 image
    if more than 1 image, bytes 7-22 are repeated with different values
    
    /// ICONDIR
    00 00 02 00 << header meaning Cursor, last two would be 01 00 if icon
    01 00 	<< nr images in this dump
    /// ICONDIRENTRY #1
    20 	<< image width = 32, note: 0 = 256+
    20 	<< image height =32, note: 0 = 256+
    10 	<< image color count = 16
    00 	<< reserved
    0c 00 	<< cursor hotspotX (12) or planes for icons
    01 00 	<< cursor hotspotY (1) or bitcount for icons
    e8 02 00 00 << size of resource = 744
    16 00 00 00 << offset in dump where icon/cursor starts = 22
    
    ------- BitmapInfoHeader starts here, followed by color table (if any) and then pixel data
    28 00 00 00   << 40 size of bitmapinfoheader structure
    20 00 00 00   << 32 width of image
    40 00 00 00   << 64 height of image (icon/cursor are always doubled)
    ....
    Based on this information, you can send the dump to the API after tweaking just 4 bytes:
    - I'll assume the entire dump is in a byte array: bData(0 to SizeOf(dump) - 1)

    After parsing the the above info, we know:
    - BitmapInfoHeader starts at byte 22 in the array, per parsing at ICONDIRENTRY# * 16 + 18
    - Size of the resource is 744, per parsing at ICONDIRENTRY# * 16 + 14
    - hotspotX & hotspotY are at bytes 10-13 in the array ICONDIRENTRY# * 16 + 10

    Since this is a cursor, copy the hotspot to the 4 bytes immediately preceding the BitmapInfoHeader.
    - preserve the original bytes if needed and restore after array sent to the API
    For i = 0 to 3: bData(18 + i) = bData(10 + i): Next

    Now send the array to the API ByRef as: bData(18). Size of data passed is 744 + 4 (including the hotspot's 4 bytes)

    Edited & FYI:
    If resource is a PNG, then the entire PNG file begins where the BitmapInfoHeader is expected and the 1st 4 bytes = 1196314761 (PNG signature). Also, if the image size is zero, I typically parse the BitmapInfoHeader/PNG header to determine actual size. And last, the color count member of the ICONDIRENTRY is not always filled in nor trustworthy. If it is important to you, it should be parsed from the BitmapInfoHeader/PNG header
    Last edited by LaVolpe; Jun 14th, 2019 at 09:14 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    I was curious and looked at your dump closer. That dump is a complete cursor resource. Sending it to the API just needs a little tweak...

    Thank you for investigating this further.

    With the help of a bitmap/cursor editor, I created a simple (32x32 pix) bitmap (16 colors) (file size 630 bytes ) ... This is just a small Red drag cursor.

    I then loaded the bitmap on a picture object that I have embedeed on an excel worksheet .

    I then copied the picture image to the clipborad using :

    Step1-
    Code:
    Pic.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
    OpenClipboard 0
    hPtr = GetClipboardData(CF_BITMAP)
    hBmp = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)
    The above sucessfully returns a valid memory handle to the bitmap in the hBmp variable.

    Then I fill-in the BitInfo.bmiHeader with the corresponding values and then I make a call to the GetDIBits API as follows:

    Step2-
    Code:
    GetDIBits hdc, hBmp , 0, BitInfo.bmiHeader.biHeight, Bits(1, 1, 1), BitInfo, DIB_RGB_COLORS
    
    SetDIBitsToDevice hdc, 0, 0, BitInfo.bmiHeader.biWidth, BitInfo.bmiHeader.biHeight, _
      0, 0, 0, BitInfo.bmiHeader.biHeight, Bits(1, 1, 1), BitInfo, DIB_RGB_COLORS
    Step3-

    Finally, I set up the necessary data for the icon structure as well as the icon masks and call CreateIconIndirect

    The above steps work sucessfully and get me a valid cursor handle that I pass to the SetCursor API and display the correct cursor image as expected.

    What I want:
    I want to store the bits of the bitmap that I placed in the clipboard (in step1) in an array and create the bitmap from the bits in that array ... I want to skip the need of copying the bitmap to the clipboard and getting the bitmap handle from there.

    I used the CreateBitmap API and passed the bitmap bits to it (I got the bitmap bits from the above call to GetDIBits) but I keep getting a black 32x32 icon

    I also tried CreateDIBSection/SetDIBits to create the memory bitmap from the stored bits but without success.

    Does the GetDIBits API retrieve the bitmap pixel data alone or the bitmap header data + the pixel data ? I think that's where lies my confusion.

    I hope I have explained the situation clearly.

    Regards.
    Last edited by JAAFAR; Jun 15th, 2019 at 12:05 AM.

  11. #11
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    If you just need a copy of the bitmap, why not use CopyImage and be done with it?

    Regarding your original idea of using the data from a valid cursor file, far less of a headache. If the cursor file has just 1 image in it, this is all that is needed...

    1. Extract just the bytes you need for your cursor from that file & save the bytes with your Excel project. This is done one time, outside of your project.
    Code:
    Dim bData() As Byte, lHotSpot As Integer
    Dim hCur As Long, fNr As Integer
    
    fNr = FreeFile()
    Open "C:\...\myCursor.cur" For Binary As #fNr   ' << change name to valid file
    ReDim bData(1 To LOF(fNr) - 18) ' need entire file less 18 bytes
    Get #fNr, 19, bData() ' start at 19th byte in file
        Get #fNr, 11, lHotSpot
        bData(1) = lHotSpot And &HFF
        bData(2) = (lHotSpot And &HFFFF&) \ &H100
        Get #fNr, 13, lHotSpot
        bData(3) = lHotSpot And &HFF
        bData(4) = (lHotSpot And &HFFFF&) \ &H100
    Close #fNr
    2. Now bData() has the bytes you need, write them to a temp file and load them into your Excel project

    3. Whenever you need the cursor, get the bytes, and assuming one-bound array...
    Code:
    hCur = CreateIconFromResourceEx(bData(1), UBound(bData), 0&, &H30000, Cx, Cy, 0&)
    FYI: the 5th byte (1-bound) of the file will tell you how many images are inside the file
    with the API:
    3rd param is 0 for cursor, 1 for icon
    And Cx,Cy can be zero unless you want to change the size of the cursor
    Last edited by LaVolpe; Jun 15th, 2019 at 10:40 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    If you just need a copy of the bitmap, why not use CopyImage and be done with it?

    Regarding your original idea of using the data from a valid cursor file, far less of a headache. If the cursor file has just 1 image in it, this is all that is needed...

    1. Extract just the bytes you need for your cursor from that file & save the bytes with your Excel project. This is done one time, outside of your project.
    Code:
    Dim bData() As Byte, lHotSpot As Integer
    Dim hCur As Long, fNr As Integer
    
    fNr = FreeFile()
    Open "C:\...\myCursor.cur" For Binary As #fNr   ' << change name to valid file
    ReDim bData(1 To LOF(fNr) - 18) ' need entire file less 18 bytes
    Get #fNr, 19, bData() ' start at 19th byte in file
        Get #fNr, 11, lHotSpot
        bData(1) = lHotSpot And &HFF
        bData(2) = (lHotSpot And &HFFFF&) \ &H100
        Get #fNr, 13, lHotSpot
        bData(3) = lHotSpot And &HFF
        bData(4) = (lHotSpot And &HFFFF&) \ &H100
    Close #fNr
    2. Now bData() has the bytes you need, write them to a temp file and load them into your Excel project

    3. Whenever you need the cursor, get the bytes, and assuming one-bound array...
    Code:
    hCur = CreateIconFromResourceEx(bData(1), UBound(bData), 0&, &H30000, Cx, Cy, 0&)
    FYI: the 5th byte (1-bound) of the file will tell you how many images are inside the file
    with the API:
    3rd param is 0 for cursor, 1 for icon
    And Cx,Cy can be zero unless you want to change the size of the cursor
    That sounds great... I never knew about this handy CreateIconFromResourceEx API function !

    I'll give this a try and will post back what the result I get.

    Thank you very much for your guidance.

  13. #13

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Ok - I seem to have managed to make this work for x32 and x64 bit.

    workbook test

    This the code I used in the excel userform module
    Code:
    Option Explicit
    
    #If VBA7 Then
        Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, source As Any, ByVal Length As LongPtr)
        Private Declare PtrSafe Function SetCursor Lib "user32" (ByVal hCursor As LongPtr) As LongPtr
        Private Declare PtrSafe Function DeleteObject Lib "gdi32" (ByVal hObject As LongPtr) As Long
        Private Declare PtrSafe Function CreateIconFromResourceEx Lib "user32.dll" (ByRef presbits As Any, ByVal dwResSize As Long, ByVal fIcon As Long, ByVal dwVer As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal Flags As Long) As Long
        Private hCur As LongPtr
    
    #Else
        Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
        Private Declare Function SetCursor Lib "user32" (ByVal hCursor As Long) As Long
        Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
        Private Declare Function CreateIconFromResourceEx Lib "user32.dll" (ByRef presbits As Any, ByVal dwResSize As Long, ByVal fIcon As Long, ByVal dwVer As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal Flags As Long) As Long
        Private hCur As Long
    
    #End If
    
    
    
    Private Sub UserForm_Initialize()
        hCur = GetCurHandle
        If hCur = 0 Then Debug.Print "failed to get a valid cursor handle."
    End Sub
    
    Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
     If hCur Then SetCursor hCur
    End Sub
    
    Private Sub UserForm_Terminate()
        DeleteObject hCur
    End Sub
    
    
    
    #If Win64 Then
        Private Function GetCurHandle() As LongPtr
        Const PTR_LEN = 6
    #Else
        Private Function GetCurHandle() As Long
        Const PTR_LEN = 4
    #End If
    
        Dim iByteCnt As Integer, iPos As Integer
        Dim vArTemp1() As Variant, vArTemp2() As Variant, vArTemp3() As Variant, vArTemp4() As Variant
        
        
        vArTemp1 = Array(0, 0, 0, 0, 40, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, 128, _
        2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, _
        0, 128, 0, 0, 0, 128, 128, 0, 128, 0, 0, 0, 128, 0, 128, 0, 128, 128, 0, 0, _
        192, 192, 192, 0, 128, 128, 128, 0, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 255, _
        0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, _
        144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, _
        0, 0, 144, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, _
        0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0)
        
        vArTemp2 = Array(0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 9, _
        0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, _
        0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 144, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, _
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 153, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, _
        0, 9, 153, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 153, 153, 0, 0, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 0, 153, 144, 153, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 153, _
        144, 0, 0, 0, 0, 0, 0, 0, 0)
        
        iPos = UBound(vArTemp1)
        ReDim Preserve vArTemp1(UBound(vArTemp1) + UBound(vArTemp2) + 1)
        CopyMemory ByVal VarPtr(vArTemp1(iPos + 1)), ByVal VarPtr(vArTemp2(0)), PTR_LEN * 4 * (UBound(vArTemp2) + 1)
        
        vArTemp3 = Array(0, 0, 0, 0, 153, 153, 153, 153, 153, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, _
        153, 153, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 153, 153, 144, 0, 0, 0, 0, _
        0, 0, 0, 0, 0, 0, 0, 153, 153, 153, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, _
        153, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 153, 153, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 0, 0, 0, 0, _
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, _
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
        255, 255, 255, 255, 255, 255, 255, 255, 255, 234, 170, 191, 255, 245, 85, 127, _
        255, 239, 255, 191, 255, 247, 255, 127, 255, 239, 255, 191, 255, 247, 255, 127)
        
        iPos = UBound(vArTemp1)
        ReDim Preserve vArTemp1(UBound(vArTemp1) + UBound(vArTemp3) + 1)
        CopyMemory ByVal VarPtr(vArTemp1(iPos + 1)), ByVal VarPtr(vArTemp3(0)), PTR_LEN * 4 * (UBound(vArTemp3) + 1)
        
        vArTemp4 = Array(255, 239, 255, 191, 255, 247, 255, 127, 255, 239, 255, 191, 255, 245, 85, 127, _
        255, 234, 170, 191, 254, 127, 255, 255, 252, 63, 255, 255, 252, 63, 255, 255, _
        248, 127, 255, 255, 120, 127, 255, 255, 48, 255, 255, 255, 16, 255, 255, 255, _
        1, 255, 255, 255, 0, 31, 255, 255, 0, 63, 255, 255, 0, 127, 255, 255, 0, 255, 255, _
        255, 1, 255, 255, 255, 3, 255, 255, 255, 7, 255, 255, 255, 15, 255, 255, 255, _
        31, 255, 255, 255, 63, 255, 255, 255, 127, 255, 255, 255)
        
        
        iPos = UBound(vArTemp1)
        ReDim Preserve vArTemp1(UBound(vArTemp1) + UBound(vArTemp4) + 1)
        CopyMemory ByVal VarPtr(vArTemp1(iPos + 1)), ByVal VarPtr(vArTemp4(0)), PTR_LEN * 4 * (UBound(vArTemp4) + 1)
        
        ReDim bytes(LBound(vArTemp1) To UBound(vArTemp1)) As Byte
        For iByteCnt = LBound(vArTemp1) To UBound(vArTemp1)
            bytes(iByteCnt) = CByte(vArTemp1(iByteCnt))
        Next
        
        GetCurHandle = CreateIconFromResourceEx(bytes(0), UBound(bytes) + 1, 0&, &H30000, 0, 0, 0&)
    
    End Function
    Thanks very much LaVolpe for your guidance and patience .. I wouldn't have been able to solve this without your help - I really appreciate it.

    Regards.
    Last edited by JAAFAR; Jun 15th, 2019 at 03:01 PM.

  14. #14
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    Glad you got it to work. Keep in mind that if you want to play with other cursor files, you need to ensure the file only has 1 image. Otherwise, that sample code to extract the needed bytes will fail. If that does apply, you can either parse the file and extract bytes or use some other app that allows you to extract individual cursors from files that have multiple cursors.

    Happy to assist

    Edited: Oh hey, are you sure about your API call? Bytes(0) & UBound(bytes)? Should it be UBound(bytes)+1 or bytes(1) instead?
    Last edited by LaVolpe; Jun 15th, 2019 at 02:20 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  15. #15

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    Glad you got it to work. Keep in mind that if you want to play with other cursor files, you need to ensure the file only has 1 image. Otherwise, that sample code to extract the needed bytes will fail. If that does apply, you can either parse the file and extract bytes or use some other app that allows you to extract individual cursors from files that have multiple cursors.

    Happy to assist

    Edited: Oh hey, are you sure about your API call? Bytes(0) & UBound(bytes)? Should it be UBound(bytes)+1 or bytes(1) instead?
    Yes I would normally use a file that has 1 image for the moment until I get a grasp of the memory layout internals of Cursors, Icons and bitmaps which I am still trying properly understand.

    As for Bytes(0) vs Bytes(1), passing Byes(1) to the CreateIconFromResourceEx API returns 0

    Regards.

  16. #16
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    Regarding my question, this is your code statement
    GetCurHandle = CreateIconFromResourceEx(bytes(0), UBound(bytes), 0&, &H30000, 0, 0, 0&)

    I think the bolded part should be: UBound(bytes)+1
    or at least: UBound(bytes) - LBound(bytes) + 1
    unless you purposely resized your array 1 byte greater than the number of bytes needed for the cursor
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  17. #17

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    Regarding my question, this is your code statement
    GetCurHandle = CreateIconFromResourceEx(bytes(0), UBound(bytes), 0&, &H30000, 0, 0, 0&)

    I think the bolded part should be: UBound(bytes)+1
    or at least: UBound(bytes) - LBound(bytes) + 1
    unless you purposely resized your array 1 byte greater than the number of bytes needed for the cursor
    Yes If I understand you correctly ,you are right. It should be UBound(bytes)+1 to include all the bytes as I am using the default Optiion Base 0.

    However, the cursor is still created without UBound(bytes)+1

  18. #18
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    The API may just assume the missing byte is zero? Better to be safe than sorry though.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  19. #19

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    The API may just assume the missing byte is zero? Better to be safe than sorry though.
    Yes- That's what I thought as well. However, the last byte happens to be 255 not 0 unless the API starts in reverse order beginning from the last element in the array.

    Anyway, I have edited the code in post #13 with the correct byte array size..

    Thank you very much.
    Last edited by JAAFAR; Jun 15th, 2019 at 03:16 PM.

  20. #20
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    Oh, here is one minor optimization...

    You can use a LONG array vs a byte array. The way bitmap/icon/cursor data is formatted (on DWord boundaries and BitmapInfo always being a multiple of 4), the number of bytes needs should always be a multiple of 4.

    That would reduce the number of lines in your Array() statements and your loop count when transferring from the variant array. However, be sure to include the & suffix, if you go that route, for each Array() entry, i.e., 0& not 0. Otherwise, the entry will be treated as Integer vs Long for values < &H10000

    Of course, you would have to tweak other parts of your code, i.e., nr of bytes sent to the API will be UBound(longs)*4+4
    Last edited by LaVolpe; Jun 15th, 2019 at 03:29 PM. Reason: clariifed when values treated as Integer vs Long
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  21. #21

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    Oh, here is one minor optimization...

    You can use a LONG array vs a byte array. The way bitmap/icon/cursor data is formatted (on DWord boundaries and BitmapInfo always being a multiple of 4), the number of bytes needs should always be a multiple of 4.

    That would reduce the number of lines in your Array() statements and your loop count when transferring from the variant array. However, be sure to include the & suffix, if you go that route, for each Array() entry, i.e., 0& not 0. Otherwise, the entry will be treated as Integer vs Long. It makes a difference for values between &H8000 to &H8FFF

    Of course, you would have to tweak other parts of your code, i.e., nr of bytes sent to the API will be UBound(longs)*4+4
    I'll look into that when I feel more confortable with handling memory parts of image files - But first, I will need to roll up my sleeves and do some studying

    Regards.

  22. #22
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    I was thinking something like the following. This sample will create a text file you can copy & paste right into your Excel module. Rename the array from "longs" to whatever you want. Using something like the following will negate needing to create those variant arrays and transferring them to another array.

    Code:
    Dim bData() As Long, n As Integer, x As Long
    Dim sText As String, fNr As Integer
    
    fNr = FreeFile()
    Open "C:\...\myCursor.cur" For Binary As #fNr <<< change to valid cursor file
    Get #fNr, 5, n
    If n <> 1 Then
        Close #fNr
        Stop ' more than 1 file in array
    End If
    Get #fNr, 15, x
    If (x Mod 4) <> 0 Then
        Close #fNr
        Stop    ' image size is expected to be multiple of 4
    End If
    
    ReDim bData(1 To x \ 4 + 1) ' image size + hotspot
    Get #fNr, 19, bData() ' start at 19th byte in file
    Get #fNr, 11, bData(1) ' get hotspot into 1st element
    Close #fNr
    
    fNr = FreeFile()
    Open "C:\...\formattedArray.txt" For Output As #fNr  ' <<< change folder
    
    n = 1
    Print #fNr, "ReDim longs(0 To " & CStr(UBound(bData) - 1) & ") As Long"
    For x = 1 To UBound(bData)
        Print #fNr, "longs(" & CStr(x - 1) & ") = " & CStr(bData(x));
        If n = 30 Then
            Print #fNr, vbCrLf;
            n = 1
        Else
            Print #fNr, ": ";
            n = n + 1
        End If
    Next
    Close #fNr
    Then your API call looks like:
    GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) * 4 + 4, 0&, &H30000, 0, 0, 0&)

    I use something like the above when I create thunks and want to hardcode the array elements inside a module/class
    Last edited by LaVolpe; Jun 16th, 2019 at 06:32 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  23. #23
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Create and load Cursor from byte array.

    I thought there was an issue that cursors must be created from locked memory that stays resident as long as the cursor handle is valid. Isn't that why they are supposed to be created from a resource?

    I can't find it, but I seem to remember an old MS KB article about display driver crashes that could lead to a Blue Screen crash in both Win9x and WinNT. But maybe that's obsolete and drivers now protect themselves?

  24. #24
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    @dilettante. If so, I'd assume that all MS APIs that create cursors take care of that, i.e., LoadImage (which is recommended over LoadCursor) and others.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  25. #25

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    I was thinking something like the following. This sample will create a text file you can copy & paste right into your Excel module. Rename the array from "longs" to whatever you want. Using something like the following will negate needing to create those variant arrays and transferring them to another array.

    Code:
    Dim bData() As Long, n As Integer, x As Long
    Dim fNr As Integer
    
    fNr = FreeFile()
    Open "C:\...\myCursor.cur" For Binary As #fnr   ' <<< change to valid cursor file
    If ((LOF(fNr) - 6) Mod 4) <> 0 Then
        Close #fNr
        Stop    ' file size is expected to be multiple of 4
    End If
    Get #fNr, 5, n
    If n <> 1 Then
        Close #fNr
        Stop ' more than 1 file in array
    End If
    ReDim bData(1 To (LOF(fNr) - 18) \ 4) ' need entire file less 18 bytes
    Get #fNr, 19, bData() ' start at 19th byte in file
    Get #fNr, 11, bData(1) ' get hotspot into 1st element
    Close #fNr
    
    fNr = FreeFile()
    Open "C:\...\formattedArray.txt" For Output As #fNr  ' <<< change to desired folder
    n = 0
    Print #fNr, "ReDim longs(0 To " & CStr(UBound(bData) - 1) & ")"
    For x = 1 To UBound(bData)
        Print #fNr, "longs(" & CStr(x - 1) & ") = " & CStr(bData(x));
        If n = 29 Then
            Print #fNr, vbCrLf;
            n = 0
        Else
            Print #fNr, ": ";
            n = n + 1
        End If
    Next
    Close #fNr
    Then your API call looks like:
    GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) * 4 + 4, 0&, &H30000, 0, 0, 0&)

    I use something like the above when I create thunks and want to hardcode the array elements inside a module/class
    Thanks LaVolpe,

    That is cool but unless I am missing something, doesn't that defeat my purpose as there will be a need for a text file along the project ?

    I might just as well have the cur file and use the LoadCursorFromFile API if that's the case.

    Regards.

  26. #26
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    No, if you run it (recently updated it), then load the text file into NotePad, you can simply copy it all and paste it into your module. That should make your module more compact, i.e.,....

    Code:
    Public Function GetCurHandle () As LongLong ???
    
    ... add pasted code here  -- removes need for all that Array() and CopyMemory stuff
    
        
        GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) * 4 + 4, 0&, &H30000, 0, 0, 0&)
    End Function
    Of course, I am assuming you needed the arrays to split the 744 bytes into managable arrays, combined them, then rewrote them into a byte array. If I misunderstood your routine, then ignore my suggestion.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  27. #27

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    No, if you run it (recently updated it), then load the text file into NotePad, you can simply copy it all and paste it into your module. That should make your module more compact, i.e.,....

    Code:
    Public Function GetCurHandle () As LongLong ???
    
    ... add pasted code here  -- removes need for all that Array() and CopyMemory stuff
    
        
        GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) * 4 + 4, 0&, &H30000, 0, 0, 0&)
    End Function
    Of course, I am assuming you needed the arrays to split the 744 bytes into managable arrays, combined them, then rewrote them into a byte array. If I misunderstood your routine, then ignore my suggestion.
    Yes your assumption is correct.

    I haven't tried your code yet but I will do later on as I am logging off now .

    I will post back with the result I get later on.

    Regards.

  28. #28

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Hi LaVolpe,

    I followed your instructions and this is the output I got from the text file :

    Code:
    Private Function GetCurHandle() As LongPtr
    
        ReDim longs(0 To 186) 
        longs(0) = 0: longs(1) = 40: longs(2) = 32: longs(3) = 64: longs(4) = 262145: longs(5) = 0: longs(6) = 640: longs(7) = 0: longs(8) = 0: longs(9) = 16: longs(10) = 0: longs(11) = 0: longs(12) = 8388608: longs(13) = 32768: longs(14) = 8421376: longs(15) = 128: longs(16) = 8388736: longs(17) = 32896: longs(18) = 12632256: longs(19) = 8421504: longs(20) = 16711680: longs(21) = 65280: longs(22) = 16776960: longs(23) = 255: longs(24) = 16711935: longs(25) = 65535: longs(26) = 16777215: longs(27) = 0: longs(28) = 0: longs(29) = 0
        longs(30) = 0: longs(31) = 0: longs(32) = 0: longs(33) = 0: longs(34) = 0: longs(35) = 0: longs(36) = 151587072: longs(37) = 151587081: longs(38) = 9: longs(39) = 0: longs(40) = -1869611008: longs(41) = -1869574000: longs(42) = 144: longs(43) = 0: longs(44) = 2304: longs(45) = 0: longs(46) = 9: longs(47) = 0: longs(48) = 9437184: longs(49) = 0: longs(50) = 144: longs(51) = 0: longs(52) = 2304: longs(53) = 0: longs(54) = 9: longs(55) = 0: longs(56) = 9437184: longs(57) = 0: longs(58) = 144: longs(59) = 0
        longs(60) = 2304: longs(61) = 0: longs(62) = 9: longs(63) = 0: longs(64) = 9437184: longs(65) = 0: longs(66) = 144: longs(67) = 0: longs(68) = 2304: longs(69) = 0: longs(70) = 9: longs(71) = 0: longs(72) = -1869611008: longs(73) = -1869574000: longs(74) = 144: longs(75) = 0: longs(76) = 151587072: longs(77) = 151587081: longs(78) = 9: longs(79) = 150994944: longs(80) = 144: longs(81) = 0: longs(82) = 0: longs(83) = -1728053248: longs(84) = 153: longs(85) = 0: longs(86) = 0: longs(87) = -1728053248: longs(88) = 153: longs(89) = 0
        longs(90) = 0: longs(91) = -1727463424: longs(92) = 144: longs(93) = 0: longs(94) = 0: longs(95) = -1727463280: longs(96) = 144: longs(97) = 0: longs(98) = 0: longs(99) = -1718026087: longs(100) = 0: longs(101) = 0: longs(102) = 0: longs(103) = -1717989223: longs(104) = 0: longs(105) = 0: longs(106) = 0: longs(107) = -1868981863: longs(108) = 0: longs(109) = 0: longs(110) = 0: longs(111) = -1717986919: longs(112) = 37017: longs(113) = 0: longs(114) = 0: longs(115) = -1717986919: longs(116) = 153: longs(117) = 0: longs(118) = 0: longs(119) = -1717986919
        longs(120) = 144: longs(121) = 0: longs(122) = 0: longs(123) = -1717986919: longs(124) = 0: longs(125) = 0: longs(126) = 0: longs(127) = -1868981863: longs(128) = 0: longs(129) = 0: longs(130) = 0: longs(131) = 10066329: longs(132) = 0: longs(133) = 0: longs(134) = 0: longs(135) = 9476505: longs(136) = 0: longs(137) = 0: longs(138) = 0: longs(139) = 39321: longs(140) = 0: longs(141) = 0: longs(142) = 0: longs(143) = 37017: longs(144) = 0: longs(145) = 0: longs(146) = 0: longs(147) = 153: longs(148) = 0: longs(149) = 0
        longs(150) = 0: longs(151) = 144: longs(152) = 0: longs(153) = 0: longs(154) = 0: longs(155) = -1: longs(156) = -1: longs(157) = -1079317761: longs(158) = 2136339967: longs(159) = -1073745921: longs(160) = 2147481599: longs(161) = -1073745921: longs(162) = 2147481599: longs(163) = -1073745921: longs(164) = 2147481599: longs(165) = -1073745921: longs(166) = 2136339967: longs(167) = -1079317761: longs(168) = -32770: longs(169) = -49156: longs(170) = -49156: longs(171) = -32776: longs(172) = -32904: longs(173) = -208: longs(174) = -240: longs(175) = -255: longs(176) = -57600: longs(177) = -49408: longs(178) = -33024: longs(179) = -256
        longs(180) = -255: longs(181) = -253: longs(182) = -249: longs(183) = -241: longs(184) = -225: longs(185) = -193: longs(186) = -129:
    
        GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) * 4 + 4, 0&, &H30000, 0, 0, 0&)
        
        Debug.Print GetCurHandle
    End Function
    Unfortunately, GetCurHandle now returns a null pointer .. I doubled checked to ensure I copied the entire longs output but nothing.

    EDIT:

    I made it work by defining the longs array as Long instead of Variant.

    So I just edited your code as follows:
    Code:
    Print #fNr, "ReDim longs(0 To " & CStr(UBound(bData) - 1) & ") As Long"
    I now just need to understand your code that extracts the bytes from the cursor file

    Regards.
    Last edited by JAAFAR; Jun 15th, 2019 at 10:33 PM.

  29. #29
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    You got it right, I got it wrong. Should be ReDim longs(0 To 186) As Long
    VB is treating it as Variant otherwise -- sorry about that & fixed it

    Edited: Regarding the code. Pretty simple. Reference post #9 for icon/cursor structure & offsets.

    2 sanity checks made to begin with:
    -- ensure only 1 image in the source file (code requires changes otherwise). Always at 5th byte in file
    -- get image/resource size and verify a multiple of 4. Size always begins at 15th byte

    Next is simply to read the number of bytes/4 into longs. We start reading 4 bytes before the actual data location because we need room for the cursor hotspot in the 1st element. The data starts at 23rd byte, so we read from the 19th byte. After that we then read the hotspot into the 1st Long, overwriting it, and that hotspot begins at 11th byte.

    As far as printing the array? Easy really. Using a counter to restrict 30 statements per line, but other than that, just formatting the text as we would if we were manually typing it out. Not 100% perfect, may have a trailing colon at the end of a line. Tweak to perfection if you want.

    Any specific questions? Just ask.

    Here's one more optimization. It won't print out a statement if the Long value is zero. Since VB/VBA initializes arrays with zero values, no need to explicitly set them to zero in a statement. Potential of significantly reducing number of statements is high. Example with a simple test cursor, 187 statements before tweak, 111 after (40% reduction)

    Code:
    Dim bData() As Long, n As Integer, x As Long
    Dim lValue As Long, bLinePrinted As Boolean, fNr As Integer
    
    fNr = FreeFile()
    Open "C:\...\myCursor.cur" For Binary As #fNr ' <<< change to valid cursor file
    Get #fNr, 5, n
    If n <> 1 Then
        Close #fNr
        Stop ' more than 1 file in array
    End If
    Get #fNr, 15, x
    If (x Mod 4) <> 0 Then
        Close #fNr
        Stop    ' image size is expected to be multiple of 4
    End If
    
    ReDim bData(1 To x \ 4 + 1) ' image size + hotspot
    Get #fNr, 19, bData() ' start at 19th byte in file
    Get #fNr, 11, bData(1) ' get hotspot into 1st element
    Close #fNr
    
    fNr = FreeFile()
    Open "C:\...\formattedArray.txt" For Output As #fNr ' <<< change folder/filename
    
    n = 1
    Print #fNr, "ReDim longs(0 To " & CStr(UBound(bData) - 1) & ") As Long"
    For x = 1 To UBound(bData)
        lValue = bData(x)
        If lValue Then Print #fNr, "longs(" & CStr(x - 1) & ") = " & CStr(lValue);
        If n = 30 Then
            If bLinePrinted Then Print #fNr, vbCrLf;
            n = 1: bLinePrinted = False
        Else
            If lValue Then Print #fNr, ": "; Else bLinePrinted = True
            n = n + 1
        End If
    Next
    Close #fNr
    Last edited by LaVolpe; Jun 16th, 2019 at 09:03 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  30. #30

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    LaVolpe,

    That's brilliant ! I now I think I understand- You already had the byte extraction code well commented but having no idea about the internal memory layout of the cursor file, I didn't pay enough attention.... Thanks a lot for the detailed explanation.

    A cool side effect is this trick of formatting the code in a text file and later pasting it in the project ... I am sure this trick will come in handy for me in future projects.

    Couple of questions if you don't mind:

    1- For the sake of experimentation and better understanding, I want to define the array bData() As Byte instead of As Long (obviously this would output larger code) then resize the array accordingly as follows :
    Code:
    ReDim bData(1 To x + 1)  '\ 4 + 1) ' image size + hotspot
    Get #fNr, 19, bData() ' start at 19th byte in file
    Get #fNr, 11, bData(1) ' get hotspot into 1st element
    Close #fNr
    Finally API call :
    Code:
     GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) + 1, 0&, &H30000, 0, 0, 0&)
    I get a null pointer - Can you spot what I am doing wrong ?


    2- As you said "BitmapInfo always being a multiple of 4" I would be interested to know how a bytes extraction code would look like for 1 image .ICO files and .BMP files taking into account their differences like hotspot etc ..

  31. #31
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    The code in post #11 uses a byte array. But to summarize

    1. The array size is wrong it needs to include 4 bytes for the hotspot, so: x + 4, not x + 1
    2. You are only reading 1 byte of the hotspot, you need to read 4 bytes
    -- just add this afterwards: Get #fNr, , bData(2): Get #fNr, , bData(3): Get #fNr, , bData(4)

    For ico files, you don't adjust for hotspot, there is no additional 4 bytes to read. The bitmap info header for icon and cursor are pretty much identical. Bitmaps don't double the .bmiHeight member of the structure, as icons/cursors do, and bitmaps can use structures other than 40 bytes, versions 2,3,4 of that structure, also a more obscure pre-Win95 version. Icons/cursors always use the 40 byte v1 structure. There are a few more differences, but those are the big ones.

    Oh, the 3rd parameter in CreateIconFromResourceEx is 1 for icons.
    Last edited by LaVolpe; Jun 16th, 2019 at 09:34 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  32. #32

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    LaVolpe,

    Brilliant ! I got it working with the bytes array with the adjustement you suggested and I can now better visualize the cursor memory layout .. now makes sense to me

    Since the memory structure of ICO files are similar (minus hotspot), I'll will experiment with one in the same fashion and see what I get.

    This was a good lesson and I learnt a lot so thank you very much for all your help.

    Regards.

  33. #33
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    You're welcome. Just remember to not adjust for hotspot. In other words, resize array correctly and begin reading from 23rd byte of the file

    FYI: CreateIconFromResourceEx is used to extract information in a format that resource files use. Inside our res files for vbResTypeIcon & vbResTypeCursor, you now know how the information is actually stored for each individual image.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  34. #34

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    You're welcome. Just remember to not adjust for hotspot. In other words, resize array correctly and begin reading from 23rd byte of the file

    FYI: CreateIconFromResourceEx is used to extract information in a format that resource files use. Inside our res files for vbResTypeIcon & vbResTypeCursor, you now know how the information is actually stored for each individual image.
    Yes the 23rd byte is where the actual image data starts for both .CUR and .ICO - ie: no need now to reserve 4 bytes before for the hotspot byte.

    Yes I would use the value of the vbResTypeIcon vb6 constant as per CreateIconFromResourceEx documentation.

    BTW, I never used res files as there is no such option in VBA.

    Regards.

  35. #35
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    One more FYI, just for grins.

    Any cursor can be converted to an icon -- use 1 in CreateIconFromResourceEx and don't adjust for the cursor hotspot

    Any icon can be converted to a cursor -- use 0 in CreateIconFromResourceEx and fake a hotspot, maybe dead center of the icon, requires parsing the icon dimensions. Or set hotspot at 0,0 to not parse dimensions, but 0,0 may be transparent in the icon.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  36. #36

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    One more FYI, just for grins.

    Any cursor can be converted to an icon -- use 1 in CreateIconFromResourceEx and don't adjust for the cursor hotspot

    Any icon can be converted to a cursor -- use 0 in CreateIconFromResourceEx and fake a hotspot, maybe dead center of the icon, requires parsing the icon dimensions. Or set hotspot at 0,0 to not parse dimensions, but 0,0 may be transparent in the icon.
    Thanks LaVolpe,

    1- I have just converted a 32x32 True color ICO file to a CUR based on your suggestion and apparently it works as expected.

    This is how I set up the Long array (image data + hotspot)

    Code:
    ReDim bData(1 To x \ 4 + 1) ' image size + hotspot
    Get #fNr, 19, bData() ' start at 19th byte in file
    bData(1) = (16 * &H10000) Or (16 And &HFFFF&) ' Hotspot at the center of the 32x32 cursor
    Or bData(1) =0 for hotspot at top left of the cursor.

    Then API call :
    Code:
    GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) * 4 + 4, 0&, &H30000, 0, 0, 0&)

    2- As for converting a CUR to an ICO, I haven't tested it but I guess this how I should build the Long array :
    Code:
    ReDim bData(1 To x \ 4) ' image size 
    Get #fNr, 23, bData() ' start at 23th byte in file
    and then API call :
    Code:
    GetCurHandle = CreateIconFromResourceEx(longs(0), UBound(longs) * 4, 1&, &H30000, 0, 0, 0&)
    I hope this is correct.

    Regards.

  37. #37
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    For #2 above... Yes. You can always test it by rendering it somewhere, using DrawIconEx (icons or cursors). Not mentioned in previous posts, be sure you destroy the created icon/cursor at some point.

    Edited: To be clear on some comments in earlier posts regarding cx,cy. Here is what MSDN says when those value are zero, for the width: The desired width, in pixels, of the icon or cursor. If this parameter is zero, the function uses the SM_CXICON or SM_CXCURSOR system metric value to set the width.

    That would lead you to believe that passing zero does not always use actual size. However, the APIs flags parameter can override that... Flag LR_DEFAULTSIZE uses the width or height specified by the system metric values for cursors or icons, if the cxDesired or cyDesired values are set to zero. If this flag is not specified and cxDesired and cyDesired are set to zero, the function uses the actual resource size.

    So when I said you could pass 0 for cx,cy and actual size would be used, I was correct. But I didn't explain why I was correct -- we are not passing LR_DEFAULTSIZE in the flags parameter.
    Last edited by LaVolpe; Jun 17th, 2019 at 07:43 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  38. #38

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    For #2 above... Yes. You can always test it by rendering it somewhere, using DrawIconEx (icons or cursors). Not mentioned in previous posts, be sure you destroy the created icon/cursor at some point.
    Thanks .

    Yes I use DeleteObject upon unloading the form.

    Now that you mention the flag parameter, this is waht the MSDN doc says about the LR_SHARED flag:
    "When you use this flag, the system will destroy the resource when it is no longer needed."
    Does that mean I could set this flag and not worry about destroying the cursor when done ?

    Also while we are on the subject, what do you think could happen if we have a cursor/icon resource handle and for some reason (like a project crash), the vb poject goes out of scope therefore we have no chance to release the resource with DeleteObject ? Does Windows release a resource when the vbaproject crashes while debugging ?

    As a side note I, I have been printing the formatted text to the immediate window. It is slower but more concise IMHO.
    Code:
        n = 1
        Debug.Print "ReDim longs(0 To " & CStr(UBound(bData) - 1) & ") As Long"
        For x = 1 To UBound(bData)
            Debug.Print "longs(" & CStr(x - 1) & ") = " & CStr(bData(x));
            If n = 30 Then
                Debug.Print vbCrLf;
                n = 1
            Else
                Debug.Print ": ";
                n = n + 1
            End If
        Next

  39. #39
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Create and load Cursor from byte array.

    DeleteObject isn't technically correct. Per MSDN, use DestroyCursor for cursors and DestroyIcon for icons.

    As for LR_SHARED, that is intended for loading from an application's resources (i.e., compiled res file). Consider the way you are loading the cursor is same as loading from a file. If so, then this applies: Do not use LR_SHARED for icons or cursors that have non-standard sizes, that may change after loading, or that are loaded from a file.

    As far as crashes go or applications completely closing/unloading... all memory related to that process is released back to the system.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  40. #40

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: Create and load Cursor from byte array.

    Quote Originally Posted by LaVolpe View Post
    DeleteObject isn't technically correct. Per MSDN, use DestroyCursor for cursors and DestroyIcon for icons.

    As for LR_SHARED, that is intended for loading from an application's resources (i.e., compiled res file). Consider the way you are loading the cursor is same as loading from a file. If so, then this applies: Do not use LR_SHARED for icons or cursors that have non-standard sizes, that may change after loading, or that are loaded from a file.

    As far as crashes go or applications completely closing/unloading... all memory related to that process is released back to the system.

    Thank you. DestroyIcon is the propper API ... That said, I read somewhere that DeleObject can just as well be used for destroying resources such as DCs,Brushes etc - Is that correct ?

    What I really meant by a vbproject crash was just the project going out of scope ie:- loosing the resource handle and therfore not being able to call the DestoyIcon\DeleteObject on it.

    Regards.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width