Reg Exp
Web Design
Notes Client
Reading/Writing Windows Clipboard
If you have a need to read the windows clipboard (or write to it) while in LotusScript, this custom class makes it easy. Create a Script Library, and call it Windows Clipboard. Go into the (Declarations) area of the script library, and put in this class definition.

First, you need to declare the API classes that you will need:

Declare Private Function GetClipboardData Lib "User32" (Byval wFormat As Long) As Long
Declare Private Function SetClipboardData Lib "user32" (Byval wFormat As Long, Byval hData As Long) As Long
Declare Private Function OpenClipboard Lib "User32" Alias "OpenClipboard" (Byval hwnd As Long) As Long
Declare Private Function CloseClipboard Lib "User32" Alias "CloseClipboard" () As Long
Declare Private Function GlobalLock Lib "kernel32" Alias "GlobalLock" (Byval hMem As Long) As Long
Declare Private Function GlobalUnlock Lib "kernel32" Alias "GlobalUnlock" (Byval hMem As Long) As Long
Declare Private Function GlobalAlloc Lib "kernel32" (Byval wFlags As Long, Byval dwBytes As Long) As Long
Declare Private Function GlobalFree Lib "kernel32" (Byval hMem As Long) As Long
Declare Private Function EmptyClipboard Lib "user32" () As Long
Declare Private Function lstrcpyLP2Str Lib "kernel32" Alias "lstrcpyA" (Byval lpString1 As String, _
Byval lpString2 As Long) As Long
Declare Private Function lstrlenLP Lib "kernel32" Alias "lstrlenA" (Byval lpString As Long) As Long
Declare Private Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Byval strDest As Any, _
Byval lpSource As Any, Byval Length As Any)
Declare Private Function GetFocus Lib "User32" Alias "GetFocus" () As Long

You will also need soem constant defined, so add those next:

Private Const CF_TEXT = 1
Private Const GMEM_MOVABLE = &H2&
Private Const GMEM_DDESHARE = &H2000&

Finally, add in the class definition. First, let's go over the property that will read from the clipboard

Class WindowsClipboard
   Public Property Get Contents As String
      Dim hClipboard As Long
      Dim LpStrl As Long
      Dim Resultl As Long
      Dim Clipboardstr As String
      If (OpenClipboard(0&) <> 0) Then
         hClipboard = GetClipboardData(CF_TEXT)
         If (hClipboard <> 0) Then
            LpStrl = GlobalLock(hClipboard)
            Clipboardstr = Space$(lstrlenLP(LpStrl))
            Resultl = lstrcpyLP2Str(Clipboardstr, LpStrl)
            Clipboardstr = "NULL"
         End If
         Call CloseClipboard()
         Clipboardstr = ""
      End If
      Contents = Clipboardstr
   End Property   ' Ends the "Get" method for the "Contents" property

The first thing the class does is get a handle to the clipboard. Then the clipboard is locked. A temporary blank area of data is made so there's a big enough block of string data to hold the results. The clipboard data is put into that blank area and the clipboard is unlocked to free it up again. The results are returned to the user.

For setting the clipboard contents, this uses the same Contents property, but this time the property is Set instead of Get.
   Public Property Set Contents As String
      Dim lSize As Long
      Dim hMem As Long
      Dim pMemory As Long
      Dim temp As Variant
      lSize = Len(Contents)+1
      hMem = GlobalAlloc(GMEM_MOVABLE Or GMEM_DDESHARE, lSize)
      If hMem = 0 Or Isnull(hMem) Then Exit Property
      pMemory = GlobalLock(hMem)
      If pMemory = 0 Or Isnull(pMemory) Then
         Exit Property
      End If
      Call MoveMemory(pMemory, Contents, lSize)
      Call GlobalUnlock(hMem)
      If (OpenClipboard(0&) <> 0) Then
         If (EmptyClipboard() <> 0) Then
            temp = SetClipboardData(CF_TEXT, hMem)
         End If
         temp = CloseClipboard()
      End If
   End Property   ' Ends the "Set" method for the "Contents" property
End Class

First, figure out how much memory needs to be allocated. This will be one more character than the size of the data being sent. Then allocate enough memory to hold this text and put the text into the allocated memory location. (This involves locking the memory, then moving the text into the locked memory, then unlocking the memory). Then we get a handle to the clipboard, just like the "get" property did. Once we have that handle, we wipe out whatever is on the clipboard. This could be text, or graphics, or anything else. After the clipboard has been cleared, then the data in memory is placed on the clipboard. Then things are cleaned up - the clipboard is closed and memory is freed.

To use this class, it's pretty easy. First, build an agent. Make sure to include the script library with the statement Use "Windows Clipboard" in the (Options) area. Then your test code is just a few lines:

Dim x As WindowsClipboard
Set x = New WindowsClipboard()
Msgbox x.Contents
x.Contents = "Check the setting of the clipboard data by putting in some text"
Msgbox x.Contents

This will give you two message boxes - one with the clipboard contents from before you ran the agent, the other with the clipboard contents we set during the running of the agent.