Click here to Skip to main content
Click here to Skip to main content

Using screensavers inside the Windows Media Player

By , 15 Jul 2011
 

Sample Image - SheepWMP.jpg

Introduction

A few days ago, I downloaded and installed the electricsheep screensaver. This is such a cool screensaver, I wanted to watch it while I worked, and I found the SheepWatcher.

So I started thinking: "that's cool, how did they do that, run the screen saver in a window?" Good old Microsoft had the anwser.

So being a Windows developer, I decided I could do better, a Windows Media Player plug-in to run ElectricSheep.scr. The first step was to get the WMP SDK:

It did not work with VS.NET 2005:

Test

OK, create a C++ project for a Windows Media Player Visualization Plug-in, we will call it SheepWMP. Actually, I wrote a quick test dialog application like so:

A small helper function to wrap CreateProcess:

static HANDLE LaunchProcess ( LPTSTR aProcessName, LPTSTR aArgs )
{
    STARTUPINFO lStartupInfo;            
    PROCESS_INFORMATION lProcessInfo;

    memset ( &lProcessInfo, 0, sizeof ( lProcessInfo ) );
    memset ( &lStartupInfo, 0, sizeof ( lStartupInfo ) );

    lStartupInfo.cb = sizeof ( lStartupInfo );
    lStartupInfo.dwFlags = STARTF_USESHOWWINDOW;
    lStartupInfo.wShowWindow = SW_SHOWNORMAL;

    // Create target process
    CreateProcess ( aProcessName, aArgs, NULL, NULL, FALSE, 0, 
                    NULL, NULL, & lStartupInfo, & lProcessInfo );

    WaitForInputIdle ( lProcessInfo.hProcess, INFINITE ) ;

    return lProcessInfo.hProcess ;
}
BOOL CSheepTestDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Set the icon for this dialog.
    // The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);   // Set big icon
    SetIcon(m_hIcon, FALSE);  // Set small icon

    TCHAR lCommand [ 1024 ] ;
    _stprintf_s ( lCommand, 1024, _T(" /p %u"), 
                  (DWORD) GetSafeHwnd () ) ;

    TCHAR lExe [ 1024 ] ;
    _stprintf_s ( lExe, 1024, 
       _T("c:\\windows\\system32\\electricsheep.scr") ) ;

    TRACE ( lCommand ) ;
    LaunchProcess ( lExe, lCommand ) ;
    return TRUE;  // return TRUE  unless you set the focus to a control
}

Code

Right, let's get to the Media Player plug-in. VS2005, with the WMPSDK, will create a basic visualization plug-in. The first steps are to remove all the rendering code and simply attach the screensaver to the desired HWND:

STDMETHODIMP CSheepWMP::RenderWindowed(TimedLevel *pLevels, 
                                       BOOL fRequiredRender )
{
....

    TCHAR lCommand [ 1024 ] ;
    _stprintf_s ( lCommand, 1024, _T(" /p %u"), 
                  (DWORD) m_hwndParent ) ;

    TCHAR lExe [ 1024 ] ;
    _stprintf_s ( lExe, 1024, 
                  _T("c:\\windows\\system32\\electricsheep.scr") ) ;

    TRACE ( lCommand ) ;
    LaunchProcess ( lExe, lCommand ) ;
....
}

But what happens when Windows Media Player changes size:

// Has the window changed dimensions
RECT lRect ;
GetClientRect ( gWnd, &lRect ) ;
if ( memcmp ( &gRect, &lRect, sizeof ( RECT ) ) != 0 )
{
    ATLTRACE ( DEFAULT_TRACE_PREFIX 
               _T("Window size changed...\n") ) ;
    memcpy ( &gRect, &lRect, sizeof ( RECT ) ) ;

    // Try to update the exinsing window
    HWND lWnd = FindWindowEx ( gWnd, NULL, 
                _T("WindowsScreenSaverClass"), NULL ) ;
    if ( lWnd ) 
    {
        ATLTRACE ( DEFAULT_TRACE_PREFIX 
                   _T("Moving screensaver window...\n") ) ;
        SetWindowPos ( lWnd, NULL, lRect . left, lRect . top, 
                       lRect . right - lRect . left, 
                       lRect . bottom - lRect . top, 
                       SWP_SHOWWINDOW ) ;
    }
}

So now, we have the basics working. If you examine my source, you will see that it locates all the Windows screensavers and can run them all inside the Window Media Player. It's done like so:

CAtlString lPath ;
SHGetFolderPath ( NULL, CSIDL_SYSTEM, NULL, 0, 
                  lPath . GetBufferSetLength ( MAX_PATH ) ) ;
lPath . ReleaseBuffer () ;

ATLTRACE ( DEFAULT_TRACE_PREFIX _T("Finding all scrs in %s\n"), lPath ) ;


CAtlString lSearch = lPath ;
PathAppend ( lSearch . GetBufferSetLength ( MAX_PATH ), DEFAULT_SCR_EXT ) ;
lSearch . ReleaseBuffer () ;

WIN32_FIND_DATA lFindFileData;
HANDLE lFind = FindFirstFile ( lSearch, &lFindFileData ) ;
if ( lFind != INVALID_HANDLE_VALUE )
{
    do
    {
        CAtlString lScr = lPath ;
        PathAppend ( lScr .GetBufferSetLength ( MAX_PATH ), 
                           lFindFileData . cFileName  ) ;
        lScr . ReleaseBuffer () ;
    
        ATLTRACE ( DEFAULT_TRACE_PREFIX _T("Adding scr, %s\n"), lScr ) ;

        m_Scrs . push_back ( lScr ) ;
    }
    while ( FindNextFile ( lFind, &lFindFileData ) ) ;

    FindClose ( lFind ) ;
}

Now, inside the Windows Media Player, we list all the screensavers using nice names. You have to get the names from the screensaver .scr files, which can be loaded like resource DLLs:

CAtlString CSheepWMP::GetScrName ( CAtlString aScr ) 
{
    // Initially get the filename and remove extension
    CAtlString lName = PathFindFileName ( aScr ) ;
    PathRemoveExtension ( lName . GetBufferSetLength ( MAX_PATH ) ) ;
    lName . ReleaseBuffer () ;

    // Load the DLL as a data file, and do not resolve any references
    ATLTRACE ( DEFAULT_TRACE_PREFIX _T("Loading library %s\n"), aScr ) ;
    HINSTANCE lInstance = LoadLibraryEx ( aScr, NULL, 
              DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE ) ;
    if ( lInstance )
    {
        // Examining all SCR, string 1 is the description
        // used by the display properties
        CAtlString lDesc ;
        LoadString ( lInstance, 1, 
                     lDesc.GetBufferSetLength(MAX_PATH), MAX_PATH ) ;
        lDesc . ReleaseBuffer () ;

        // Clean up
        FreeLibrary ( lInstance ) ;

        // If we have a valid description use it
        if ( lDesc . IsEmpty () == FALSE )
        {
            ATLTRACE ( DEFAULT_TRACE_PREFIX 
                       _T("Set scr name to description, %s\n"), lDesc ) ;
            lName = lDesc ;
        }
    }
    return lName ;
}

That's all!

History

  • 15 July, 2011: Updated source for new version of Electric Sheep. Also included the C# .NET implementation and the Microsoft Windows setup script.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Justin Hallet
Web Developer
Australia Australia
Member
Developing windows applications for over 15 years now starting on Win 3.1 with Object Oriented Pascal, progressed to C++ and OWL, in 1996 switch to MFC and never looked back, now focusing on .NET/Mono.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionNot Working - Windows 7 64bit & electricsheep-2.7b34memberMarc Rasch28 Apr '12 - 10:06 
Installed the latest version:
 
electricsheep-2.7b34.exe
 
Running Windows 7 64-bit
 
Get a black screen.
QuestionSource PackagememberJustin Hallet17 Jul '11 - 13:42 
The source package has been updated to include support for latest version of Electric Sheep, also now includes a C# .NET implementation.
GeneralA bit of troublememberMember 776079316 Mar '11 - 15:21 
I had this on my old computer and it worked great! Now I'm trying to use it on my laptop and I'm having a bit of trouble. The .exe worked fine and installed. Now the screensaver option appears on my media player visualizer list. However the option of Electric Sheep does not! I have checked that Electric Sheep is installed properly and indeed works as a screensaver for my laptop (it is currently set as default). I tried the code swap provided for later versions of Electric Sheep but honestly I'm not that code-savvy and I don't know what to do with source files etc. Any advice on how to get this thing working would be very appreciated!
GeneralElectric Sheep WMP Plug InmemberSpecter138 Feb '09 - 10:14 
just a small suggestion, i would do it myself, but i'll admit that it's a bit out of my depth. the electric sheep rating system (i.e. pushing up and down to rate the sheep)in the media player when it is in full screen changes the play count of the song your listening to. i don't really know how to change it, so i figured i'd talk to you. feel free to e-mail me, shspecter13@hotmail.com.
GeneralElectric Sheep 2.7 Beta 10 (and later)memberfolderol26 Jan '09 - 1:37 
Thanks for the nice plugin! If you don't get it to work with later versions of Electric Sheep, change the path in SheepWMP.cpp from #define DEFAULT_SCR_FILENAME _T("c:\\windows\\system32\\electricsheep.scr") to #define DEFAULT_SCR_FILENAME _T("C:\\Windows\\Electricsheep_2_7b10.scr") (in case of Electric Sheep 2.7 Beta 10).
QuestionHOW DO I GET THE PLUGIN TO INSTALLmemberZBow15 Oct '08 - 6:07 
I UNZIPPED IT BUT THE ISS EXTENTION DOESN'T WORK ON MY SYSTEM
QuestionChanging the Visualization in Media PlayermemberFadik26 Sep '06 - 8:32 
Hi,
 
I have been looking for one whole day for this, I am not able to find a way to alter/loop through the different vis. effects using code, I must change it from the normal win. media player, then run my application and it'll take the new visualization set using wmp.
 
Any ideas/help on how to achieve this would be great.
Using wmp10 or 11 on VS.net 2003 C#.
 

 
Regards,
Fadi .K
AnswerRe: Changing the Visualization in Media PlayermemberJustin Hallet26 Sep '06 - 21:57 
Hi Fadi,
 
Not exactly sure what you are trying to do here, I am not an expert on the WMP SDK, all idea was use the template vis.plugin to achieve my goal. There should be some doco on the SDK in the MSDN.
 
Justin

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 15 Jul 2011
Article Copyright 2006 by Justin Hallet
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid