In order to copy some information to the Windows clipboard in LotusScript, I use some Windows API calls for years now. Since it's Windows only and all Notes clients for Windows were 32-bit, I never had to consider 64-bit calls - until now with Notes 14 being 64-bit only.
The API call to set clipboard text is
Declare Function SetClipboardData Lib "User32" (Byval wFormat As Long, Byval hMem As Long) As Long
But in order to call this, I have to prepare the text in a "buffer" to handle it over to SetClipboardData. For this I use
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, Byval Length As Long)
And the call of this function crashes Notes 14 64-bit immediately.
What do I need to change for the 64-bit Notes client?
More of the code:
(Declarations)
' Clipboard formats
'
' see: http://msdn2.microsoft.com/en-us/library/ms649013.aspx
Public Const CF_BITMAP = 2 ' handle to a bitmap (HBITMAP, http://msdn2.microsoft.com/en-us/library/aa383751.aspx).
Public Const CF_DIB = 8 ' memory object containing a BITMAPINFO (http://msdn2.microsoft.com/en-us/library/ms532284.aspx) structure followed by the bitmap bits.
Public Const CF_DIBV5 = 17 ' Windows 2000/XP: memory object containing a BITMAPV5HEADER (http://msdn2.microsoft.com/en-us/library/ms532331.aspx) structure followed by the bitmap color space information and the bitmap bits.
Public Const CF_DIF = 5 ' Software Arts' Data Interchange Format.
Public Const CF_DSPBITMAP = &H82 ' Bitmap display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in bitmap format in lieu of the privately formatted data.
Public Const CF_DSPENHMETAFILE = &H8E ' Enhanced metafile display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in enhanced metafile format in lieu of the privately formatted data.
Public Const CF_DSPMETAFILEPICT = &H83 ' Metafile-picture display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in metafile-picture format in lieu of the privately formatted data.
Public Const CF_DSPTEXT = &H81 ' Text display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in text format in lieu of the privately formatted data.
Public Const CF_ENHMETAFILE = 14 ' handle to an enhanced metafile (HENHMETAFILE, http://msdn2.microsoft.com/en-us/library/aa383751.aspx).
Public Const CF_GDIOBJFIRST = &H300 ' through CF_GDIOBJLAST:
Public Const CF_GDIOBJLAST = &H3FF ' Range of integer values for application-defined Microsoft Windows Graphics Device Interface (GDI) object clipboard formats. Handles associated with clipboard formats in this range are not automatically deleted using the GlobalFree function when the clipboard is emptied. Also, when using values in this range, the hMem parameter is not a handle to a GDI object, but is a handle allocated by the GlobalAlloc function with the GMEM_MOVEABLE flag.
Public Const CF_HDROP = 15 ' handle to type HDROP (http://msdn2.microsoft.com/en-us/library/aa383751.aspx) that identifies a list of files. An application can retrieve information about the files by passing the handle to the DragQueryFile functions.
Public Const CF_LOCALE = 16 ' data is a handle to the locale identifier associated with text in the clipboard. When you close the clipboard, if it contains CF_TEXT data but no CF_LOCALE data, the system automatically sets the CF_LOCALE format to the current input language. You can use the CF_LOCALE format to associate a different locale with the clipboard text.
' An application that pastes text from the clipboard can retrieve this format to determine which character set was used to generate the text.
' Note that the clipboard does not support plain text in multiple character sets. To achieve this, use a formatted text data type such as Rich Text Format (RTF) instead.
' Windows NT/2000/XP: The system uses the code page associated with CF_LOCALE to implicitly convert from CF_TEXT to CF_UNICODETEXT. Therefore, the correct code page table is used for the conversion.
Public Const CF_METAFILEPICT = 3 ' handle to a metafile picture format as defined by the METAFILEPICT (http://msdn2.microsoft.com/en-us/library/ms649017.aspx) structure. When passing a CF_METAFILEPICT handle by means of Dynamic Data Exchange (DDE), the application responsible for deleting hMem should also free the metafile referred to by the CF_METAFILEPICT handle.
Public Const CF_OEMTEXT = 7 ' text format containing characters in the OEM character set. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
Public Const CF_OWNERDISPLAY = &H80 ' Owner-display format. The clipboard owner must display and update the clipboard viewer window, and receive the WM_ASKCBFORMATNAME, WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_SIZECLIPBOARD, and WM_VSCROLLCLIPBOARD messages. The hMem parameter must be NULL.
Public Const CF_PALETTE = 9 ' handle to a color palette. Whenever an application places data in the clipboard that depends on or assumes a color palette, it should place the palette on the clipboard as well.
' If the clipboard contains data in the CF_PALETTE (logical color palette) format, the application should use the SelectPalette and RealizePalette functions to realize (compare) any other data in the clipboard against that logical palette.
' When displaying clipboard data, the clipboard always uses as its current palette any object on the clipboard that is in the CF_PALETTE format.
Public Const CF_PENDATA = 10 ' data for the pen extensions to the Microsoft Windows for Pen Computing.
Public Const CF_PRIVATEFIRST = &H200 ' through CF_PRIVATELAST:
Public Const CF_PRIVATELAST = &H2FF ' Range of integer values for private clipboard formats. Handles associated with private clipboard formats are not freed automatically; the clipboard owner must free such handles, typically in response to the WM_DESTROYCLIPBOARD message.
Public Const CF_RIFF = 11 ' represents audio data more complex than can be represented in a CF_WAVE standard wave format.
Public Const CF_SYLK = 4 ' Microsoft Symbolic Link (SYLK) format.
Public Const CF_TEXT = 1 ' text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text.
Public Const CF_WAVE = 12 ' represents audio data in one of the standard wave formats, such as 11 kHz or 22 kHz Pulse Code Modulation (PCM).
Public Const CF_TIFF = 6 ' tagged-image file format.
Public Const CF_UNICODETEXT = 13 ' Windows NT/2000/XP: unicode text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
' Win-API functions used
Declare Function OpenClipboard Lib "User32" (Byval hWnd As Long) As Long
Declare Function CountClipboardFormats Lib "User32" () As Long
Declare Function EnumClipboardFormats Lib "User32" (Byval wFormat As Long) As Long
Declare Function GetClipboardData Lib "User32" (Byval wFormat As Long) As Long
Declare Function SetClipboardData Lib "User32" (Byval wFormat As Long, Byval hMem As Long) As Long
Declare Function EmptyClipboard Lib "User32" () As Long
Declare Function CloseClipboard Lib "User32" () As Long
Declare Function GlobalAlloc Lib "kernel32" (Byval wFlags&, Byval dwBytes As Long) As Long
Declare Function GlobalLock Lib "kernel32" (Byval hMem As Long) As Long
Declare Function GlobalUnlock Lib "kernel32" (Byval hMem As Long) As Long
Declare Function lstrcpy Lib "kernel32" (Byval lpString1 As String, Byval lpString2 As Long) As Long
Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (Byval lpString As Any) As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, Byval Length As Long)
Public Sub SetClipboardText(Byval text As String)
'/**
' * puts text into clipboard.
' *
' * @param text to put into the clipboard.
' *
' * @author Thomas Bahn <tbahn@assono.de>, Bernd Hort <bhort@assono.de>
' * @version 2014-07-24
' */
Const GMEM_MOVEABLE = &H2
Const GMEM_ZEROINIT = &H40
Const GMEM_GHND = (GMEM_MOVEABLE Or GMEM_ZEROINIT)
Dim replaceList List As String
Dim handleForBuffer As Long
Dim pointerToBuffer As Long
Dim errorNr As Long
If Not IsDebugMode Then On Error Goto errorHandler
If session.Platform <> PLATFORM_W32 And session.Platform <> PLATFORM_W64 Then
replaceList("<%PLATFORM%>") = session.Platform
MessageBox ReplaceSubstringByList(GetProperty(COMMONS_LIBRARY & ".errmsg.unsupported.specific.platform"), replaceList), MB_OK + MB_ICONSTOP
Exit Sub
End If
' create buffer
handleForBuffer = GlobalAlloc(GMEM_GHND, Len(text) + 1)
If Isnull(handleForBuffer) Then ' NULL means error
errorNr = GetLastWinAPIError()
Error errorNr, GetLastWinAPIErrorText() & " (" & Cstr(errorNr) & ")"
End If
pointerToBuffer = GlobalLock(handleForBuffer)
If Isnull(pointerToBuffer) Then ' NULL means error
errorNr = GetLastWinAPIError()
Error errorNr, GetLastWinAPIErrorText() & " (" & Cstr(errorNr) & ")"
End If
' copy text to buffer
Call CopyMemory(Byval pointerToBuffer, Byval text, Len(text))
If GlobalUnlock(handleForBuffer) = 0 Then
errorNr = GetLastWinAPIError()
'If errorNr <> ERROR_SUCCESS Then
If errorNr <> NO_ERROR And errorNr <> 87 Then
Error errorNr, GetLastWinAPIErrorText() & " (" & Cstr(errorNr) & ")"
End If
End If
If OpenClipboard(0&) = 0 Then ' 0 means error
errorNr = GetLastWinAPIError()
Error errorNr, GetLastWinAPIErrorText() & " (" & Cstr(errorNr) & ")"
End If
If EmptyClipboard = 0 Then ' 0 means error
errorNr = GetLastWinAPIError()
Error errorNr, GetLastWinAPIErrorText() & " (" & Cstr(errorNr) & ")"
End If
If Isnull(SetClipboardData(CF_TEXT, handleForBuffer)) Then ' NULL means error
errorNr = GetLastWinAPIError()
Error errorNr, GetLastWinAPIErrorText() & " (" & Cstr(errorNr) & ")"
End If
If CloseClipboard = 0 Then ' 0 means error
errorNr = GetLastWinAPIError()
Error errorNr, GetLastWinAPIErrorText() & " (" & Cstr(errorNr) & ")"
End If
Exit Sub
errorHandler:
If HandleError() = RESUME_NEXT_LINE Then Resume Next
Call RethrowError()
End Sub