Monitor the clipboard

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Monitor the clipboard

Post by BackupUser »

Code updated for 5.20+

Restored from previous forum. Originally posted by Justin.

This code uses a window callback to monitor the clipboard for a change, if it is a text change it will display it.

msdn link:
http://msdn.microsoft.com/library/defau ... pboard.asp

Code: Select all

Procedure CBCallback(hwnd,msg,wParam,lParam)
  Shared hwndNextViewer
  ReturnValue=#PB_ProcessPureBasicEvents
  
  Select msg
    Case #WM_CHANGECBCHAIN
      ;If the next window is closing, repair the chain
      If hwnd = hwndNextViewer 
        hwndNextViewer = hwnd
        ;Otherwise, pass the message to the next link
      Else
        If hwndNextViewer<>#Null 
          SendMessage_(hwndNextViewer,msg,wParam,lParam)
        EndIf 
      EndIf 
      ReturnValue=1 
      
    Case #WM_DRAWCLIPBOARD ;clipboard contents changed
      cbtxt$=GetClipboardText() ;text only
      If cbtxt$<>"" : MessageRequester("Clipboard Change",cbtxt$,0) : EndIf 
      ;Pass the message to the next window in clipboard viewer chain
      SendMessage_(hwndNextViewer,msg,wParam,lParam)
      ReturnValue=1
  EndSelect 
  
  ProcedureReturn ReturnValue
EndProcedure

hwnd=OpenWindow(0,200,200,300,100,"Monitoring Clipboard",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)

hwndNextViewer=SetClipboardViewer_(hwnd)
SetWindowCallback(@CBCallback())

Repeat 
Until WaitWindowEvent()=#PB_Event_CloseWindow 

;remove the pb window from the chain of clipboard viewers 
ChangeClipboardChain_(hwnd,hwndNextViewer)
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Is there any way to get both the Rich Text from the clipboard AND the plain
text together, perhaps into two variables? I'd like to be able to get both at
the same time, but it seems I can only get plain text...
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

This should do the trick:

Code: Select all

.
.
CF_RTF.l = RegisterClipboardFormat_("Rich Text Format")
.
.
.
rtfData = GetClipboardData_(CF_RTF) ; get RTF data
.
.
txtData = GetClipboardData_(#CF_TEXT) ; get plain text
.
.
.
Good programmers don't comment their code. It was hard to write, should be hard to read.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

PB, did it work as expected?
Good programmers don't comment their code. It was hard to write, should be hard to read.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

I haven't had a chance to test it yet... I'm hoping to get some time later
tonight (it's 9:20am here and I don't finish work till 5:30pm).

Background of my question: I want to search/replace certain text in the
clipboard, but my problem is how to know whether the format in the
clipboard is Rich Text or Plain Text. Because if I get the text and then
use ReplaceString on it, and then use SetClipboardText, then it'll destroy
any Rich Text formatting that's there (or will it?).

So basically, I need to do search/replace on the clipboard but set the new
clipboard with the original text format, which I'm not sure how to do. But
with your tip, hopefully I'll work it out. :)

Does all this make sense? I just read it and got confused. :lol:
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

PB wrote:I just read it and got confused. :lol:
Me too :lol:

Let's see how you progress, maybe things are clearer then ;)
Good programmers don't comment their code. It was hard to write, should be hard to read.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> Let's see how you progress, maybe things are clearer then ;)

Not much clearer, I'm afraid. :(

Okay, it's like this: When you copy text in Microsoft Word, it's stored in the
clipboard as rich text. That is, when you paste that clipboard into another
Word document, it keeps the font, color, style, size, etc.

Now, if I use the PureBasic GetClipboardText command, it only gets the
plain text, and strips out the font, color, style, size. What I want to do is
get the clipboard text, do a search/replace on it, then copy it back to the
clipboard. But, as I said, if I do this then it loses the font, color, etc, and
the clipboard now holds just a plain text version of the replaced text.
So, if I copy a red bold phrase from Word, do the search/replace, then
paste it back, it gets pasted back as a black plain phrase, instead of red
bold with the changes. I wanted to retain that formatting, but I can't find
a way to do it.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

Get your RTF Text like I wrote in my previous post and after replacing use
SetClipboardData() instead of SetClipboardText(). This way the formatting
remains.

Code: Select all

rtfData.l = GetClipboardData(CF_RTF)
replaced.s = ReplaceString(PeekS(rtfData), "PureBasic", "PUREBASIC", 1)
SetClipboardData(CF_RTF, replaced)
I tried it, it works.
Good programmers don't comment their code. It was hard to write, should be hard to read.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Thanks traumatic -- I was trying to resave it with SetClipboardText instead
of SetClipboardData! :oops: Thanks for your help on this; it's very appreciated.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

You're welcome! I'm glad it works now. :)
Good programmers don't comment their code. It was hard to write, should be hard to read.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re:

Post by Dude »

I needed to do this today (search and replace RTF text in the clipboard) but per my post at http://www.purebasic.fr/english/viewtop ... 3&p=480142 you'll see that the Get/SetClipboardData() commands no longer exist. :( Can someone please post a workaround if they know how?

Below is what I've tried (in Unicode), which doesn't work. The answer may be here: https://support.microsoft.com/en-us/kb/258513 but I don't quite follow it.

Code: Select all

; Assume that the word "PureBasic" is bold and red,
; so that replacing it will also be bold and red.

CF_RTF=RegisterClipboardFormat_("Rich Text Format")

If OpenClipboard_(0)

  c=GetClipboardData_(CF_RTF)

  cliprtf$=PeekS(@c)
  cliprtf$=ReplaceString(cliprtf$,"PureBasic","PUREBASIC")
  
  SetClipboardData_(CF_RTF,cliprtf$)
  
  CloseClipboard_()

EndIf
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Monitor the clipboard

Post by RASHAD »

Hi

Code: Select all

; Assume that the word "PureBasic" is bold and red,
; so that replacing it will also be bold and red.

CF_RTF=RegisterClipboardFormat_("Rich Text Format")

If OpenClipboard_(0)
    cbHnd = GetClipboardData_(CF_RTF)
    txtLen = lstrlen_(cbHnd)*SizeOf(character)
    cliprtf$ = Space(txtLen)    
    CopyMemory_( cliprtf$, cbHnd, txtLen)
    cliprtf$ = PeekS(@cliprtf$,txtLen,#PB_UTF8)
    cliprtf$=ReplaceString(cliprtf$,"PureBasic","PUREBASIC")
    CloseClipboard_()
    Debug cliprtf$
EndIf

;Ascii or Unicode
; {\rtf1\fbidis\ansi\ansicpg1256\deff0\nouicompat\deflang3073{\fonttbl{\f0\fnil\fcharset0 Arial;}}
; {\colortbl ;\red255\green0\blue0;}
; {\*\generator Riched20 10.0.10240}\viewkind4\uc1 
; \pard\ltrpar\sa200\sl276\slmult1\cf1\b\fs32\lang9 PUREBASIC\b0\par
; }
Egypt my love
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Monitor the clipboard

Post by Dude »

Thanks Rashad: cliprtf$ does indeed hold the replaced text; but how do I put that back into the clipboard as rich text?

If I use SetClipboardText(cliprtf$), then pasting it in Word (and also WordPad and Gmail) removes all formatting and does it as plain text.

And using SetClipboardData_(CF_RTF,@cliprtf$) doesn't do it either, it just pastes the original text. :(

Basically, the goal is that I'm cutting rich text from Word with Ctrl+X, running your procedure, and pasting the replaced text back into Word again with Ctrl+V.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Monitor the clipboard

Post by RASHAD »

Hi Dude

Code: Select all

; Assume that the word "PureBasic" is bold and red,
; so that replacing it will also be bold and red.

CF_RTF=RegisterClipboardFormat_("Rich Text Format")

If OpenClipboard_(0)
    cbHnd = GetClipboardData_(CF_RTF)
    txtLen = lstrlen_(cbHnd)*SizeOf(character)
    cliprtf$ = Space(txtLen)   
    CopyMemory_( cliprtf$, cbHnd, txtLen)
    cliprtf$ = PeekS(@cliprtf$,txtLen,#PB_UTF8)
    cliprtf$=ReplaceString(cliprtf$,"PureBasic","PUREBASIC")
    mem = GlobalAlloc_(#GHND,lstrlen_(cliprtf$)*SizeOf(character)+1)
    lpstr = GlobalLock_(mem)
    PokeS(lpstr,cliprtf$,-1,#PB_UTF8)
    GlobalUnlock_(mem)
    EmptyClipboard_()
    SetClipboardData_(CF_RTF,mem)
    CloseClipboard_()   
    GlobalFree_(mem)
EndIf

  If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    EditorGadget(0, 8, 8, 306, 133)
    For a = 0 To 5
      AddGadgetItem(0, a, "Line "+Str(a))
    Next
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf

; Now You can paste the revised text into the editor gadget using Ctrl-V
Egypt my love
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Monitor the clipboard

Post by Dude »

THANK YOU, RASHAD! :D

Image
Post Reply