Skip to content

Commit

Permalink
Support desktop without wallpaper
Browse files Browse the repository at this point in the history
  • Loading branch information
cbucher committed Mar 6, 2016
1 parent bacad57 commit cffa15c
Showing 1 changed file with 105 additions and 31 deletions.
136 changes: 105 additions & 31 deletions Console/Wallpaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,29 +81,69 @@ unsigned int __stdcall _MyThreadFunction(void* arg)

DWORD WallPaperThread::Process(HANDLE hStopSignal)
{
HKEY hkey;
LSTATUS rc = ::RegOpenKeyEx(
HKEY_CURRENT_USER,
L"Control Panel\\Desktop",
0,
KEY_READ,
&hkey);

if( rc != ERROR_SUCCESS )
Win32Exception::Throw("RegOpenKeyEx", rc);

unique_ptr<HKEY__, RegCloseKeyHelper>hkeyPtr(hkey);

std::unique_ptr<void, CloseHandleHelper>regkeyChangeNotification(
LSTATUS rc;
std::unique_ptr<HKEY__, RegCloseKeyHelper> hkeyControlPanelPtr;

{
HKEY hkey;
rc = ::RegOpenKeyEx(
HKEY_CURRENT_USER,
L"Control Panel",
0,
KEY_READ,
&hkey);

if( rc != ERROR_SUCCESS )
Win32Exception::Throw("RegOpenKeyEx", rc);

hkeyControlPanelPtr.reset(hkey);
}

std::unique_ptr<HKEY__, RegCloseKeyHelper> hkeyDesktopPtr;

{
HKEY hkey;
rc = ::RegOpenKeyEx(
hkeyControlPanelPtr.get(),
L"Desktop",
0,
KEY_READ,
&hkey);

if( rc != ERROR_SUCCESS )
Win32Exception::Throw("RegOpenKeyEx", rc);

hkeyDesktopPtr.reset(hkey);
}

std::unique_ptr<HKEY__, RegCloseKeyHelper> hkeyColorsPtr;

{
HKEY hkey;
rc = ::RegOpenKeyEx(
hkeyControlPanelPtr.get(),
L"Colors",
0,
KEY_READ,
&hkey);

if( rc != ERROR_SUCCESS )
Win32Exception::Throw("RegOpenKeyEx", rc);

hkeyColorsPtr.reset(hkey);
}

std::unique_ptr<void, CloseHandleHelper> regkeyChangeNotification(
::CreateEvent(NULL, FALSE, TRUE, NULL));
if( regkeyChangeNotification.get() == nullptr )
Win32Exception::ThrowFromLastError("CreateEvent");

unique_ptr<void, FindCloseChangeNotificationHelper>folderChangeNotification(INVALID_HANDLE_VALUE);
unique_ptr<void, FindCloseChangeNotificationHelper> folderChangeNotification(INVALID_HANDLE_VALUE);

wchar_t szWallpaper[_MAX_PATH] = L"";
wchar_t szWallpaperStyle [16] = L"";
wchar_t szTileWallpaper [16] = L"";
wchar_t szBackground [16] = L"";
long long llWallPaperFileSize = 0;
bool boolInit = true;

Expand All @@ -127,9 +167,10 @@ DWORD WallPaperThread::Process(HANDLE hStopSignal)
wchar_t szWallpaperTmp[_MAX_PATH];
wchar_t szWallpaperStyleTmp[16];
wchar_t szTileWallpaperTmp[16];
wchar_t szBackgroundTmp[16];

rc = ::RegQueryValueEx(
hkeyPtr.get(),
hkeyDesktopPtr.get(),
L"Wallpaper",
NULL,
&dwType,
Expand All @@ -139,7 +180,7 @@ DWORD WallPaperThread::Process(HANDLE hStopSignal)
Win32Exception::Throw("RegQueryValueEx", rc);

rc = ::RegQueryValueEx(
hkeyPtr.get(),
hkeyDesktopPtr.get(),
L"WallpaperStyle",
NULL,
&dwType,
Expand All @@ -149,16 +190,33 @@ DWORD WallPaperThread::Process(HANDLE hStopSignal)
Win32Exception::Throw("RegQueryValueEx", rc);

rc = ::RegQueryValueEx(
hkeyPtr.get(),
hkeyDesktopPtr.get(),
L"TileWallpaper",
NULL,
&dwType,
(LPBYTE)szTileWallpaperTmp, &(dwValueSize = static_cast<DWORD>(sizeof(szTileWallpaperTmp))));

rc = ::RegQueryValueEx(
hkeyColorsPtr.get(),
L"Background",
NULL,
&dwType,
(LPBYTE)szBackgroundTmp, &(dwValueSize = static_cast<DWORD>(sizeof(szBackgroundTmp))));

if( rc != ERROR_SUCCESS )
Win32Exception::Throw("RegQueryValueEx", rc);

if( wcscmp(szWallpaperTmp, szWallpaper) ||
if( wcscmp(szBackground, szBackgroundTmp) )
{
// the background color has changed!
// there is no wallpaper file
// but we must signal the desktop modification
wcscpy_s(szBackground, szBackgroundTmp);

boolWallpaperChangeHasChanged = true;
}

if( wcscmp(szWallpaperTmp, szWallpaper) ||
wcscmp(szWallpaperStyleTmp, szWallpaperStyle) ||
wcscmp(szTileWallpaperTmp, szTileWallpaper) )
{
Expand All @@ -171,23 +229,32 @@ DWORD WallPaperThread::Process(HANDLE hStopSignal)
::memcpy(szWallpaperFolder, szWallpaper, sizeof(szWallpaperFolder));
::PathRemoveFileSpec(szWallpaperFolder);

folderChangeNotification.reset(
::FindFirstChangeNotification(
szWallpaperFolder,
FALSE,
FILE_NOTIFY_CHANGE_SIZE));

if( folderChangeNotification.get() == INVALID_HANDLE_VALUE )
Win32Exception::ThrowFromLastError("FindFirstChangeNotification");
if( szWallpaperFolder[0] )
{
// if a wallpaper is set
// we monitor the wallpaper folder
folderChangeNotification.reset(
::FindFirstChangeNotification(
szWallpaperFolder,
FALSE,
FILE_NOTIFY_CHANGE_SIZE));

if( folderChangeNotification.get() == INVALID_HANDLE_VALUE )
Win32Exception::ThrowFromLastError("FindFirstChangeNotification");
}
else
{
folderChangeNotification.reset(INVALID_HANDLE_VALUE);
}

if( !boolInit )
boolWallpaperChangeHasChanged = true;
}

// reactive registry monitoring
rc = ::RegNotifyChangeKeyValue(
hkeyPtr.get(),
FALSE,
hkeyControlPanelPtr.get(),
TRUE,
REG_NOTIFY_CHANGE_LAST_SET,
regkeyChangeNotification.get(),
TRUE
Expand All @@ -212,8 +279,15 @@ DWORD WallPaperThread::Process(HANDLE hStopSignal)
if( boolWallpaperChangeHasChanged || boolCheckWallpaperChange || boolInit )
{
struct _stat64 theStat;
if( _wstat64(szWallpaper, &theStat) )
throw std::exception(_sys_errlist[errno]);
if( szWallpaper[0] )
{
if( _wstat64(szWallpaper, &theStat) )
throw std::exception(_sys_errlist[errno]);
}
else
{
theStat.st_size = 0;
}

if( boolInit )
boolInit = false;
Expand Down

0 comments on commit cffa15c

Please sign in to comment.