Link to home
Start Free TrialLog in
Avatar of igor84
igor84

asked on

Showing graphics on the desktop in Realtime (best answer 1000 points)

hi,

i want to show on the desktop transparent 3D wave (that is similar to the screen saver in Win 95 the ball that looks like it getting out of the screen) i wont to show it on real time and without holding the system that means that the transparent wave will be showen in the background and the user could continue working on the computer without the interruption of the wave.

p.s if you have question about this send a comment.

Need your help
     Igor.
Avatar of Epsylon
Epsylon

I don't think you will find a good solution for this. The transparency will make it to slow.
Avatar of igor84

ASKER


for epsylon

so what do you offer what a solution do you have ?
I don't have one and I think noone else will. You need some kind of layer to make it fast enough. The desktop doesn't have this, so you have to draw-clear-draw-clear and so on. This results in flickering and an annoying desktop window.
Try this and you will see what I mean:


procedure TForm1.Button1Click(Sender: TObject);
var C: TCanvas;
    W: integer;
    i: Integer;
begin
  C:=TCanvas.Create;
  C.Brush.Style := bsClear;
  C.Handle:=GetDC(0);
  for i := 0 to 50 do
  begin
    C.Ellipse(100 + i * 10, 100, 300 + i * 10, 300);
    Sleep(100);
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, 0, SPIF_SENDCHANGE);
  end;
  ReleaseDC(0,C.Handle);
  C.Free;

end;
Avatar of igor84

ASKER

ok i saw it there werer some blinking i agree with you it was also my problem but a few years ago i saw something close to what i want to do and there were no blinking so it is possible to do but how ? it is the question !
I think you must have seen something that resided in a (borderless) window.
Avatar of igor84

ASKER

what is the difference ?
Why not just use an animated gif on the desktop, outside of your code.  You will have to set the desktop as a webpage and drop the gif into an html.
listening
Avatar of igor84

ASKER

to d32coder :

can you make me an example and send to my mail.

p.s i still not thinking that this is the right way but i want to see how your idea works.

Igor
ASKER CERTIFIED SOLUTION
Avatar of Baksa
Baksa

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Can I suggest a nasty solution? Why not screen grab the desktop and use that as the backdrop for your form (or constructed output image). That way you wouldn't need to worry about the transparency at all

The Neil =:)
Avatar of igor84

ASKER

for all : i want the wave be shown not only on the desktop but on all the screen.



to baksa it looks very good but there are still small blinking .
but how i make the wave ?
I dont really know what you mean by "making the wave", but I have made freeware component that will scroll any given text like wave (in fact like sine graph), you can download source for this component from http://www.torry.net/scrollingtext.htm, component name is TWaveScroll. There you can see how sine scroll is done, source is fairly commented.

About flicking, IMHO flicking will be there if you use GDI, only way is to use DirectX, download DelphiX, excelent delphi component for directX.
Avatar of igor84

ASKER

for baksa :

1. what i do with DelphiX ?

2. run your program and when the elipse is shown ,show other program on that spot and you will se the rectangle of the previous program.

3.the wave : if you remmber in win 95 there were screensaver that looked like a 3D ball .
i want to make something simmilar to that but instead of a ball i want to make a wave that starts at the top of the screen an goes to the end of it .
1. DelphiX is delphi wrapper for DirectX, with delphiX you can quickly and easy make DirectX graphics and use DirectX sprites, and best thing for your program is sprite, there will be no flicking, no need for erasing and saving the background, DirectX and video board hardware will take care of this tasks, and they are much faster than GDI.
So, with DelphiX you can use DirectX in your programs.

2. Yes, if you examine the source you will see why is that, if you, or some other program change background when sleep(10) is executing this will happen, becouse background is grabbed before, I can't think elegant way to avoid this, except sprites :)
I send you this example just to show you an another way, this is not the solution for your problem.

3. Yes, I know what you mean, but I really don't have time to write such program for you, and this NOT an easy task, to do it right, IMHO only was is DirectX, so my advice is : download DelphiX, compile and run all examples you'll find in that archive and you will see what DirectX can do. For all examples you have source and you can find out and see how it is done, and M$ directX SDK will be good to have. You can download DelphiX from :
http://www.yks.ne.jp/~hori/index-e.html

Avatar of igor84

ASKER

for baksa : if i want to show your ellipse once evrey 50 ms what i need to write ?

p.s do you have icq ?
Avatar of igor84

ASKER

to baksa : wheen you will have time (for this 1000 pts promissed).
You need to put sleep(50)

My ICQ # is 114485916 , but I don't have ICQ always online, I will have it online for next 30 minutes, so we can chat.
igor84, I had another way, why not make transparent form, for win 2000 this is easy and here is the example, for win9x you will have to find such code your self, or write it, try searching the web.

Here is w2k version :


******************************* TransForm.dfm *************



object Form1: TForm1
  Left = 446
  Top = 217
  BorderIcons = []
  BorderStyle = bsNone
  Caption = 'Form1'
  ClientHeight = 117
  ClientWidth = 356
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnHide = FormHide
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 3
    Top = -5
    Width = 414
    Height = 119
    Caption = 'Antonio !'
    Font.Charset = EASTEUROPE_CHARSET
    Font.Color = clWindowText
    Font.Height = -96
    Font.Name = 'Trebuchet MS'
    Font.Style = [fsBold, fsItalic]
    ParentFont = False
  end
  object Timer1: TTimer
    Interval = 5
    OnTimer = Timer1Timer
    Left = 5
    Top = 87
  end
end

******************************* TransForm.pas *************

unit TransForm;

interface

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


type
  TForm1 = class(TForm)
    Label1: TLabel;
    Timer1: TTimer;
    procedure FormShow(Sender: TObject);
    procedure FormHide(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  public
    Direction: TPoint;
  end;


function TransparentWind(const Handle: THandle; Level: Byte; Toggle: Boolean): Boolean;
function LoadWin2k: Boolean;
function UnLoadWin2k: Boolean;
function WinVer: Integer;
function GetTrans(Int: Integer): Byte;



const
  OS_WINNT = 1; { WINDOWS NT}
  OS_WIN32 = 0; { WINDOWS 95 OR 98}
  OS_WINS = 2; { WIN32 UNDER WIN3.1}
  OS_WINNT4 = 3; { NT 4 }
  OS_WIN2k = 4; { Win2k - duh! }

var
  Form1: TForm1;
  TransLoaded: Boolean;
  maxX,maxY:integer;


implementation


var
  LayerFunc: Function(Handle: HWND; crKey: DWord; bAlpha: Byte; dwFlags: DWORD): Bool; stdcall;
  hDLL: HWND;

const
  WS_EX_LAYERED = $00080000;
  LWA_COLORKEY = $00000001;
  LWA_ALPHA = $00000002;
  ULW_COLORKEY = $00000001;
  ULW_ALPHA = $00000002;
  ULW_OPAQUE = $00000004;

{$R *.DFM}

{ TForm1 }

procedure TForm1.FormShow(Sender: TObject);
begin
  loadwin2K;
  transparentwind(Handle, 140, True);
  Direction := Point(1,2);
  Timer1.Enabled := True;

  // stay on top
  SetWindowPos(Handle,
                   HWND_TOPMOST,
                   Left,
                   Top,
                   Width,
                   Height,
                   SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);



end;

procedure TForm1.FormHide(Sender: TObject);
begin
  unloadWin2K;
end;

(*
procedure TForm1.WMMove(var Message: TWMMove);
var
  xp, yp: integer;
begin
  xp := Message.XPos;
  yp := Message.YPos;
  BitBlt(Canvas.Handle,0,0,Width,Height, screenDC, xp + Width,yp, SRCCOPY);
end;
*)

{*************************************************************************

  File:    Win2k.Pas
  Version: 1.0.0
  Author:  Jamie Frater
  E.Mail:  jamie@frater.com or jfrater@globe.net.nz
  Web:     http://www.frater.com
  IRC:     WraithX or Wrayth at EFNet
  Date:    17 October 1999

  Delphi:  2, 3, 4, 5
  BCB:     ???

  License: Don't redistribute for cash.  Don't change and
           redistribute under your name.  Let me know
           if you fix anything or improve anything and
           I will add it to the main release with credits.

  Desc:    This unit contains a series of defines and methods
           from winuser.h for Windows 2000

  Use:     I don't have time to write a help file sorry.
           You will have to figure out what each function
           does- though it is fairly obvious in most
           cases.

     In your main form create add LoadWin2k.  In the OnClose or OnDestroy use
     UnloadWin2k.  I am using this method so that you don't get export
     errors on machines which don't have Win2k.

           You can check if you are in Win2k by doing WinVer = OS_WIN2k

           Once you have loaded it, you simply do TransparentWindow(WindowHandle, Level, Toggle);
           Toggle turns transparency on or off.  A good level to use is 192.

           GetTrans is used so you can set up a nice TrackBar with 6 levels for the user to pick
           from for his preferred level of transparency.

           Explicit Imported methods (Don't use these unless you are 100% sure the user
           is running Win2k.)  You should use my methods for dynamic loading instead:

     Function SetLayeredWindowAttributes(Handle: HWND; crKey: TColor; bAlpha: Byte; dwFlags: DWORD): Bool; stdcall;
     function SetLayeredWindowAttributes; external 'user32.dll' name 'SetLayeredWindowAttributes;


*************************************************************************}


function GetTrans(Int: Integer): Byte;
begin
  case Int of
    0: result := 0;
    1: result := 40;
    2: result := 80;
    3: result := 120;
    4: result := 160;
    5: result := 200;
    6: result := 240
  else
    result := 0;
  end;

end;

function WinVer: Integer;
var
  OSVerInfo: TOSVersionInfo;
begin
  try
    OSVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
    GetVersionEx(OSVerInfo);
    result := OSVerInfo.dwMajorVersion;
    case OSVerInfo.dwPlatformID of
      VER_PLATFORM_WIN32s: Result := OS_WINS;
      VER_PLATFORM_WIN32_WINDOWS: result := OS_WIN32;
      VER_PLATFORM_WIN32_NT: begin
        case OSVerInfo.dwMajorVersion of
          1: result := OS_WINNT;
          2: result := OS_WINNT;
          3: result := OS_WINNT;
          4: result := OS_WINNT4;
          5: result := OS_WIN2k;
        end;
      end
    else
      result := OSVerInfo.dwPlatformID;
    end;
  except
    result := -1;
  end;
end;

function LoadTransDLL: Boolean;
begin
  try
    hDLL := LoadLibrary('user32.dll');
    if hDLL <> 0 then
      @LayerFunc := GetProcAddress(hDLL, 'SetLayeredWindowAttributes');
    result := true;
  except
    result := false;
  end;
end;

function LoadWin2k: Boolean;
begin
  if WinVer = OS_WIN2k then
  begin
    try
      if LoadTransDll then
      begin
        Result := True;
        TransLoaded := True;
      end
      else
      begin
        result := false;
        TransLoaded := false;
      end;
    except
      TransLoaded := false;
      result := false;
    end;
  end
  else
    result := false;
end;

function UnLoadWin2k: Boolean;
begin
  if WinVer = OS_WIN2k then
  begin
    try
      @LayerFunc := Nil;
      FreeLibrary(HDLL);
      result := true;
    except
      result := false;
    end;
  end
  else
    result := False;
end;

function TransparentWind(const Handle: THandle; Level: Byte; Toggle: Boolean): Boolean;
var
  dwLong,
  nAlpha: DWORD;
begin
  if WinVer = OS_WIN2k then
  begin
    if Toggle = true then
    begin // turn it on
      try
        if Level < 10 then Level := 10 // anything lower is blank
        else
          if Level > 240 then Level := 240; // anything higher is blank

        dwLong := GetWindowLong(Handle, GWL_EXSTYLE);
        nAlpha := Level;
        SetWindowLong(Handle, GWL_EXSTYLE, dwLong or WS_EX_LAYERED);
        LayerFunc(Handle, RGB(0,0,0), nAlpha, LWA_ALPHA);
        result := true;
      except
        result := false;
      end;
    end
    else
    begin // turn it off
      try
        dwLong := GetWindowLong(Handle, GWL_EXSTYLE);
        SetWindowLong(Handle, GWL_EXSTYLE, dwLong and (NOT WS_EX_LAYERED));
        result := true;
      except
        result := false;
      end;
    end;
    end

  else
    result := false; // oops- this isn't win2k
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Left := Left + Direction.X;
  Top := Top + Direction.Y;

  if (Left+Width >= Screen.Width) or (Left<1) then
    Direction.x := Direction.x * -1;

  if (Top+Height >= Screen.Height) or (Top <1) then
    Direction.y := Direction.y * -1;

end;

end.


Avatar of igor84

ASKER

i prommised 1000 points for the full answer i got only one half so i decide to give Baksa 520 points for his good answer

thank you all from helphing me !!!


Igor