Demonstration: Manipulating the Clipboard in Delphi

Here’s a quick demonstration of how easy programming is in Delphi.

This small app allows you to copy text and past it again right away with it converted to proper case or upper case.  This was written for a ZTree user that had a bunch of files that he wanted t rename to partially uppercase.  There was no way to pick out the part of the name he wanted in upper case. So I wrote this routine to allow him to highlight part of the text, hit copy and then hit paste.  And viola, he it would be fixed.

So in Delphi, how do you access the clip board? Well, it couldn’t be simpler.  Just add the clipbrd unit to your uses statement like this:

[delphi]uses Clipbrd;[/delphi]

Then you can read and write to the clipboard  as text like this:

[delphi]A := Clipboard.AsText;
Clipboard.AsText := A + ‘BC’;[/delphi]

Of course it is best to check that you are dealing with text befor you try to get the information back from the clipboard.  That can be done like this:

[delphi]if (Clipboard.HasFormat(CF_TEXT)) then DoIt;[/delphi]

See! It is THAT straight forward.  If you want to see what  other clipboard formats there are, just highlight CF_TEXT in Delphi and hit F1 and you’ll get a full list.

Value Meaning
CF_TEXT Text with a CR-LF combination at the end of each line. A null character identifies the end of the text.
CF_BITMAP A Windows bitmap graphic.
CF_METAFILEPICT A Windows metafile graphic.
CF_PICTURE An object of type TPicture.
CF_COMPONENT Any persistent object.

So the instructions to create a full app are quite simple:
In Delphi, create a new app. In the Object Inspector, Name the main form frmCBFix, change the Border style to bsToolWindow, and change the form style to fsStayOnTop

Place a TEdit on the form and name it editCorrected text, clearing the default text value.

Add Clipbrd to the uses.

Put a TTimer on the form and double click the timer event in the Object Inspector.

Paste the following code into the unit replacing the automatic generated Timer1Timer procedure:

Converts a string to proper case by capitalizing each letter after a space or
punctuation. The only common punctuation not used is the apostrophe/single
quote. This avoids changing don’t to Don’T, but will sentences quoted
inside single quotes will not have their first letter capitalized.
function ProperCase(aSrcStr: String): String;
Len, Index: integer;
aSrcStr := Lowercase(aSrcStr);
Len := Length(aSrcStr);
aSrcStr[1] := UpperCase(string(aSrcStr[1]))[1];
for Index := 1 to Len – 1
do begin
if (aSrcStr[Index] in [‘ ‘,’$’,'”‘,'(‘,’)’,’`’,’!’,’?’,’<','!','>‘,’#’,’=’,’+’,’:’,’,’,’/’,’.’,’&’,’-‘,'{‘,’}’,'[‘,’]’,’|’])
then aSrcStr[Index + 1] := UpperCase(String(aSrcStr[Index + 1]))[1];
Result := aSrcStr;

Fires periodically (orignally every 250ms), checks the clip board for text,
if it has changed, convert it to proper case and put the result in the
clipboard and the edit control.
procedure TfrmCBFix.Timer1Timer(Sender: TObject);
begin // Timer1Timer
if Clipboard.HasFormat(CF_TEXT)
then begin
if (editCorrectedText.Text <> Clipboard.AsText)
then begin
editCorrectedText.Text := ProperCase(Clipboard.AsText);
Clipboard.AsText := editCorrectedText.Text;
end; // Timer1Timer [/delphi]
And you’re done!

Here are the files for this project:

The WordPress 2.0 theme competition ends today

Today is the last day for submissions.  I hope this means there are pleanty of good themes coming out soon.  Now that I know a little about this, I realize that this competition is being done the right way.  In reality, appearance, which to the new WordPress user seems to all there is to themes, is MUCH less important than the underpinnings and design of the theme.  In this competion, prizes are being given for How the theme was written and what features it includes.  In stead of, or perhaps in addition to, the theme appearance.  See here:

Feature: Category choices.

It would be neat if a browser could only see the categories on a blog that they are interested in.  If the theme could save a cookie with a bitmap of the blogs themes, the user could ignore stuff like  this that they do not care about.  Why would a delphi programmer care about a possible feature I intend to maybe someday include in a theme May or May Not ever get around to writing.

Feature: TRUE blog pages.

The theme must be able to support pages with internal HTML.

This should be done in a way that can be made a standard for other themes and this should be relayed to the other people in the competition prior to the theme releases.  This REALLY should be a standard for WordPress in general.

 In order for me to create a new page at that fits in with the current blog, all I need to do is wrap PHP or HTML in these two lines:

<?php require(dirname(__FILE__).’/includes/custompage_top_yar.php’); ?>

<?php require(dirname(__FILE__).’/includes/custompage_btm_yar.php’); ?>

If I do that, then I can put ANYTHING in there.  Under the current WordPress pages lay out, you are restricted to the type of content allowed in WordPress posts.  That’s insufficient if you want to create true webpages like:\fleet.php or\subscribetome.php or\useronline.php

An option would be to allow the theme options tab to do it by itself…

Display the program that will run when type a name at the cmd prompt

You can also find this file here:

:: ************************************************************************* ::  SearchPath.Bat                                               10/31/2005 ::  Written by Brian Layman (AKA Capt. Queeg) ::  Visit him at ::  ::  A batch written to display the program that would be run when ::  a filename is typed at the command prompt.  Just a demo for ::  Hartmut at ::  ::  Usage: SearchPath ProgramName[.EXT] ::  ::  History: ::     10/31/2005 - BL - Created ::     11/01/2005 - BL - Removed Temp File Usage ::     02/28/2006 - BL - Changed my URL ::  :: ************************************************************************* @echo Off :: All this is boiled down to one subroutine that sets a variable of the :: same name. call :SearchedFilePath %1 :: If no program is found, say so. if "%SearchedFilePath%"=="" echo There is no matching program in the search path :: If a program was found, echo its name. if NOT "%SearchedFilePath%"=="" echo %SearchedFilePath% :: Clear out our temp variable set SearchedFilePath= :: Quit GOTO :EOF :: ************************************************************************* :: ************************************************************************* ::  Support procedures :: ::  These routines are called with a CALL directive and the GOTO :EOF ::  terminates that CALL but does not terminate the entire running of the ::  batch file. :: ************************************************************************* :: ************************************************************************* :SearchedFilePath ::  Returns the full path to a passed file in the searchpath :: ::  Returns blank if not found. :: :: ************************************************************************* : set SearchedFilePath=    :: Set the default value to blank.   set SearchedFilePath=   :: If there is no extension handle it   if "%~x1"=="" Call :SearchWithExtensions %1&GOTO :EOF   :: There is no extension, is it blank?   if "%1"=="" GOTO :EOF   :: So, we have an extension.  That means we can do a simple search.   :: %~dp$PATH:1 automatically searches the path for us.  It is a   :: variable set by the Call command.   set  SearchedFilePath=%~dp$PATH:1%1   if "%SearchedFilePath%"=="%1" set SearchedFilePath=&GOTO :EOF   GOTO :EOF :: ************************************************************************* :: ************************************************************************* :SearchWithExtensions ::  Iterates the extensions gathered from the PATHEXT environment ::  and searches until the file is found. :: ::  Returns blank if not found. :: :: *************************************************************************     :: Initialize a counter for looking at multiple search results in one line     set cnt=0     :SearchLoop       :: Break out after 20  checks.       :: If you might have more than 20 extensions, increase this value.       :: If you could find out how many periods there are in the temp file, you could optimize this.       if "%cnt%"=="20" GOTO :SearchLoopCleanup       set /A cnt=%cnt%+1       :: Continually search the single line file returning each sequential search result and recursively pass it to the       :: SearchedFilePath routine.  When we ask for a token # that doesn't exist and blank is returned, abort out.       for /F "tokens=%cnt% delims=.;" %%C in ("%PATHEXT%") do call :SearchedFilePath %1.%%C       if "%SearchedFilePath%"== "" GOTO :SearchLoop         :SearchLoopCleanup       :: Clear our Temp variable       set cnt=   GOTO :EOF :: *************************************************************************


Borland Dies.

By now every Delphi programmer knows about this.  But for all others, here you go:

Borland has release the first version of Delphi, since Delphi 5 in 1999ish, that has been truely worth the upgrade price.  Delphi 2006 (D9) pretty much guarantees the success of the company by being the ONLY compiler fill a niche (Win32 development) that MS’s move to dot .net created.  Only ONE of the new MS compilers will allow you to write a Win32 bit app (VC++ still allows it but VB, VC#, VJ# etc do not  Thanks Liviu! ) Delphi is IT for the next 7-10 years while Win32 apps will still be allowed (basically for the life span of Windows XP and Vista).

Having such a high quality tool that practically guaranteed sales in a totally open vertical market, left Borland’s newest poker-playing-turn-around-guy, Tod Nielsen – the newest in a string of CEOs dedicated to the destruction of Borland – no choice but to kill the company by dropping all code development tools 100 days after he took the job.

“We’re still all about development, but less about the creation of code,” Nielsen said.  – HUH??????

The interesting thing is that the Delphi community user base is SO frustrated with the management decisions of the last 7 years that they have thrown up their arms and said “Fine. Do it. And good riddance.” 

 Read the details:


Addendum – I just found out that in the fall of 2005 a Borland stock holder (the largest?) had offered Borland 125 million for their language suites.  Borland turned him down out of hand.  Now a few months later, they’ve begun to think “hmmm, that was a lot of green!  Let’s do it!”  Of course now that they are the ones wanting to make the deal, not the buyers, they’ll be lucky to get 2/3 the original offer.   Which I should be happy with I guess.  It means the people buying the IDE products will have all the more money to invest in them… 

Oh and if you are a news group reader, David “I” has been out on the groups lately trying to restore confidence in the product.

I still can’t beleive they’ve done this after such a succesful production release. But I guess you always clean your car just before you sell it, too.