Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing on the Desktop Background (WIN32)

Tags:

c++

winapi

Is there any way to draw on the desktop background in WIN32 and also receive notifications when the desktop background is repainted?

I tried this:

desk = GetDesktopWindow();
dc = GetDC(desk);
MoveToEx(dc,0,0,NULL);
LineTo(dc,1680,1050);
ReleaseDC(desk,dc);

But it draws on the whole screen, even over windows that are on the screen.

like image 256
Razvi Avatar asked Jul 24 '09 08:07

Razvi


2 Answers

You can use Spy++ to find which window is the desktop background window.

On my system I see the following hierarchy:

  • Window 000100098 "Program Manager" Progman
    • Window 0001009E "" SHELLDLL_DefView
      • Window 00100A0 "FolderView" SysListView32

I guess you are referring to the SysListView32 - the window with all the icons. You can use FindWindowEx to find this window.

Edit You should use a combination of FindWindowEx and EnumerateChildWindows. The code presented below can be compiled in a command line box like this: cl /EHsc finddesktop.cpp /DUNICODE /link user32.lib

#include <windows.h>
#include <iostream>
#include <string>

BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
  std::wstring windowClass;
  windowClass.resize(255);

  unsigned int chars = ::RealGetWindowClass(hwnd, &*windowClass.begin(), windowClass.size());
  windowClass.resize(chars);

  if (windowClass == L"SysListView32")
  {
    HWND* folderView = reinterpret_cast<HWND*>(lParam);
    *folderView = hwnd;

    return FALSE;
  }

  return TRUE;
}

int wmain()
{
  HWND parentFolderView = ::FindWindowEx(0, 0, L"Progman", L"Program Manager");
  if (parentFolderView == 0)
  {
    std::wcout << L"Couldn't find Progman window, error: 0x" << std::hex << GetLastError() << std::endl;
  }

  HWND folderView = 0;
  ::EnumChildWindows(parentFolderView, EnumChildProc, reinterpret_cast<LPARAM>(&folderView));

  if (folderView == 0)
  {
    std::wcout << L"Couldn't find FolderView window, error: 0x" << std::hex << GetLastError() << std::endl;
  }
  HWND desktopWindow = ::GetDesktopWindow();

  std::wcout << L"Folder View: " << folderView << std::endl;
  std::wcout << L"Desktop Window: " << desktopWindow << std::endl;

  return 0;
}

Here are the results after running finddesktop.exe

Folder View: 000100A0
Desktop Window: 00010014

As you can see the window handles are quite different.

like image 65
Cristian Adam Avatar answered Oct 04 '22 13:10

Cristian Adam


Just quoting MSDN:

The GetDesktopWindow function returns a handle to the desktop window. The desktop window covers the entire screen. The desktop window is the area on top of which other windows are painted.

So you are getting a Window with nested windows on them. I'm not quite a WIN32 user, but I think the approach here is get to the lower level, take control of the graphic object that is painting the background picture, and draw there.

like image 26
fixmycode Avatar answered Oct 04 '22 14:10

fixmycode