Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does VLC play videos on the desktop?

A while back, I noticed that VLC has the ability to play videos directly on the desktop. When I did so at my school, on Windows XP, it played underneath the icons. When I tried at home, on Windows 7, it hid the icons. I'm not sure if it's the operating system or if it's an update of VLC, but I'm interested in playing it underneath the icons.

After noticing this, I had an idea to make an animated desktop of sorts. Nothing special, just a few select videos for my own use. The idea I started with was to play a video in my own window (using mciSendString) and do a PrintWindow of each frame, save it to a file, and set the desktop wallpaper as the file. I've since lost the specific code, but it wasn't quite working, and, needless to say, would perform horribly.

Coming back to it, I realized there must be a much more efficient way than that anyway, but I can't quite grasp what that is.

I tried (all in Windows 7 now) setting the video's parent window to GetDesktopWindow, to the effect of minimizing all windows leaving behind a new window on the taskbar playing the video, but being able to see the desktop through clicking the aero peek button or hitting Win+D.

I then tried the same with a parent window of the desktop's folder view window. The result was the same dimensioned window playing the video, but this time, the desktop could not be accessed, and no new window was created. It's like it was playing over top of most of the desktop, but the gadgets go over top and the areas toward the right and bottom still show due to the smaller playing window size.

What does VLC do to play it on the desktop itself, looking as if it's a dynamic wallpaper? Is it significantly harder to make it play underneath the icons (and gadgets if you add in Windows 7, I suppose)? The program itself will be used on Windows XP. I'm not sure if DirectShow has anything that might help, but I'm willing to use it, among other Windows API areas besides just MCI. I'd prefer the solution to be in C++, if it makes a difference. .NET would also work well, but might take a bit of extra time working in.

like image 476
chris Avatar asked Sep 14 '12 01:09

chris


2 Answers

VLC sets the wallpaper to a specific color, then uses DirectDraw to update that color key within an overlay surface defined for the desktop.

I've never done it myself, but here are a few places to look for more information:

  • Overlay Color Keys
  • IDirectDrawSurface
  • VLC source code
like image 97
Terrance Avatar answered Oct 10 '22 00:10

Terrance


You can just take desktop handle and draw your own components or data

try this,

#include <stdafx.h>
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

VOID OnPaint(HDC hdc)
{
   Graphics graphics(hdc);
   Pen      pen(Color(255, 0, 0, 255));
   graphics.DrawLine(&pen, 0, 0, 200, 100);
}

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
   HWND                hWnd;
   MSG                 msg;
   WNDCLASS            wndClass;
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR           gdiplusToken;

   // Initialize GDI+.
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

   wndClass.style          = CS_HREDRAW | CS_VREDRAW;
   wndClass.lpfnWndProc    = WndProc;
   wndClass.cbClsExtra     = 0;
   wndClass.cbWndExtra     = 0;
   wndClass.hInstance      = hInstance;
   wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
   wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
   wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
   wndClass.lpszMenuName   = NULL;
   wndClass.lpszClassName  = TEXT("GettingStarted");

   RegisterClass(&wndClass);

   hWnd = GetDesktopWindow();

   ShowWindow(hWnd, iCmdShow);
   UpdateWindow(hWnd);

   while(GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   GdiplusShutdown(gdiplusToken);
   return msg.wParam;
}  // WinMain

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
   WPARAM wParam, LPARAM lParam)
{
   HDC          hdc;
   PAINTSTRUCT  ps;

   switch(message)
   {
   case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      OnPaint(hdc);
      EndPaint(hWnd, &ps);
      return 0;
   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
} // WndProc
like image 23
Abhishek Pachlegaonkar Avatar answered Oct 10 '22 02:10

Abhishek Pachlegaonkar