• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 944
  • Last Modified:

Write a value to Desktop screen

Hi.

Currently i have a label on a form that displays a value (that changes every second).

I'd like to write this values to the desktop screen above every open window...
Is that possible ?

Thanks in advance :)
0
CodedK
Asked:
CodedK
  • 4
  • 3
  • 3
  • +4
6 Solutions
 
CodedKAuthor Commented:
>>> to the desktop screen...

Not to the desktop ... but just to the screen ... above every application.
0
 
2266180Commented:
it's called OSD (On SCreen Display). here is an exmaple: http://solair.eunet.yu/~beginner/#osd
0
 
CodedKAuthor Commented:
Hi ciuly :)

Thanks for your super fast answer... but is there any free / open source for that ?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
2266180Commented:
I found this code: http://www.codeproject.com/w2k/forecast.asp
you could try and translate it to delphi (I haven't look at it). if you can't get it done and noone comes with anotehr solution, I'll look into it tomorrow.
0
 
2266180Commented:
I also found the following on EE (guess this should have been the first place to search :D)
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20463114.html?query=OSD+screen+display&topics=85
this is not an actual use of the OSD, but rather it is using a form to do the trick. I guess it worths checking it out
0
 
sun4sundayCommented:
Copying solution from my knowledge base

if (GetWindowLong(HANDLE,GWL_EXSTYLE) and WS_EX_TOPMOST)=WS_EX_TOPMOST then
  // topmost window
else
  //normal window


also check
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20640288.html

sun4sunday
0
 
atul_parmarCommented:
Hi,

First thing you will have to replace your TLabel with TStaticText because labels don't have window handle so we can set it to be the topmost window.

Then use the following lines to set it topmost (as long as your app runs).
  Windows.SetParent(StaticText1.Handle, 0);
  SetWindowPos(StaticText1.Handle, HWND_TOPMOST, 0, 0, StaticText1.Width, StaticText1.Height, 0);
0
 
ZhaawZSoftware DeveloperCommented:
I'm too lazy/tired to read all the answers, so I believe someone has already answered.. Anyway, here's what I would do:
1) create border-less window that's placed on top of all other windows
2) put a label on it (or draw text manually in form)
3) set window transparency so that only text is visible

Here's source with creating that stuff and changing text:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;
  transp : record
    wcl : WndClass;
    frm : cardinal;
    lbl : cardinal;
    fnt : TFont;
  end;

implementation

{$R *.dfm}

function TransparerntLabelWndProc (wnd, msg : cardinal; wParam, lParam : integer) : integer; stdcall;
begin
if msg = wm_close then result := 0 else result := DefWindowProc(wnd, msg, wParam, lParam);
end;

procedure CreateTransparerntLabel;
begin
with transp do begin
  ZeroMemory(@wcl, sizeof(wcl));
  with wcl do begin
    lpfnWndProc   := @TransparerntLabelWndProc;
    hInstance     := SysInit.hInstance;
    hCursor       := LoadCursor(0, idc_arrow);
    hbrBackground := color_btnface + 1;
    lpszClassName := 'TransparerntLabel';
  end;
  windows.RegisterClass(wcl);
  frm := CreateWindowEx(
    ws_ex_topmost or ws_ex_layered,
    wcl.lpszClassName, nil,
    ws_visible or ws_popup,
    screen.Width - 200, 50, 200, 50,
    0, 0, hInstance, nil
  );
  SetLayeredWindowAttributes(frm, GetSysColor(color_btnface), 0, lwa_colorkey);
  lbl := CreateWindowEx(
    0,
    'static', 'initial text',
    ws_visible or ws_child or ss_center or ss_centerimage,
    0, 0, 200, 50,
    frm, 0, hInstance, nil
  );
  fnt := TFont.Create;
  fnt.Name := 'Courier New';
  fnt.Style := [fsBold];
  fnt.Size := 16;
  SendMessage(lbl, wm_setfont, fnt.Handle, 0);
end;
end;

procedure DestroyTransparerntLabel;
begin
DestroyWindow(transp.lbl);
DestroyWindow(transp.frm);
windows.UnregisterClass(transp.wcl.lpszClassName, hInstance);
transp.fnt.Destroy;
end;

procedure SetTransparerntText(txt : string);
begin
SetWindowText(transp.lbl, pchar(txt));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
CreateTransparerntLabel;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DestroyTransparerntLabel;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
case random(3) of
  0 : SetTransparerntText('1st text');
  1 : SetTransparerntText('2nd text');
  2 : SetTransparerntText('3rd text');
end;
end;

end.
0
 
ZhaawZSoftware DeveloperCommented:
forgot one thing... 48th line of source ("ws_ex_topmost or ws_ex_layered") should be "ws_ex_topmost or ws_ex_layered or ws_ex_toolwindow" (ws_ex_toolwindow will hide it from toolbar)..

  windows.RegisterClass(wcl);
  frm := CreateWindowEx(
    ws_ex_topmost or ws_ex_layered or ws_ex_toolwindow, // here it is
    wcl.lpszClassName, nil,
    ws_visible or ws_popup,
    screen.Width - 200, 50, 200, 50,
    0, 0, hInstance, nil
  );
0
 
Russell LibbySoftware Engineer, Advisory Commented:

Here is code for an easy to use class that allows for an on screen display (top left/right, bottom left/right or center screen) You only need to create an instance, and set whatever text is to be displayed and set the visible property to true. You can also show some text with a timeout value so when the delay is reached the osd will autohide itself. It maintains a watchdog timer (fires every 1000ms) to ensure that the display is not obscured by TaskManager, or other window that has the top most flag set. The only note is that it works on Win2K and up.

Hope this helps,
Russell



Example project usage:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, OSD;

type
  TForm1         =  class(TForm)
     Timer1:     TTimer;
     procedure   FormCreate(Sender: TObject);
     procedure   FormDestroy(Sender: TObject);
     procedure   Timer1Timer(Sender: TObject);
  private
     // Private declarations
     FOSD:       TOSD;
  public
     // Public declarations
  end;

var
  Form1:         TForm1;

implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FOSD:=TOSD.Create;
  FOSD.Location:=olCenter;
  FOSD.Visible:=True;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FOSD.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  FOSD.Text:=Format('GetTickCount = %d', [GetTickCount]);
end;

end.

--- unit1 dfm ---

object Form1: TForm1
  Left = 307
  Top = 205
  Width = 412
  Height = 191
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object Timer1: TTimer
    OnTimer = Timer1Timer
    Left = 16
    Top = 12
  end
end

--- OSD.pas ---

unit OSD;
////////////////////////////////////////////////////////////////////////////////
//
//   Unit        :  OSD
//   Author      :  rllibby
//   Date        :  06.06.2006
//   Description :  Object wrapper for an OSD (on screen display) class. The code
//                  is an adaptation from source located on CodeProject at:
//
//                  http://www.codeproject.com/w2k/forecast.asp
//
////////////////////////////////////////////////////////////////////////////////
interface

////////////////////////////////////////////////////////////////////////////////
//   Include units
////////////////////////////////////////////////////////////////////////////////
uses
  Windows, SysUtils, Classes, Messages, Forms;

////////////////////////////////////////////////////////////////////////////////
//   Missing windows defines and functions
///////////////////////////////////////////////////////////////////////////////
const
  WS_EX_LAYERED     =  $00080000;

const
  LWA_COLORKEY      =  $00000001;
  LWA_ALPHA         =  $00000002;

function   SetLayeredWindowAttributes(hwnd: HWND; crKey: COLORREF; bAlpha: Byte; dwFlags: DWORD): BOOL; stdcall; external 'user32.dll';

////////////////////////////////////////////////////////////////////////////////
//   OSD constants
///////////////////////////////////////////////////////////////////////////////
const
  OSD_TIMERHIDE     =  1;
  OSD_WATCHDOG      =  2;
  OSD_HEIGHT        =  80;
  OSD_STYLE         =  WS_VISIBLE or WS_POPUP;
  OSD_STYLEEX       =  WS_EX_LAYERED or WS_EX_TOOLWINDOW or WS_EX_TOPMOST or WS_EX_TRANSPARENT;

////////////////////////////////////////////////////////////////////////////////
//   OSD type declaration
///////////////////////////////////////////////////////////////////////////////
type
  TOSDLocation      =  (olTopLeft, olTopRight, olBottomLeft, olBottomRight, olCenter);

////////////////////////////////////////////////////////////////////////////////
//   OSD class declaration
///////////////////////////////////////////////////////////////////////////////
type
  TOSD              =  class(TObject)
  private
     // Private declarations
     FFont:         HFONT;
     FTimeout:      UINT;
     FWatchDog:     UINT;
     FWindow:       HWND;
     FText:         String;
     FInstance:     Pointer;
     FLocation:     TOSDLocation;
     function       GetLocationRect: TRect;
     function       GetDesktopRect: TRect;
     function       AllocateFont: HFONT;
     procedure      ResetTimer;
  protected
     // Protected declarations
     function       GetVisible: Boolean;
     procedure      Paint;
     procedure      SetVisible(Value: Boolean);
     procedure      SetText(Value: String);
     procedure      SetLocation(Value: TOSDLocation);
     procedure      WndProc(var Message: TMessage);
  public
     // Public declarations
     constructor    Create;
     destructor     Destroy; override;
     procedure      Show(DisplayText: String; Timeout: LongWord);
     property       Location: TOSDLocation read FLocation write SetLocation;
     property       Text: String read FText write SetText;
     property       Visible: Boolean read GetVisible write SetVisible;
  end;

implementation

////////////////////////////////////////////////////////////////////////////////
//   Protected declarations
///////////////////////////////////////////////////////////////////////////////
var
  bIsRegistered:    Boolean;
  OSDTempClass:     TWndClassEx;
  OSDWindowClass:   TWndClassEx =  (
                                      style:         CS_HREDRAW or CS_VREDRAW;
                                      lpfnWndProc:   @DefWindowProc;
                                      cbClsExtra:    0;
                                      cbWndExtra:    0;
                                      hInstance:     0;
                                      hIcon:         0;
                                      hCursor:       0;
                                      hbrBackground: 0;
                                      lpszMenuName:  nil;
                                      lpszClassName: 'TOSDWindowClass'
                                   );

//// TOSD //////////////////////////////////////////////////////////////////////
procedure TOSD.WndProc(var Message: TMessage);
begin

  // Message handling
  case Message.Msg of
     WM_PAINT             :
     begin
        // Check the text length
        if (Length(FText) = 0) then
           // Call default window procedure
           Message.Result:=DefWindowProc(FWindow, Message.Msg, Message.wParam, Message.lParam)
        else
        begin
           // Custom paint handler
           Paint;
           // Return zero
           Message.Result:=0;
        end;
     end;
     WM_TIMER             :
     begin
        // Check timer id
        if (Message.wParam = OSD_TIMERHIDE) then
        begin
           // Reset the timer
           ResetTimer;
           // Hide the window
           SetVisible(False);
        end
        else if (Message.wParam = OSD_WATCHDOG) then
        begin
           // Check visibility
           if GetVisible then
           begin
              // Check topmost window
              if (GetTopWindow(0) <> FWindow) then
              begin
                 // Update window position
                 SetWindowPos(FWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
              end;
           end;
        end;
     end;
  else
     // Call default window procedure
     Message.Result:=DefWindowProc(FWindow, Message.Msg, Message.wParam, Message.lParam);
  end;

end;

procedure TOSD.Paint;
var  psSelf:        TPaintStruct;
     rcSelf:        TRect;
     dwFormat:      UINT;
     hdcPaint:      HDC;
begin

  // Begin paint
  hdcPaint:=BeginPaint(FWindow, psSelf);

  // Check handle
  if (hdcPaint <> 0) then
  begin
     // Resource protection
     try
        // Update canvas
        SetTextColor(hdcPaint, RGB(0, 255, 0));
               SetBkMode(hdcPaint, TRANSPARENT);
               SelectObject(hdcPaint, FFont);
        // Get window rect
               GetClientRect(FWindow, rcSelf);
        // Is there text to draw?
        if (Length(FText) > 0) then
        begin
           // Paint the text based on location
           case FLocation of
              // Top left
              olTopLeft      :
              begin
                 Inc(rcSelf.Left, 10);
                 Inc(rcSelf.Top, 10);
                 dwFormat:=DT_LEFT;
              end;
              // Top right
              olTopRight     :
              begin
                 Dec(rcSelf.Right);
                 Inc(rcSelf.Top, 10);
                 dwFormat:=DT_RIGHT;
              end;
              // Bottom left
              olBottomLeft   :
              begin
                 Inc(rcSelf.Left, 10);
                 Dec(rcSelf.Bottom, 10);
                 dwFormat:=DT_LEFT;
              end;
              // Bottom right
              olBottomRight  :
              begin
                 Dec(rcSelf.Right, 10);
                 Dec(rcSelf.Bottom, 10);
                 dwFormat:=DT_RIGHT;
              end;
              // Centered
              olCenter     :
              begin
                 dwFormat:=DT_CENTER or DT_VCENTER;
              end;
           else
              // Default to top left
              Inc(rcSelf.Left, 10);
              Inc(rcSelf.Top, 10);
              dwFormat:=DT_LEFT;
           end;
           // Draw the text
           DrawText(hdcPaint, Pointer(FText), Length(FText), rcSelf, dwFormat or DT_NOCLIP or DT_NOPREFIX or DT_SINGLELINE);
        end;
     finally
        // End the paint
               EndPaint(FWindow, psSelf);
     end;
  end;

end;

procedure TOSD.Show(DisplayText: String; Timeout: LongWord);
begin

  // Reset existing timer
  ResetTimer;

  // Create timer
  FTimeout:=SetTimer(FWindow, OSD_TIMERHIDE, Timeout, nil);

  // Check handle
  if (FTimeout <> 0) then
  begin
     // Update text
     FText:=DisplayText;
     // Show window
     SetVisible(True);
  end;

end;

procedure TOSD.SetText(Value: String);
begin

  // Check for changes
  if (CompareStr(Value, FText) <> 0) then
  begin
     // Update the text
     FText:=Value;
     // Invalidate if window is visible
     if GetVisible then InvalidateRect(FWindow, nil, True);
  end;

end;

function TOSD.GetLocationRect: TRect;
begin

  // Get desktop rect
  result:=GetDesktopRect;

  // Check location
  case FLocation of
     olTopLeft,
     olTopRight     :  result.Bottom:=result.Top+OSD_HEIGHT;
     olBottomLeft,
     olBottomRight  :  result.Top:=result.Bottom-OSD_HEIGHT;
     olCenter       :
     begin
        result.Top:=((result.Bottom-result.Top)-OSD_HEIGHT) div 2;
        result.Bottom:=result.Top+OSD_HEIGHT;
     end;
  else
     // Default to top left
     result.Bottom:=result.Top+OSD_HEIGHT;
  end;

end;

function TOSD.GetVisible: Boolean;
begin

  // Determine if window is visible
  result:=IsWindowVisible(FWindow);

end;

procedure TOSD.SetVisible(Value: Boolean);
begin

  // Set visibility
  if Value then
  begin
     // Show the window
     ShowWindow(FWindow, SW_SHOW);
     // Invalidate the rect so it repaints
     InvalidateRect(FWindow, nil, True);
  end
  else
     // Hide the window
     ShowWindow(FWindow, SW_HIDE);

end;

function TOSD.GetDesktopRect: TRect;
var  hwndDesk:      HWND;
begin

  // Get desktop hwnd
  hwndDesk:=GetDesktopWindow;

  // Get client rect for desktop
  GetClientRect(hwndDesk, result);

end;

function TOSD.AllocateFont: HFONT;
var  hdcDesk:       HDC;
     dwHeight:      Integer;
begin

  // Get desktop canvas
  hdcDesk:=GetDC(0);

  // Resource protection
  try
     // Get height for font
     dwHeight:=MulDiv(-18, GetDeviceCaps(hdcDesk, LOGPIXELSY), 72);
     // Create font
            result:=CreateFont(dwHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, DEFAULT_PITCH, 'Verdana');
  finally
     // Release the canvas handle
            ReleaseDC(0, hdcDesk);
  end;

end;

procedure TOSD.SetLocation(Value: TOSDLocation);
var  rcSelf:        TRect;
     bVisible:      Boolean;
begin

  // Determine if changes
  if (Value <> FLocation) then
  begin
     // Update location
     FLocation:=Value;
     // Get desired window location
     rcSelf:=GetLocationRect;
     // Get current state
     bVisible:=GetVisible;
     // Resource protection
     try
        // Hide if visible
        if bVisible then
        begin
           ShowWindow(FWindow, SW_HIDE);
           UpdateWindow(FWindow);
        end;
        // Move the window
        MoveWindow(FWindow, rcSelf.Left, rcSelf.Top, rcSelf.Right-rcSelf.Left, rcSelf.Bottom-rcSelf.Top, True);
     finally
        // Reshow if the window has previously showing
        if bVisible then ShowWindow(FWindow, SW_SHOW);
     end;
  end;

end;

procedure TOSD.ResetTimer;
begin

  // Check timer id and window handle
  if (FTimeout <> 0) then
  begin
     // Kill the timer
     KillTimer(FWindow, FTimeout);
     // Reset the timer identifier
     FTimeout:=0;
  end;

end;

constructor TOSD.Create;
var  rcSelf:        TRect;
begin

  // Perform inherited
  inherited Create;

  // Set defaults
  SetLength(FText, 0);
  FTimeout:=0;
  FFont:=AllocateFont;
  FLocation:=olTopLeft;
  FInstance:=MakeObjectInstance(WndProc);

  // Get window rect based on location
  rcSelf:=GetLocationRect;

  // Create window for the on screen display
  FWindow:=CreateWindowEx(OSD_STYLEEX, OSDWindowClass.lpszClassName, nil, OSD_STYLE, rcSelf.Left, rcSelf.Top, rcSelf.Right-rcSelf.Left, OSD_HEIGHT, GetDesktopWindow, 0, HInstance, nil);

  // Check window handle
  if IsWindow(FWindow) then
  begin
     // Set the window procedure
     SetWindowLong(FWindow, GWL_WNDPROC, Longint(FInstance));
     // Make sure the window is initially hidden
            ShowWindow(FWindow, SW_HIDE);
     // Update the window
            UpdateWindow(FWindow);
     // Set layered attributes for the window
            SetLayeredWindowAttributes(FWindow, 0, 0, LWA_COLORKEY);
     // Set watchdog timer for staying on top
     FWatchDog:=SetTimer(FWindow, OSD_WATCHDOG, 1000, nil);
  end;

end;

destructor TOSD.Destroy;
begin

  // Resource protection
  try
     // Destroy the timeout timer
     ResetTimer;
     // Kill the watchdog timer
     KillTimer(FWindow, FWatchDog);
     // Destroy the window
     if IsWindow(FWindow) then DestroyWindow(FWindow);
     // Free the method instance
     FreeObjectInstance(FInstance);
     // Destroy the font
     DeleteObject(FFont);
  finally
     // Perform inherited
     inherited Destroy;
  end;

end;

initialization

  // Set values for window class
  OSDWindowClass.cbSize:=SizeOf(TWndClassEx);
  OSDWindowClass.hInstance:=HInstance;
  OSDWindowClass.hbrBackground:=GetStockObject(BLACK_BRUSH);
  OSDWindowClass.hCursor:=LoadCursor(0, IDC_ARROW);

  // Determine if registered
  bIsRegistered:=GetClassInfoEx(HInstance, OSDWindowClass.lpszClassName, OSDTempClass);

  // Check to see if this class is already registered
  if not(bIsRegistered) or (OSDTempClass.lpfnWndProc <> @DefWindowProc) then
  begin
     // Check to see if we need to unregister the class
     if bIsRegistered then Windows.UnregisterClass(OSDWindowClass.lpszClassName, HInstance);
     // Re-register the window class
     Windows.RegisterClassEx(OSDWindowClass);
  end;

finalization

  // Unregister the window class
  Windows.UnregisterClass(OSDWindowClass.lpszClassName, HInstance);

end.
0
 
Russell LibbySoftware Engineer, Advisory Commented:

Full source with a few enhancements:

  http://users.adelphia.net/~rllibby/downloads/OSD.zip

Regards,
Russell
0
 
AmigoJackCommented:
you can view www.coolmon.org - its a tool to display system information on the desktop. the sourcecode (written in delphi) can be downloaded freely.

if you want to let your program run also under win9X and dont care to have a regular form around the label you want to display everywhere (like a rectangle with a nontransparent content) i could give you also an alternative solution
0
 
CodedKAuthor Commented:
Thank you all... very good answers :)
I'll probably use Russells code.

Russell is it possible to place the text at a certain (x , y) on screen ?
0
 
atul_parmarCommented:
Use SetWindowPos Win32API function. as I shown
SetWindowPos(StaticText1.Handle, HWND_TOPMOST, 0, 0, StaticText1.Width, StaticText1.Height, 0);
0
 
Russell LibbySoftware Engineer, Advisory Commented:

Yes, absolutely... the code just needed to be adjusted slightly. Be mindful though, that when using the olExact location, the output text rectangle will be calculated by subtracting the desktop's bottom/left pos by the specified x,y pos. So if you set the location to the right edge of desktop, then you most likely wont get anything to display. Anyways, I am posting the full source, as well as a little demo project that shows the features (and output results).

Regards,
Russell

--- OSD ---

unit OSD;
////////////////////////////////////////////////////////////////////////////////
//
//   Unit        :  OSD
//   Author      :  rllibby
//   Date        :  06.06.2006
//   Description :  Object wrapper for an OSD (on screen display) class. The code
//                  is an adaptation from source located on CodeProject at:
//
//                  http://www.codeproject.com/w2k/forecast.asp
//
//   Updates     :  - Object safely handles cases where the window is destroyed
//                  by external means. (eg, a WM_CLOSE or WM_DESTROY is sent to it)
//
//                  - Object responds to the WM_SETTEXT message and updates its text
//                  accordingly. Also responds to a WM_SETFONT message by creating
//                  a font indirectly based on the passed font handle.
//
//                  - TextColor can be changed at run time.
//
//                  - The window resizes itself to the size required to draw the
//                  text, while preserving the desired location on the screen.
//                  Multiline text is also handled.
//
//                  - Text alignment can be set (left, right, center) which
//                  controls how multiline text is drawn.
//
//                  - Object correctly handles a WM_DISPLAYCHANGE when the
//                  screen resolution changes.
//
//                  - Optimizations to window size and pos handling
//
//                  - Perform(...) procedure added to mimic TControl's handling
//                  of messages; really nothing more than a shortcut to SendMessage.
//
//                  - Allow for exact X, Y positioning on screen. The max text
//                  rectangle is calculated by using the bottom left bounds of
//                  the desktop.
//
//                  - Exposed the Font directly to the user as a Delphi TFont.
//                  The color for the text is still specified in TextColor, and
//                  allows changing text color without having to recalc window
//                  size and position (unlike changing the font face, size, style,
//                  etc)
//
////////////////////////////////////////////////////////////////////////////////
interface

////////////////////////////////////////////////////////////////////////////////
//   Include units
////////////////////////////////////////////////////////////////////////////////
uses
  Windows, SysUtils, Messages, Classes, Graphics, Forms;

////////////////////////////////////////////////////////////////////////////////
//   Missing windows defines and functions
///////////////////////////////////////////////////////////////////////////////
const
  WS_EX_LAYERED     =  $00080000;

const
  LWA_COLORKEY      =  $00000001;
  LWA_ALPHA         =  $00000002;

function   SetLayeredWindowAttributes(hwnd: HWND; crKey: COLORREF; bAlpha: Byte; dwFlags: DWORD): BOOL; stdcall; external 'user32.dll';

////////////////////////////////////////////////////////////////////////////////
//   OSD type declarations
///////////////////////////////////////////////////////////////////////////////
type
  TOSDLocation      =  (olTopLeft, olTopRight, olBottomLeft, olBottomRight, olCenter, olExact);
  TOSDTextAlign     =  (oaLeft, oaRight, oaCenter);

////////////////////////////////////////////////////////////////////////////////
//   OSD constants
///////////////////////////////////////////////////////////////////////////////
const
  OSD_TIMERHIDE     =  1;
  OSD_WATCHDOG      =  2;
  OSD_OFFSET        =  40;
  OSD_TIMERVALUE    =  1000;
  OSD_TEXTSIZE      =  18;
  OSD_TEXTFONT      =  'Verdana';
  OSD_STYLE         =  WS_VISIBLE or WS_POPUP;
  OSD_STYLEEX       =  WS_EX_LAYERED or WS_EX_TOOLWINDOW or WS_EX_TOPMOST or WS_EX_TRANSPARENT;
  OSD_TEXTALIGN:    Array [oaLeft..oaCenter] of Integer = (DT_LEFT, DT_RIGHT, DT_CENTER);

////////////////////////////////////////////////////////////////////////////////
//   OSD class declaration
///////////////////////////////////////////////////////////////////////////////
type
  TOSD              =  class(TObject)
  private
     // Private declarations
     FTimeout:      UINT;
     FWatchDog:     UINT;
     FWindow:       HWND;
     FXPos:         Integer;
     FYPos:         Integer;
     FText:         String;
     FFont:         TFont;
     FTextAlign:    TOSDTextAlign;
     FTextColor:    COLORREF;
     FInstance:     Pointer;
     FLocation:     TOSDLocation;
     procedure      DeallocWindow;
     function       GetDesktopRect: TRect;
     function       GetLocationPoint: TPoint;
     procedure      ResetTimer;
     procedure      UpdateWindowPosSize;
  protected
     // Protected declarations
     function       GetVisible: Boolean;
     procedure      OnFontChange(Sender: TObject);
     procedure      Paint;
     procedure      SetFont(Value: TFont);
     procedure      SetLocation(Value: TOSDLocation);
     procedure      SetText(Value: String);
     procedure      SetTextAlign(Value: TOSDTextAlign);
     procedure      SetTextColor(Value: COLORREF);
     procedure      SetVisible(Value: Boolean);
     procedure      SetXPos(Value: Integer);
     procedure      SetYPos(Value: Integer);
     procedure      WndProc(var Message: TMessage);
  public
     // Public declarations
     constructor    Create;
     destructor     Destroy; override;
     function       Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
     procedure      Show(DisplayText: String; Timeout: LongWord);
     procedure      SetExactLocation(X, Y: Integer);
     property       Font: TFont read FFont write SetFont;
     property       Handle: HWND read FWindow;
     property       Location: TOSDLocation read FLocation write SetLocation;
     property       Text: String read FText write SetText;
     property       TextAlign: TOSDTextAlign read FTextAlign write SetTextAlign;
     property       TextColor: COLORREF read FTextColor write SetTextColor;
     property       Visible: Boolean read GetVisible write SetVisible;
     property       XPos: Integer read FXPos write SetXPos;
     property       YPos: Integer read FYPos write SetYPos;
  end;

implementation

////////////////////////////////////////////////////////////////////////////////
//   Protected declarations
///////////////////////////////////////////////////////////////////////////////
var
  bIsRegistered:    Boolean;
  OSDTempClass:     TWndClassEx;
  OSDWindowClass:   TWndClassEx =  (
                                      style:         CS_HREDRAW or CS_VREDRAW;
                                      lpfnWndProc:   @DefWindowProc;
                                      cbClsExtra:    0;
                                      cbWndExtra:    0;
                                      hInstance:     0;
                                      hIcon:         0;
                                      hCursor:       0;
                                      hbrBackground: 0;
                                      lpszMenuName:  nil;
                                      lpszClassName: 'TOSDWindowClass'
                                   );

//// TOSD //////////////////////////////////////////////////////////////////////
procedure TOSD.WndProc(var Message: TMessage);
begin

  // Message handling
  case Message.Msg of
     WM_DESTROY           :
     begin
        // Kill timers and clear window handle
        DeallocWindow;
        // Pass to default window procedure
        Message.Result:=DefWindowProc(FWindow, Message.Msg, Message.wParam, Message.lParam);
     end;
     WM_PAINT             :
     begin
        // Check the text length
        if (Length(FText) = 0) then
           // Call default window procedure
           Message.Result:=DefWindowProc(FWindow, Message.Msg, Message.wParam, Message.lParam)
        else
        begin
           // Custom paint handler
           Paint;
           // Return zero
           Message.Result:=0;
        end;
     end;
     WM_SETTEXT           :
     begin
        // Update the text with the passed value
        if (Message.lParam = 0) then
           // Clear text
           SetText(EmptyStr)
        else
           // Set new text
           SetText(PChar(Message.lParam));
     end;
     WM_SETFONT           :
     begin
        // Update the font handle
        if (Message.wParam = 0) then
        begin
           // Reset to defaults
           FFont.Name:=OSD_TEXTFONT;
           FFont.Size:=OSD_TEXTSIZE;
           FFont.Style:=[fsBold];
        end
        else
           // Update the font based on the handle
           FFont.Handle:=Message.wParam;
        // Set message result
        Message.Result:=0;
     end;
     WM_TIMER             :
     begin
        // Check timer id
        if (Message.wParam = OSD_TIMERHIDE) then
        begin
           // Reset the timer
           ResetTimer;
           // Hide the window
           SetVisible(False);
        end
        else if (Message.wParam = OSD_WATCHDOG) then
        begin
           // Check visibility
           if GetVisible then
           begin
              // Check topmost window
              if (GetTopWindow(0) <> FWindow) then
              begin
                 // Update window position
                 SetWindowPos(FWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
              end;
           end;
        end;
        // Processed
        Message.Result:=0;
     end;
     WM_DISPLAYCHANGE     :
     begin
        // Screen resolution has changed, update the window
        UpdateWindowPosSize;
        // Set result
        Message.Result:=0;
     end;
  else
     // Call default window procedure
     Message.Result:=DefWindowProc(FWindow, Message.Msg, Message.wParam, Message.lParam);
  end;

end;

procedure TOSD.DeallocWindow;
begin

  // Resource protection
  ResetTimer;

  // Resource protection
  try
     // Check watchdog
     if (FWatchdog <> 0) and (FWindow <> 0) then
     begin
        // Kill watchdog timer
        KillTimer(FWindow, FWatchdog);
        // Reset watchdog identifier
        FWatchdog:=0;
     end;
  finally
     // Clear window handle
     FWindow:=0;
  end;

end;

procedure TOSD.Paint;
var  psSelf:        TPaintStruct;
     rcSelf:        TRect;
     hdcPaint:      HDC;
begin

  // Begin paint
  hdcPaint:=BeginPaint(FWindow, psSelf);

  // Check handle
  if (hdcPaint <> 0) then
  begin
     // Resource protection
     try
        // Get client rect
        GetClientRect(FWindow, rcSelf);
        // Update canvas
        Windows.SetTextColor(hdcPaint, FTextColor);
           SetBkMode(hdcPaint, TRANSPARENT);
               SelectObject(hdcPaint, FFont.Handle);
        // Draw the text
        DrawText(hdcPaint, Pointer(FText), Length(FText), rcSelf, OSD_TEXTALIGN[FTextAlign] or DT_NOCLIP or DT_NOPREFIX or DT_WORDBREAK);
     finally
        // End paint
               EndPaint(FWindow, psSelf);
     end;
  end;

end;

procedure TOSD.Show(DisplayText: String; Timeout: LongWord);
begin

  // Reset existing timer
  ResetTimer;

  // Check window
  if IsWindow(FWindow) then
  begin
     // Create timer
     FTimeout:=SetTimer(FWindow, OSD_TIMERHIDE, Timeout, nil);
     // Check handle
     if (FTimeout <> 0) then
     begin
        // Update text
        SetText(DisplayText);
        // Show window
        SetVisible(True);
     end;
  end;

end;

procedure TOSD.OnFontChange(Sender: TObject);
begin

  // Update the window pos size
  UpdateWindowPosSize;

end;

procedure TOSD.SetFont(Value: TFont);
begin

  // Check passed font value
  if Assigned(Value) then
     // Assign from font
     FFont.Assign(Value)
  else
  begin
     // Reset font to defaults
     FFont.Name:=OSD_TEXTFONT;
     FFont.Size:=OSD_TEXTSIZE;
     FFont.Style:=[fsBold];
  end;

end;

procedure TOSD.SetExactLocation(X, Y: Integer);
begin

  // Update location and X, Y values
  FLocation:=olExact;
  FXPos:=X;
  FYPos:=Y;

  // Update the window pos size
  UpdateWindowPosSize;

end;

procedure TOSD.SetXPos(Value: Integer);
begin

  // Check for changes
  if (FXPos <> Value) then
  begin
     // Update the XPos
     FXPos:=Value;
     // Is location type set to exact?
     if (FLocation = olExact) then UpdateWindowPosSize;
  end;

end;

procedure TOSD.SetYPos(Value: Integer);
begin

  // Check for changes
  if (FYPos <> Value) then
  begin
     // Update the YPos
     FYPos:=Value;
     // Is location type set to exact?
     if (FLocation = olExact) then UpdateWindowPosSize;
  end;

end;

procedure TOSD.SetTextColor(Value: COLORREF);
begin

  // Check for changes
  if (Value <> FTextColor) then
  begin
     // Update the text color
     FTextColor:=Value;
     // Invalidate if window is visible
     if IsWindow(FWindow) and GetVisible then InvalidateRect(FWindow, nil, True);
  end;

end;

procedure TOSD.SetLocation(Value: TOSDLocation);
var  rcSelf:        TRect;
     ptSelf:        TPoint;
     bRecalc:       Boolean;
begin

  // Determine if changed
  if (Value <> FLocation) then
  begin
     // Determine if a recalc is required. A recalc will be required if the
     // current value is olExact or is changing to olExact
     bRecalc:=(Value = olExact) or (FLocation = olExact);
     // Update location type
     FLocation:=Value;
     // Check window
     if IsWindow(FWindow) then
     begin
        // Recalc required?
        if bRecalc then
           // Update window pos size
           UpdateWindowPosSize
        else
        begin
           // Get desired window location
           ptSelf:=GetLocationPoint;
           // Get client rect
           GetClientRect(FWindow, rcSelf);
           // Move the window
           MoveWindow(FWindow, ptSelf.x, ptSelf.y, rcSelf.Right - rcSelf.Left, rcSelf.Bottom - rcSelf.Top, True);
        end;
     end;
  end;

end;

procedure TOSD.UpdateWindowPosSize;
var  rcText:        TRect;
     rcSelf:        TRect;
     ptSelf:        TPoint;
     hdcSelf:       HDC;
begin

  // Check window
  if IsWindow(FWindow) then
  begin
     // Get maximum rect that we can draw in
     rcText:=GetDesktopRect;
     // Get current window rect
     GetWindowRect(FWindow, rcSelf);
     // Check for empty string
     if (Length(FText) = 0) then
     begin
        // Zero width and height
        rcText.Right:=0;
        rcText.Bottom:=0;
     end
     else
     begin
        // Check location setting
        if (FLocation = olExact) then
        begin
           // Update the width and height
           Dec(rcText.Right, FXPos);
           Dec(rcText.Bottom, FYPos);
        end
        else
        begin
           // Account for the text offsets
           Dec(rcText.Right, OSD_OFFSET * 2);
           Dec(rcText.Bottom, OSD_OFFSET * 2);
        end;
        // Get our window dc
        hdcSelf:=GetDC(FWindow);
        // Resource protection
        try
           // Set the font that we use for drawing
           SelectObject(hdcSelf, FFont.Handle);
           // Calculate the rect that is required for drawing
           DrawText(hdcSelf, Pointer(FText), Length(FText), rcText, OSD_TEXTALIGN[FTextAlign] or DT_CALCRECT or DT_NOCLIP or DT_NOPREFIX or DT_WORDBREAK);
           // Determine if width / height changed
           if ((rcSelf.Right - rcSelf.Left) <> (rcText.Right - rcText.Left)) or ((rcSelf.Bottom - rcSelf.Top) <> (rcText.Bottom - rcText.Top)) then
           begin
              // Set the window's new width and height
              SetWindowPos(FWindow, 0, 0, 0, rcText.Right - rcText.Left, rcText.Bottom - rcText.Top, SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOMOVE);
              // Get desired window location
              ptSelf:=GetLocationPoint;
              // Move the window
              MoveWindow(FWindow, ptSelf.x, ptSelf.y, rcText.Right - rcText.Left, rcText.Bottom - rcText.Top, True);
           end
           else
           begin
              // Get desired window location
              ptSelf:=GetLocationPoint;
              // Check to see if location changed
              if (ptSelf.x <> rcSelf.Left) or (ptSelf.y <> rcSelf.Top) then
              begin
                 // Move the window to the new location
                 MoveWindow(FWindow, ptSelf.x, ptSelf.y, rcText.Right - rcText.Left, rcText.Bottom - rcText.Top, True);
              end;
           end;
        finally
           // Release the canvas handle
           ReleaseDC(FWindow, hdcSelf);
        end;
     end;
     // Force a repaint
     InvalidateRect(FWindow, nil, True);
  end;

end;

procedure TOSD.SetTextAlign(Value: TOSDTextAlign);
begin

  // Check for changes
  if (Value <> FTextAlign) then
  begin
     // Update the text
     FTextAlign:=Value;
     // Update the window position and size
     UpdateWindowPosSize;
  end;

end;

procedure TOSD.SetText(Value: String);
begin

  // Check for changes
  if (CompareStr(Value, FText) <> 0) then
  begin
     // Update the text
     FText:=Value;
     // Update the window position and size
     UpdateWindowPosSize;
  end;

end;

function TOSD.GetLocationPoint: TPoint;
var  rcDesk:        TRect;
     rcSelf:        TRect;
begin

  // Get desktop rect
  rcDesk:=GetDesktopRect;

  // Check window
  if IsWindow(FWindow) then
  begin
     // Get client rect
     GetClientRect(FWindow, rcSelf);
     // Check location
     case FLocation of
        // Top left of screen
        olTopLeft      :
        begin
           result.x:=OSD_OFFSET;
           result.y:=OSD_OFFSET;
        end;
        // Top right of screen
        olTopRight     :
        begin
           result.x:=(rcDesk.Right - (rcSelf.Right - rcSelf.Left)) - OSD_OFFSET;
           result.y:=OSD_OFFSET;
        end;
        // Bottom left of screen
        olBottomLeft   :
        begin
           result.x:=OSD_OFFSET;
           result.y:=(rcDesk.Bottom - (rcSelf.Bottom - rcSelf.Top)) - OSD_OFFSET;
        end;
        // Bottom right of screen
        olBottomRight  :
        begin
           result.x:=(rcDesk.Right - (rcSelf.Right - rcSelf.Left)) - OSD_OFFSET;
           result.y:=(rcDesk.Bottom - (rcSelf.Bottom - rcSelf.Top)) - OSD_OFFSET;
        end;
        // Center of screen
        olCenter       :
        begin
           result.x:=((rcDesk.Right - rcDesk.Left) - (rcSelf.Right - rcSelf.Left)) div 2;
           result.y:=((rcDesk.Bottom - rcDesk.Top) - (rcSelf.Bottom - rcSelf.Top)) div 2;
        end;
        // Exact X, Y position
        olExact        :
        begin
           result.x:=FXPos;
           result.y:=FYPos;
        end;
     else
        // Default to top left
        result.x:=OSD_OFFSET;
        result.y:=OSD_OFFSET;
     end;
  end
  else
     // Return null point
     FillChar(result, SizeOf(result), 0);

end;

function TOSD.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
begin

  // Check window
  if IsWindow(FWindow) then
     // Send message to our window
     result:=SendMessage(FWindow, Msg, WParam, LParam)
  else
     // Return zero
     result:=0;

end;

function TOSD.GetVisible: Boolean;
begin

  // Determine if window is visible
  result:=IsWindowVisible(FWindow);

end;

procedure TOSD.SetVisible(Value: Boolean);
begin

  // Check window
  if IsWindow(FWindow) then
  begin
     // Set visibility
     if Value then
     begin
        // Show the window
        ShowWindow(FWindow, SW_SHOWNOACTIVATE);
        // Invalidate the rect so it repaints
        InvalidateRect(FWindow, nil, True);
     end
     else
        // Hide the window
        ShowWindow(FWindow, SW_HIDE);
  end;

end;

function TOSD.GetDesktopRect: TRect;
var  hwndDesk:      HWND;
begin

  // Get desktop hwnd
  hwndDesk:=GetDesktopWindow;

  // Get client rect for desktop
  GetClientRect(hwndDesk, result);

end;

procedure TOSD.ResetTimer;
begin

  // Check timer id and window handle
  if (FTimeout <> 0) then
  begin
     // Kill the timer
     KillTimer(FWindow, FTimeout);
     // Reset the timer identifier
     FTimeout:=0;
  end;

end;

constructor TOSD.Create;
begin

  // Perform inherited
  inherited Create;

  // Set defaults
  SetLength(FText, 0);
  FTimeout:=0;
  FXPos:=0;
  FYPos:=0;
  FLocation:=olTopLeft;
  FTextAlign:=oaLeft;
  FTextColor:=RGB(0, 255, 0);
  FInstance:=MakeObjectInstance(WndProc);
  FFont:=TFont.Create;
  FFont.Name:=OSD_TEXTFONT;
  FFont.Size:=OSD_TEXTSIZE;
  FFont.Style:=[fsBold];
  FFont.OnChange:=OnFontChange;

  // Create window for the on screen display
  FWindow:=CreateWindowEx(OSD_STYLEEX, OSDWindowClass.lpszClassName, nil, OSD_STYLE, OSD_OFFSET, OSD_OFFSET, 0, 0, GetDesktopWindow, 0, HInstance, nil);

  // Check window handle
  if IsWindow(FWindow) then
  begin
     // Set the window procedure
     SetWindowLong(FWindow, GWL_WNDPROC, Longint(FInstance));
     // Make sure the window is initially hidden
            ShowWindow(FWindow, SW_HIDE);
     // Update the window
            UpdateWindow(FWindow);
     // Set layered attributes for the window
         SetLayeredWindowAttributes(FWindow, 0, 0, LWA_COLORKEY);
     // Set watchdog timer for staying on top
     FWatchDog:=SetTimer(FWindow, OSD_WATCHDOG, OSD_TIMERVALUE, nil);
  end;

end;

destructor TOSD.Destroy;
begin

  // Resource protection
  try
     // Destroy the window
     if IsWindow(FWindow) then DestroyWindow(FWindow);
     // Free the method instance
     FreeObjectInstance(FInstance);
     // Free the font
     FFont.Free;
  finally
     // Perform inherited
     inherited Destroy;
  end;

end;

initialization

  // Set values for window class
  OSDWindowClass.cbSize:=SizeOf(TWndClassEx);
  OSDWindowClass.hInstance:=HInstance;
  OSDWindowClass.hbrBackground:=GetStockObject(BLACK_BRUSH);
  OSDWindowClass.hCursor:=LoadCursor(0, IDC_ARROW);

  // Determine if registered
  bIsRegistered:=GetClassInfoEx(HInstance, OSDWindowClass.lpszClassName, OSDTempClass);

  // Check to see if this class is already registered
  if not(bIsRegistered) or (OSDTempClass.lpfnWndProc <> @DefWindowProc) then
  begin
     // Check to see if we need to unregister the class
     if bIsRegistered then Windows.UnregisterClass(OSDWindowClass.lpszClassName, HInstance);
     // Re-register the window class
     Windows.RegisterClassEx(OSDWindowClass);
  end;

finalization

  // Unregister the window class
  Windows.UnregisterClass(OSDWindowClass.lpszClassName, HInstance);

end.


-- demo unit source --

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, OSD, StdCtrls;

type
  TForm1            =  class(TForm)
     btnText:       TButton;
     btnFont:       TButton;
     btnTextColor:  TButton;
     btnLocation:   TButton;
     dlgColor:      TColorDialog;
     dlgFont:       TFontDialog;
     ComboBox1:     TComboBox;
     txtText:       TMemo;
     Edit1:         TEdit;
     Edit2:         TEdit;
     Label1:        TLabel;
     Label2:        TLabel;
     btnAlignment:  TButton;
     ComboBox2:     TComboBox;
     procedure      FormCreate(Sender: TObject);
     procedure      FormDestroy(Sender: TObject);
     procedure      btnTextClick(Sender: TObject);
     procedure      btnFontClick(Sender: TObject);
     procedure      btnTextColorClick(Sender: TObject);
     procedure      Edit1KeyPress(Sender: TObject; var Key: Char);
     procedure      btnLocationClick(Sender: TObject);
     procedure      btnAlignmentClick(Sender: TObject);
  private
     // Private declarations
     FOSD:       TOSD;
  protected
     // Protected declarations
  public
     // Public declarations
  end;

var
  Form1:         TForm1;

implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin

  // Create on screen display
  FOSD:=TOSD.Create;
  FOSD.Text:=FOSD.ClassName;
  FOSD.Visible:=True;

  // Update the user interface
  txtText.Text:=FOSD.Text;
  ComboBox1.ItemIndex:=0;
  ComboBox2.ItemIndex:=0;

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin

  // Free on screen display
  FOSD.Free;

end;

procedure TForm1.btnTextClick(Sender: TObject);
begin

  // Update the text
  FOSD.Text:=txtText.Text;

end;

procedure TForm1.btnFontClick(Sender: TObject);
begin

  // Update the dialog font
  dlgFont.Font.Assign(FOSD.Font);

  // Get new font and assign to on screen display
  if dlgFont.Execute then FOSD.Font.Assign(dlgFont.Font);

end;

procedure TForm1.btnTextColorClick(Sender: TObject);
begin

  // Update the dialog color
  dlgColor.Color:=FOSD.TextColor;

  // Get new font and assign to on screen display
  if dlgColor.Execute then FOSD.TextColor:=ColorToRGB(dlgColor.Color);

end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin

  if not(Key in [#8, '0'..'9']) then Key:=#0;
 
end;

procedure TForm1.btnLocationClick(Sender: TObject);
begin

  if (TOSDLocation(ComboBox1.ItemIndex) = olExact) then
     // Can also use XPos, YPos and set Location = olExact, but this will
     // cause 3 recalcs, vs the 1 for using SetExactLocation
     FOSD.SetExactLocation(StrToIntDef(Edit1.Text, 0), StrToIntDef(Edit2.Text, 0))
  else
     // Set location
     FOSD.Location:=TOSDLocation(ComboBox1.ItemIndex);

end;

procedure TForm1.btnAlignmentClick(Sender: TObject);
begin

  FOSD.TextAlign:=TOSDTextAlign(ComboBox2.ItemIndex);
 
end;

end.

-- demo dfm --

object Form1: TForm1
  Left = 376
  Top = 270
  BorderIcons = [biSystemMenu]
  BorderStyle = bsDialog
  Caption = 'OSD Demo'
  ClientHeight = 260
  ClientWidth = 319
  Color = clBtnFace
  Font.Charset = ANSI_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  Scaled = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 80
    Top = 184
    Width = 26
    Height = 13
    Caption = 'X Pos'
  end
  object Label2: TLabel
    Left = 188
    Top = 184
    Width = 26
    Height = 13
    Caption = 'Y Pos'
  end
  object btnText: TButton
    Left = 12
    Top = 12
    Width = 93
    Height = 21
    Caption = 'Text Property'
    TabOrder = 0
    OnClick = btnTextClick
  end
  object btnFont: TButton
    Left = 112
    Top = 108
    Width = 93
    Height = 21
    Caption = 'Font'
    TabOrder = 1
    OnClick = btnFontClick
  end
  object txtText: TMemo
    Left = 112
    Top = 12
    Width = 193
    Height = 89
    TabOrder = 2
  end
  object btnTextColor: TButton
    Left = 216
    Top = 108
    Width = 93
    Height = 21
    Caption = 'Text Color'
    TabOrder = 3
    OnClick = btnTextColorClick
  end
  object btnLocation: TButton
    Left = 12
    Top = 152
    Width = 93
    Height = 21
    Caption = 'Location'
    TabOrder = 4
    OnClick = btnLocationClick
  end
  object ComboBox1: TComboBox
    Left = 112
    Top = 152
    Width = 197
    Height = 22
    Style = csOwnerDrawFixed
    ItemHeight = 16
    TabOrder = 5
    Items.Strings = (
      'Top Left'
      'Top Right'
      'Bottom Left'
      'Bottom Right'
      'Center Screen'
      'Exact Position')
  end
  object Edit1: TEdit
    Left = 112
    Top = 180
    Width = 57
    Height = 21
    MaxLength = 4
    TabOrder = 6
    Text = '0'
    OnKeyPress = Edit1KeyPress
  end
  object Edit2: TEdit
    Left = 220
    Top = 180
    Width = 57
    Height = 21
    MaxLength = 4
    TabOrder = 7
    Text = '0'
    OnKeyPress = Edit1KeyPress
  end
  object btnAlignment: TButton
    Left = 12
    Top = 224
    Width = 93
    Height = 21
    Caption = 'Text Alignment'
    TabOrder = 8
    OnClick = btnAlignmentClick
  end
  object ComboBox2: TComboBox
    Left = 112
    Top = 224
    Width = 193
    Height = 22
    Style = csOwnerDrawFixed
    ItemHeight = 16
    TabOrder = 9
    Items.Strings = (
      'Left'
      'Right'
      'Center')
  end
  object dlgColor: TColorDialog
    Ctl3D = True
    Left = 20
    Top = 88
  end
  object dlgFont: TFontDialog
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    MinFontSize = 0
    MaxFontSize = 0
    Left = 48
    Top = 88
  end
end

0
 
Russell LibbySoftware Engineer, Advisory Commented:
The short answer to the positioning question, using the above code:

  // Create on screen display
  with TOSD.Create do
  begin
     // Set text, exact location, then display
     Text:='Some text to display';
     SetExactLocation(100, 100);
     Visible:=True;
  end;


Russell
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 4
  • 3
  • 3
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now