[futurebasic] Re: [FB] Append a String to the Clipboard in Carbon

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : June 2002 : Group Archive : Group : All Groups

From: RICH LOVE <richlove@...>
Date: Sun, 16 Jun 2002 10:42:32 -0500
Alain,

If I modify the DoAppend function to use a string instead of a text edit
field, Why does it add a control character to the beginning of the string
when it goes to the clipboard?


local fn DoAppend
dim teH     as ..TERec
dim @ textH as handle

// get a handle to the text string

x$ = "mystring"
textH = FN NewString (x$)

long if fn HandToHand( textH ) = _noErr
// append the data duplicated to the clipboard text
fn AppendTextToClipboard( textH )
// get rid of the copy handle
call DisposeHandle( textH )
xelse
beep : beep
end if
end fn

Rich Love - Carnation Software
  Terminal emulations for Macintosh - MacWise, MacToPic Plus and SBMac.
  Email Checker, Carnation Desktop Pictures, Desktop Screen Saver,
  Index & Shutdown, One Touch Scan and QuitAll
  Visit our home page at http://www.carnation-software.com
  512 858-9234


> From: Alain Pastor <pixmix@...>
> Organization: Pix & Mix
> Reply-To: futurebasic@...
> Date: Sun, 16 Jun 2002 09:51:44 +0200
> To: futurebasic@...
> Subject: Re: [FB] Append a String to the Clipboard in Carbon
> 
> RICH LOVE wrote:
>> 
>> Ken,
>> 
>> That works great!
>> Thanks very much.
>> FYI, it works under OS X (which is all I need) but crashes when booted under
>> OS 9 saying it is out of memory trying to dispose a handle.
>> 
> I don't know about your crash, but I got a memory problem related to
> container with the code posted by Ken under Mac OS 9.2.2. I have not
> tried to find the cause of the trouble, instead I have used the
> original program to test another approach without the use of containers.
> 
> While containers may be handy, I don't like that much to be forced to
> add global variables in my programs. I always try to keep them at the
> minimum. Not that containers variables would eat too much memory space
> but it is also slightly more difficult to reuse the functions in other
> projects if they refer to containers.
> I think it is a good habit to build self contained functions in local
> mode. You can see the benefits as soon as you start a new project.
> 
> It is also a good habit whenever possible to free the memory allocated
> in the same function you have asked for it. I saw that Ken didn't do
> that. It is OK in very short demos, but in real projects you might
> easily loose tracks on what is going on with memory.
> 
> Here is my hack of Ken's code (not tested under OS X):
> 
> 
> /*
> 
>  Append text to clipboard based on Ken Shmidheiser's demo
>                                                    Alain
> 
> */
> 
> 
> /*
>    this function gets a copy of the raw text
>    from the clipboard. It returns a _nil handle
>    if the operation fails.
> */
> local mode
> local fn GetClipboardText
> dim as handle     scrapTextH
> dim as long     @ length
> dim as ScrapRef @ theScrapRef
> 
> scrapTextH = _nil
> // getting the scrap reference
> long if fn GetCurrentScrap( theScrapRef ) = _noErr
> // checking for text
> long if fn GetScrapFlavorSize( theScrapRef,¬
>           _"TEXT", length ) = _noErr
> // if length is not null, we've got some
> long if length
> // making a new handle with an appropriate size
> scrapTextH = fn NewHandleClear( length )
> long if scrapTextH
> // getting the text from the clipboard
> HLock( scrapTextH )
> Long if fn GetScrapFlavorData( theScrapRef,¬
>           _"TEXT", length, #[scrapTextH] ) != _noErr
> beep : beep
> end if
> HUnlock( scrapTextH )
> Xelse
> beep : beep
> end if
> end if
> end if
> end if
> end fn = scrapTextH
> 
> /*
>    this function puts some raw text pointed to
>    by a handle into the clipboard
> */
> local mode
> local fn TextToClipboard( textH as handle )
> dim as OSStatus      err
> dim as ScrapRef @ theScrapRef
> 
> Long if textH
> // clear the scrap
> err = fn ClearCurrentScrap
> // get the scrap reference
> long if fn GetCurrentScrap( theScrapRef ) = _noErr
> HLock( textH )
> // put text into the scrap
> err = fn PutScrapFlavor( theScrapRef, _"TEXT",¬
>      _kScrapFlavorMaskNone, fn GetHandleSize( textH ), #[textH] )
> HUnlock( textH )
> if err then beep : beep
> end if
> end if
> 
> end fn
> 
> /*
>    this function appends data to
>    the clipboard text (if any)
> */
> local mode
> local fn AppendTextToClipboard( textH as handle )
> dim clipTextH as handle
> 
> // getting the existing clipboard text
> clipTextH = fn GetClipboardText
> // if no text found create an empty handle
> if clipTextH = _nil then clipTextH = fn NewHandle( 0 )
> long if clipTextH
> // append the data
> long if fn HandAndHand( textH, clipTextH  ) = _noErr
> // copy to clipboard
> fn TextToClipboard( clipTextH )
> xelse
> beep : beep
> end if
> // we don't need anymore the handle
> DisposeHandle( clipTextH )
> end if
> 
> end fn
> 
> local fn buildMenus
> 
> apple menu "(Ken's Clipboard Demo..."
> 
> menu 1, 0, _enable, "File"
> menu 1, 1, _enable, "Quit"
> 
> edit menu 2
> 
> end fn
> 
> local fn buildWindow
> dim as rect r
> 
> setrect( r, 0, 0, 500, 370)
> window -1,"Ken's Clipboard Tester",@r,_docNoGrow
> 
> text _applFont, 12
> edit = 4
> setrect( r, 20, 20, 280, 34)
> edit field -1,"What would you like to do?",@r,_statNoframed,_leftJust
> 
> setrect( r, 300, 50, 462, 310)
> edit field -2,"",@r,_framed,_leftJust
> setrect( r, 463, 47, 480, 313)
> SCROLL BUTTON -2,0,0,0,0, @r, _scrollOther
> 
> setrect( r, 24, 232, 276, 246)
> edit field -3,"",@r,_statNoframed,_leftJust
> 
> setrect( r, 24, 258, 263, 332)
> edit field -4,"",@r,_framed,_leftJust
> setrect( r, 263, 256, 278, 334)
> SCROLL BUTTON -4,0,0,0,0, @r, _scrollOther
> 
> 
> setrect( r, 20, 50, 280, 74)
> button 10,1,"View clipboard text",@r,_push
> 
> offsetrect( r, 0, 60 )
> button 20,1,"Clear clipboard",@r,_push
> 
> offsetrect( r, 0, 60 )
> button 30,1,"Enter text for clipboard append",@r,_push
> 
> setrect( r, 300, 330, 480, 350)
> button 40,0,"Append text to clipboard",@r,_push
> 
> edit field 0
> 
> window 1
> 
> end fn
> 
> local fn ClearButtons
> edit$(4) = ""
> button 40,0
> end fn
> 
> /*
>    this function displays the text
>    contained in the clipboard
> */
> local fn ViewClipboardText
> dim scrapTextH as handle
> dim textLen    as long
> 
> fn ClearButtons
> // get the clipboard text
> scrapTextH = fn GetClipboardText
> long if scrapTextH
> /*
>    OK, now we've got our handle
>    comes the tricky part. I wanted to
>    use the syntax : EDIT$(_efNumber) = @myHandle
>    In that case myHandle must be a ZTEXT handle
>    which is specific to FB. It consists of a
>    leading integer specifying the text length,
>    followed by the raw text optionally followed
>    by style information.
> */
> // get the length of the clipboard text
> textLen = fn GetHandleSize( scrapTextH )
> // increase the handle size to make room for the integer
> SetHandleSize( scrapTextH, sizeof(int) + textLen )
> long if fn MemError = _noErr
> // move the data to free space at the beginning of the handle
> BlockMove([scrapTextH], [scrapTextH] + sizeof(int), textLen )
> // store the text length in the two first bytes
> scrapTextH..nil% = textLen
> // put the "ZTEXT" handle in the edit field
> Edit$(2) = &scrapTextH
> end if
> end if
> end fn
> 
> local fn ClearClipboard
> long if fn ClearCurrentScrap = _noErr
> fn ClearButtons
> Edit$(2) = ""
> end if
> end fn
> 
> local fn AllowAppendText
> edit$(3) = "Please enter text to append here:"
> button 40,1
> edit field 4
> end fn
> 
> /*
>    this function copies the raw text
>    from an edit field and appends it to
>    the existing clipboard text.
> */
> local fn DoAppend
> dim teH     as ..TERec
> dim @ textH as handle
> 
> // get a handle to the Text Edit record
> teH   = tehandle( 4 )
> // make an "alias" of the text handle
> textH = teH..hText
> // copy the data
> long if fn HandToHand( textH ) = _noErr
> // append the data duplicated to the clipboard text
> fn AppendTextToClipboard( textH )
> // get rid of the copy handle
> DisposeHandle( textH )
> fn ViewClipboardText
> xelse
> beep : beep
> end if
> end fn
> 
> local fn DoDialog
> dim as long evnt, id
> 
> evnt = dialog(0)
> id = dialog(evnt)
> 
> select case( evnt )
> case _wndClose
> select( id )
> case 1 : gFBQuit = _zTrue
> end select
> 
> case _btnClick
> select( id )
> case 10 : fn ViewClipboardText
> case 20 : fn ClearClipboard
> case 30 : fn AllowAppendText
> case 40 : fn DoAppend
> end select
> 
> end select
> 
> end fn
> 
> local fn DoMenu
> dim as long menuID, itemID
> 
> menuID = menu(_menuID)
> itemID = menu(_itemID)
> 
> select case( menuID )
> case 1 : gFBQuit = _zTrue
> end select
> menu
> 
> end fn
> 
> on dialog fn DoDialog
> on menu   fn DoMenu
> 
> fn buildMenus
> fn buildWindow
> 
> do
> handleevents
> until gFBQuit
> end
> 
> 
> -- 
> Cheers,
> 
> Alain
> 
> --
> To unsubscribe, send ANY message to <futurebasic-unsubscribe@...>
> 
>