Sunday, August 15, 2010

Generic method to invoke a save dialog

There are many times when you need to invoke a Save dialog(TSaveDialog) and more likely you do NOT wish to add another component on the form... here's what I came up with:
(add "Dialogs" to uses clause)
function SaveFileExecute(const Filter: string;
  var FileName: string): Boolean;
  SaveDialog: TSaveDialog;
  // variable used to let us know that the user is intending to save
  // it will cover the "Overwrite file" prompt
  bExecuted: Boolean;
  // label used to retry the save process
// label!!
  // initialize variable and result
  bExecuted := False;
  Result := False;
  // create a TSaveDialog instance
  SaveDialog := TSaveDialog.Create(NIL);
    // set the filter
    SaveDialog.Filter := Filter;
    // execute the dialog
    Result := SaveDialog.Execute;
    // store the result
    bExecuted := Result;
    if Result then begin
      // set the file name WARNING it's a OUT VARIABLE
      FileName := SaveDialog.FileName;
      // check if the user tries to overwrite file
      if FileExists(FileName) then
        // user is attempting to overwrite a file, prompt with
        // Yes, No and Cancel, some users feel more comfortable to click Cancel
        Result := (MessageDlg(
          Format('File "%s" already exists, overwrite?', [FileName]),
          mtConfirmation, mbYesNoCancel, 0) = mrYes);
    end; // if Result then begin
    // free allocated memory
  end; // tryf
  if (NOT Result) and bExecuted then
    // user selected No or Cancel in file overwrite, restart the process
    goto lRetry;

Thursday, August 5, 2010

Create ambient color

There are times when you have to display charts with statistical data such as year to date sales, quarter sales, etc.
That's fine until your chart data changes every X period of time, let's say each 5 minutes, in this case the customer needs to somehow know that from last time he saw the statistical information has changed(or refreshed), you can do this by changing the background color of the chart, does not really matter if you choose to make the background gradient(it will look better tho) or not.
Changing the background color will make the user know the data has been changed(refreshed) without him having to think about it(the power of mind...).
We create a array of web colors because most users surf the web daily and they are very familiar with this colors...

Add Graphics and Math to uses clause, add Randomize to initialization section, copy-paste the following code:
  CAMBIENT_COLORS: array[0..WebColorsCount -1] of TColor = (
    clWebSnow, clWebFloralWhite, clWebLavenderBlush, clWebOldLace,
    clWebIvory, clWebCornSilk, clWebBeige, clWebAntiqueWhite,
    clWebWheat, clWebAliceBlue, clWebGhostWhite, clWebLavender,
    clWebSeashell, clWebLightYellow, clWebPapayaWhip, clWebNavajoWhite,
    clWebMoccasin, clWebBurlywood, clWebAzure, clWebMintcream,
    clWebHoneydew, clWebLinen, clWebLemonChiffon, clWebBlanchedAlmond,
    clWebBisque, clWebPeachPuff, clWebTan, clWebYellow,
    clWebDarkOrange, clWebRed, clWebDarkRed, clWebMaroon,
    clWebIndianRed, clWebSalmon, clWebCoral, clWebGold,
    clWebTomato, clWebCrimson, clWebBrown, clWebChocolate,
    clWebSandyBrown, clWebLightSalmon, clWebLightCoral, clWebOrange,
    clWebOrangeRed, clWebFirebrick, clWebSaddleBrown, clWebSienna,
    clWebPeru, clWebDarkSalmon, clWebRosyBrown, clWebPaleGoldenrod,
    clWebLightGoldenrodYellow, clWebOlive, clWebForestGreen, clWebGreenYellow,
    clWebChartreuse, clWebLightGreen, clWebAquamarine, clWebSeaGreen,
    clWebGoldenRod, clWebKhaki, clWebOliveDrab, clWebGreen,
    clWebYellowGreen, clWebLawnGreen, clWebPaleGreen, clWebMediumAquamarine,
    clWebMediumSeaGreen, clWebDarkGoldenRod, clWebDarkKhaki, clWebDarkOliveGreen,
    clWebDarkgreen, clWebLimeGreen, clWebLime, clWebSpringGreen,
    clWebMediumSpringGreen, clWebDarkSeaGreen, clWebLightSeaGreen, clWebPaleTurquoise,
    clWebLightCyan, clWebLightBlue, clWebLightSkyBlue, clWebCornFlowerBlue,
    clWebDarkBlue, clWebIndigo, clWebMediumTurquoise, clWebTurquoise,
    clWebCyan, clWebAqua, clWebPowderBlue, clWebSkyBlue,
    clWebRoyalBlue, clWebMediumBlue, clWebMidnightBlue, clWebDarkTurquoise,
    clWebCadetBlue, clWebDarkCyan, clWebTeal, clWebDeepskyBlue,
    clWebDodgerBlue, clWebBlue, clWebNavy, clWebDarkViolet,
    clWebDarkOrchid, clWebMagenta, clWebFuchsia, clWebDarkMagenta,
    clWebMediumVioletRed, clWebPaleVioletRed, clWebBlueViolet, clWebMediumOrchid,
    clWebMediumPurple, clWebPurple, clWebDeepPink, clWebLightPink,
    clWebViolet, clWebOrchid, clWebPlum, clWebThistle,
    clWebHotPink, clWebPink, clWebLightSteelBlue, clWebMediumSlateBlue,
    clWebLightSlateGray, clWebWhite, clWebLightgrey, clWebGray,
    clWebSteelBlue, clWebSlateBlue, clWebSlateGray, clWebWhiteSmoke,
    clWebSilver, clWebDimGray, clWebMistyRose, clWebDarkSlateBlue,
    clWebDarkSlategray, clWebGainsboro, clWebDarkGray, clWebBlack

function GetAmbientRandomColor: TColor;

    // makes the color lighter by Percent
   // the higher the value of Percent the closer to white
    function LighterColor(Color: TColor; Percent: Byte): TColor;
      vRed: Byte;
      vGreen: Byte;
      vBlue: Byte;
      Color := ColorToRGB(Color);
      vRed := GetRValue(Color);
      vGreen := GetGValue(Color);
      vBlue := GetBValue(Color);
      vRed := vRed + MulDiv(255 - vRed, Percent, 100);
      vGreen := vGreen + MulDiv(255 - vGreen, Percent, 100);
      vBlue := vBlue + MulDiv(255 - vBlue, Percent, 100);
      // generate the LighterColor color
      Result := RGB(vRed, vGreen, vBlue);
    end; // function LighterColor(Color: TColor; Percent: Byte): TColor;

  Index: Integer;
  // generate a random Index
  Index := RandomRange(Low(CAMBIENT_COLORS), High(CAMBIENT_COLORS));
  Result := LighterColor(CAMBIENT_COLORS[Index], 70);

Monday, August 2, 2010


I always knew there's something fishy related to C/C++, but this is hilarious!
Now here's a interesting article(stolen from:

Was it a parody? If so then maybe this one I've had a copy of for at least
15 years:


In an announcement that has stunned the computer industry, Ken Thompson,
Dennis Ritchie and Brian Kernighan admitted that the Unix operating system
and C programming language created by them is an elaborate prank kept alive
for over 20 years. Speaking at the recent UnixWorld Software Development
Forum, Thompson revealed the following:

"In 1969, AT&T had just terminated their work with the GE/Honeywell/AT&T
Multics project. Brian and I had started work with an early release of
Pascal from Professor Nichlaus Wirth's ETH labs in Switzerland and we were
impressed with its elegant simplicity and power. Dennis had just finished
reading 'Bored of the Rings', a National Lampoon parody of the Tolkien's
'Lord of the Rings' trilogy. As a lark, we decided to do parodies of the
Multics environment and Pascal. Dennis and I were responsible for the
operating environment. We looked at Multics and designed the new OS to be as
complex and cryptic as possible to maximize casual users' frustration
levels, calling it Unix as a parody of Multics, as well as other more risque
allusions. We sold the terse command language to novitiates by telling them
that it saved them typing.

Then Dennis and Brian worked on a warped version of Pascal, called 'A'.

'A' looked a lot like Pascal, but elevated the notion of the direct memory
address (which Wirth had banished) to the central concept of the language.
This was Dennis's contribution, and he in fact coined the term "pointer" as
an innocuous sounding name for a truly malevolent construct. Brian must be
credited with the idea of having absolutely no standard I/O specification:
this ensured that at least 50% of the typical commercial program would have
to be re-coded when changing hardware platforms. Brian was also responsible
for pitching this lack of I/O as a feature: it allowed us to describe the
language as "truly portable".

When we found others were actually creating real programs with A, we removed
compulsory type-checking on function arguments. Later, we added a notion we
called "casting": this allowed the programmer to treat an integer as though
it were a 50kb user-defined structure. When we found that some programmers
were simply not using pointers, we eliminated the ability to pass structures
to functions, enforcing their use in even the simplest applications. We
sold this, and many other features, as enhancements to the efficiency of the
language. In this way, our prank evolved into B, BCPL, and finally C.

We stopped when we got a clean compile on the following syntax:

for(;P("\n"),R-;P("|"))for(e=C;e-;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);

At one time, we joked about selling this to the Soviets to set their
computer science progress back 20 or more years.

Unfortunately, AT&T and other US corporations actually began using Unix and
C. We decided we'd better keep mum, assuming it was just a passing phase.

In fact, it's taken US companies over 20 years to develop enough expertise
to generate useful applications using this 1960's technological parody. We
are impressed with the tenacity of the general Unix and C programmer. In
fact, Brian, Dennis and I have never ourselves attempted to write a
commercial application in this environment.

We feel really guilty about the chaos, confusion and truly awesome
programming projects that have resulted from our silly prank so long ago."

Dennis Ritchie said: "What really tore it (just when AIDA was catching on),
was that Bjarne Stroustrup caught onto our joke. He extended it to further
parody Smalltalk. Like us, he was caught by surprise when nobody laughed.
So he added multiple inheritance, virtual base classes, and later ...
templates. All to no avail. So we now have compilers that can compile
100,000 lines per second, but need to process header files for 25 minutes
before they get to the meat of "Hello, World".

Major Unix and C vendors and customers, including AT&T, Microsoft,
Hewlett-Packard, GTE, NCR, and DEC have refused comment at this time.

Blogroll(General programming and Delphi feeds)