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@...> > >