0

We recently upgraded everyone from 32- to 64-bit Microsoft Access (365, but that didn't change).

A while back I wrote a sub that accepted an HTML-formatted string and placed it into the clipboard as an HTML object. This way, the user could pop over to another app (such as Teams or Outlook) and hit paste. The receiving app would "see" it as HTML and not plain text and format it as such.

I added the obligatory "ptrsafe" to each of the declarations. It compiles and runs, but nothing gets put into the clipboard. There's no error. The clipboard just doesn't get anything.

Here's the entire code:

Option Explicit
Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare PtrSafe Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
Private Declare PtrSafe Function RegisterClipboardFormat Lib "user32" Alias "RegisterClipboardFormatA" (ByVal lpString As String) As Long
Private Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal cbLength As Long)
Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
Private Declare PtrSafe Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpData As Long) As Long
Private Const m_sDescription = _
                  "Version:1.0" & vbCrLf & _
                  "StartHTML:aaaaaaaaaa" & vbCrLf & _
                  "EndHTML:bbbbbbbbbb" & vbCrLf & _
                  "StartFragment:cccccccccc" & vbCrLf & _
                  "EndFragment:dddddddddd" & vbCrLf

Private m_cfHTMLClipFormat As Long
Function RegisterCF() As Long
   'Register the HTML clipboard format
   If (m_cfHTMLClipFormat = 0) Then
      m_cfHTMLClipFormat = RegisterClipboardFormat("HTML Format")
   End If
   RegisterCF = m_cfHTMLClipFormat

End Function
Public Sub PutHTMLClipboard(sHtmlFragment As String, _
   Optional sContextStart As String = "<HTML><BODY>", _
   Optional sContextEnd As String = "</BODY></HTML>")

   Dim sData As String

   If RegisterCF = 0 Then Exit Sub

   'Add the starting and ending tags for the HTML fragment
   sContextStart = sContextStart & "<!--StartFragment -->"
   sContextEnd = "<!--EndFragment -->" & sContextEnd

   'Build the HTML given the description, the fragment and the context.
   'And, replace the offset place holders in the description with values
   'for the offsets of StartHMTL, EndHTML, StartFragment and EndFragment.
   sData = m_sDescription & sContextStart & sHtmlFragment & sContextEnd
   sData = Replace(sData, "aaaaaaaaaa", _
                   Format(Len(m_sDescription), "0000000000"))
   sData = Replace(sData, "bbbbbbbbbb", Format(Len(sData), "0000000000"))
   sData = Replace(sData, "cccccccccc", Format(Len(m_sDescription & _
                   sContextStart), "0000000000"))
   sData = Replace(sData, "dddddddddd", Format(Len(m_sDescription & _
                   sContextStart & sHtmlFragment), "0000000000"))
   'Add the HTML code to the clipboard
   If CBool(OpenClipboard(0)) Then

      Dim hMemHandle As Long, lpData As Long

      hMemHandle = GlobalAlloc(0, Len(sData) + 10)

      If CBool(hMemHandle) Then

         lpData = GlobalLock(hMemHandle)   'Problem May be Here?
         If lpData <> 0 Then

            CopyMemory ByVal lpData, ByVal sData, Len(sData)
            GlobalUnlock hMemHandle
            EmptyClipboard
            SetClipboardData m_cfHTMLClipFormat, hMemHandle

         End If

      End If

      Call CloseClipboard
   End If
   
End Sub

I marked, with a comment, where I think the culprit is (or at least, one of the culprits). The function GlobalLock(hMemHandle) always returns 0, which seems to mean some kind of error.

I suspect if someone can help me here, I might be able to get it running.

David
  • 1
  • 1

1 Answers1

0

The link above didn't work for me (it only seemed to work with plain text), but it gave me enough example code to find this post with a Class that is very excellent.

Injecting RTF code in the Clipboard to paste into MS Word as RTF text via a VBA macro

Thanks!

David
  • 1
  • 1
  • Hi, thanks for answering. In the interest of keeping your answer relevant in the future when this link may no longer be valid, please provide at least a summary of the information in the link. – Mmm Mar 03 '23 at 22:13