Friday, October 28, 2005

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

  1. It only supports Text format.
  2. 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

0 Comments:

Post a Comment

<< Home