xoblite™ / Blackbox for Windows bb5 | RC6 preview | 0.25.2.14
http://xoblite.net/
Wallpaper Class Reference

#include <Wallpaper.h>

Public Member Functions

void ExecuteRootCommand ()
 
void ParseBSetBG ()
 
void ParseBSetRoot ()
 
COLORREF GetColorRef (LPSTR colorAsString)
 
void SetDesktopColor (COLORREF color)
 
void SetWallpaper (LPSTR wpPath, LPSTR wpStyle)
 
void SetModula (int x, int y, COLORREF fg, COLORREF bg)
 
void SetGradient (int type, bool interlaced, COLORREF from, COLORREF to)
 
PBITMAPINFO CreateBitmapInfoStruct (HBITMAP hBitmap)
 
void CreateBMPFile (LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBitmap)
 

Member Function Documentation

◆ ExecuteRootCommand()

void Wallpaper::ExecuteRootCommand ( )
42{
44 else if (IsInString(pSettings->rootCommand, "bsetroot")) ParseBSetRoot();
45
46 pSettings->wallpaperPerWorkspaceSemaphore = false; // Reset if previously set by switchToDesktop() in Workspaces.cpp (i.e. when wallpaper per workspace is enabled)
47}
bool IsInString(LPCSTR inputString, LPCSTR searchString)
Definition BBApi.cpp:2519
Settings * pSettings
Definition Blackbox.cpp:46
bool wallpaperPerWorkspaceSemaphore
Definition Settings.h:311
char rootCommand[MAX_LINE_LENGTH]
Definition Settings.h:570
void ParseBSetBG()
Definition Wallpaper.cpp:54
void ParseBSetRoot()
Definition Wallpaper.cpp:75

◆ ParseBSetBG()

void Wallpaper::ParseBSetBG ( )
55{
56 // bsetbg.exe <-tile|-full|-center> <image.jpg>
57
58 char szOption_1[MAX_LINE_LENGTH], szOption_2[MAX_LINE_LENGTH], szOption_3[MAX_LINE_LENGTH], szOption_4[MAX_LINE_LENGTH];
59 char* tokens[4];
60 tokens[0] = szOption_1;
61 tokens[1] = szOption_2;
62 tokens[2] = szOption_3;
63 tokens[3] = szOption_4;
64 szOption_1[0] = szOption_2[0] = szOption_3[0] = szOption_4[0] = '\0';
65 BBTokenize(pSettings->rootCommand, tokens, 4, NULL);
66
67 SetWallpaper(szOption_3, szOption_2);
68}
int BBTokenize(LPCSTR szString, char *lpszBuffers[], DWORD dwNumBuffers, LPSTR szExtraParameters)
Definition BBApi.cpp:316
#define MAX_LINE_LENGTH
Definition BBApi.h:64
void SetWallpaper(LPSTR wpPath, LPSTR wpStyle)
Definition Wallpaper.cpp:238

◆ ParseBSetRoot()

void Wallpaper::ParseBSetRoot ( )
76{
77 // bsetroot.exe -solid <colour>
78 // bsetroot.exe -bitmap <tile|stretch|center> <image.bmp>
79 // bsetroot.exe -bitmap <tile|stretch|center> <image.bmp> -solid <colour>
80 // bsetroot.exe -gradient <type+interlaced> -from <colour> -to <colour>
81 // bsetroot.exe -mod <x> <y> -fg <colour> -bg <colour>
82
83 char szOption_1[MAX_LINE_LENGTH], szOption_2[MAX_LINE_LENGTH], szOption_3[MAX_LINE_LENGTH], szOption_4[MAX_LINE_LENGTH], szOption_5[MAX_LINE_LENGTH], szOption_6[MAX_LINE_LENGTH], szOption_7[MAX_LINE_LENGTH], szOption_8[MAX_LINE_LENGTH];
84 char* tokens[8];
85 tokens[0] = szOption_1;
86 tokens[1] = szOption_2;
87 tokens[2] = szOption_3;
88 tokens[3] = szOption_4;
89 tokens[4] = szOption_5;
90 tokens[5] = szOption_6;
91 tokens[6] = szOption_7;
92 tokens[7] = szOption_8;
93 szOption_1[0] = szOption_2[0] = szOption_3[0] = szOption_4[0] = szOption_5[0] = szOption_6[0] = szOption_7[0] = szOption_8[0] = '\0';
94 BBTokenize(pSettings->rootCommand, tokens, 8, NULL);
95
96 char msg[350];
97
98 //====================
99
100 // Execute any -solid commands... (see above)
101 if (IsInString(pSettings->rootCommand, "-solid"))
102 {
103 COLORREF solidColor;
104
105 if (!IsInString(pSettings->rootCommand, "-bitmap")) // bsetroot.exe -solid <colour>
106 {
107 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID)"(None)", SPIF_SENDCHANGE); // Remove any existing wallpaper
108 solidColor = ReadColor(NULL, szOption_3, szOption_3);
109 }
110 else solidColor = ReadColor(NULL, szOption_6, szOption_6); // bsetroot.exe -bitmap <tile|stretch|center> <image.bmp> -solid <colour>
111
112 int lpaElements[1] = { COLOR_BACKGROUND };
113 COLORREF lpaRgbValues[1] = { solidColor };
114
115 // Set the new desktop colour...
117 {
118 sprintf(msg, "Setting the desktop colour to %s .", szOption_3);
119 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
120 }
121 SetSysColors(1, lpaElements, lpaRgbValues);
122
123 if (!IsInString(pSettings->rootCommand, "-bitmap")) return;
124 }
125
126 //====================
127
128 // Execute any -bitmap commands... (see above)
129 if (IsInString(pSettings->rootCommand, "-bitmap"))
130 {
131 SetWallpaper(szOption_4, szOption_3);
132 return;
133 }
134
135 //====================
136
137 // Execute any -mod commands... (see above)
138 if (IsInString(szOption_2, "-mod"))
139 {
140 int x = 4, y = 4;
141 x = atoi(szOption_3);
142 y = atoi(szOption_4);
143
144 COLORREF fg = 0xffffff, bg = 0x000000;
145 if (IsInString(szOption_5, "-fg")) fg = ReadColor(NULL, szOption_6, szOption_6);
146 if (IsInString(szOption_5, "-bg")) bg = ReadColor(NULL, szOption_6, szOption_6);
147 if (IsInString(szOption_7, "-fg")) fg = ReadColor(NULL, szOption_8, szOption_8);
148 if (IsInString(szOption_7, "-bg")) bg = ReadColor(NULL, szOption_8, szOption_8);
149
150 // sprintf(msg, "bsetroot %s %d %d %s %s %s %s", szOption_2, x, y, szOption_5, szOption_6, szOption_7, szOption_8);
151 // SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
152
153 SetModula(x, y, fg, bg);
154 return;
155 }
156
157 //====================
158
159 // Execute any -gradient commands... (see above)
160 if (IsInString(szOption_2, "-gradient"))
161 {
162 // First we check the gradient "type"...
163 int type = B_HORIZONTAL; // B_HORIZONTAL is the default type...
164 if (IsInString(szOption_3, "vertical")) type = B_VERTICAL;
165 else if (IsInString(szOption_3, "crossdiagonal")) type = B_CROSSDIAGONAL; // Note: Must be checked before "diagonal"... :)
166 else if (IsInString(szOption_3, "diagonal")) type = B_DIAGONAL;
167 else if (IsInString(szOption_3, "pipecross")) type = B_PIPECROSS;
168 else if (IsInString(szOption_3, "elliptic")) type = B_ELLIPTIC;
169 else if (IsInString(szOption_3, "rectangle")) type = B_RECTANGLE;
170 else if (IsInString(szOption_3, "pyramid")) type = B_PYRAMID;
171
172 // ...then we check the "interlaced" flag...
173 bool interlaced = false;
174 if (IsInString(szOption_3, "interlaced")) interlaced = true;
175
176 // ...and finally the "from" and "to" colours...
177 COLORREF from = 0xffffff, to = 0x000000;
178 if (IsInString(szOption_4, "-from")) from = GetColorRef(szOption_5);
179 if (IsInString(szOption_6, "-to")) to = GetColorRef(szOption_7);
180
181 SetGradient(type, interlaced, from, to);
182 return;
183 }
184
185 //====================
186
187 // Unknown bsetroot command
188 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)"Error parsing style rootCommand! (unknown bsetroot command)");
189}
COLORREF ReadColor(LPCSTR fp, LPCSTR szString, LPCSTR szDefault)
Definition BBApi.cpp:558
HWND GetBBWnd()
Definition BBApi.cpp:128
#define B_VERTICAL
Definition BBApi.h:73
#define B_CROSSDIAGONAL
Definition BBApi.h:75
#define BB_CONSOLEMESSAGE
Definition BBApi.h:165
#define B_ELLIPTIC
Definition BBApi.h:77
#define CONSOLE_REGULAR_MESSAGE
Definition BBApi.h:297
#define B_HORIZONTAL
Definition BBApi.h:72
#define B_DIAGONAL
Definition BBApi.h:74
#define B_PIPECROSS
Definition BBApi.h:76
#define CONSOLE_ERROR_MESSAGE
Definition BBApi.h:300
#define B_PYRAMID
Definition BBApi.h:79
#define B_RECTANGLE
Definition BBApi.h:78
void SetModula(int x, int y, COLORREF fg, COLORREF bg)
Definition Wallpaper.cpp:367
COLORREF GetColorRef(LPSTR colorAsString)
Definition Wallpaper.cpp:196
void SetGradient(int type, bool interlaced, COLORREF from, COLORREF to)
Definition Wallpaper.cpp:455

◆ GetColorRef()

COLORREF Wallpaper::GetColorRef ( LPSTR colorAsString)
197{
198 COLORREF color;
199 if (colorAsString[0] == '#') color = strtol(&colorAsString[1], NULL, 16);
200 else color = strtol(colorAsString, NULL, 16);
201
202 return RGB(GetBValue(color), GetGValue(color), GetRValue(color)); // Convert to BGR format...
203}

◆ SetDesktopColor()

void Wallpaper::SetDesktopColor ( COLORREF color)
211{
212 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID)"(None)", SPIF_SENDCHANGE); // Remove any existing wallpaper
213 int lpaElements[1] = { COLOR_BACKGROUND };
214 COLORREF lpaRgbValues[1] = { color };
215
216 char colorAsString[10];
217 sprintf(colorAsString, "#%02x%02x%02x", (BYTE)GetRValue(color), (BYTE)GetGValue(color), (BYTE)GetBValue(color));
218
220 {
221 char msg[50];
222 sprintf(msg, "Setting the desktop colour to %s.", colorAsString);
223 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
224 }
225
226 // Remember the manually applied desktop colour as the "last applied" rootCommand in case Designer mode wants to Save it later on... (see Broams.cpp)
227 sprintf(pSettings->rootCommand, "bsetroot -solid %s", colorAsString);
229
230 SetSysColors(1, lpaElements, lpaRgbValues);
231}
bool CopyStringToClipboard(LPSTR string)
Definition BBApi.cpp:3450

◆ SetWallpaper()

void Wallpaper::SetWallpaper ( LPSTR wpPath,
LPSTR wpStyle )
239{
240 if (strchr(wpPath, '\"')) StrRemoveEncap(wpPath);
241 if (strchr(wpPath, '$')) ReplaceShellFolders(wpPath);
242 if (strchr(wpPath, '%')) ReplaceEnvVars(wpPath);
243
244 char path[MAX_PATH];
245 if (IsInString(wpPath, ":")) strcpy(path, wpPath); // Full path (i.e. includes ":" which is a reserved character for drive names)
246 else if (!IsInString(wpPath, "\\")) // Filename only -> Look for the image in the default wallpaper folder
247 {
248 strcpy(path, pSettings->wallpapersFolder);
249 strcat(path, "\\");
250 strcat(path, wpPath);
251 }
252 else if (!IsInString(wpPath, pSettings->SF_blackboxPath)) // Relative path from the Blackbox folder
253 {
254 strcpy(path, pSettings->SF_blackboxPath);
255 strcat(path, "\\");
256 strcat(path, wpPath);
257 }
258
259 if (!FileExists(path))
260 {
261 char msg[MAX_LINE_LENGTH];
262 sprintf(msg, "Error setting the desktop wallpaper - File not found! (%s).", path);
263 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)msg);
264 return;
265 }
266
267 //====================
268
269 int pointer = strlen(path) - 4;
270
271 // We only need to check the last 4 characters to get the extension...
272 // (we allow JPG/JPEG, PNG, and BMP files as wallpaper images)
273 if (!_stricmp(&path[pointer], ".jpg")
274 || !_stricmp(&path[pointer], ".png")
275 || !_stricmp(&path[pointer], ".bmp")
276 || !_stricmp(&path[pointer], "jpeg"))
277 {
278 /*
279 if (GetAsyncKeyState(VK_CONTROL) & 0x8000) strcpy(arguments, "-center "); // Is the control key held down? -> Centered mode
280 else if (GetAsyncKeyState(VK_SHIFT) & 0x8000) strcpy(arguments, "-full "); // Is the shift key held down? -> Stretched mode
281 else strcpy(arguments, "-tile "); // Default -> Tiled mode
282 */
283
284 char wallpaperStyle[10];
285
286 // Update the registry keys defining if the wallpaper should be tiled/centered/stretched...
287 // * WallpaperStyle key -> Fill 10, Fit 6, Stretch 2, Tile 0, Center 0, Span 22.
288 // * TileWallpaper key -> Set to 1 if Tile, 0 if any other setting.
289 HKEY key;
290 if (RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\Desktop\\", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
291 {
292 LSTATUS result;
293 if (IsInString(wpStyle, "tile"))
294 {
295 result = RegSetValueEx(key, "WallpaperStyle", 0, REG_SZ, (unsigned char*)"0", 2);
296 result = RegSetValueEx(key, "TileWallpaper", 0, REG_SZ, (unsigned char*)"1", 2);
297 strcpy(wallpaperStyle, "tiled");
298 }
299 else if (IsInString(wpStyle, "center"))
300 {
301 result = RegSetValueEx(key, "WallpaperStyle", 0, REG_SZ, (unsigned char*)"1", 2);
302 result = RegSetValueEx(key, "TileWallpaper", 0, REG_SZ, (unsigned char*)"0", 2);
303 strcpy(wallpaperStyle, "centered");
304 }
305 else if (IsInString(wpStyle, "span")) // -> A single wallpaper spanning across multiple monitors
306 {
307 result = RegSetValueEx(key, "WallpaperStyle", 0, REG_SZ, (unsigned char*)"22", 2);
308 result = RegSetValueEx(key, "TileWallpaper", 0, REG_SZ, (unsigned char*)"0", 2);
309 strcpy(wallpaperStyle, "spanned");
310 }
311 else // if (IsInString(wpStyle, "stretch") || IsInString(wpStyle, "full"))
312 {
313 result = RegSetValueEx(key, "WallpaperStyle", 0, REG_SZ, (unsigned char*)"2", 2);
314 result = RegSetValueEx(key, "TileWallpaper", 0, REG_SZ, (unsigned char*)"0", 2);
315 strcpy(wallpaperStyle, "stretched");
316 }
317
318 RegCloseKey(key);
319
320 if (result != ERROR_SUCCESS)
321 {
322 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)"Error writing to the wallpaper style registry keys!");
323 return;
324 }
325 }
326 else
327 {
328 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)"Error opening the wallpaper style registry keys!");
329 return;
330 }
331
332 // ...set the image to be the new desktop wallpaper...
334 {
335 char msg[1024];
336 if (IsInString(path, pSettings->SF_currentThemePath)) sprintf(msg, "Setting the desktop wallpaper to $CurrentTheme$%s (%s).", &path[strlen(pSettings->SF_currentThemePath)], wallpaperStyle);
337 else if (IsInString(path, pSettings->SF_blackboxPath)) sprintf(msg, "Setting the desktop wallpaper to $Blackbox$%s (%s).", &path[strlen(pSettings->SF_blackboxPath)], wallpaperStyle);
338 else sprintf(msg, "Setting the desktop wallpaper to %s (%s).", path, wallpaperStyle);
339 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
340 }
341 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)path, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
342
344 {
345 // ...and copy a matching rootCommand to the clipboard for
346 // possibly updating of a style in case it was a good match! =]
347 char* stylePtr = wpStyle;
348 if (wpStyle[0] == '-') stylePtr++;
349 char rootCmd[MAX_LINE_LENGTH];
350 if (IsInString(path, pSettings->SF_currentThemePath)) sprintf(rootCmd, "rootCommand: bsetbg -%s \"$CurrentTheme$%s\"", stylePtr, &path[strlen(pSettings->SF_currentThemePath)]);
351 else if (IsInString(path, pSettings->SF_blackboxPath)) sprintf(rootCmd, "rootCommand: bsetbg -%s \"%s\"", stylePtr, &path[strlen(pSettings->SF_blackboxPath) + 1]);
352 else sprintf(rootCmd, "rootCommand: bsetbg -%s \"%s\"", stylePtr, path);
353 CopyStringToClipboard(rootCmd);
354
355 // Finally, remember the manually applied wallpaper as the "last applied" rootCommand in case Designer mode wants to Save it later on... (see Broams.cpp)
356 strcpy(pSettings->rootCommand, &rootCmd[13]);
357 }
358 }
359 else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)"Error setting the desktop wallpaper - only JPG/JPEG, PNG and BMP files are supported.");
360}
bool FileExists(LPCSTR szFileName)
Definition BBApi.cpp:819
LPSTR StrRemoveEncap(LPSTR string)
Definition BBApi.cpp:406
void ReplaceEnvVars(LPSTR string)
Definition BBApi.cpp:2594
void ReplaceShellFolders(LPSTR string)
Definition BBApi.cpp:2633
char SF_currentThemePath[MAX_PATH]
Definition Settings.h:385
char wallpapersFolder[MAX_PATH]
Definition Settings.h:321
char SF_blackboxPath[MAX_PATH]
Definition Settings.h:377

◆ SetModula()

void Wallpaper::SetModula ( int x,
int y,
COLORREF fg,
COLORREF bg )
368{
369 PAINTSTRUCT ps;
370 HWND dwnd = GetDesktopWindow();
371 HDC hdc = BeginPaint(dwnd, &ps);
372 HDC buf = CreateCompatibleDC(NULL);
373 PBYTE pixels;
374
375// int width = GetSystemMetrics(SM_CXSCREEN);
376// int height = GetSystemMetrics(SM_CYSCREEN);
377 int width = x;
378 int height = y;
379 if (pSettings->scalingFactorHiDPI > 1) // Adapt bsetroot parameters to the current HiDPI scaling factor? (-> aligned with scaling aware style rendering etc)
380 {
382 height *= pSettings->scalingFactorHiDPI;
383 }
384
385 BITMAPINFOHEADER bv4info;
386 bv4info.biSize = sizeof(BITMAPINFOHEADER);
387 bv4info.biWidth = width;
388 bv4info.biHeight = height;
389 bv4info.biPlanes = 1;
390 bv4info.biBitCount = 32;
391 bv4info.biCompression = BI_RGB;
392
393 BITMAPINFO bminfo;
394 bminfo.bmiHeader = bv4info;
395
396 HBITMAP bitmap = CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, (PVOID*)&pixels, NULL, 0);
397 if (bitmap) SelectObject(buf, bitmap);
398
399 //====================
400
401 int count = 0;
402// for (int vertical = 1; vertical < height; vertical++)
403 for (int vertical = 0; vertical < height; vertical++)
404 {
405 for (int horizontal = 0; horizontal < width; horizontal++)
406 {
407// if ((vertical % y) == 0)
408 if ((vertical == 0) || (pSettings->doubleScaleHiDPI && (vertical == 1)))
409 {
410 pixels[count + 2] = GetRValue(fg);
411 pixels[count + 1] = GetGValue(fg);
412 pixels[count] = GetBValue(fg);
413 }
414 else
415 {
416// if ((horizontal % x) == 0)
417 if ((horizontal == 0) || (pSettings->doubleScaleHiDPI && (horizontal == 1)))
418 {
419 pixels[count + 2] = GetRValue(fg);
420 pixels[count + 1] = GetGValue(fg);
421 pixels[count] = GetBValue(fg);
422 }
423 else
424 {
425 pixels[count + 2] = GetRValue(bg);
426 pixels[count + 1] = GetGValue(bg);
427 pixels[count] = GetBValue(bg);
428 }
429 }
430 count += 4;
431 }
432 }
433
434 //====================
435
436 char path[MAX_PATH];
437 GetBlackboxPath(path, sizeof(path));
438 strcat(path, "bsetroot.bmp");
439
440 PBITMAPINFO pbmpi = CreateBitmapInfoStruct(bitmap);
441 CreateBMPFile(path, pbmpi, bitmap);
442
443 DeleteDC(buf);
444 DeleteObject(bitmap);
445 EndPaint(dwnd, &ps);
446
447 SetWallpaper(path, "tile");
448}
bool WINAPI GetBlackboxPath(LPSTR pszPath, int nMaxLen)
Definition BBApi.cpp:214
int scalingFactorHiDPI
Definition Settings.h:327
bool doubleScaleHiDPI
Definition Settings.h:326
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBitmap)
Definition Wallpaper.cpp:468
void CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBitmap)
Definition Wallpaper.cpp:510

◆ SetGradient()

void Wallpaper::SetGradient ( int type,
bool interlaced,
COLORREF from,
COLORREF to )
456{
457 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"Sorry, bsetroot -gradient is not yet supported... (stay tuned).");
458 return;
459}
#define CONSOLE_INFORMATION_MESSAGE
Definition BBApi.h:298

◆ CreateBitmapInfoStruct()

PBITMAPINFO Wallpaper::CreateBitmapInfoStruct ( HBITMAP hBitmap)
469{
470 BITMAP bmp;
471 PBITMAPINFO pbmi;
472
473 // Retrieve the bitmap's color format, width and height...
474 if (!GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bmp)) return NULL;
475
476 // Convert the bitmap's color format to depth in bits...
477 WORD cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
478 if (cClrBits == 1) cClrBits = 1;
479 else if (cClrBits <= 4) cClrBits = 4;
480 else if (cClrBits <= 8) cClrBits = 8;
481 else if (cClrBits <= 16) cClrBits = 16;
482 else if (cClrBits <= 24) cClrBits = 24;
483 else cClrBits = 32;
484
485 // Allocate memory for the BITMAPINFO structure... (this contains a BITMAPINFOHEADER structure and an array of RGBQUAD data structures)
486 if (cClrBits != 24) pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * (1 << cClrBits)));
487 else pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)); // There is no RGBQUAD array for the 24-bit-per-pixel format...
488
489 // Initialize the fields in the BITMAPINFO structure...
490 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
491 pbmi->bmiHeader.biWidth = bmp.bmWidth;
492 pbmi->bmiHeader.biHeight = bmp.bmHeight;
493 pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
494 pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
495 pbmi->bmiHeader.biCompression = BI_RGB; // The bitmap is not compressed
496 pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits + 31) & ~31) / 8 * pbmi->bmiHeader.biHeight;
497 if (cClrBits < 16) pbmi->bmiHeader.biClrUsed = (1 << cClrBits);
498 pbmi->bmiHeader.biClrImportant = 0;
499
500 return pbmi;
501}

◆ CreateBMPFile()

void Wallpaper::CreateBMPFile ( LPTSTR pszFile,
PBITMAPINFO pbi,
HBITMAP hBitmap )
511{
512 HANDLE hf; // File handle
513 BITMAPFILEHEADER hdr; // Bitmap file-header
514 PBITMAPINFOHEADER pbih; // Bitmap info-header
515 LPBYTE lpBits; // Memory pointer
516 DWORD dwTotal; // Total count of bytes
517 DWORD cb; // Incremental count of bytes
518 BYTE* hp; // Byte pointer
519 DWORD dwTmp;
520
521 HDC hDC;
522
523 pbih = (PBITMAPINFOHEADER)pbi;
524 lpBits = (LPBYTE)GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
525 if (!lpBits) return;
526
527 hDC = CreateCompatibleDC(NULL);
528
529 if (!GetDIBits(hDC, hBitmap, 0, (WORD)pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS))
530 {
531 DeleteDC(hDC);
532 GlobalFree((HGLOBAL)lpBits);
533 }
534
535 // Create the .bmp file...
536 hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD)0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
537 if (hf != INVALID_HANDLE_VALUE)
538 {
539 hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
540
541 // Calculate the size of the entire file...
542 hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage);
543 hdr.bfReserved1 = 0;
544 hdr.bfReserved2 = 0;
545
546 // Calculate the offset to the array of color indices...
547 hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD);
548
549 // Copy the BITMAPFILEHEADER into the file...
550 if (WriteFile(hf, (LPVOID)&hdr, sizeof(BITMAPFILEHEADER), (LPDWORD)&dwTmp, NULL))
551 {
552 // Copy the BITMAPINFOHEADER and RGBQUAD array into the file...
553 if (WriteFile(hf, (LPVOID)pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof(RGBQUAD), (LPDWORD)&dwTmp, (NULL)))
554 {
555 // Copy the array of color indices into the file...
556 dwTotal = cb = pbih->biSizeImage;
557 hp = lpBits;
558 if (WriteFile(hf, (LPSTR)hp, (int)cb, (LPDWORD)&dwTmp, NULL))
559 {
560 // Close the file...
561 CloseHandle(hf);
562 }
563 }
564 }
565 }
566
567 DeleteDC(hDC);
568 GlobalFree((HGLOBAL)lpBits);
569}