Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

SetClipboardData and GetClipboardData functions


  • Please log in to reply
32 replies to this topic
gongchao6330
  • Members
  • 24 posts
  • Last active: Jul 17 2011 06:26 AM
  • Joined: 25 Mar 2009
I have test the "GetClipboardData" functon with Word, but it returns nothing. Can you tell me why?

automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006
.rtf seems to be a complicated topic as there are quite a lot format options, you need to look at the topic really from the detailed perspective.

gongchao6330
  • Members
  • 24 posts
  • Last active: Jul 17 2011 06:26 AM
  • Joined: 25 Mar 2009
I have tried all the options, but it still return nothing. How about that?

p::
CF_TEXT = 1 
CF_UNICODETEXT = 13 
CF_RTF = Rich Text Format 
CF_RTFNOOBJS = Rich Text Format Without Objects 
CF_DIB = 8 
CF_DIBV5 = 17

GetClipboardData(CF_TEXT, str) 
MsgBox %str% 
GetClipboardData(CF_UNICODETEXT, str) 
MsgBox %str% 
GetClipboardData(CF_RTF, str) 
MsgBox %str% 
return


aldoniel
  • Members
  • 1 posts
  • Last active: Nov 25 2009 01:37 PM
  • Joined: 08 Nov 2009
Thanks you very much for your work PhiLho, it works very well !

(although it takes a few hours to get everything working, especially if at first you have no idea how autohotkey or the windows clipboard works...)

I could only paste the Rich Text clipboard into Word and WordPad. When I attempt pasting it into Notepad or any other application, nothing shows up. They probably need multiple clipboard formats. I wonder, is HTML any better? Could you add support to HTML clipboards?


This script already support this function, I just used it to set a hotkey to send formatted text to notepad, wordpad, open office, and mozilla products.
To do this, you need to add to the clipboard the following types :

CF_TEXT
Rich Text Format (get this one from a wordpad ctrl-c)
HTML Format (and the last three from seamonkey, maybe thunderbird composing ?)
text/_moz_htmlcontext
text/html

(the last three of them are needed by mozilla products, or at least seamonkey, I didn't try with firefox.)

I used PhiLho's Hex2Bin function for the last two types (see Frhed if you don't have an hex editor at hand)
I also strongly recommend CLCL if you have no idea how the windows clipboard works : it simply display it using a tree-view style, that's all you need to know)

AmourSpirit
  • Members
  • 93 posts
  • Last active: Mar 01 2016 04:28 PM
  • Joined: 01 Dec 2010
Ok, I have spent way too many hours tring to get this to work.
Can someone please help me with this.

For some reason the following code only puts the first character on the clipboard "S".

#SingleInstance force
#NoEnv

CF_TEXT := 1
myData := "Sigh!"

SetClipBoardData(CF_TEXT, myData, 0, true)

MsgBox, All Done
ExitApp


SetClipboardData(_format, ByRef @data, _dataSize=0, _bEmptyClipboard=true)
{
   local res, mem, str, cfFormat, errorCode

   errorCode = 0

   If (_dataSize = 0)
   {
      ; Assume it is a simple string; otherwise, should provide real length...
      _dataSize := StrLen(@data)
	  If (_dataSize = 0)
      {
         errorCode = SIZE
         Goto SCD_End
      }
   }

   ; Open the clipboard, and empty it.
   res := DllCall("OpenClipboard", "Uint", 0)
   If (res = 0)
   {
      errorCode = OC
      Goto SCD_End
   }
   If (_bEmptyClipboard)
   {
      DllCall("EmptyClipboard")
   }

   ; Allocate a global memory object for the text
   mem := DllCall("GlobalAlloc"
         , "Uint", 2 ; GMEM_MOVEABLE
         , "Uint", _dataSize + 1) ; +1 in case it is a zero-terminated string
   If (mem = 0)
   {
      errorCode = GA
      Goto SCD_End
   }

   ; Lock the handle and copy the text to the buffer
   str := DllCall("GlobalLock", "Uint", mem)
   ; str is a pointer to a memory area, so is treated as Uint
   DllCall("RtlMoveMemory"
         , "Uint", str
         , "Str", @data
         , "Uint",_dataSize)
   ; In case it is a zero-terminated string, we put the final zero
   DllCall("RtlZeroMemory", "Uint", str + _dataSize, "Uint", 1)
   DllCall("GlobalUnlock", "Uint", mem)

   ; Handle format
   If _format is integer
   {
      cfFormat := _format
   }
   Else
   {
      cfFormat := DllCall("RegisterClipboardFormat", "Str", _format)
      If (cfFormat = 0)
      {
         errorCode = RCF
         Goto SCD_End
      }
   }

   ; Place the handle on the clipboard
   res := DllCall("SetClipboardData"
         , "Uint", cfFormat
         , "Uint", mem)
   If (res = 0)
   {
      errorCode = SCD
      Goto SCD_End
   }

SCD_End:
   If errorCode != 0
   {
      errorCode = %errorCode%  (%A_LastError%)
   }
   ; Close the clipboard
   DllCall("CloseClipboard")

   ErrorLevel := errorCode
}

I am using win 7 x64 but got the same result in a win xp x86 virtual machine.

kenn
  • Members
  • 407 posts
  • Last active: Jan 14 2015 08:16 PM
  • Joined: 11 Oct 2010
Compatibility issue, it works well on AHK Basic, I just tried.

hoppfrosch
  • Members
  • 399 posts
  • Last active: Feb 26 2016 05:31 AM
  • Joined: 25 Jan 2006
It's more a UNICODE issue - works well with AHK_L Ansi ...


   ...
   DllCall("RtlMoveMemory"         
            , "Uint", str
            [color=red] , "Str", @data
           , "Uint",_dataSize)[/color] 
    DllCall("RtlZeroMemory", "Uint", [color=red]str + dataSize[/color], "Uint", 1)
   ...


You probably have to use UNICODE Variants/values here ... (you also have to consider when determining datasize, that UNICODE needs more memory ...)

_________________________

;     (.)~(.)   
;    (-------)                                    
;---ooO-----Ooo---------------------------------------------------
;    Hoppfrosch  - AHK 1.1.05.06 Unicode 32bit on Win7 Ultimate
;-----------------------------------------------------------------                        
;    ( )   ( )                            
;    /|\   /|\


kenn
  • Members
  • 407 posts
  • Last active: Jan 14 2015 08:16 PM
  • Joined: 11 Oct 2010
@hoppfrosch thanks a lot, I'm learning.

AmourSpirit
  • Members
  • 93 posts
  • Last active: Mar 01 2016 04:28 PM
  • Joined: 01 Dec 2010
Does anyone know the answer to solve this. It is currently outside my scope of knowledge.

It's more a UNICODE issue - works well with AHK_L Ansi ...


   ...
   DllCall("RtlMoveMemory"         
            , "Uint", str
            [color=red] , "Str", @data
           , "Uint",_dataSize)[/color] 
    DllCall("RtlZeroMemory", "Uint", [color=red]str + dataSize[/color], "Uint", 1)
   ...



You probably have to use UNICODE Variants/values here ... (you also have to consider when determining datasize, that UNICODE needs more memory ...)

_________________________

[code=auto:0]



Deo
  • Members
  • 199 posts
  • Last active: Jan 31 2014 03:19 PM
  • Joined: 16 May 2010
check this
http://www.autohotke...pic.php?t=79998
you can do what above example shows with one line:
WinClipboard.Clear() ;if you want to clear the clipboard
WinClipboard.SetText( "Sigh!" )
WinClipboard.AppendText( "Hello!" ) ;to append text
though it is intended for unicode x32/x64, ansi will not work

AmourSpirit
  • Members
  • 93 posts
  • Last active: Mar 01 2016 04:28 PM
  • Joined: 01 Dec 2010
I am not sure this class would work for me as Ultimately I need to set html onto the clipboard. I Posted my solution for Unicode below this post

check this
http://www.autohotke...pic.php?t=79998
you can do what above example shows with one line:

WinClipboard.Clear() ;if you want to clear the clipboard
WinClipboard.SetText( "Sigh!" )
WinClipboard.AppendText( "Hello!" ) ;to append text
though it is intended for unicode x32/x64, ansi will not work



AmourSpirit
  • Members
  • 93 posts
  • Last active: Mar 01 2016 04:28 PM
  • Joined: 01 Dec 2010
This is my Solution to get copying "Html Format" to the clipboard. This was tested on Windows 7 x64 AutoHotkkey_L v1.1.05.04.
I found no issues so far with this script.

CF_HTML := "HTML Format"

pushHTML(sHtmlFragment, title = "", sourceUrl = "")
{
Header =
(
Version:1.0
StartHTML:aaaaaaaa
EndHTML:bbbbbbbb
StartFragment:cccccccc
EndFragment:dddddddd
StartSelection:cccccccc
EndSelection:cccccccc
)
; http://blogs.msdn.com/b/jmstall/archive/2007/01/21/sample-code-html-clipboard.aspx
Pre := "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN""><HTML><HEAD><TITLE>" . title . "</TITLE></HEAD><BODY><!--StartFragment-->"
Post := "<!--EndFragment--></BODY></HTML>"

   offSet := 6
   sData := Header
	if (sourceUrl){
		sData := sData . "SourceURL:" . sourceUrl
	}
   iStartHTML := StrLen(sData) + offSet
   
   sData := sData . Pre
   iStartFrag := StrLen(sData) + offSet
   
   sData := sData . sHtmlFragment
   iEndFrag := StrLen(sData) + offSet
   
   sData := sData . Post
   iEndHTML := StrLen(sData) + offSet
   iPadLen := 8
   StringReplace sData, sData, aaaaaaaa, % StrPad(iStartHTML, "0", iPadLen)
   StringReplace sData, sData, bbbbbbbb, % StrPad(iEndHTML, "0", iPadLen)
   StringReplace sData, sData, cccccccc, % StrPad(iStartFrag, "0", iPadLen), All
   StringReplace  sData, sData, dddddddd, % StrPad(iEndFrag, "0", iPadLen)

   Return, sData
}  

StrPad(Str, PadChar,PadLen,Left=1)
{
	StringLen, sLen, str
	
	if (sLen >= PadLen)
		return str
	
	sDif := PadLen - sLen
	strPad := ""
	
	Loop, %sDif%
	{
		strPad := strPad . PadChar
	}
	Retval := ""
	If (Left=1) 
	{
		Retval := strPad . Str
	}
	else
	{
		Retval := str . strPad
	}
	return Retval
}

SetClipboardData(_format, ByRef @data, _dataSize=0, _bEmptyClipboard=true)
{
   local res, mem, str, cfFormat, errorCode
   errorCode = 0

   If (_dataSize = 0)
   {
      ; Assume it is a simple string; otherwise, should provide real length...
      _dataSize := StrLen(@data)
	  If (_dataSize = 0)
      {
         errorCode = SIZE
         Goto SCD_End
      }
   }

   ; Open the clipboard, and empty it.
   res := DllCall("OpenClipboard", "Uint", 0)
   If (res = 0)
   {
      errorCode = OC
      Goto SCD_End
   }
   If (_bEmptyClipboard)
   {
      DllCall("EmptyClipboard")
   }

   ; Allocate a global memory object for the text
   mem := DllCall("GlobalAlloc"
         , "Uint", 2 ; GMEM_MOVEABLE
         , "Uint", _dataSize + 1) ; +1 in case it is a zero-terminated string
   If (mem = 0)
   {
      errorCode = GA
      Goto SCD_End
   }

   ; Lock the handle and copy the text to the buffer
   str := DllCall("GlobalLock", "Uint", mem)
   ; str is a pointer to a memory area, so is treated as Uint
  
   ;~ ; In case it is a zero-terminated string, we put the final zero
   [color=red]StrPut(@data, str , _dataSize +1,Encoding = "utf-16")[/color]
   DllCall("GlobalUnlock", "Uint", mem)

   ; Handle format
   If _format is integer
   {
      cfFormat := _format
   }
   Else
   {
      cfFormat := DllCall("RegisterClipboardFormat", "Str", _format)
      If (cfFormat = 0)
      {
         errorCode = RCF
         Goto SCD_End
      }
   }

   ; Place the handle on the clipboard
   res := DllCall("SetClipboardData"
         , "Uint", cfFormat
         , "Uint", mem)
   If (res = 0)
   {
      errorCode = SCD
      Goto SCD_End
   }

SCD_End:
   If errorCode != 0
   {
      errorCode = %errorCode%  (%A_LastError%)
   }
   ; Close the clipboard
   DllCall("CloseClipboard")

   ErrorLevel := errorCode
}

; only needed if you want to retrieve the html from the clipboard
ClipboardGet_HTML( byref Data ) { ; www.autohotkey.com/forum/viewtopic.php?p=392624#392624
 If CBID := DllCall( "RegisterClipboardFormat", Str,"HTML Format", Uint )
  If DllCall( "IsClipboardFormatAvailable", Uint,CBID ) <> 0
   If DllCall( "OpenClipboard", Uint,0 ) <> 0
    If hData := DllCall( "GetClipboardData", Uint,CBID, Uint )
       DataL := DllCall( "GlobalSize", Uint,hData, Uint )
     , pData := DllCall( "GlobalLock", Uint,hData, Uint )
     , VarSetCapacity( data, dataL * ( A_IsUnicode ? 2 : 1 ) ), StrGet := "StrGet"
     , A_IsUnicode ? Data := %StrGet%( pData, dataL, 0 )
                   : DllCall( "lstrcpyn", Str,Data, Uint,pData, Uint,DataL )
     , DllCall( "GlobalUnlock", Uint,hData )
 DllCall( "CloseClipboard" )
Return dataL ? dataL : 0
}
Simple Example:
RawHtml := "<h2><span style='color: rgb(0, 100, 0);'><u>Hello World</u></span></h2>"
Html := pushHTML(RawHtml, "My Hello World")
SetClipboardData(CF_HTML, Html)
MsgBox, % Html
MsgBox, Html is now on the clipboard and can be pasted into a Html editor.


AmourSpirit
  • Members
  • 93 posts
  • Last active: Mar 01 2016 04:28 PM
  • Joined: 01 Dec 2010
Can anyone help with this? in Chrome or Dreamweaver the "Html Format" works fine but Firefox will not paste anything. It say in this post that firefox needs "text/html" format on the clipboard.
Html := pushHTML(OutputText)
	SetClipBoardData("HTML Format", Html, 0, false)
	SetClipBoardData("text/html", Html, 0, true)

This is What gets pasted into Firefox ( gmail or online html editor such as tinyMCE )

敖獲潩㩮⸰ਹ瑓牡䡴䵔㩌〰〰〰㔹䔊摮呈䱍〺〰〰㌵ਲ਼瑓牡䙴慲浧湥㩴〰〰㄰㜲䔊摮牆条敭瑮〺〰〰〵㰱呈䱍㰾佂奄㰾ⴡ匭慴瑲牆条敭瑮ⴭ匾敥䔠敶湲瑯㩥䠠汥潬圠牯摬‬愼栠敲㵦攢敶湲瑯㩥⼯瘯敩⽷ㄱ㐷㤸㜶猯〱⼹昲晤㈱㤷愭捣ⵦ㌴㘰㠭ㄹⴳ㈵戰㉤㤰㍦㘰㈯摦ㅦ㜲ⴹ捡晣㐭〳ⴶ㤸㌱㔭〲摢〲昹〳⼶㸢猼慰瑳汹㵥挧汯牯›杲⡢ⰰㄠ㠲‬⤰✻䐾獥瑫灯⼼灳湡㰾愯ⰾ㰠⁡牨晥✽瑨灴㩳⼯睷⹷癥牥潮整挮浯瘯敩⽷昲晤㈱㤷愭捣ⵦ㌴㘰㠭ㄹⴳ㈵戰㉤㤰㍦㘰氿捯污㵥湥渣㈽摦ㅦ㜲ⴹ捡晣㐭〳ⴶ㤸㌱㔭〲摢〲昹〳✶琠牡敧㵴弧汢湡❫圾扥⼼㹡映牯映牵桴牥椠普牯慭楴湯㰮ⴡ䔭摮牆条敭瑮ⴭ㰾䈯䑏㹙⼼呈䱍>

In Chrome ( gmail ) or Dreamweaver the html paste fine.
For Example:
See Evernote: Hello World, Desktop, Web for further information.

I am using AutoHotkey_L Unicode on Window 7 x64

mparsons
  • Members
  • 5 posts
  • Last active: Feb 11 2012 08:27 PM
  • Joined: 22 Jan 2012
anybody had any luck getting this to work with putting formatted HTML on the clipboard?

Any help on getting this to work would be really appreciated

  • Guests
  • Last active:
  • Joined: --
@AmourSpirit: see first page where Firefox is mentioned, it uses a different format.