VLC如何在桌面上播放视频?

8
前段时间,我注意到VLC有能力直接在桌面上播放视频。当我在学校使用Windows XP时,它会在图标下方播放。当我在家中使用Windows 7时,它会隐藏图标。我不确定是操作系统还是VLC的更新,但我对在图标下方播放很感兴趣。
注意到这一点后,我想制作一个动态桌面。没什么特别的,只是为了自己使用几个选定的视频。我最初的想法是在自己的窗口中播放视频(使用“mciSendString”),并对每个帧进行“PrintWindow”,将其保存到文件中,并将桌面壁纸设置为该文件。后来我忘记了具体的代码,但它并没有完全起作用,而且无需说,性能会非常差。
回过头来看,我意识到肯定有比那更有效的方法,但我无法完全理解那是什么。
我尝试过(现在都在Windows 7中)将视频的父窗口设置为“GetDesktopWindow”,以便最小化所有窗口,留下一个新窗口在任务栏上播放视频,但可以通过单击Aero Peek按钮或按Win + D键查看桌面。
然后我尝试了同样的方法,将父窗口设置为桌面的文件夹视图窗口。结果是同样尺寸的窗口播放视频,但这次无法访问桌面,并且没有创建新窗口。就像它正在顶部播放大多数桌面一样,但小部件在上方,右侧和底部区域仍然显示,因为播放窗口尺寸较小。
VLC是如何在桌面上播放视频的,看起来像是动态壁纸?让它在图标下方播放是否更难(如果你添加了Windows 7中的小部件呢)?该程序将在Windows XP上使用。我不确定DirectShow是否有任何有用的东西,但我愿意使用它,除了MCI之外,还可以使用其他Windows API领域。如果有区别,我更喜欢C++的解决方案。.NET也可以,但可能需要额外的时间来工作。

我认为你可以在Windows XP上将网页设置为壁纸,但我不确定它是否适用于Windows 7。那么,想法是在ActiveX(因为你标记了C ++)控件中播放它,但我认为这非常受限制。虽然,可能有其他更优雅的方法来实现你想要的东西。 - nullpotent
@iccthedral,如果它能工作,那就是一件好事。我没有使用过ActiveX控件,但我肯定可以开始尝试。我只会在学校使用它,所以只在XP上工作不是问题。 - chris
除非你只是为了好玩而想自己做这个,否则可以使用此工具在Windows 7上启用Windows DreamScene。工具下载链接:http://www.dreamsceneseven.com/ 。 - Praetorian
@Prætorian,我有时候可能会在我的电脑上尝试一下,谢谢。虽然我认为自己亲手做这件事会很有趣,但学校是我可以利用空闲时间使用类似工具的首选环境。 - chris
2个回答

7
VLC将壁纸设置为特定颜色,然后使用DirectDraw在为桌面定义的叠加表面中更新该颜色键。我自己从未做过这件事,但是有几个地方可以查找更多信息:
- 叠加色键 - IDirectDrawSurface - VLC源代码

1
它运行得非常好,谢谢。只有几个小问题需要解决,我就能很好地完成 :) - chris

2
你可以使用桌面句柄来绘制自己的组件或数据。
试试这个:
#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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接