A FOX
Consulting & Design
Free Code Tidbits



Hey, does anyone else remember the old Unofficial Delphi Developers FAQ? No? Well, it was a while ago, but this is sorta our version of that site, with random snippits of code we've written or used throughout our development projects.

Communicating Directly With A Printer In Windows
Sending A Text File To The Printer
geditstr() Highlighted String Editor For DOS
Turning NUMLOCK Key ON In Windows
Simple, Fast Sort Routine
Displaying a TIFF Image in a SRS Report




Code TidbitLanguage
Communicating Directly With A Printer In WindowsDelphi

Have you ever wanted to directly access a printer in Windows NT, or any Windows environment for that matter? Well, here's a way to do it using Delphi:

type
  TPassThroughData = record
    nLen: Word;
    Data: array[0..255] of Byte;
  end;

procedure DirectPrint(s: string);
var
  PTBlock: TPassThroughData;
begin
  PTBlock.nLen := Length(s);
  StrPCopy(@PTBlock.Data, s);
  Escape(Printer.Handle, PASSTHROUGH, 0, @PTBlock, nil);
end;

Then, from your main code, use something like this (the example here deomonstrates how to send some PJL printer formatting commands to an HP LaserJet 4 printer):

Printer.BeginDoc;
DirectPrint(#27+'%-12345X@PJL'+#13+#10);
DirectPrint('@PJL DEFAULT POWERSAVE = OFF'+#13+#10);
DirectPrint('@PJL DEFAULT COPIES = 1'+#13+#10);
DirectPrint('@PJL DEFAULT RESOLUTION = 600'+#13+#10);
DirectPrint('@PJL RESET'+#13+#10);
DirectPrint(#27+'%-12345X'+#13+#10);
DirectPrint(#27+'&l1x1h2a0O');
DirectPrint(#13+#10+'Test of direct print. Hello, World!'+#13+#10);
Printer.EndDoc;

Back To Top


Code TidbitLanguage
Sending A Text File To The PrinterDelphi

Here's a nice little function to quickly dump a text file directly to the default printer:

uses Printers;

Procedure PrintFile(fname : String);
var
  txtfile   : System.TextFile;
  prnfile   : System.TextFile;
  s         : String;
  i         : Byte;
begin
  AssignFile(txtfile,fname);
  reset(txtfile);
  AssignPrn(prnfile);
  rewrite(prnfile);
  Printer.Canvas.Font.Name:='Courier New';
  Printer.Canvas.Font.Size:=10;
  while not EOF(txtfile) do
  begin
    ReadLn(txtfile,s);
    WriteLn(prnfile,s);
  end;
  CloseFile(txtfile);
  CloseFile(prnfile);
end;

Back To Top


Code TidbitLanguage
Geditstr() - Highlighted String Field Editor for DOSTurbo C++

This is a function we made many many years ago to highlight a string input field and allow a user to edit it. The code originally came from a book on Turbo C++ but we added some enhancements to it.

View Code. . .

Here is an example of how to use the function.

char things[20]="abcdefg";
int x;
printf("Example of geditstr() function.\n");
printf("Enter things: ");
x=geditstr(15,wherey(),things, sizeof(things));
printf("\nString 'things' now contains '%s'.\n",things);

Back To Top


Code TidbitLanguage
Turning NUMLOCK Key ON Under WindowsDelphi

Ever want to keep users from turning OFF the NUMLOCK Key? Sometimes in accounting environments users depend on the 10-key part of the keyboard for doing their input, and if someone accidentally turn NUMLOCK off it can throw the users for a loop. Here's the solution:

Windows 95/98:

var
  buff     : TKeyboardState;
  scancode : byte;
begin
  GetKeyboardState(buff);           // Grab status of keyboard
  if (buff[VK_NUMLOCK] = 0) then    // if NUMLOCK is not on...
  begin
    buff[VK_NUMLOCK]:= 1;
    SetKeyboardState(buff);
  end;
end;

Windows NT/2000/XP:

var
  buff     : TKeyboardState;
  scancode : byte;
begin
  GetKeyboardState(buff);           // Grab status of keyboard
  if (buff[VK_NUMLOCK] = 0) then    // if NUMLOCK is not on...
  begin
    scancode := MapVirtualKey(VK_NUMLOCK, 0);
    keybd_event(VK_NUMLOCK, scancode, KEYEVENTF_EXTENDEDKEY, 0);
    keybd_event(VK_NUMLOCK, scancode, KEYEVENTF_EXTENDEDKEY + KEYEVENTF_KEYUP, 0);
  end;
end;

Back To Top


Code TidbitLanguage
Simple, Fast Sort RoutineC

This is a simple yet fast sort routine we've used for various things. It sorts an array of type "long".

void SortBuffer(long *InputBuffer, long *OutputBuffer)
{
  static short offset, limit, swaprow, row;
  static long swapvar;

  /* Copy the contents of the InputBuffer to the OutputBuffer */
  memcpy(OutputBuffer, InputBuffer, sizeof(long)*BUFFER_SIZE);

  offset = BUFFER_SIZE>>1;
  while(offset>0)
  {
    limit = BUFFER_SIZE-offset;
    do
    {
      swaprow=0;
      for(row=1;row<=limit;row++)
      {
        if(OutputBuffer[row-1]>OutputBuffer[row-1+offset])
        {
          /* Swap the two buffer elements */
          swapvar=OutputBuffer[row-1];
          OutputBuffer[row-1]=OutputBuffer[row-1+offset];
          OutputBuffer[row-1+offset]=swapvar;
          swaprow=row;
        }
      }
      limit=swaprow-offset;
    } while(swaprow>0);
    offset = offset>>1;
  }
}

Back To Top


Code TidbitLanguage
Displaying a TIFF image in an SRS Report.NET

It continues to be a challenge to figure out why Microsoft does anything. Example: the TIFF Image format is THE banking industry standard image exchange format, yet Microsoft fails to build in support for it in its SQL Server Reporting Services software. After a little googling I was surprised to find out quite a few other people are also wondering how to display a TIFF image in their Report Server reports.

No published answer existed and everyone's forum posts were left unanswered and abandoned, and now I think I know why since I solved it--it is a serious PAIN IN THE PATOOKIE and no one wants to give up the secret after going through all the work for it. As for myself, while I cannot divulge my source code, I can at least outline the technique I used.

The meat of the matter: To be able to display the TIFF image, convert it to a JPEG, and you need to write a custom assembly with a function to do the conversion:

1. Pass the image data to your conversion function in a Byte() array.
2. Put the image data into a System.Drawing.Bitmap object.
3. Use the image's .save method and an image format of ImageFormat.Jpeg.
4. Return the name of that file as the function's return value.

In your report (under Properties), add a reference to your assembly's class and make an instance of the function call. Then, reference the picture as source = external and value = filename returned by the conversion code. Simple as pie, huh?

Now, here's the hitch: because this technique requires the SRS assembly to access a physical disk, you need to grant permission rights to the class in the SRS configuration files, and also assert those rights inside the class using the System.Security.Permissions.FileIOPermission class and .Assert method. Now, THIS IS A MESS! Thankfully microsoft has published a quite useful article that gives step-by-step instructions on how to grant permissions to custom assemblies called by reports.

For more information on building custom assemblies and using them in reports I suggest the book "Miscorosft SQL Server 2005: Reporting Services" by Michael Lisin and Jom Joseph.

Back To Top


back to main page.