programming a screensaver in windows

ok i have posted this message because i am tired of searching the web for resources that will teach me how to program a screen saver in windows. I know that a screen saver is just a .exe renamed .scr but how do i get it to diplay the properties dialog when required, the preview screen when required? When i rename a .exe and select the program in the screensaver drop down list it starts it up rather than just providing a preview. Does anybody know how to make a .exe behave just like a screensaver???

Comments

  • SephirothSephiroth Fayetteville, NC, USA
    : ok i have posted this message because i am tired of searching the web for resources that will teach me how to program a screen saver in windows. I know that a screen saver is just a .exe renamed .scr but how do i get it to diplay the properties dialog when required, the preview screen when required? When i rename a .exe and select the program in the screensaver drop down list it starts it up rather than just providing a preview. Does anybody know how to make a .exe behave just like a screensaver???
    :
    Actually I thought there were some differences. I myself would like to do some screen-saver coding in GL, but have yet to find all the documentation needed to do so.

    -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]

  • : : ok i have posted this message because i am tired of searching the web for resources that will teach me how to program a screen saver in windows. I know that a screen saver is just a .exe renamed .scr but how do i get it to diplay the properties dialog when required, the preview screen when required? When i rename a .exe and select the program in the screensaver drop down list it starts it up rather than just providing a preview. Does anybody know how to make a .exe behave just like a screensaver???
    : :
    : Actually I thought there were some differences. I myself would like to do some screen-saver coding in GL, but have yet to find all the documentation needed to do so.
    :
    : -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
    :
    :

    I'd been wondering about screensaver coding a while back also, Here is a (verry basic) WinAPI only skeleton of a screensaver I'd been playing with then:
    [code]
    //Ball ScreenSaver.cpp
    #include
    #include

    LRESULT WINAPI ScreenSaverChildProc(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam);
    LRESULT WINAPI ScreenSaverProc(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam)
    {
    static HWND hChild = NULL;
    HINSTANCE hInst = hMainInstance;
    int nMaxX = 0;
    int nMaxY = 0;
    int nWndSize = 0;
    switch(message) {
    case WM_CREATE:
    WNDCLASS wc;
    wc.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC ;
    wc.lpfnWndProc = (WNDPROC) ScreenSaverChildProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = NULL;
    wc.hCursor = NULL;
    wc.hbrBackground = NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "NTDEVCLASS";

    RegisterClass(&wc);

    if(nMaxX == 0) { //Get the desktop size
    RECT rect;
    GetClientRect(hWnd,&rect);
    HDC hdc;
    hdc = GetDC(hWnd);
    nMaxX = rect.right;
    nMaxY = rect.bottom;
    nWndSize = (int) ((float)nMaxY* .35f);
    ::ReleaseDC(hWnd,hdc);
    }

    hChild = CreateWindow(wc.lpszClassName, "Child1", WS_CHILD | WS_VISIBLE,
    0, 0, nWndSize, nWndSize, hWnd, NULL, hInst, NULL);

    break;

    case WM_DESTROY:
    KillTimer(hWnd, 1);
    DestroyWindow(hChild);
    PostQuitMessage(0);
    break;

    case WM_TIMER:
    break;

    default: return DefScreenSaverProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }

    BOOL WINAPI ScreenSaverConfigureDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    return false;
    }

    BOOL WINAPI RegisterDialogClasses(HANDLE hInst) {
    return true;
    }

    ///////////////////////////////////////////////////////////////////////
    //SSchild.cpp
    #include
    #include
    #include "resource.h"

    HBITMAP hbmBall, hbmMask, hbmBuffer;
    HDC hdcBuffer;
    BITMAP bm;

    int ballX, ballY;
    int deltaX, deltaY;
    int deltaValue = 14;
    int ANIM_WIDTH, ANIM_HEIGHT;

    void EraseBall(HDC hdc){
    RECT rc;
    rc.left = ballX;
    rc.top = ballY;
    rc.right = ballX + bm.bmWidth;
    rc.bottom = ballY + bm.bmHeight;
    FillRect(hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
    }

    void DrawBall(HDC hdc){
    HDC hdcMemory;
    hdcMemory = CreateCompatibleDC(hdc);
    SelectObject(hdcMemory, hbmMask);
    BitBlt(hdc, ballX, ballY, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCAND);
    SelectObject(hdcMemory, hbmBall);
    BitBlt(hdc, ballX, ballY, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCPAINT);
    DeleteDC(hdcMemory);
    }

    void UpdateBall(void){
    ballX += deltaX;
    ballY += deltaY;
    if(ballX < 0){
    ballX = 0;
    deltaX = deltaValue;
    }
    else if(ballX + bm.bmWidth > ANIM_WIDTH){
    ballX = ANIM_WIDTH - bm.bmWidth;
    deltaX = -deltaValue;
    }
    if(ballY < 0){
    ballY = 0;
    deltaY = deltaValue;
    }
    else if(ballY + bm.bmHeight > ANIM_HEIGHT){
    ballY = ANIM_HEIGHT - bm.bmHeight;
    deltaY = -deltaValue;
    }
    }


    LRESULT WINAPI ScreenSaverChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    { int retVal;
    switch(message) {
    case WM_CREATE:
    RECT rcWindow, rcClient, rc;
    hbmBall = LoadBitmap(hMainInstance, (LPCTSTR)MAKEINTRESOURCE(BALL));
    hbmMask = LoadBitmap(hMainInstance, (LPCTSTR)MAKEINTRESOURCE(MASK));
    if(!hbmBall || !hbmMask) {
    MessageBox(hWnd, "Load of resources failed.", "Error", MB_OK | MB_ICONEXCLAMATION);
    return -1;
    }

    ANIM_WIDTH = GetSystemMetrics(SM_CXSCREEN);
    ANIM_HEIGHT = GetSystemMetrics(SM_CYSCREEN);
    hdcBuffer = CreateCompatibleDC(0);
    SelectObject(hdcBuffer, hbmBall);
    hbmBuffer = CreateCompatibleBitmap(hdcBuffer, ANIM_WIDTH, ANIM_HEIGHT);
    SelectObject(hdcBuffer, hbmBuffer);
    if(!hbmBuffer){
    MessageBox(hWnd, "Buffer creation failed.", "Error", MB_OK | MB_ICONEXCLAMATION);
    return -1;
    }

    rc.left = rc.top = 0;
    rc.right = ANIM_WIDTH;
    rc.bottom = ANIM_HEIGHT;
    FillRect(hdcBuffer, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
    GetObject(hbmBall, sizeof(bm), &bm);
    SetTimer(hWnd, 1, 10, NULL);

    ballX = ballY = 0;
    deltaX = deltaY = deltaValue;

    GetWindowRect(hWnd, &rcWindow);
    GetClientRect(hWnd, &rcClient);
    if(rcClient.right != ANIM_WIDTH || rcClient.bottom != ANIM_HEIGHT) {
    MoveWindow(hWnd, rcWindow.left, rcWindow.top,
    ((rcWindow.right - rcWindow.left) - rcClient.right) + ANIM_WIDTH,
    ((rcWindow.bottom - rcWindow.top) - rcClient.bottom) + ANIM_HEIGHT, TRUE);
    }
    break;

    case WM_TIMER:
    if(hbmBall && hbmMask) {
    HDC hdcWindow;
    hdcWindow = GetDC(hWnd);
    EraseBall(hdcBuffer);
    UpdateBall();
    DrawBall(hdcBuffer);
    BitBlt(hdcWindow, 0, 0, ANIM_WIDTH, ANIM_HEIGHT, hdcBuffer, 0, 0, SRCCOPY);
    ReleaseDC(hWnd, hdcWindow);
    }
    break;

    case WM_PAINT:
    if(hbmBall && hbmMask) {
    PAINTSTRUCT ps;
    HDC hdcWindow;
    hdcWindow = BeginPaint(hWnd, &ps);
    BitBlt(hdcWindow, 0, 0, ANIM_WIDTH, ANIM_HEIGHT, hdcBuffer, 0, 0, SRCCOPY);
    EndPaint(hWnd, &ps);
    }
    break;

    case WM_DESTROY:
    KillTimer(hWnd, 1);
    PostQuitMessage(0);
    break;

    case WM_KEYDOWN:
    case WM_ACTIVATE:
    case WM_MOUSEMOVE:
    case WM_SETCURSOR:
    case WM_SYSKEYDOWN:
    case WM_SYSCOMMAND:
    case WM_NCACTIVATE:
    case WM_ACTIVATEAPP:
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    retVal = DefScreenSaverProc(hWnd, message, wParam, lParam);
    DefScreenSaverProc(hMainWindow, message, wParam, lParam);
    return retVal;

    default: return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }
    [/code]

    Hope that helps
    Stoic Joker
  • SephirothSephiroth Fayetteville, NC, USA
    But when you compile this, will it compile to .scr or .exe?

    -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]

  • alright boys i am back. I have just actually found a way to program my own screen savers. Well to start off with any .exe file renamed as .src (or .scr i think) can be loaded and executed as a screen saver. just copy in to the windows folder and then check your screensaver list.
    Now the next thing is how do we bring up the setup dialog when we need to and when to show the preview. Alright i have noticed that windows communicates with the screensavers using command line parameters. so basically there are three parameters /p /c /s

    yourexerenamedscr.scr /p (or) /c:(number) or /s

    now /p is given as the parameter when the program wants the little preview in the tiny screen in the screensaver dialog.

    /c is when it wants you to open up your setup dialog (Note /c: is followed by a 5 or 6 digit number. I dont know what the number is for but please shed some light on this if you can, the number only changes when you reopen the display dialog window.)

    Then finally comes /s this is to tell the program that it should start this can be given when the screensaver is starting or the preview button is clicked.

    *******Problem********

    But there is one problem with all this When you are asked to show the preview i dont know how to get the coordinates of the little screen where i have to draw the preview. One solution i though would be to grab the HANDLE for the Display Properties window and check its top and left then calulate the screen coors from there, But i am sure that there is a registry entry for this some one please help out on this one.
  • : But when you compile this, will it compile to .scr or .exe?
    :
    : -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
    :
    :
    I was using MSVC++ 6 for the project, & just changed the name of the output file to .scr in project options. The "catch" was getting the screen saver code included so the exe/scr would respond correctly to the test & configure command line switches that windows transparently uses.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories