Click here to Skip to main content
Email Password   helpLost your password?

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!

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralElectric Sheep WMP Plug In
Specter13
11:14 8 Feb '09  
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)
folderol
2:37 26 Jan '09  
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 INSTALL
ZBow
7:07 15 Oct '08  
I UNZIPPED IT BUT THE ISS EXTENTION DOESN'T WORK ON MY SYSTEM
QuestionChanging the Visualization in Media Player
Fadik
9:32 26 Sep '06  
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 Player
Justin Hallet
22:57 26 Sep '06  
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


Last Updated 7 Jun 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010