Results 1 to 10 of 10

Thread: [VB6/VBA] A clipboard management class (currently have issues in x64)

  1. #1

    Thread Starter
    Member
    Join Date
    Apr 2019
    Posts
    63

    Post [VB6/VBA] A clipboard management class (currently have issues in x64)

    Hi All,

    Thought you might appreciate this clipboard management class. It should work in VB6 assuming I have the declares setup correctly.

    The source code can be found here:

    stdClipboard.cls



    Unfortunately my sub `protSetFilesText(ByVal sFiles As String)` works fine in 32-bit VBA, but for whatever reason it's crashing in 64-bit VBA on this line:

    Code:
    Call CopyMemory(lpClipMemory + Len(tDropFiles), StrPtr(sFiles), LenB(sFiles))
    I checked, initially thought it was some page read error causing a crash in the runtime so I increased the clipboard memory block size i.e.

    Code:
      hClipMemory = GlobalAlloc(GAlloc.GHND, Len(tDropFiles) + LenB(sFiles)+10) 'arbitrary 10 bytes added to check if it's a size issue
    Looks like this doesn't fix the issue so I'm at a bit of a loss... I'm thinking perhaps it's best in general to construct the CD_HDROP as an array of bytes and inject it into the clipboard that way, but I figured I'd ask here in case there were any other ideas as to what could be causing the issue?

    At the moment I have decided to disable this functionality specifically in Win64, however this isn't really a good work around of course. Hopefully we can work out a fix this...

  2. #2
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    Btw, now you have GlobalFree(hClipMemory) commented out but you *do* need to call it if SetClipboardData fails for some reason.

    This is a common pattern when handles are transfered to the system -- don't free it unless set function fails.

    For instance when setting a clipping region to a window the system starts owning the region unless set region fails in which case you have to free the region handle yourself.

    It's curious that all the sample code in the SO link fail to provide for this typical error handling.

    Edit: Btw, this is the only place you add offset to lpClipMemory (not sure about any other LongPtr variable). Try calculating lpClipMemory = lpClipMemory + Len(tDropFiles) on separate line and then pass lpClipMemory to CopyMemory.

    cheers,
    </wqw>

  3. #3

    Thread Starter
    Member
    Join Date
    Apr 2019
    Posts
    63

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    Quote Originally Posted by wqweto View Post
    Btw, now you have GlobalFree(hClipMemory) commented out but you *do* need to call it if SetClipboardData fails for some reason.
    This is a common pattern when handles are transfered to the system -- don't free it unless set function fails.
    For instance when setting a clipping region to a window the system starts owning the region unless set region fails in which case you have to free the region handle yourself.
    It's curious that all the sample code in the SO link fail to provide for this typical error handling.
    Ooo!! Great catch, totally missed that potential issue!

    Quote Originally Posted by wqweto View Post
    Edit: Btw, this is the only place you add offset to lpClipMemory (not sure about any other LongPtr variable). Try calculating lpClipMemory = lpClipMemory + Len(tDropFiles) on separate line and then pass lpClipMemory to CopyMemory.
    Interesting idea! I'll certainly give that a go. If not I'll look into constructing a byte array instead

    Edit: Just tested and seems that at least if this isn't the only cause, as the crash still occurred. It certainly could be one of the issues which is causing the crash though. I almost wish I had a memory viewer, i think some of those exist so that might be an avenue to look at...

    Edit: Tbh, I think it actually make a lot of sense to change the declaration of DROPFILES to:

    Code:
    Private Type DROPFILES
      pFiles As Long
      pt As POINTAPI
      fNC As Long
      fWide As Long
      yFiles() as byte
    End Type
    Edit: On second thought, i think yFiles would be a safe array, so that probably doesnt make sense at all...
    Last edited by sancarn; Oct 12th, 2020 at 08:33 AM.

  4. #4
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,418

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    You do know, that the VBA7-constant checks the Office-Version, not the Bitness of the Office-Version?

    I've run into a similiar Problem, when the company i work for switched from Office2016-32Bit to Office2019-64-Bit.

    In O2016-32-Bit i didn't even need the PtrSafe-Qualifier in my declares, nor did my code complain about Long as Pointers vs. LongPtr!

    I solved it by changing everything to "#If Win64 Then ......#End If"
    Replaced all checks on VBA7 with Win64, changed the Pointers from Long to LongPtr, inserted PtrSafe, and voila.

    EDIT: Those O2016-32-Bit were running on Win7/Win10-64Bit, so #If Win64 doesn't check the Bitness of the OS, but of Office!
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  5. #5

    Thread Starter
    Member
    Join Date
    Apr 2019
    Posts
    63

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    Quote Originally Posted by Zvoni View Post
    You do know, that the VBA7-constant checks the Office-Version, not the Bitness of the Office-Version?

    I've run into a similiar Problem, when the company i work for switched from Office2016-32Bit to Office2019-64-Bit.

    In O2016-32-Bit i didn't even need the PtrSafe-Qualifier in my declares, nor did my code complain about Long as Pointers vs. LongPtr!

    I solved it by changing everything to "#If Win64 Then ......#End If"
    Replaced all checks on VBA7 with Win64, changed the Pointers from Long to LongPtr, inserted PtrSafe, and voila.

    EDIT: Those O2016-32-Bit were running on Win7/Win10-64Bit, so #If Win64 doesn't check the Bitness of the OS, but of Office!
    Yes I realise that indeed, but Ptrsafe declares and LongPtr are concepts added in VBA7, so a check for VBA7 suffices from the point of view of declaration But this is why I checked for win64 when adding my "Not implemented" error

  6. #6
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    OP does use Win64 in stdClipboard.cls so they must be aware of VBA7 vs Win64 preprocessor constants.

    Btw, the error handling with CriticalRaise call is error prone itself. For instance in protSetFilesText the indicated error source looks like "Value [LET]" until GlobalFree failure where it switches to "Value [GET]" unless I don't understand the gist of it.

    I prefer plain C error handling with GoTo for API failures, esp. when using Win32 facility with Err.LastDllError like this

    Err.Riase IIf(Err.LastDllError < 0, Err.LastDllError, &H80070000 Or Err.LastDllError), MODULE_NAME & "." & FUNC_NAME & sApiSource

    . . . which translates the number Err.LastDllError into localized textual Err.Description without calls to FormatMessage API. (For instance Err.Raise &H80070000 Or 5 raises localized "Permission denied" error)

    cheers,
    </wqw>

  7. #7

    Thread Starter
    Member
    Join Date
    Apr 2019
    Posts
    63

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    Quote Originally Posted by wqweto View Post
    OP does use Win64 in stdClipboard.cls so they must be aware of VBA7 vs Win64 preprocessor constants.

    Btw, the error handling with CriticalRaise call is error prone itself. For instance in protSetFilesText the indicated error source looks like "Value [LET]" until GlobalFree failure where it switches to "Value [GET]" unless I don't understand the gist of it.

    I prefer plain C error handling with GoTo for API failures, esp. when using Win32 facility with Err.LastDllError like this

    Err.Riase IIf(Err.LastDllError < 0, Err.LastDllError, &H80070000 Or Err.LastDllError), MODULE_NAME & "." & FUNC_NAME & sApiSource

    . . . which translates the number Err.LastDllError into localized textual Err.Description without calls to FormatMessage API. (For instance Err.Raise &H80070000 Or 5 raises localized "Permission denied" error)

    cheers,
    </wqw>
    Damn, never knew that, that is really useful thanks! Really too bad there isn't a download button for this forums knowledge :P

    Btw, the error handling with CriticalRaise call is error prone itself. For instance in protSetFilesText the indicated error source looks like "Value [LET]" until GlobalFree failure where it switches to "Value [GET]" unless I don't understand the gist of it.
    That's where copy paste takes you... Thanks as always, should be fixed in commit now To be honest I'm starting to become doubtful of my reliance on stdError... Stack traces are nice, but not automatic, and lack of option explicit in the module is a problem... So it becomes difficult to support both `stdError` and `Err`... There other fixable issues, but anyway, that's a bit off topic...

  8. #8
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,418

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    Between your working 32-Bit and not working 64-Bit-Version: Have you checked if there is a difference between Len(tDropFiles) vs. LenB(tDropFiles)?
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  9. #9

    Thread Starter
    Member
    Join Date
    Apr 2019
    Posts
    63

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    Quote Originally Posted by Zvoni View Post
    Between your working 32-Bit and not working 64-Bit-Version: Have you checked if there is a difference between Len(tDropFiles) vs. LenB(tDropFiles)?
    No difference, always 20 bytes, which makes sense, we use Longs. There should only really be a difference if LongPtr is used.

  10. #10
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,418

    Re: [VB6/VBA] A clipboard management class (currently have issues in x64)

    Have you checked, if "lpClipMemory + Len(tDropFiles)" in your copymemory-call actually translates to a Memory-Address?
    Add to Watch-Window:
    lpClipMemory
    Len(tDropFiles)
    lpClipMemory + Len(tDropFiles)

    I remember that with LongPtr-Type the Watch-Window shows a "^" at the end of the Value, which had me always stumped when checking RecordCount of an ADO-Recordset (which shows the caret, too!), and that one always gave me a Type-Mismatch.
    Last edited by Zvoni; Oct 19th, 2020 at 01:56 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

Tags for this Thread

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