Screen Saver

I have made a simple screen saver, and I want to respond to the /p parameter to show a preview of the screen saver in the small moniter on the Display properties window.  I know that the second parameter is the handle to a canvas, or something, so windows runs the screen saver with some thing like this:  ScreenSaver.exe /p 3344   I can make the application create a form if the first parameter is /p, and then draw on the computer screen by using the getdc(...) function.  So when you select the screen saver, windows executes it and the drawing begins on the small moniter.  But when it is executed, the display window is deactivated and the focus goes to the screen saver form.  How can I stop this?  Also, when you now select a different screen saver, my one is still running, and conflicts with the other one that is drawing on the same canvas.

Any help on this matter will be useful.
LVL 1
bogieman_Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

TheNeilCommented:
You shouldn't need to create a form with the /p parameter, just output to the window specified by the handle passed (the way I've done it is to construct the display on an in-memory bitmap and then throw that at the handle passed by Windows).

I've written stuff in the past that does this and didn't have any problems so I know that it CAN be done without any problems. One thing you do have to be careful of is multiple instances of your screen saver being run. Add some code so that your saver terminates if a previous version is running (I can give you this if you need it) and get rid of creating the form when the /p parameter is used

The Neil
0
intheCommented:
hi,
i agree with TheNeil , i have example of screensaver and it uses the in memory bitmap method .
0
bogieman_Author Commented:
Well, I have already made it only run once, but could you just show me what you mean with that in-memory bitmap stuff?  Cheers.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

intheCommented:
here is some of the code from the demo,showing to check what the state is (run preview / run screensaver mode etc}

see the code at about the lines :
 if SSmode = ssPreview then ...
(if you want i can mail you the complete source)and sorry bout the formatting its a bit erratic in places ;-)
Regards Barry

program Simple;
uses  Forms,  SysUtils,  Windows,  Graphics,  Classes,
  Ssave in 'SSave.pas' {Scrn},
  Codespot in 'CodeSpot.pas',
  Ssetup in 'SSetup.pas' {Setup},
  Globals in 'Globals.pas';

{$E SCR}
{$R *.RES}

var  
  MySem       : THandle;
  Arg1,  Arg2 : String;
  DemoWnd     : HWnd;
  MyRect      : TRect;
  MyCanvas    : TCanvas;
  x, y,
  dx, dy      : Integer;
  MyBkgBitmap,
  InMemBitmap : TBitmap;
  ScrWidth,
  ScrHeight   : Integer;
  SysDir      : String;
  NewLen      : Integer;
  MyMod       : THandle;

  PwdFunc     : function (a : PChar; ParentHandle : THandle; b, c : Integer) :
                    Integer; stdcall;
begin
  Arg1 := UpperCase(ParamStr(1));
  Arg2 := UpperCase(ParamStr(2));
  if (Copy(Arg1,1,2) = '/A') or (Copy(Arg1,1,2) = '-A') or
     (Copy(Arg1,1,1) = 'A') then    SSMode := ssSetPwd;
  if (Copy(Arg1,1,2) = '/P') or (Copy(Arg1,1,2) = '-P') or
     (Copy(Arg1,1,1) = 'P') then    SSMode := ssPreview;
  if (Copy(Arg1,1,2) = '/C') or (Copy(Arg1,1,2) = '-C') or
     (Copy(Arg1,1,1) = 'C') or (Arg1 = '') then
    SSMode := ssConfig;
  if SSMode = ssSetPwd then begin
    SetLength(SysDir,MAX_PATH);
    NewLen := GetSystemDirectory(PChar(SysDir),MAX_PATH);
    SetLength(SysDir,NewLen);
    if (Length(SysDir) > 0) and (SysDir[Length(SysDir)] <> '\') then
      SysDir := SysDir+'\';
    MyMod := LoadLibrary(PChar(SysDir+'MPR.DLL'));
    if MyMod <> 0 then begin
      PwdFunc := GetProcAddress(MyMod,'PwdChangePasswordA');
      if Assigned(PwdFunc) then        PwdFunc('SCRSAVE',StrToInt(Arg2),0,0);
      FreeLibrary(MyMod);    end;    Halt;  end;
  MySem := CreateSemaphore(nil,0,1,'SimpleSaverSemaphore');
  if ((MySem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)) then begin
    CloseHandle(MySem);
    Halt;
  end;
  Application.Initialize;

  if SSMode = ssPreview then begin
    DemoWnd := StrToInt(Arg2);
    while not IsWindowVisible(DemoWnd) do
      Application.ProcessMessages;
    GetWindowRect(DemoWnd,MyRect);
    ScrWidth := MyRect.Right-MyRect.Left+1;
    ScrHeight := MyRect.Bottom-MyRect.Top+1;
    MyRect := Rect(0,0,ScrWidth-1,ScrHeight-1);
    MyCanvas := TCanvas.Create;
    MyCanvas.Handle := GetDC(DemoWnd);
    MyCanvas.Pen.Color := clWhite;
    x := (ScrWidth div 2)-16;
    y := (ScrHeight div 2)-16;
    dx := 1;
    dy := 1;
    MyBkgBitmap := TBitmap.Create;
    with MyBkgBitmap do begin
      Width := ScrWidth;
      Height := ScrHeight;
    end;
    MyBkgBitmap.Canvas.FillRect(Rect(0,0,ScrWidth-1,ScrHeight-1));
    InMemBitmap := TBitmap.Create;
    with InMemBitmap do begin
      Width := ScrWidth;
      Height := ScrHeight;
    end;
    while IsWindowVisible(DemoWnd) do begin
      InMemBitmap.Canvas.CopyRect(MyRect,MyBkgBitmap.Canvas,MyRect);
      InMemBitmap.Canvas.Draw(x,y,Application.Icon);
      MyCanvas.CopyRect(MyRect,InMemBitmap.Canvas,MyRect);
      Sleep(10);
      Application.ProcessMessages;
      if (x = 0) or (x = (ScrWidth-33)) then
        dx := -dx;
      if (y = 0) or (y = (ScrHeight-33)) then
        dy := -dy;
      x := x+dx;
      y := y+dy;
    end;
    MyBkgBitmap.Free;
    InMemBitmap.Free;
    MyCanvas.Free;
    CloseHandle(MySem);
    Halt;
  end;

  DesktopBitmap := TBitmap.Create;
  with DesktopBitmap do begin
    Width := Screen.Width;    Height := Screen.Height;  end;
  BitBlt(DesktopBitmap.Canvas.Handle,0,0,Screen.Width,Screen.Height,
          GetDC(GetDesktopWindow),0,0,SrcCopy);  if SSMode = ssConfig then begin
    Application.CreateForm(TSetup, Setup);  end else
    Application.CreateForm(TScrn,Scrn);  Application.Run;  DesktopBitmap.Free;
  CloseHandle(MySem);end.
0
TheNeilCommented:
Well rather than outputing your screen saver directly to the screen (which you shouldn't be doing anyway if you're doing drawing yourself (doesn't apply if you're outputting video or something) as it's far too slow) output everything to a bitmap in memory.

Just create your TBitmap in the following way (this will be a bit hazy as I can't remember the API routine to draw a bitmap)

VAR
  bmpTemp_Screen : TBitmap;
BEGIN
  bmpTemp_Screen := TBitmap.Create;
  bmpTemp_screen.Width := 200;
  bmpTemp_Screen.Height := 200;

  //Draw whatever it is you need to draw onto bmpTemp_Screen

  //Output the bitmap to the screen using the API routine that I can't remember off the top of my head
 
  bmpTemp_Screen.Free;
END;

This help?

The Neil
0
bogieman_Author Commented:
Right, I haven't used that yet, inthe, but could you e-mail all of it to me anyway at bogieman_@hotmail.com, so I can have a closer look.  Thanks.
0
intheCommented:
ok have sent (sorry i forget to take the .scr fie out of zip file).
0
bogieman_Author Commented:
I have not had a chance to get the e-mail but could you tell me how to use the:
PwdFunc'SCRSAVE',StrToIntArg2),0,0) function - I can get it to display the actual password confimation dialog, but how do I get the password string?
     
0
intheCommented:
see in ssave.pas at the procedure TScrn.GetPassword; which is called onkeydown of form
some code pasted here:

MyMod := LoadLibrary(PChar(SysDir+'PASSWORD.CPL'));
          if MyMod = 0 then
            OkToClose := True
          else begin
            PwdFunc := GetProcAddress(MyMod,'VerifyScreenSavePwd');
            if PwdFunc(Handle) then
              OkToClose := True;
            FreeLibrary(MyMod);
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
bogieman_Author Commented:
That, and the other stuff is fine - thanks
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.