MultiClipboard
Someone proposed to implement MultiClipboard feature in VFP just like MS Office does. I feel it is interesting and I started to do some research on it and develop a small prototype.
1. I use VS tool Spy++ to get know what window message would be sent out.
2. I searched for some related info from MSDN library. I found a clipboard example but written in VC++.
3. I tried to translate the code to VFP.
Thank you for VFP9 enhancement of BindEvent() made us easy to respond to Windows Message.
The code below respond to Clipboard Content Changed event and add it to collection.
Limitation
- It only supports Text format.
- It doesn't handle PASTE "event". I personally feel that we got to implement replacement of edit menu and subclass VFP native controls in order to "respond" to PASTE "event". For example, getting string from collection and show in textbox. Any advice?
Enhancment
We can use enhanced collection control to have stack feature - LIFO.
I am willing to share this code for SednaX project if it is useful for anyone.
#DEFINE GWL_WNDPROC (-4)
#DEFINE WM_DRAWCLIPBOARD 0x0308
#DEFINE CF_TEXT 1
PUBLIC loClipEN
loClipEN = CREATEOBJECT("ClipboardEvent")
DEFINE CLASS ClipboardEvent AS Custom
nOldProc=0
colClipboard = .NULL.
PROCEDURE INIT
*--------------------------------------------------
DECLARE LONG SendMessage IN WIN32API ;
LONG, LONG, LONG, LONG
DECLARE LONG GetWindow IN Win32API LONG, LONG
DECLARE INTEGER GetWindowLong IN WIN32API ;
INTEGER nHWND, INTEGER nIndex
DECLARE INTEGER CallWindowProc IN WIN32API ;
INTEGER lpPrevWndFunc, ;
INTEGER nHWND, ;
INTEGER nMsg, ;
INTEGER wParam, ;
INTEGER lParam
DECLARE INTEGER IsClipboardFormatAvailable IN WIN32API ;
INTEGER uFormat
DECLARE INTEGER OpenClipboard IN WIN32API ;
INTEGER nHWND
DECLARE INTEGER GetClipboardData IN WIN32API ;
INTEGER uFormat
DECLARE STRING GlobalLock IN WIN32API ;
INTEGER hglb
DECLARE INTEGER GlobalUnlock IN WIN32API ;
INTEGER hglb
DECLARE INTEGER CloseClipboard IN WIN32API
THIS.nOldProc=GetWindowLong(_VFP.HWND, GWL_WNDPROC)
SET LIBRARY TO Home() + 'FoxTools.fll'
THIS.colClipboard = CREATEOBJECT("Collection")
*--Bind the main VFP window to WM_DRAWCLIPBOARD
BindEvent(_VFP.Hwnd,WM_DRAWCLIPBOARD,This,'HandleMsg')
ENDPROC
PROCEDURE DESTROY
UNBINDEVENTS(_VFP.Hwnd,WM_DRAWCLIPBOARD)
ENDPROC
PROCEDURE HandleMsg
LPARAMETERS nHWND,nMsg,wParam,lParam
LOCAL lptstr, hglb, lnRetVal
*-- Only handle Text format clipboard
IF IsClipboardFormatAvailable(CF_TEXT) = 1 ;
AND OpenClipboard(nHWND) = 1
hglb = GetClipboardData(CF_TEXT)
IF NOT ISNULL(hglb)
*-- Get the text from clipboard, _CLIPTEXT always return single line text
*-- This will return multiline text.
lptstr = GlobalLock(hglb)
GlobalUnlock(hglb)
ENDIF
CloseClipboard()
*-- Add clipboard to collection
THIS.colClipboard.Add(lptstr)
ENDIF
*-- Must call SendMessage function to pass the message on to
*-- the next window in the clipboard viewer chain
lnRetVal = SendMessage(nHWND, nMsg,wParam,lParam )
RETURN CallWindowProc(THIS.nOldProc,nHWND,nMsg,wParam,lParam)
ENDPROC
ENDDEFINE