1: /*
     2:  ============================================================================
     3:  xoblite™ -> an advanced "extended shell" for Microsoft® Windows® 11
     4:  Copyright © 2002-2026 Karl Henrik Henriksson [qwilk/@xoblite]
     5:  Copyright © 2001-2004 The Blackbox for Windows Development Team
     6:  http://xoblite.net/ + https://github.com/xoblite/
     7:  ============================================================================
     8: 
     9:   Blackbox for Windows is free software, released under the
    10:   GNU General Public License (GPL version 2 or later), with an extension
    11:   that allows linking of proprietary modules under a controlled interface.
    12:   What this means is that plugins etc. are allowed to be released
    13:   under any license the author wishes. Please note, however, that the
    14:   original Blackbox gradient math code used in Blackbox for Windows
    15:   is available under the BSD license.
    16: 
    17:   http://www.fsf.org/licenses/gpl.html
    18:   http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
    19:   http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
    20: 
    21:   This program is distributed in the hope that it will be useful,
    22:   but WITHOUT ANY WARRANTY; without even the implied warranty of
    23:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    24:   GNU General Public License for more details.
    25: 
    26:   For additional license information, please read the included license.html.
    27: 
    28:  ============================================================================
    29: */
    30: 
    31: #include "Broams.h" 
    32: #include <io.h> 
    33: 
    34: extern Settings *pSettings;
    35: extern MenuCommon* pMenuCommon;
    36: extern Dock *pDock;
    37: extern Console *pConsole;
    38: extern Desktop* pDesktop;
    39: extern PluginManager *pPluginManager;
    40: extern Toolbar *pToolbar;
    41: extern Taskbar *pTaskbar;
    42: extern Tooltips* pTooltips;
    43: extern Workspaces* pWorkspaces;
    44: extern Hotkeys* pHotkeys;
    45: extern Wallpaper* pWallpaper;
    46: 
    47: unsigned int numberOfFiles, currentFile, randomFile;
    48: char pathToScan[MAX_PATH];
    49: char pathToFile[MAX_PATH];
    50: 
    51: //===========================================================================
    52: // Function: ExecuteBroam
    53: // Purpose: Executes all broadcast messages (bro@ms) targeting the core shell
    54: //===========================================================================
    55: 
    56: bool ExecuteBroam(LPSTR broam, HINSTANCE hMainInstance)
    57: {
    58:     if (pSettings) pSettings->Statistics.executedBroams++; // Update statistics
    59: 
    60:     if (!_strnicmp(broam, "@xoblite", 8)) // xoblite core bro@ms
    61:     {
    62:         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)broam); // Display the bro@m in the console...
    63: 
    64:         static char msg[MAX_LINE_LENGTH];
    65:         char token1[MAX_LINE_LENGTH], token2[MAX_LINE_LENGTH], token3[MAX_LINE_LENGTH], token4[MAX_LINE_LENGTH], extra[MAX_LINE_LENGTH];
    66:         LPSTR tokens[4];
    67:         tokens[0] = token1;
    68:         tokens[1] = token2;
    69:         tokens[2] = token3;
    70:         tokens[3] = token4;
    71: 
    72:         token1[0] = token2[0] = token3[0] = token4[0] = extra[0] = '\0';
    73:         BBTokenize(broam, tokens, 4, extra);
    74: 
    75:         //====================
    76: 
    77:         if (!_stricmp(token2, "About"))
    78:         {
    79:             if (!_stricmp(token3, "Plugins"))
    80:             {
    81:                 if (pPluginManager) pPluginManager->AboutPlugins();
    82:             }
    83:             else if (!_stricmp(token3, "Style"))
    84:             {
    85:                 char aboutStyle[MAX_LINE_LENGTH], a1[MAX_LINE_LENGTH], a2[MAX_LINE_LENGTH], a3[MAX_LINE_LENGTH], a4[MAX_LINE_LENGTH], a5[MAX_LINE_LENGTH];
    86:                 strcpy_s(a1, sizeofArray(a1), ReadString(pSettings->styleFile, "style.name:", "[Style name not specified]"));
    87:                 strcpy_s(a2, sizeofArray(a2), ReadString(pSettings->styleFile, "style.author:", "[Author not specified]"));
    88:                 strcpy_s(a3, sizeofArray(a3), ReadString(pSettings->styleFile, "style.date:", ""));
    89:                 strcpy_s(a4, sizeofArray(a4), ReadString(pSettings->styleFile, "style.credits:", ""));
    90:                 strcpy_s(a5, sizeofArray(a5), ReadString(pSettings->styleFile, "style.comments:", ""));
    91:                 sprintf_s(aboutStyle, sizeofArray(aboutStyle), "%s   \nby %s   \n%s   \n\n%s   \n\n%s   ", a1, a2, a3, a4, a5);
    92:                 SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"About the current style...", (LPARAM)aboutStyle);
    93:             }
    94:             else if (!_stricmp(token3, "Hide"))
    95:             {
    96:                 SendMessage(GetBBWnd(), BB_POPUPMESSAGE, NULL, NULL); // Hide any visible About popup dialogs... (this can be useful e.g. for certain @Script's)
    97:             }
    98:             else
    99:             {
   100:                 char buffer[MAX_LINE_LENGTH];
   101:                 ULONG* size = 0;
   102:                 DWORD number = GetFileVersionInfoSize("Blackbox.exe", size);
   103:                 GetFileVersionInfo("Blackbox.exe", NULL, number, (LPVOID)buffer);
   104:                 void* value;
   105:                 UINT bytes;
   106:                 VerQueryValue(buffer, TEXT("\\StringFileInfo\\000004b0\\FileVersion"), &value, &bytes); // Make sure the correct version encoding is used (currently "000004b0" = language neutral)
   107: 
   108:                 char title[32];
   109:                 strcpy_s(title, sizeofArray(title), "About xoblite...");
   110:                 char body[MAX_LINE_LENGTH];
   111: 
   112:                 if (pSettings->debugLogging)
   113:                 {
   114:                     char buildType[32];
   115:                     if (pSettings->runningUnderWOW64) strcpy_s(buildType, sizeofArray(buildType), "64-bit on ");
   116:                     else strcpy_s(buildType, sizeofArray(buildType), "32-bit on ");
   117:                     if (pSettings->machineArchitecture == IMAGE_FILE_MACHINE_I386) strcat_s(buildType, sizeofArray(buildType), "Intel CPU");
   118:                     else if (pSettings->machineArchitecture == IMAGE_FILE_MACHINE_AMD64) strcat_s(buildType, sizeofArray(buildType), "AMD CPU");
   119:                     else if (pSettings->machineArchitecture == IMAGE_FILE_MACHINE_ARM64) strcat_s(buildType, sizeofArray(buildType), "ARM CPU");
   120:                     else strcat_s(buildType, sizeofArray(buildType), "unknown CPU");
   121: 
   122:                     sprintf_s(body, sizeofArray(body), "xoblite\x99 %s | %s\n", (LPCSTR)value, buildType); // Note: We currently do not offer x64 (64-bit) nor ARM builds, but maybe later...?
   123:                 }
   124:                 else sprintf_s(body, sizeofArray(body), "xoblite\x99 %s\n", (LPCSTR)value);
   125: 
   126:                 strcat_s(body, sizeofArray(body),
   127:                     "\xA9 2002-2026 Karl Henrik Henriksson [qwilk/@xoblite]\n"
   128:                     "\xA9 2001-2004 The Blackbox for Windows Development Team\n\n"
   129:                     "Contains a heavily modified version of the BImage rendering engine\n"
   130:                     "used in the original \"Blackbox\" window manager for the X Window System\n"
   131:                     "\xA9 1997-2000 Bradley T Hughes\n"
   132:                     "\xA9 2001-2002 Sean 'Shaleh' Perry\n\n"
   133:                     "More information about xoblite can be found in the documentation... :)\n\n"
   134:                     "http://xoblite.net/\n"
   135:                     "https://github.com/xoblite/ (used for issue reporting only)");     // Note: Used for issue reporting only; for various reasons the source code documentation etc is nowadays back on xoblite.net
   136:                 SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)title, (LPARAM)body);
   137:             }
   138: 
   139:             return true;
   140:         }
   141: 
   142:         //====================
   143: 
   144:         else if (!_stricmp(token2, "Run"))
   145:         {
   146:             CreateRunBox(hMainInstance, NULL, ""); // No input string here -> Starts with last entered command, all selected.
   147:             return true;
   148:         }
   149: 
   150:         //====================
   151: 
   152:         else if (!_stricmp(token2, "CheckForUpdates"))
   153:         {
   154:             bool silent = false;
   155:             _beginthread(checkForUpdates, 0, &silent);
   156:             return true;
   157:         }
   158: 
   159:         //====================
   160: 
   161:         else if (!_stricmp(token2, "LoadPlugin"))
   162:         {
   163:             if (strnlen_s(token3, sizeofArray(token3))) pPluginManager->LoadPlugin(token3);
   164:             else
   165:             {
   166:                 if (pMenuCommon) pMenuCommon->Hide();
   167:                 pPluginManager->LoadPluginDialog();
   168:             }
   169:             return true;
   170:         }
   171:         else if (!_stricmp(token2, "UnloadPlugin"))
   172:         {
   173:             if (token3[0] == '#')
   174:             {
   175:                 int pluginNumber = atoi(&token3[1]) - 1;  // Nb. Using more human friendly 1-N numbering for the UnloadPlugin bro@ms!
   176: 
   177:                 if (!_stricmp(token4, "<Yes>")) pPluginManager->UnloadPlugin(NULL, pluginNumber); // <- User answering "Yes" when asked if he/she wants to unload the specified plugin...
   178:                 else
   179:                 {
   180:                     char msg[MAX_LINE_LENGTH], pluginName[MAX_LINE_LENGTH];
   181:                     strcpy_s(pluginName, sizeofArray(pluginName), pPluginManager->GetPluginInfo(pluginNumber, PLUGIN_NAME));
   182:                     sprintf_s(msg, sizeofArray(msg), "Are you sure you want to unload %s?", pluginName);
   183: 
   184:                     char popupBroam[MAX_LINE_LENGTH];
   185:                     sprintf_s(popupBroam, sizeofArray(popupBroam), "@xoblite UnloadPlugin %s <Yes>", token3);
   186: 
   187:                     SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)msg, (LPARAM)popupBroam);
   188:                 }
   189:             }
   190:             else pPluginManager->UnloadPlugin(token3, -1);
   191: 
   192:             return true;
   193:         }
   194:         else if (!_stricmp(token2, "TogglePluginLoaded"))
   195:         {
   196:             char path[MAX_LINE_LENGTH];
   197:             if (strnlen_s(extra, sizeofArray(extra))) sprintf_s(path, sizeofArray(path), "%s %s %s", token3, token4, extra);
   198:             else if (strnlen_s(token4, sizeofArray(token4))) sprintf_s(path, sizeofArray(path), "%s %s", token3, token4);
   199:             else strcpy_s(path, sizeofArray(path), token3);
   200: 
   201:             if (strnlen_s(path, sizeofArray(path)))
   202:             {
   203:                 if (strchr(path, '\"')) StrRemoveEncap(path);
   204:                 if (strchr(path, '$')) ReplaceShellFolders(path);
   205:                 if (strchr(path, '%')) ReplaceEnvVars(path);
   206: 
   207:                 if (pPluginManager->IsPluginLoaded(path)) pPluginManager->UnloadPlugin(path, -1);
   208:                 else pPluginManager->LoadPlugin(path);
   209:             }
   210: 
   211:             return true;
   212:         }
   213: 
   214: 
   215:         //====================
   216: 
   217:         else if (!_stricmp(token2, "Toolbar"))
   218:         {
   219:             if (!_stricmp(token3, "Hide") && !pSettings->toolbarHidden) PostMessage(GetBBWnd(), BB_TOGGLETOOLBAR, 0, 0);
   220:             else if (!_stricmp(token3, "Show") && pSettings->toolbarHidden) PostMessage(GetBBWnd(), BB_TOGGLETOOLBAR, 0, 0);
   221:             else if (!_stricmp(token3, "Toggle"))
   222:             {
   223:                 if (strnlen_s(token4, sizeofArray(token4)) > 0)
   224:                 {
   225:                     if (!_stricmp(token4, "Label")) // -> Toggle the toolbar workspace label...
   226:                     {
   227:                         if (!pSettings->toolbarLabelHidden) pSettings->toolbarLabelHidden = true;
   228:                         else pSettings->toolbarLabelHidden = false;
   229:                         WriteBool(pSettings->xobrcFile, "xoblite.toolbar.label.hidden:", pSettings->toolbarLabelHidden);
   230:                     }
   231:                     else if (!_stricmp(token4, "DownUp")) // -> Toggle the toolbar workspace selection buttons... (i.e. the leftmost buttons with "down/up" arrows)
   232:                     {
   233:                         if (!pSettings->toolbarDownUpButtonsHidden) pSettings->toolbarDownUpButtonsHidden = true;
   234:                         else pSettings->toolbarDownUpButtonsHidden = false;
   235:                         WriteBool(pSettings->xobrcFile, "xoblite.toolbar.downup.buttons.hidden:", pSettings->toolbarDownUpButtonsHidden);
   236:                     }
   237:                     else if (!_stricmp(token4, "LeftRight")) // -> Toggle the toolbar taskbar mode selection buttons... (i.e. the rightmost buttons with "left/right" arrows)
   238:                     {
   239:                         if (!pSettings->toolbarLeftRightButtonsHidden) pSettings->toolbarLeftRightButtonsHidden = true;
   240:                         else pSettings->toolbarLeftRightButtonsHidden = false;
   241:                         WriteBool(pSettings->xobrcFile, "xoblite.toolbar.leftright.buttons.hidden:", pSettings->toolbarLeftRightButtonsHidden);
   242:                     }
   243:                     else if (!_stricmp(token4, "Clock")) // -> Toggle the toolbar clock...
   244:                     {
   245:                         if (!pSettings->toolbarClockHidden) pSettings->toolbarClockHidden = true;
   246:                         else pSettings->toolbarClockHidden = false;
   247:                         WriteBool(pSettings->xobrcFile, "xoblite.toolbar.clock.hidden:", pSettings->toolbarClockHidden);
   248:                     }
   249:                     else if (!_stricmp(token4, "Asymmetry")) // -> Toggle toolbar label/clock assymetry allowed...
   250:                     {
   251:                         if (!pSettings->toolbarAllowAsymmetry) pSettings->toolbarAllowAsymmetry = true;
   252:                         else pSettings->toolbarAllowAsymmetry = false;
   253:                         WriteBool(pSettings->xobrcFile, "xoblite.toolbar.allow.asymmetry:", pSettings->toolbarAllowAsymmetry);
   254:                     }
   255: 
   256:                     pToolbar->UpdatePosition();
   257:                     PlaySoundFX(SFX_TOGGLE_ELEMENT);
   258:                 }
   259:                 else PostMessage(GetBBWnd(), BB_TOGGLETOOLBAR, 0, 0); // -> Toggle the toolbar itself...
   260:             }
   261:             else if (!_stricmp(token3, "Placement"))
   262:             {
   263:                 char placement[255];
   264:                 sprintf_s(placement, sizeofArray(placement), "%s %s", token4, extra); // <- We need to merge these back as Manual placements include space chars in them!
   265:                 pSettings->ParsePlacement(placement, &pSettings->ToolbarPlacement);
   266:                 pSettings->WritePlacement(&pSettings->ToolbarPlacement);
   267:                 pToolbar->UpdatePosition();
   268:                 if (pDock && (pSettings->DockPlacement.placement == PLACEMENT_OPPOSITE_TOOLBAR)) pDock->UpdatePosition();
   269:                 pDesktop->UpdateDesktopWindow(); // In case e.g. the workspace indicators need to be moved given the new toolbar placement
   270:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   271:             }
   272:             else if (!_stricmp(token3, "Orientation"))
   273:             {
   274:                 if (!_stricmp(token4, "Vertical")) pSettings->toolbarVertical = true;
   275:                 else pSettings->toolbarVertical = false;
   276:                 pToolbar->UpdatePosition();
   277:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   278:                 WriteBool(pSettings->xobrcFile, "xoblite.toolbar.vertical:", pSettings->toolbarVertical);
   279:             }
   280:             else if (!_stricmp(token3, "ToggleOrientation"))
   281:             {
   282:                 if (!pSettings->toolbarVertical) pSettings->toolbarVertical = true;
   283:                 else pSettings->toolbarVertical = false;
   284:                 pToolbar->UpdatePosition();
   285:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   286:                 WriteBool(pSettings->xobrcFile, "xoblite.toolbar.vertical:", pSettings->toolbarVertical);
   287:             }
   288:             else if (!_stricmp(token3, "Width"))
   289:             {
   290:                 int screenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
   291:                 int width = atoi(token4);
   292: 
   293:                 if (!pSettings->toolbarVertical) // Toolbar in horizontal orientation
   294:                 {
   295:                     if (width <= 100) // -> Parse width value as % of screen width (minimum 30% of screen width, maximum 100% of screen width)
   296:                     {
   297:                         if (width < 30) width = 30;
   298:                     }
   299:                     else // if (width > 100) -> Parse width value as number of pixels (again, minimum 30% of screen width, maximum 100% of screen width)
   300:                     {
   301:                         int minWidth = (screenWidth * 30) / 100;
   302:                         if (width < minWidth) width = minWidth;
   303:                         else if (width > screenWidth) width = screenWidth;
   304:                     }
   305: 
   306:                     if (width != pSettings->toolbarHorizontalWidth)
   307:                     {
   308:                         pSettings->toolbarHorizontalWidth = width;
   309:                         pToolbar->UpdateWidth(); // This will also save the new value to xoblite.rc
   310:                     }
   311:                 }
   312:                 else // Toolbar in vertical orientation
   313:                 {
   314:                     if (width <= 100) // -> Parse width value as % of screen width (minimum 5% of screen width, maximum 25% of screen width)
   315:                     {
   316:                         if (width < 5) width = 5;
   317:                         else if (width > 25) width = 25;
   318:                     }
   319:                     else // if (width > 100) -> Parse width value as number of pixels (again, minimum 5% of screen width, maximum 25% of screen width)
   320:                     {
   321:                         int minWidth = (screenWidth * 5) / 100;
   322:                         int maxWidth = (screenWidth * 25) / 100;
   323:                         if (width < minWidth) width = minWidth;
   324:                         else if (width > maxWidth) width = maxWidth;
   325:                     }
   326: 
   327:                     if (width != pSettings->toolbarVerticalWidth)
   328:                     {
   329:                         pSettings->toolbarVerticalWidth = width;
   330:                         pToolbar->UpdateWidth(); // This will also save the new value to xoblite.rc
   331:                     }
   332:                 }
   333:             }
   334:             else if (!_stricmp(token3, "Transparency"))
   335:             {
   336:                 if (!_stricmp(token4, "Label")) // -> Alpha transparency for the toolbar label (i.e. using per pixel alpha)
   337:                 {
   338:                     pSettings->toolbarLabelTransparencyAlpha = atoi(extra);
   339:                     WriteInt(pSettings->xobrcFile, "xoblite.toolbar.label.transparency.alpha:", pSettings->toolbarLabelTransparencyAlpha);
   340:                 }
   341:                 else if (!_stricmp(token4, "WindowLabel")) // -> Alpha transparency for the toolbar windowLabel (i.e. using per pixel alpha)
   342:                 {
   343:                     pSettings->toolbarWindowLabelTransparencyAlpha = atoi(extra);
   344:                     WriteInt(pSettings->xobrcFile, "xoblite.toolbar.windowlabel.transparency.alpha:", pSettings->toolbarWindowLabelTransparencyAlpha);
   345:                 }
   346:                 else if (!_stricmp(token4, "Clock")) // -> Alpha transparency for the toolbar clock (i.e. using per pixel alpha)
   347:                 {
   348:                     pSettings->toolbarClockTransparencyAlpha = atoi(extra);
   349:                     WriteInt(pSettings->xobrcFile, "xoblite.toolbar.clock.transparency.alpha:", pSettings->toolbarClockTransparencyAlpha);
   350:                 }
   351:                 else if (!_stricmp(token4, "Button")) // -> Alpha transparency for the toolbar buttons (i.e. using per pixel alpha)
   352:                 {
   353:                     pSettings->toolbarButtonTransparencyAlpha = atoi(extra);
   354:                     WriteInt(pSettings->xobrcFile, "xoblite.toolbar.button.transparency.alpha:", pSettings->toolbarButtonTransparencyAlpha);
   355:                 }
   356:                 else if (!_stricmp(token4, "ActiveTask")) // -> Alpha transparency for the taskbar's currently active task (i.e. using per pixel alpha)
   357:                 {
   358:                     pSettings->taskbarActiveTransparencyAlpha = atoi(extra);
   359:                     WriteInt(pSettings->xobrcFile, "xoblite.taskbar.active.transparency.alpha:", pSettings->taskbarActiveTransparencyAlpha);
   360:                 }
   361:                 else // -> Alpha transparency for the toolbar itself (cf. regular window level alpha, but here using per pixel alpha applied before the other toolbar element's per pixel alpha's)
   362:                 {
   363:                     pSettings->toolbarTransparencyAlpha = atoi(token4);
   364:                     WriteInt(pSettings->xobrcFile, "xoblite.toolbar.transparency.alpha:", pSettings->toolbarTransparencyAlpha);
   365:                 }
   366: 
   367:                 if (pToolbar) pToolbar->UpdateToolbarWindow();
   368:             }
   369:             else if (!_stricmp(token3, "Label"))
   370:             {
   371:                 if (!_stricmp(token4, "Click"))
   372:                 {
   373:                     char button[MAX_LINE_LENGTH], command[MAX_LINE_LENGTH];
   374:                     LPSTR override[1];
   375:                     override[0] = button;
   376:                     button[0] = command[0] = '\0';
   377:                     BBTokenize(extra, override, 1, command);
   378: 
   379:                     if (!_stricmp(button, "DL"))
   380:                     {
   381:                         strcpy_s(pSettings->toolbarLabelDLClickOverride, sizeofArray(pSettings->toolbarLabelDLClickOverride), command);
   382:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.label.dlclick.override:", pSettings->toolbarLabelDLClickOverride);
   383:                         return true;
   384:                     }
   385:                     else if (!_stricmp(button, "R"))
   386:                     {
   387:                         strcpy_s(pSettings->toolbarLabelRClickOverride, sizeofArray(pSettings->toolbarLabelRClickOverride), command);
   388:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.label.rclick.override:", pSettings->toolbarLabelRClickOverride);
   389:                         return true;
   390:                     }
   391:                     else if (!_stricmp(button, "M"))
   392:                     {
   393:                         strcpy_s(pSettings->toolbarLabelMClickOverride, sizeofArray(pSettings->toolbarLabelMClickOverride), command);
   394:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.label.mclick.override:", pSettings->toolbarLabelMClickOverride);
   395:                         return true;
   396:                     }
   397:                     else if (!_stricmp(button, "X1"))
   398:                     {
   399:                         strcpy_s(pSettings->toolbarLabelX1ClickOverride, sizeofArray(pSettings->toolbarLabelX1ClickOverride), command);
   400:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.label.x1click.override:", pSettings->toolbarLabelX1ClickOverride);
   401:                         return true;
   402:                     }
   403:                     else if (!_stricmp(button, "X2"))
   404:                     {
   405:                         strcpy_s(pSettings->toolbarLabelX2ClickOverride, sizeofArray(pSettings->toolbarLabelX2ClickOverride), command);
   406:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.label.x2click.override:", pSettings->toolbarLabelX2ClickOverride);
   407:                         return true;
   408:                     }
   409:                 }
   410:             }
   411:             else if (!_stricmp(token3, "Clock"))
   412:             {
   413:                 if (!_stricmp(token4, "Click"))
   414:                 {
   415:                     char button[MAX_LINE_LENGTH], command[MAX_LINE_LENGTH];
   416:                     LPSTR override[1];
   417:                     override[0] = button;
   418:                     button[0] = command[0] = '\0';
   419:                     BBTokenize(extra, override, 1, command);
   420: 
   421:                     if (!_stricmp(button, "DL"))
   422:                     {
   423:                         strcpy_s(pSettings->toolbarClockDLClickOverride, sizeofArray(pSettings->toolbarClockDLClickOverride), command);
   424:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.clock.dlclick.override:", pSettings->toolbarClockDLClickOverride);
   425:                         return true;
   426:                     }
   427:                     else if (!_stricmp(button, "R"))
   428:                     {
   429:                         strcpy_s(pSettings->toolbarClockRClickOverride, sizeofArray(pSettings->toolbarClockRClickOverride), command);
   430:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.clock.rclick.override:", pSettings->toolbarClockRClickOverride);
   431:                         return true;
   432:                     }
   433:                     else if (!_stricmp(button, "M"))
   434:                     {
   435:                         strcpy_s(pSettings->toolbarClockMClickOverride, sizeofArray(pSettings->toolbarClockMClickOverride), command);
   436:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.clock.mclick.override:", pSettings->toolbarClockMClickOverride);
   437:                         return true;
   438:                     }
   439:                     else if (!_stricmp(button, "X1"))
   440:                     {
   441:                         strcpy_s(pSettings->toolbarClockX1ClickOverride, sizeofArray(pSettings->toolbarClockX1ClickOverride), command);
   442:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.clock.x1click.override:", pSettings->toolbarClockX1ClickOverride);
   443:                         return true;
   444:                     }
   445:                     else if (!_stricmp(button, "X2"))
   446:                     {
   447:                         strcpy_s(pSettings->toolbarClockX2ClickOverride, sizeofArray(pSettings->toolbarClockX2ClickOverride), command);
   448:                         WriteString(pSettings->xobrcFile, "xoblite.toolbar.clock.x2click.override:", pSettings->toolbarClockX2ClickOverride);
   449:                         return true;
   450:                     }
   451:                 }
   452:             }
   453:             else if (!_stricmp(token3, "Button"))
   454:             {
   455:                 if (!_stricmp(token4, "Down"))
   456:                 {
   457:                     strcpy_s(pSettings->toolbarDownButtonOverride, sizeofArray(pSettings->toolbarDownButtonOverride), extra);
   458:                     WriteString(pSettings->xobrcFile, "xoblite.toolbar.downbutton.override:", pSettings->toolbarDownButtonOverride);
   459:                     return true;
   460:                 }
   461:                 else if (!_stricmp(token4, "Up"))
   462:                 {
   463:                     strcpy_s(pSettings->toolbarUpButtonOverride, sizeofArray(pSettings->toolbarUpButtonOverride), extra);
   464:                     WriteString(pSettings->xobrcFile, "xoblite.toolbar.upbutton.override:", pSettings->toolbarUpButtonOverride);
   465:                     return true;
   466:                 }
   467:                 else if (!_stricmp(token4, "Left"))
   468:                 {
   469:                     strcpy_s(pSettings->toolbarLeftButtonOverride, sizeofArray(pSettings->toolbarLeftButtonOverride), extra);
   470:                     WriteString(pSettings->xobrcFile, "xoblite.toolbar.leftbutton.override:", pSettings->toolbarLeftButtonOverride);
   471:                     return true;
   472:                 }
   473:                 else if (!_stricmp(token4, "Right"))
   474:                 {
   475:                     strcpy_s(pSettings->toolbarRightButtonOverride, sizeofArray(pSettings->toolbarRightButtonOverride), extra);
   476:                     WriteString(pSettings->xobrcFile, "xoblite.toolbar.rightbutton.override:", pSettings->toolbarRightButtonOverride);
   477:                     return true;
   478:                 }
   479:             }
   480:             else if (!_stricmp(token3, "MoveToMouse"))
   481:             {
   482:                 pToolbar->MoveToMouse();
   483:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   484:             }
   485:             else if (!_stricmp(token3, "MoveToTop"))
   486:             {
   487:                 SetForegroundWindow(pToolbar->hToolbarWnd);
   488:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   489:             }
   490:             else if (!_stricmp(token3, "ToggleRoundedCorners"))
   491:             {
   492:                 if (!pSettings->toolbarRoundedCorners) pSettings->toolbarRoundedCorners = true;
   493:                 else pSettings->toolbarRoundedCorners = false;
   494:                 pToolbar->UpdatePosition();
   495:                 WriteBool(pSettings->xobrcFile, "xoblite.toolbar.rounded:", pSettings->toolbarRoundedCorners);
   496:             }
   497:             else if (!_stricmp(token3, "ToggleAlwaysOnTop")) pToolbar->ToggleAlwaysOnTop();
   498:             else if (!_stricmp(token3, "ToggleSnapToEdges"))
   499:             {
   500:                 if (!pSettings->toolbarSnapToEdges) pSettings->toolbarSnapToEdges = true;
   501:                 else pSettings->toolbarSnapToEdges = false;
   502:                 WriteBool(pSettings->xobrcFile, "xoblite.toolbar.snapToEdges:", pSettings->toolbarSnapToEdges);
   503:             }
   504: 
   505:             return true;
   506:         }
   507: 
   508:         //====================
   509: 
   510:         else if (!_stricmp(token2, "Taskbar"))
   511:         {
   512:             if (!_stricmp(token3, "Hide"))
   513:             {
   514:                 pTaskbar->ChangeTaskbarMode(TASKBAR_MODE_HIDDEN); // Hide the taskbar == Show the toolbar.windowLabel instead...
   515:             }
   516:             else if (!_stricmp(token3, "Mode"))
   517:             {
   518:                 if (!_stricmp(token4, "Bars")) pTaskbar->ChangeTaskbarMode(TASKBAR_MODE_BARS);
   519:                 else if (!_stricmp(token4, "Bars+Icons")) pTaskbar->ChangeTaskbarMode(TASKBAR_MODE_BARSICONS);
   520:                 else if (!_stricmp(token4, "Icons")) pTaskbar->ChangeTaskbarMode(TASKBAR_MODE_ICONS);
   521:                 else if (!_stricmp(token4, "Hidden")) pTaskbar->ChangeTaskbarMode(TASKBAR_MODE_HIDDEN);
   522:                 else pTaskbar->ChangeTaskbarMode(TASKBAR_MODE_BARSICONS);
   523:             }
   524:             else if (!_stricmp(token3, "Items"))
   525:             {
   526:                 pSettings->taskbarMaxItems = atoi(token4);
   527:                 if (pToolbar)
   528:                 {
   529:                     pTaskbar->taskButtonsOffset = 0;
   530:                     pToolbar->UpdatePosition();
   531:                 }
   532:                 WriteInt(pSettings->xobrcFile, "xoblite.taskbar.max.items:", pSettings->taskbarMaxItems);
   533:             }
   534:             else if (!_stricmp(token3, "Sort"))
   535:             {
   536:                 if (!_stricmp(token4, "Last")) // Last used
   537:                 {
   538:                     pSettings->taskbarSorting = TASKBAR_SORT_BY_LAST_USED;
   539:                     WriteString(pSettings->xobrcFile, "xoblite.taskbar.sorting:", "LastUsed");
   540:                 }
   541:                 else if (!_stricmp(token4, "Follow")) // Follow active
   542:                 {
   543:                     pSettings->taskbarSorting = TASKBAR_SORT_FOLLOW_ACTIVE;
   544:                     WriteString(pSettings->xobrcFile, "xoblite.taskbar.sorting:", "FollowActive");
   545:                 }
   546:                 else // Disabled
   547:                 {
   548:                     pSettings->taskbarSorting = TASKBAR_SORT_DISABLED;
   549:                     WriteString(pSettings->xobrcFile, "xoblite.taskbar.sorting:", "Disabled");
   550:                 }
   551:                 if (pToolbar) pToolbar->UpdateToolbarWindow();
   552:             }
   553:             else if (!_stricmp(token3, "IconSaturation"))
   554:             {
   555:                 pSettings->taskbarSaturationValue = atoi(token4);
   556:                 if (pToolbar) pToolbar->UpdateToolbarWindow();
   557:                 WriteInt(pSettings->xobrcFile, "xoblite.taskbar.saturation:", pSettings->taskbarSaturationValue);
   558:             }
   559:             else if (!_stricmp(token3, "IconHue"))
   560:             {
   561:                 pSettings->taskbarHueIntensity = atoi(token4);
   562:                 if (pToolbar) pToolbar->UpdateToolbarWindow();
   563:                 WriteInt(pSettings->xobrcFile, "xoblite.taskbar.hue:", pSettings->taskbarHueIntensity);
   564:             }
   565:             else if (!_stricmp(token3, "ToggleShowTaskWorkspace"))
   566:             {
   567:                 if (!pSettings->taskbarShowTaskWorkspace) pSettings->taskbarShowTaskWorkspace = true;
   568:                 else pSettings->taskbarShowTaskWorkspace = false;
   569:                 if (pToolbar) pToolbar->UpdateToolbarWindow();
   570:                 WriteBool(pSettings->xobrcFile, "xoblite.taskbar.show.task.workspace:", pSettings->taskbarShowTaskWorkspace);
   571:             }
   572:             else if (!_stricmp(token3, "ToggleCurrentOnly"))
   573:             {
   574:                 pTaskbar->ToggleCurrentOnly();
   575:             }
   576:             else if (!_stricmp(token3, "ToggleFlashing"))
   577:             {
   578:                 if (!pSettings->taskbarFlashing) pSettings->taskbarFlashing = true;
   579:                 else pSettings->taskbarFlashing = false;
   580:                 WriteBool(pSettings->xobrcFile, "xoblite.taskbar.flashing:", pSettings->taskbarFlashing);
   581:             }
   582:             else if (!_stricmp(token3, "ToggleActiveSatHue"))
   583:             {
   584:                 if (!pSettings->taskbarActiveSatHue) pSettings->taskbarActiveSatHue = true;
   585:                 else pSettings->taskbarActiveSatHue = false;
   586:                 if (pToolbar) pToolbar->UpdateToolbarWindow();
   587:                 WriteBool(pSettings->xobrcFile, "xoblite.taskbar.active.SatHue:", pSettings->taskbarActiveSatHue);
   588:             }
   589: //          else if (!_stricmp(token3, "ToggleActiveLivePreview"))
   590: //          {
   591: //              if (!pSettings->taskbarActiveLivePreview) pSettings->taskbarActiveLivePreview = true;
   592: //              else pSettings->taskbarActiveLivePreview = false;
   593: //              if (pToolbar) pToolbar->UpdateToolbarWindow();
   594: //              WriteBool(pSettings->xobrcFile, "xoblite.taskbar.active.live.preview:", pSettings->taskbarActiveLivePreview);
   595: //          }
   596:             else if (!_stricmp(token3, "ToggleInactiveBackground"))
   597:             {
   598:                 if (!pSettings->taskbarInactiveBackground) pSettings->taskbarInactiveBackground = true;
   599:                 else pSettings->taskbarInactiveBackground = false;
   600:                 if (pToolbar) pToolbar->UpdateToolbarWindow();
   601:                 WriteBool(pSettings->xobrcFile, "xoblite.taskbar.inactive.background:", pSettings->taskbarInactiveBackground);
   602:             }
   603:             else if (!_stricmp(token3, "TogglePreviews"))
   604:             {
   605:                 if (!pSettings->taskbarPreviews) pSettings->taskbarPreviews = true;
   606:                 else pSettings->taskbarPreviews = false;
   607:                 WriteBool(pSettings->xobrcFile, "xoblite.taskbar.previews:", pSettings->taskbarPreviews);
   608:             }
   609:             else if (!_stricmp(token3, "ToggleTooltips"))
   610:             {
   611:                 if (pTooltips) pTooltips->ToggleTooltips();
   612:             }
   613:             else if (!_stricmp(token3, "QuitCurrentTask"))
   614:             {
   615:                 HWND hwnd = pTaskbar->GetActiveWindow();
   616:                 if (IsIconic(hwnd)) ShowWindow(hwnd, SW_RESTORE);
   617:                 SetForegroundWindow(hwnd);
   618:                 PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
   619:             }
   620:             else if (!_stricmp(token3, "ZoomCurrentTask"))
   621:             {
   622:                 HWND hwnd = pTaskbar->GetActiveWindow();
   623:                 if (!IsIconic(hwnd))
   624:                 {
   625:                     if (IsZoomed(hwnd)) ShowWindow(hwnd, SW_RESTORE);
   626:                     else ShowWindow(hwnd, SW_MAXIMIZE);
   627:                 }
   628:             }
   629: /*
   630:             else if (!_stricmp(token2, "CycleTasks"))
   631:             {
   632:                 HWND hwnd = pTaskbar->GetActiveWindow();
   633:                 ShowWindow(hwnd, SW_RESTORE);
   634: //              SetWindowPos(hwnd, HWND_NOTOPMOST, 1050, 10, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
   635:                 SetWindowPos(hwnd, HWND_NOTOPMOST, -100, 10, 200, 700, SWP_NOZORDER);
   636: 
   637:                 int nextTask = pTaskbar->FindTask(pTaskbar->GetActiveWindow()) + 1;
   638:                 if (nextTask >= (int)pTaskbar->taskList.size()) nextTask = 0;
   639:                 hwnd = pTaskbar->taskList[nextTask]->hwnd;
   640:                 ShowWindow(hwnd, SW_RESTORE);
   641:                 SetForegroundWindow(hwnd);
   642:                 SendMessage(GetBBWnd(), BB_BRINGTOFRONT, 0, (LPARAM)hwnd);
   643: //              SetWindowPos(hwnd, HWND_NOTOPMOST, 10, 10, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
   644:                 SetWindowPos(hwnd, HWND_NOTOPMOST, 150, 10, 1200, 700, SWP_NOZORDER);
   645:             }
   646: */
   647:             return true;
   648:         }
   649: 
   650:         //====================
   651: 
   652:         else if (!_stricmp(token2, "Dock"))
   653:         {
   654:             if (!_stricmp(token3, "Hide") && !pSettings->dockHidden) PostMessage(GetBBWnd(), BB_TOGGLEDOCK, 0, 0);
   655:             else if (!_stricmp(token3, "Show") && pSettings->dockHidden) PostMessage(GetBBWnd(), BB_TOGGLEDOCK, 0, 0);
   656:             else if (!_stricmp(token3, "Toggle")) PostMessage(GetBBWnd(), BB_TOGGLEDOCK, 0, 0);
   657:             else if (!_stricmp(token3, "Placement"))
   658:             {
   659:                 char placement[255];
   660:                 sprintf_s(placement, sizeofArray(placement), "%s %s", token4, extra); // Note: We need to merge these back as Manual placement strings include space chars in them!
   661:                 pSettings->ParsePlacement(placement, &pSettings->DockPlacement);
   662:                 pSettings->WritePlacement(&pSettings->DockPlacement);
   663:                 if (pDock) pDock->UpdatePosition();
   664:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   665:             }
   666:             else if (!_stricmp(token3, "Orientation"))
   667:             {
   668:                 if (!_stricmp(token4, "Vertical")) pSettings->dockVertical = true;
   669:                 else pSettings->dockVertical = false;
   670:                 if (pDock) pDock->UpdateDockWindow();
   671:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   672:                 WriteBool(pSettings->xobrcFile, "xoblite.dock.vertical:", pSettings->dockVertical);
   673:             }
   674:             else if (!_stricmp(token3, "ToggleOrientation"))
   675:             {
   676:                 if (!pSettings->dockVertical) pSettings->dockVertical = true;
   677:                 else pSettings->dockVertical = false;
   678:                 if (pDock) pDock->UpdateDockWindow();
   679:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   680:                 WriteBool(pSettings->xobrcFile, "xoblite.dock.vertical:", pSettings->dockVertical);
   681:             }
   682:             else if (!_stricmp(token3, "Transparency"))
   683:             {
   684:                 pSettings->dockTransparencyAlpha = atoi(token4);
   685:                 if (pDock) SetTransparency(pDock->hDockWnd, pSettings->dockTransparencyAlpha);
   686:                 WriteInt(pSettings->xobrcFile, "xoblite.dock.transparency.alpha:", pSettings->dockTransparencyAlpha);
   687:             }
   688:             else if (!_stricmp(token3, "TogglePuzzlePositioning"))
   689:             {
   690:                 if (!pSettings->dockPuzzlePositioning) pSettings->dockPuzzlePositioning = true;
   691:                 else pSettings->dockPuzzlePositioning = false;
   692:                 if (pDock) pDock->UpdateDockWindow();
   693:                 WriteBool(pSettings->xobrcFile, "xoblite.dock.puzzle.positioning:", pSettings->dockPuzzlePositioning);
   694:             }
   695:             else if (!_stricmp(token3, "ToggleAlwaysOnTop"))
   696:             {
   697:                 if (pDock) pDock->ToggleAlwaysOnTop();
   698:             }
   699:             else if (!_stricmp(token3, "ToggleSnapToEdges"))
   700:             {
   701:                 if (!pSettings->dockSnapToEdges) pSettings->dockSnapToEdges = true;
   702:                 else pSettings->dockSnapToEdges = false;
   703:                 WriteBool(pSettings->xobrcFile, "xoblite.dock.snapToEdges:", pSettings->dockSnapToEdges);
   704:             }
   705: 
   706:             return true;
   707:         }
   708: 
   709:         //====================
   710: 
   711:         else if (!_stricmp(token2, "Menu"))
   712:         {
   713:             if (!_stricmp(token3, "Show"))
   714:             {
   715:                 if (!_stricmp(token4, "Configuration")) SendMessage(GetBBWnd(), BB_MENU, 2, 0); // -> Show configuration menu
   716:                 else if (!_stricmp(token4, "Workspaces")) SendMessage(GetBBWnd(), BB_MENU, 1, 0); // -> Show workspaces menu
   717:                 else SendMessage(GetBBWnd(), BB_MENU, 0, 0); // -> Show main menu
   718:                 PlaySoundFX(SFX_MENU_SHOW);
   719:             }
   720:             else if (!_stricmp(token3, "Hide"))
   721:             {
   722:                 if (pMenuCommon) pMenuCommon->Hide();
   723:             }
   724:             else if (!_stricmp(token3, "Transparency"))
   725:             {
   726:                 if (!_stricmp(token4, "Title")) // -> Alpha transparency for the menu title (i.e. using per pixel alpha)
   727:                 {
   728:                     pSettings->menuTitleTransparencyAlpha = atoi(extra);
   729:                     WriteInt(pSettings->xobrcFile, "xoblite.menu.title.transparency.alpha:", pSettings->menuTitleTransparencyAlpha);
   730:                 }
   731:                 else if (!_stricmp(token4, "Frame")) // -> Alpha transparency for the menu frame (i.e. using per pixel alpha)
   732:                 {
   733:                     pSettings->menuFrameTransparencyAlpha = atoi(extra);
   734:                     WriteInt(pSettings->xobrcFile, "xoblite.menu.frame.transparency.alpha:", pSettings->menuFrameTransparencyAlpha);
   735:                 }
   736:                 else if (!_stricmp(token4, "Grip")) // -> Alpha transparency for the menu grip (i.e. using per pixel alpha)
   737:                 {
   738:                     pSettings->menuGripTransparencyAlpha = atoi(extra);
   739:                     WriteInt(pSettings->xobrcFile, "xoblite.menu.grip.transparency.alpha:", pSettings->menuGripTransparencyAlpha);
   740:                 }
   741:                 else if (!_stricmp(token4, "Active")) // -> Alpha transparency for the active menu item (i.e. using per pixel alpha)
   742:                 {
   743:                     pSettings->menuActiveTransparencyAlpha = atoi(extra);
   744:                     WriteInt(pSettings->xobrcFile, "xoblite.menu.active.transparency.alpha:", pSettings->menuActiveTransparencyAlpha);
   745:                 }
   746:                 else // -> Alpha transparency for the menu itself (cf. regular window level alpha, but here using per pixel alpha applied before the other menu element's per pixel alpha's)
   747:                 {
   748:                     pSettings->menuTransparencyAlpha = atoi(token4);
   749:                     WriteInt(pSettings->xobrcFile, "xoblite.menu.transparency.alpha:", pSettings->menuTransparencyAlpha);
   750:                 }
   751: 
   752:                 // ###################################################################################################################
   753:                 // Note: Since there can be any number of open menues at any time, they will be updated with new transparency alpha's
   754:                 // on the fly when accessing them, rather than being force updated from here... (maybe I'll add this later though [?])
   755:                 // ###################################################################################################################
   756:             }
   757:             else if (!_stricmp(token3, "ToggleRoundedCorners"))
   758:             {
   759:                 if (!pSettings->menuRoundedCorners) pSettings->menuRoundedCorners = true;
   760:                 else pSettings->menuRoundedCorners = false;
   761:                 pMenuCommon->Hide();
   762:                 SendMessage(GetBBWnd(), BB_RECONFIGURE, 0, 0); // Note: We need to perform a full reconfigure as the submenu gap is adaptively calculated during style parsing... (i.e. BB_REDRAWGUI is not enough)
   763:                 WriteBool(pSettings->xobrcFile, "xoblite.menu.rounded:", pSettings->menuRoundedCorners);
   764:                 return true;
   765:             }
   766:             else if (!_stricmp(token3, "ToggleSeparators"))
   767:             {
   768:                 if (!pSettings->menuSeparators) pSettings->menuSeparators = true;
   769:                 else pSettings->menuSeparators = false;
   770:                 WriteBool(pSettings->xobrcFile, "xoblite.menu.separators:", pSettings->menuSeparators);
   771:                 PostMessage(GetBBWnd(), BB_RESTART, 0, 0); // Note: We need to perform a full restart here as actual menu separator items are not created if not enabled...
   772:                 return true;
   773:             }
   774:             else if (!_stricmp(token3, "SetRCPath"))
   775:             {
   776:                 menuPath(token4);
   777:                 if (pMenuCommon) delete pMenuCommon;
   778:                 pMenuCommon = new MenuCommon();
   779:                 pMenuCommon->Initialize(hMainInstance);
   780:             }
   781: 
   782:             return true;
   783:         }
   784: 
   785:         //====================
   786: 
   787:         else if (!_stricmp(token2, "Console"))
   788:         {
   789:             if (!_stricmp(token3, "Hide") && !pSettings->consoleHidden) PostMessage(GetBBWnd(), BB_TOGGLECONSOLE, 0, 0);
   790:             else if (!_stricmp(token3, "Show") && pSettings->consoleHidden) PostMessage(GetBBWnd(), BB_TOGGLECONSOLE, 0, 0);
   791:             else if (!_stricmp(token3, "Toggle")) PostMessage(GetBBWnd(), BB_TOGGLECONSOLE, 0, 0);
   792:             else if (!_stricmp(token3, "ToggleMaximized"))
   793:             {
   794:                 pConsole->ToggleMaximized();
   795:             }
   796:             else if (!_stricmp(token3, "Placement"))
   797:             {
   798:                 char placement[255];
   799:                 sprintf_s(placement, sizeofArray(placement), "%s %s", token4, extra); // <- We need to merge these back as Manual placements include space chars in them!
   800:                 pSettings->ParsePlacement(placement, &pSettings->ConsolePlacement);
   801:                 pSettings->WritePlacement(&pSettings->ConsolePlacement);
   802:                 pConsole->UpdatePosition();
   803:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
   804:             }
   805:             else if (!_stricmp(token3, "Messages"))
   806:             {
   807:                 if (!_stricmp(token4, "Maximized"))
   808:                 {
   809:                     pSettings->consoleMaximizedMessages = atoi(extra);
   810:                     WriteInt(pSettings->xobrcFile, "xoblite.console.maximized.messages:", pSettings->consoleMaximizedMessages);
   811:                 }
   812:                 else if (!_stricmp(token4, "Restored"))
   813:                 {
   814:                     pSettings->consoleRestoredMessages = atoi(extra);
   815:                     WriteInt(pSettings->xobrcFile, "xoblite.console.restored.messages:", pSettings->consoleRestoredMessages);
   816:                 }
   817:                 pConsole->UpdatePosition();
   818:             }
   819:             else if (!_stricmp(token3, "Transparency"))
   820:             {
   821:                 pSettings->consoleTransparencyAlpha = atoi(token4);
   822:                 WriteInt(pSettings->xobrcFile, "xoblite.console.transparency.alpha:", pSettings->consoleTransparencyAlpha);
   823:                 pConsole->UpdatePosition();
   824:             }
   825:             else if (!_stricmp(token3, "ToggleDesktopMode"))
   826:             {
   827:                 if (!pSettings->consoleDesktopMode) pSettings->consoleDesktopMode = true;
   828:                 else pSettings->consoleDesktopMode = false;
   829:                 pConsole->UpdatePosition();
   830:                 WriteBool(pSettings->xobrcFile, "xoblite.console.desktop.mode:", pSettings->consoleDesktopMode);
   831:             }
   832:             else if (!_stricmp(token3, "ToggleRoundedCorners"))
   833:             {
   834:                 if (!pSettings->consoleRoundedCorners) pSettings->consoleRoundedCorners = true;
   835:                 else pSettings->consoleRoundedCorners = false;
   836:                 pConsole->UpdatePosition();
   837:                 WriteBool(pSettings->xobrcFile, "xoblite.console.rounded:", pSettings->consoleRoundedCorners);
   838:             }
   839:             else if (!_stricmp(token3, "ClearHistory"))
   840:             {
   841:                 pConsole->ClearHistory(true);
   842:             }
   843: 
   844:             return true;
   845:         }
   846: 
   847:         //====================
   848: 
   849:         else if (!_stricmp(token2, "Desktop"))
   850:         {
   851:             if (!_stricmp(token3, "Toggle"))
   852:             {
   853:                 if (!_stricmp(token4, "Clock"))
   854:                 {
   855:                     if (!pSettings->desktopClockHidden) pSettings->desktopClockHidden = true;
   856:                     else pSettings->desktopClockHidden = false;
   857:                     pDesktop->UpdateDesktopWindow();
   858:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.clock.hidden:", pSettings->desktopClockHidden);
   859:                     return true;
   860:                 }
   861:                 else if (!_stricmp(token4, "Weekday"))
   862:                 {
   863:                     if (!pSettings->desktopWeekdayHidden) pSettings->desktopWeekdayHidden = true;
   864:                     else pSettings->desktopWeekdayHidden = false;
   865:                     pDesktop->UpdateDesktopWindow();
   866:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.weekday.hidden:", pSettings->desktopWeekdayHidden);
   867:                     return true;
   868:                 }
   869:                 else if (!_stricmp(token4, "Date"))
   870:                 {
   871:                     if (!pSettings->desktopDateHidden) pSettings->desktopDateHidden = true;
   872:                     else pSettings->desktopDateHidden = false;
   873:                     pDesktop->UpdateDesktopWindow();
   874:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.date.hidden:", pSettings->desktopDateHidden);
   875:                     return true;
   876:                 }
   877:                 else if (!_stricmp(token4, "Greeting"))
   878:                 {
   879:                     if (!pSettings->desktopGreetingHidden) pSettings->desktopGreetingHidden = true;
   880:                     else pSettings->desktopGreetingHidden = false;
   881:                     pDesktop->UpdateDesktopWindow();
   882:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.greeting.hidden:", pSettings->desktopGreetingHidden);
   883:                     return true;
   884:                 }
   885:                 else if (!_stricmp(token4, "Indicator"))
   886:                 {
   887:                     if (!pSettings->desktopWorkspaceIndicatorHidden) pSettings->desktopWorkspaceIndicatorHidden = true;
   888:                     else pSettings->desktopWorkspaceIndicatorHidden = false;
   889:                     pDesktop->UpdateDesktopWindow();
   890:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.indicator.hidden:", pSettings->desktopWorkspaceIndicatorHidden);
   891:                     return true;
   892:                 }
   893:                 else if (!_stricmp(token4, "Border"))
   894:                 {
   895:                     if (!pSettings->desktopBorderHidden) pSettings->desktopBorderHidden = true;
   896:                     else pSettings->desktopBorderHidden = false;
   897:                     pDesktop->UpdateDesktopWindow();
   898:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.border.hidden:", pSettings->desktopBorderHidden);
   899:                     return true;
   900:                 }
   901:                 else if (!_stricmp(token4, "ClockWeekdayDate"))
   902:                 {
   903:                     if (!pSettings->desktopClockHidden) pSettings->desktopClockHidden = true;
   904:                     else pSettings->desktopClockHidden = false;
   905:                     if (!pSettings->desktopWeekdayHidden) pSettings->desktopWeekdayHidden = true;
   906:                     else pSettings->desktopWeekdayHidden = false;
   907:                     if (!pSettings->desktopDateHidden) pSettings->desktopDateHidden = true;
   908:                     else pSettings->desktopDateHidden = false;
   909:                     pDesktop->UpdateDesktopWindow();
   910:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.clock.hidden:", pSettings->desktopClockHidden);
   911:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.weekday.hidden:", pSettings->desktopWeekdayHidden);
   912:                     WriteBool(pSettings->xobrcFile, "xoblite.desktop.date.hidden:", pSettings->desktopDateHidden);
   913:                     return true;
   914:                 }
   915:             }
   916:             else if (!_stricmp(token3, "Clock"))
   917:             {
   918:                 if (!_stricmp(token4, "Placement"))
   919:                 {
   920:                     pSettings->ParsePlacement(extra, &pSettings->desktopClockPlacement);
   921:                     pSettings->WritePlacement(&pSettings->desktopClockPlacement);
   922:                     pDesktop->UpdateDesktopWindow();
   923:                     return true;
   924:                 }
   925:                 else if (!_stricmp(token4, "Transparency"))
   926:                 {
   927:                     pSettings->desktopClockTransparencyAlpha = atoi(extra);
   928:                     WriteInt(pSettings->xobrcFile, "xoblite.desktop.clock.transparency.alpha:", pSettings->desktopClockTransparencyAlpha);
   929:                     pDesktop->UpdateDesktopWindow();
   930:                 }
   931:                 else if (!_stricmp(token4, "Font"))
   932:                 {
   933:                     StyleItem tempStyleItem;
   934:                     ParseFontString(extra, &tempStyleItem);
   935:                     if (strnlen_s(tempStyleItem.Font, sizeofArray(tempStyleItem.Font)))
   936:                     {
   937:                         strcpy_s(pSettings->desktopClockFont, tempStyleItem.Font);
   938:                         pSettings->desktopClockFontHeight = tempStyleItem.FontHeight;
   939:                         pSettings->desktopClockFontWeight = tempStyleItem.FontWeight;
   940:                         pSettings->desktopClockFontDefined = true;
   941:                         WriteString(pSettings->xobrcFile, "xoblite.desktop.clock.font:", extra);
   942:                     }
   943:                     pDesktop->UpdateDesktopWindow();
   944:                 }
   945:                 else if (!_stricmp(token4, "Regular") || !_stricmp(token4, "Text") || !_stricmp(token4, "Binary"))
   946:                 {
   947:                     strcpy_s(pSettings->desktopClockType, sizeofArray(pSettings->desktopClockType), token4);
   948:                     pDesktop->UpdateDesktopWindow();
   949:                     WriteString(pSettings->xobrcFile, "xoblite.desktop.clock.type:", pSettings->desktopClockType);
   950:                     return true;
   951:                 }
   952:             }
   953:             else if (!_stricmp(token3, "Weekday"))
   954:             {
   955:                 if (!_stricmp(token4, "Placement"))
   956:                 {
   957:                     pSettings->ParsePlacement(extra, &pSettings->desktopWeekdayPlacement);
   958:                     pSettings->WritePlacement(&pSettings->desktopWeekdayPlacement);
   959:                     pDesktop->UpdateDesktopWindow();
   960:                     return true;
   961:                 }
   962:                 else if (!_stricmp(token4, "Transparency"))
   963:                 {
   964:                     pSettings->desktopWeekdayTransparencyAlpha = atoi(extra);
   965:                     WriteInt(pSettings->xobrcFile, "xoblite.desktop.weekday.transparency.alpha:", pSettings->desktopWeekdayTransparencyAlpha);
   966:                     pDesktop->UpdateDesktopWindow();
   967:                 }
   968:                 else if (!_stricmp(token4, "Font"))
   969:                 {
   970:                     StyleItem tempStyleItem;
   971:                     ParseFontString(extra, &tempStyleItem);
   972:                     if (strnlen_s(tempStyleItem.Font, sizeofArray(tempStyleItem.Font)))
   973:                     {
   974:                         strcpy_s(pSettings->desktopWeekdayFont, tempStyleItem.Font);
   975:                         pSettings->desktopWeekdayFontHeight = tempStyleItem.FontHeight;
   976:                         pSettings->desktopWeekdayFontWeight = tempStyleItem.FontWeight;
   977:                         pSettings->desktopWeekdayFontDefined = true;
   978:                         WriteString(pSettings->xobrcFile, "xoblite.desktop.weekday.font:", extra);
   979:                     }
   980:                     pDesktop->UpdateDesktopWindow();
   981:                 }
   982:             }
   983:             else if (!_stricmp(token3, "Date"))
   984:             {
   985:                 if (!_stricmp(token4, "Placement"))
   986:                 {
   987:                     pSettings->ParsePlacement(extra, &pSettings->desktopDatePlacement);
   988:                     pSettings->WritePlacement(&pSettings->desktopDatePlacement);
   989:                     pDesktop->UpdateDesktopWindow();
   990:                     return true;
   991:                 }
   992:                 else if (!_stricmp(token4, "Transparency"))
   993:                 {
   994:                     pSettings->desktopDateTransparencyAlpha = atoi(extra);
   995:                     WriteInt(pSettings->xobrcFile, "xoblite.desktop.date.transparency.alpha:", pSettings->desktopDateTransparencyAlpha);
   996:                     pDesktop->UpdateDesktopWindow();
   997:                 }
   998:                 else if (!_stricmp(token4, "Font"))
   999:                 {
  1000:                     StyleItem tempStyleItem;
  1001:                     ParseFontString(extra, &tempStyleItem);
  1002:                     if (strnlen_s(tempStyleItem.Font, sizeofArray(tempStyleItem.Font)))
  1003:                     {
  1004:                         strcpy_s(pSettings->desktopDateFont, tempStyleItem.Font);
  1005:                         pSettings->desktopDateFontHeight = tempStyleItem.FontHeight;
  1006:                         pSettings->desktopDateFontWeight = tempStyleItem.FontWeight;
  1007:                         pSettings->desktopDateFontDefined = true;
  1008:                         WriteString(pSettings->xobrcFile, "xoblite.desktop.date.font:", extra);
  1009:                     }
  1010:                     pDesktop->UpdateDesktopWindow();
  1011:                 }
  1012:             }
  1013:             else if (!_stricmp(token3, "Greeting"))
  1014:             {
  1015:                 if (!_stricmp(token4, "Placement"))
  1016:                 {
  1017:                     pSettings->ParsePlacement(extra, &pSettings->desktopGreetingPlacement);
  1018:                     pSettings->WritePlacement(&pSettings->desktopGreetingPlacement);
  1019:                     pDesktop->UpdateDesktopWindow();
  1020:                     return true;
  1021:                 }
  1022:                 else if (!_stricmp(token4, "Transparency"))
  1023:                 {
  1024:                     pSettings->desktopGreetingTransparencyAlpha = atoi(extra);
  1025:                     WriteInt(pSettings->xobrcFile, "xoblite.desktop.greeting.transparency.alpha:", pSettings->desktopGreetingTransparencyAlpha);
  1026:                     pDesktop->UpdateDesktopWindow();
  1027:                 }
  1028:                 else if (!_stricmp(token4, "Font"))
  1029:                 {
  1030:                     StyleItem tempStyleItem;
  1031:                     ParseFontString(extra, &tempStyleItem);
  1032:                     if (strnlen_s(tempStyleItem.Font, sizeofArray(tempStyleItem.Font)))
  1033:                     {
  1034:                         strcpy_s(pSettings->desktopGreetingFont, tempStyleItem.Font);
  1035:                         pSettings->desktopGreetingFontHeight = tempStyleItem.FontHeight;
  1036:                         pSettings->desktopGreetingFontWeight = tempStyleItem.FontWeight;
  1037:                         pSettings->desktopGreetingFontDefined = true;
  1038:                         WriteString(pSettings->xobrcFile, "xoblite.desktop.greeting.font:", extra);
  1039:                     }
  1040:                     pDesktop->UpdateDesktopWindow();
  1041:                 }
  1042:             }
  1043:             else if (!_stricmp(token3, "Color"))
  1044:             {
  1045:                 if ((*token4 != '#') || (strnlen_s(token4, sizeofArray(token4)) != 7)) return false; // Check if the input is a #RRGGBB format string...
  1046: 
  1047:                 if (*token4 == '#') memmove(token4, token4+1, strnlen_s(token4, sizeofArray(token4)));
  1048:                 COLORREF color = strtol(token4, NULL, 16);
  1049:                 color = RGB(GetBValue(color), GetGValue(color), GetRValue(color)); // Swap from RGB to BGR format...
  1050:                 pWallpaper->SetDesktopColor(color);
  1051:                 return true;
  1052:             }
  1053:             else if (!_stricmp(token3, "Widget"))
  1054:             {
  1055:                 if (!_stricmp(token4, "Color"))
  1056:                 {
  1057:                     if ((*extra != '#') || (strnlen_s(extra, sizeofArray(extra)) != 7)) return false; // Check if the input is a #RRGGBB format string...
  1058: 
  1059:                     if (*extra == '#') memmove(extra, extra +1, strnlen_s(extra, sizeofArray(extra)));
  1060:                     COLORREF color = strtol(extra, NULL, 16);
  1061:                     pSettings->desktopWidgetColor = RGB(GetBValue(color), GetGValue(color), GetRValue(color)); // Swap from RGB to BGR format...
  1062:                     pDesktop->UpdateDesktopWindow();
  1063:                     if (pDock) pDock->UpdateDockWindow(); // (...because the dock inherits the desktop widget color if it's empty.)
  1064:                     WriteColor(pSettings->xobrcFile, "xoblite.desktop.widget.color:", pSettings->desktopWidgetColor);
  1065:                     return true;
  1066:                 }
  1067:             }
  1068:             else if (!_stricmp(token3, "Click"))
  1069:             {
  1070:                 if (!_stricmp(token4, "R"))
  1071:                 {
  1072:                     strcpy_s(pSettings->desktopRClickOverride, sizeofArray(pSettings->desktopRClickOverride), extra);
  1073:                     WriteString(pSettings->xobrcFile, "xoblite.desktop.rclick.override:", pSettings->desktopRClickOverride);
  1074:                     return true;
  1075:                 }
  1076:                 else if (!_stricmp(token4, "M"))
  1077:                 {
  1078:                     strcpy_s(pSettings->desktopMClickOverride, sizeofArray(pSettings->desktopMClickOverride), extra);
  1079:                     WriteString(pSettings->xobrcFile, "xoblite.desktop.mclick.override:", pSettings->desktopMClickOverride);
  1080:                     return true;
  1081:                 }
  1082:                 else if (!_stricmp(token4, "X1"))
  1083:                 {
  1084:                     strcpy_s(pSettings->desktopX1ClickOverride, sizeofArray(pSettings->desktopX1ClickOverride), extra);
  1085:                     WriteString(pSettings->xobrcFile, "xoblite.desktop.x1click.override:", pSettings->desktopX1ClickOverride);
  1086:                     return true;
  1087:                 }
  1088:                 else if (!_stricmp(token4, "X2"))
  1089:                 {
  1090:                     strcpy_s(pSettings->desktopX2ClickOverride, sizeofArray(pSettings->desktopX2ClickOverride), extra);
  1091:                     WriteString(pSettings->xobrcFile, "xoblite.desktop.x2click.override:", pSettings->desktopX2ClickOverride);
  1092:                     return true;
  1093:                 }
  1094:             }
  1095: 
  1096:             return false;
  1097:         }
  1098: 
  1099:         //====================
  1100: 
  1101:         else if (!_stricmp(token2, "Hotkey"))
  1102:         {
  1103:             int hotkeyNumber = atoi(&token3[1]) - 1; // Nb. Using more human friendly 1-N numbering for the Hotkey bro@ms! (...though in practise likely only to be used internally within xoblite :))
  1104: 
  1105:             if (hotkeyNumber > (int)pHotkeys->hotkeyList.size()) return false;
  1106:             else pHotkeys->ExecuteHotkey(pHotkeys->hotkeyList[hotkeyNumber]->ID);
  1107: 
  1108:             return true;
  1109:         }
  1110: 
  1111:         //====================
  1112: 
  1113:         else if (!_stricmp(token2, "Workspaces"))
  1114:         {
  1115:             if (isdigit(token3[0]))
  1116:             {
  1117:                 int ws = atoi(token3);
  1118:                 if ((ws < 1) || (ws > pSettings->numberOfWorkspaces))
  1119:                 {
  1120:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"... Error: The requested workspace does not exist.");
  1121:                     return false;
  1122:                 }
  1123: 
  1124:                 PostMessage(GetBBWnd(), BB_WORKSPACE, 4, (ws-1)); // Note: Internally workspaces are referenced 0-m, while externally as 1-n.
  1125:             }
  1126:             else if (!_stricmp(token3, "Next"))
  1127:             {
  1128:                 PostMessage(GetBBWnd(), BB_WORKSPACE, 1, 0);
  1129:             }
  1130:             else if (!_stricmp(token3, "Previous"))
  1131:             {
  1132:                 PostMessage(GetBBWnd(), BB_WORKSPACE, 0, 0);
  1133:             }
  1134:             else if (!_stricmp(token3, "New"))
  1135:             {
  1136:                 PostMessage(GetBBWnd(), BB_WORKSPACE, 2, 0); // -> Add new workspace
  1137:             }
  1138:             else if (!_stricmp(token3, "Remove"))
  1139:             {
  1140:                 PostMessage(GetBBWnd(), BB_WORKSPACE, 3, 0); // -> Remove last workspace
  1141:             }
  1142:             else if (!_stricmp(token3, "ToggleMousewheelChanging"))
  1143:             {
  1144:                 if (!pSettings->mousewheelChanging) pSettings->mousewheelChanging = true;
  1145:                 else pSettings->mousewheelChanging = false;
  1146:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.workspaces.mousewheel.changing:", pSettings->mousewheelChanging);
  1147:             }
  1148:             else if (!_stricmp(token3, "ToggleFollowActive"))
  1149:             {
  1150:                 if (!pSettings->followActive) pSettings->followActive = true;
  1151:                 else pSettings->followActive = false;
  1152:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.workspaces.followActive:", pSettings->followActive);
  1153:             }
  1154:             else if (!_stricmp(token3, "ToggleWallpaperPerWorkspace"))
  1155:             {
  1156:                 if (!pSettings->wallpaperPerWorkspace) pSettings->wallpaperPerWorkspace = true;
  1157:                 else pSettings->wallpaperPerWorkspace = false;
  1158:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.workspaces.wallpapers:", pSettings->wallpaperPerWorkspace);
  1159:             }
  1160:             else if (!_stricmp(token3, "GatherWindows"))
  1161:             {
  1162:                 if (pWorkspaces) pWorkspaces->GatherWindows();
  1163:             }
  1164: 
  1165:             return true;
  1166:         }
  1167: 
  1168:         //====================
  1169: 
  1170:         else if (!_stricmp(token2, "Plugins"))
  1171:         {
  1172:             if (!_stricmp(token3, "Hide") && !pSettings->pluginsHidden) PostMessage(GetBBWnd(), BB_TOGGLEPLUGINS, 0, 0);
  1173:             else if (!_stricmp(token3, "Show") && pSettings->pluginsHidden) PostMessage(GetBBWnd(), BB_TOGGLEPLUGINS, 0, 0);
  1174:             else if (!_stricmp(token3, "Toggle")) PostMessage(GetBBWnd(), BB_TOGGLEPLUGINS, 0, 0);
  1175: //          else if (!_stricmp(token3, "About") && pPluginManager) pPluginManager->AboutPlugins(); // Note: Reverse duplicate of @xoblite About Plugins
  1176: 
  1177:             return true;
  1178:         }
  1179: 
  1180:         //====================
  1181: 
  1182:         else if (!_stricmp(token2, "Global"))
  1183:         {
  1184: /*
  1185:             if (!_stricmp(token3, "FocusNewWindows"))
  1186:             {
  1187:                 if (!pSettings->focusNewWindows) pSettings->focusNewWindows = true;
  1188:                 else pSettings->focusNewWindows = false;
  1189:                 WriteBool(pSettings->xobrcDefaultFile, "session.screen0.focusNewWindows:", pSettings->focusNewWindows);
  1190:             }
  1191:             else if (!_stricmp(token3, "FocusLastWindow"))
  1192:             {
  1193:                 if (!pSettings->focusLastWindow) pSettings->focusLastWindow = true;
  1194:                 else pSettings->focusLastWindow = false;
  1195:                 WriteBool(pSettings->xobrcDefaultFile, "session.screen0.focusLastWindow:", pSettings->focusLastWindow);
  1196:             }
  1197:             else if (!_stricmp(token3, "OpaqueWindowMoving"))
  1198:             {
  1199:                 if (!pSettings->opaqueMove) pSettings->opaqueMove = true;
  1200:                 else pSettings->opaqueMove = false;
  1201:                 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, pSettings->opaqueMove, NULL, SPIF_SENDCHANGE);
  1202:                 WriteBool(pSettings->xobrcDefaultFile, "session.opaqueMove:", pSettings->opaqueMove);
  1203:             }
  1204:             else if (!_stricmp(token3, "FullMaximization"))
  1205:             {
  1206:                 if (!pSettings->fullMaximization) pSettings->fullMaximization = true;
  1207:                 else pSettings->fullMaximization = false;
  1208:                 pToolbar->UpdateDesktopArea();
  1209:                 WriteBool(pSettings->xobrcDefaultFile, "session.screen0.fullMaximization:", pSettings->fullMaximization);
  1210:             }
  1211: */
  1212:             if (!_stricmp(token3, "HiDPI"))
  1213:             {
  1214:                 bool savedWriteProtection = pSettings->writeProtection;
  1215:                 pSettings->writeProtection = false;
  1216: 
  1217: //              if (GetAsyncKeyState(VK_MENU) & 0x8000) pSettings->scalingFactorHiDPI = 2;
  1218: //              else pSettings->scalingFactorHiDPI = atoi(token4);
  1219:                 pSettings->scalingFactorHiDPI = atoi(token4);
  1220:                 if (pSettings->scalingFactorHiDPI < 1) pSettings->scalingFactorHiDPI = 1; // Safeguard
  1221:                 if (pSettings->scalingFactorHiDPI > 4) pSettings->scalingFactorHiDPI = 4; // Safeguard
  1222:                 WriteInt(pSettings->xobrcDefaultFile, "xoblite.hidpi.scaling.factor:", pSettings->scalingFactorHiDPI);
  1223: 
  1224:                 pSettings->writeProtection = savedWriteProtection;
  1225: 
  1226:                 PostMessage(GetBBWnd(), BB_RESTART, 0, 0);
  1227: 
  1228:                 char msg[255];
  1229:                 if (savedWriteProtection) strcpy_s(msg, sizeofArray(msg), "Temporarily bypassing write protection: ");
  1230:                 else strcpy_s(msg, sizeofArray(msg), "");
  1231:                 sprintf_s(msg, sizeofArray(msg), "xoblite HiDPI scaling factor set to %dx. ", pSettings->scalingFactorHiDPI);
  1232:                 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
  1233:             }
  1234:             else if (!_stricmp(token3, "ToggleMultiMonitorPlacements"))
  1235:             {
  1236:                 if (!pSettings->multimonPlacements) pSettings->multimonPlacements = true;
  1237:                 else pSettings->multimonPlacements = false;
  1238:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.multimonitor.placements:", pSettings->multimonPlacements);
  1239: 
  1240:                 // Update core shell elements + notify plugins that the available screen resolution or desktop work area has changed...
  1241:                 if (pDesktop) pDesktop->UpdateDesktopWindow();
  1242:                 if (pToolbar) pToolbar->UpdatePosition();
  1243:                 if (pConsole) pConsole->UpdatePosition();
  1244:                 if (pDock) pDock->UpdatePosition();
  1245:                 SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_DESKTOP, 0);
  1246: 
  1247:                 PlaySoundFX(SFX_TOGGLE_ELEMENT);
  1248:             }
  1249:             else if (!_stricmp(token3, "ToggleFullscreenDetection"))
  1250:             {
  1251:                 if (!pSettings->fullscreenDetection) pSettings->fullscreenDetection = true;
  1252:                 else pSettings->fullscreenDetection = false;
  1253:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.fullscreen.detection:", pSettings->fullscreenDetection);
  1254:             }
  1255:             else if (!_stricmp(token3, "ToggleSoundFX"))
  1256:             {
  1257:                 if (!pSettings->enableSoundFX) pSettings->enableSoundFX = true;
  1258:                 else pSettings->enableSoundFX = false;
  1259:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.sound.effects:", pSettings->enableSoundFX);
  1260:             }
  1261:             else if (!_stricmp(token3, "ToggleDesignerMode"))
  1262:             {
  1263:                 char xDGUIpath[MAX_PATH];
  1264:                 sprintf_s(xDGUIpath, sizeofArray(xDGUIpath), "%s\\%s", pSettings->SF_blackboxPath, "xDesignerGUI.dll");
  1265:                 if (!pSettings->designerModeEnabled)
  1266:                 {
  1267:                     pSettings->designerModeEnabled = true;
  1268:                     if (!pPluginManager->IsPluginLoaded("xDesignerGUI.dll")) pPluginManager->LoadPlugin(xDGUIpath);
  1269:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"Designer mode enabled.");
  1270:                 }
  1271:                 else
  1272:                 {
  1273:                     pSettings->designerModeEnabled = false;
  1274:                     if (pPluginManager->IsPluginLoaded("xDesignerGUI.dll")) pPluginManager->UnloadPlugin(xDGUIpath, -1);
  1275:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"Designer mode disabled.");
  1276:                 }
  1277:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.designer.mode:", pSettings->designerModeEnabled);
  1278:             }
  1279:             else if (!_stricmp(token3, "ToggleRootCommands"))
  1280:             {
  1281:                 if (!pSettings->disableRootCommands) pSettings->disableRootCommands = true;
  1282:                 else pSettings->disableRootCommands = false;
  1283:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.disable.rootCommands:", pSettings->disableRootCommands);
  1284:             }
  1285:             else if (!_stricmp(token3, "ToggleThemeFonts"))
  1286:             {
  1287:                 if (!pSettings->disableThemeFonts)
  1288:                 {
  1289:                     pSettings->disableThemeFonts = true;
  1290:                     UnregisterThemeFonts();
  1291:                 }
  1292:                 else
  1293:                 {
  1294:                     pSettings->disableThemeFonts = false;
  1295:                     RegisterThemeFonts();
  1296:                 }
  1297:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.disable.theme.fonts:", pSettings->disableThemeFonts);
  1298:             }
  1299:             else if (!_stricmp(token3, "ToggleScriptSupport"))
  1300:             {
  1301:                 if (!pSettings->disableScriptSupport) pSettings->disableScriptSupport = true;
  1302:                 else pSettings->disableScriptSupport = false;
  1303: 
  1304:                 WriteBool(pSettings->xobrcDefaultFile, "xoblite.disable.script.support:", pSettings->disableScriptSupport);
  1305: 
  1306:                 if (pSettings->disableScriptSupport) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_WARNING_MESSAGE, (LPARAM)"@Script support disabled.");
  1307:                 else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_WARNING_MESSAGE, (LPARAM)"@Script support enabled.");
  1308:             }
  1309:             else if (!_stricmp(token3, "SetEditor"))
  1310:             {
  1311:                 if (strnlen_s(token4, sizeofArray(token4)) > 0)
  1312:                 {
  1313:                     if (strnlen_s(extra, sizeofArray(extra))) sprintf_s(pSettings->preferredEditor, sizeofArray(pSettings->preferredEditor), "\"%s %s\"", token4, extra);
  1314:                     else sprintf_s(pSettings->preferredEditor, sizeofArray(pSettings->preferredEditor), "\"%s\"", token4);
  1315:                     WriteString(pSettings->xobrcDefaultFile, "xoblite.editor:", pSettings->preferredEditor);
  1316:                 }
  1317:             }
  1318: 
  1319:             return true;
  1320:         }
  1321: 
  1322:         //====================
  1323: 
  1324:         else if (!_stricmp(token2, "Window"))
  1325:         {
  1326:             if (!pTaskbar) return false;
  1327: 
  1328:             HWND hwnd = pTaskbar->GetActiveWindow();
  1329:             if (hwnd == NULL) return false;
  1330: 
  1331:             if (!_stricmp(token3, "Toggle"))
  1332:             {
  1333:                 if (!_stricmp(token4, "Sticky"))
  1334:                 {
  1335:                     ToggleSticky(hwnd);
  1336:                     if (pToolbar) pToolbar->UpdatePosition();
  1337:                 }
  1338:             }
  1339:             else if (!_stricmp(token3, "Workspace"))
  1340:             {
  1341:                 if (!_stricmp(token4, "Next") && pWorkspaces) pWorkspaces->MoveWindowToNextWorkspace(hwnd);
  1342:                 else if (!_stricmp(token4, "Previous") && pWorkspaces) pWorkspaces->MoveWindowToPreviousWorkspace(hwnd);
  1343:                 else if ((strnlen_s(token4, sizeofArray(token4)) > 0))
  1344:                 {
  1345:                     int workspace = atoi(&token4[0]) - 1;
  1346:                     if (pWorkspaces) pWorkspaces->MoveWindowToWorkspace(hwnd, workspace);
  1347:                 }
  1348:             }
  1349:             else if (!_stricmp(token3, "Zoom"))
  1350:             {
  1351:                 if (!IsIconic(hwnd))
  1352:                 {
  1353:                     if (IsZoomed(hwnd)) ShowWindow(hwnd, SW_RESTORE);
  1354:                     else ShowWindow(hwnd, SW_MAXIMIZE);
  1355:                 }
  1356:             }
  1357:             else if (!_stricmp(token3, "Shade")) pDesktop->ShadeWindow();
  1358:             else if (!_stricmp(token3, "Lower")) pDesktop->LowerWindow();
  1359:             else if (!_stricmp(token3, "Grow"))
  1360:             {
  1361:                 if (!_stricmp(token4, "Width")) pDesktop->GrowWindowWidth();
  1362:                 else if (!_stricmp(token4, "Height")) pDesktop->GrowWindowHeight();
  1363:             }
  1364:             else if (!_stricmp(token3, "Tile"))
  1365:             {
  1366:                 if (IsInString(token4, "Left"))
  1367:                 {
  1368:                     if (IsInString(token4, "Top")) pTaskbar->TileWindow(PLACEMENT_TOP_LEFT);
  1369:                     else if (IsInString(token4, "Center")) pTaskbar->TileWindow(PLACEMENT_CENTER_LEFT);
  1370:                     else if (IsInString(token4, "Bottom")) pTaskbar->TileWindow(PLACEMENT_BOTTOM_LEFT);
  1371:                     else pTaskbar->TileWindow(PLACEMENT_LEFT_HALF);
  1372:                 }
  1373:                 else if (IsInString(token4, "Right"))
  1374:                 {
  1375:                     if (IsInString(token4, "Top")) pTaskbar->TileWindow(PLACEMENT_TOP_RIGHT);
  1376:                     else if (IsInString(token4, "Center")) pTaskbar->TileWindow(PLACEMENT_CENTER_RIGHT);
  1377:                     else if (IsInString(token4, "Bottom")) pTaskbar->TileWindow(PLACEMENT_BOTTOM_RIGHT);
  1378:                     else pTaskbar->TileWindow(PLACEMENT_RIGHT_HALF);
  1379:                 }
  1380:                 else if (IsInString(token4, "Center"))
  1381:                 {
  1382:                     if (IsInString(token4, "Top")) pTaskbar->TileWindow(PLACEMENT_TOP_CENTER);
  1383:                     else if (IsInString(token4, "Bottom")) pTaskbar->TileWindow(PLACEMENT_BOTTOM_CENTER);
  1384:                     else if (IsInString(token4, "CenterCenter")) pTaskbar->TileWindow(PLACEMENT_CENTER_CENTER);
  1385:                     else pTaskbar->TileWindow(PLACEMENT_CENTERED); // <- "Default" placement centered at 2/3 screen size
  1386:                 }
  1387:                 else if (IsInString(token4, "Top")) pTaskbar->TileWindow(PLACEMENT_TOP_HALF);
  1388:                 else if (IsInString(token4, "Bottom")) pTaskbar->TileWindow(PLACEMENT_BOTTOM_HALF);
  1389:                 else
  1390:                 {
  1391:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"... Error: The requested window tiling position is not supported.");
  1392:                     return false;
  1393:                 }
  1394:             }
  1395:             else if (!_stricmp(token3, "Float")) pTaskbar->TileWindow(PLACEMENT_DEFAULT);
  1396:             else if (!_stricmp(token3, "Quit"))
  1397:             {
  1398:                 if (IsIconic(hwnd)) ShowWindow(hwnd, SW_RESTORE);
  1399:                 SetForegroundWindow(hwnd);
  1400:                 PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
  1401:             }
  1402: 
  1403:             return true;
  1404:         }
  1405: 
  1406:         //====================
  1407: 
  1408:         else if (!_stricmp(token2, "ToggleWriteProtection"))
  1409:         {
  1410:             if (!pSettings->writeProtection)
  1411:             {
  1412:                 // Note: Since write protection blocks writes to config files, we need to save
  1413:                 // the new "true" value to file *before* we actually enable write protection...
  1414:                 WriteBool(pSettings->xobrcFile, "xoblite.write.protection:", true);
  1415:                 pSettings->writeProtection = true;
  1416:                 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_WARNING_MESSAGE, (LPARAM)"Write protection enabled.");
  1417:             }
  1418:             else
  1419:             {
  1420:                 // Note: Since write protection blocks writes to config files, we need to
  1421:                 // disable write protection *before* we save the new "false" value to file...
  1422:                 pSettings->writeProtection = false;
  1423:                 WriteBool(pSettings->xobrcFile, "xoblite.write.protection:", false);
  1424:                 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_WARNING_MESSAGE, (LPARAM)"Write protection disabled.");
  1425:             }
  1426: 
  1427:             return true;
  1428:         }
  1429: 
  1430:         //====================
  1431: 
  1432:         else if (!_stricmp(token2, "Edit"))
  1433:         {
  1434:             char cmdPlusArgs[MAX_LINE_LENGTH];
  1435: 
  1436:             if (!_stricmp(token3, "Style")) // -> Edit the *currently* selected style! (nb. since this can change dynamically over time, the path can not be stored statically in e.g. a hotkey)
  1437:             {
  1438:                 sprintf_s(cmdPlusArgs, sizeofArray(cmdPlusArgs), "%s %s", pSettings->preferredEditor, pSettings->styleFile);
  1439:             }
  1440:             else if (!_stricmp(token3, "Configuration")) // -> Edit the *currently* selected theme's xoblite.rc! (...)
  1441:             {
  1442:                 sprintf_s(cmdPlusArgs, sizeofArray(cmdPlusArgs), "%s %s", pSettings->preferredEditor, pSettings->xobrcFile);
  1443:             }
  1444:             else if (!_stricmp(token3, "Menu")) // -> Edit the globally defined menu.rc!
  1445:             {
  1446:                 sprintf_s(cmdPlusArgs, sizeofArray(cmdPlusArgs), "%s %s", pSettings->preferredEditor, pSettings->menuFile);
  1447:             }
  1448:             else if (!_stricmp(token3, "Hotkeys")) // -> Edit the globally defined hotkeys.rc!
  1449:             {
  1450:                 sprintf_s(cmdPlusArgs, sizeofArray(cmdPlusArgs), "%s %s", pSettings->preferredEditor, pSettings->hotkeysFile);
  1451:             }
  1452:             else if (!_stricmp(token3, "Plugins")) // -> Edit the *currently* selected theme's plugins.rc!
  1453:             {
  1454:                 sprintf_s(cmdPlusArgs, sizeofArray(cmdPlusArgs), "%s %s", pSettings->preferredEditor, pSettings->pluginsFile);
  1455:             }
  1456:             else // -> Edit any other file!
  1457:             {
  1458:                 if (strchr(token3, '$')) ReplaceShellFolders(token3);
  1459:                 if (strchr(token3, '%')) ReplaceEnvVars(token3);
  1460: 
  1461:                 // As the plain tokenizing above may have misinterpreted spaces in the supplied argument(s), let's merge applicable tokens again...
  1462:                 sprintf_s(cmdPlusArgs, sizeofArray(cmdPlusArgs), "%s %s %s %s", pSettings->preferredEditor, token3, token4, extra);
  1463:             }
  1464: 
  1465:             BBSmartExecute(cmdPlusArgs);
  1466: 
  1467:             return true;
  1468:         }
  1469: 
  1470:         //====================
  1471: 
  1472:         else if (!_stricmp(token2, "Set"))
  1473:         {
  1474:             if (!_stricmp(token3, "Style"))
  1475:             {
  1476:                 if (strnlen_s(token4, sizeofArray(token4))) PostMessage(GetBBWnd(), BB_SETSTYLE, 0, (LPARAM)token4);
  1477:                 return true;
  1478:             }
  1479:             else if (!_stricmp(token3, "Theme"))
  1480:             {
  1481:                 if (strnlen_s(token4, sizeofArray(token4))) PostMessage(GetBBWnd(), BB_SETTHEME, 0, (LPARAM)token4);
  1482:                 return true;
  1483:             }
  1484:         }
  1485: /*
  1486:         else if (!_stricmp(token2, "SetStyle")) // Legacy syntax
  1487:         {
  1488:             if (strnlen_s(token3, sizeofArray(token3))) PostMessage(GetBBWnd(), BB_SETSTYLE, 0, (LPARAM)token3);
  1489:             return true;
  1490:         }
  1491:         else if (!_stricmp(token2, "SetTheme")) // Legacy syntax
  1492:         {
  1493:             if (strnlen_s(token3, sizeofArray(token3))) PostMessage(GetBBWnd(), BB_SETTHEME, 0, (LPARAM)token3);
  1494:             return true;
  1495:         }
  1496: */
  1497: 
  1498:         //====================
  1499: 
  1500:         else if (!_stricmp(token2, "Random"))
  1501:         {
  1502:             int type;
  1503:             if (!_stricmp(token3, "Style")) type = BROAM_RANDOM_STYLE;
  1504:             else if (!_stricmp(token3, "Wallpaper")) type = BROAM_RANDOM_WALLPAPER;
  1505:             else return false;
  1506:             
  1507:             if (strnlen_s(token4, sizeofArray(token4))) // Was a path specified? (i.e. 4th argument -> @xoblite Random <Style/Wallpaper> <path> )
  1508:             {
  1509:                 strcpy_s(pathToScan, sizeofArray(pathToScan), token4);
  1510:                 if (strchr(pathToScan, '\"')) StrRemoveEncap(pathToScan);
  1511:                 if (strchr(pathToScan, '$')) ReplaceShellFolders(pathToScan);
  1512:                 if (strchr(pathToScan, '%')) ReplaceEnvVars(pathToScan);
  1513:             }
  1514:             else // If not, use the styles/wallpaper folder defined in xoblite.rc as default path...
  1515:             {
  1516:                 if (type == BROAM_RANDOM_STYLE) strcpy_s(pathToScan, sizeofArray(pathToScan), pSettings->stylesFolder);
  1517:                 else strcpy_s(pathToScan, sizeofArray(pathToScan), pSettings->wallpapersFolder);
  1518:             }
  1519: 
  1520:             numberOfFiles = currentFile = randomFile = 0;
  1521:             FindRandomFile(pathToScan, type, false); // Count the number of files...
  1522: 
  1523:             if (numberOfFiles == 0)
  1524:             {
  1525:                 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)"@xoblite Random -> No applicable files found at the specified path!");
  1526:                 return false;
  1527:             }
  1528: 
  1529:             randomFile = (rand() % numberOfFiles) + 1; // Select a random file... (note: srand() seeding is done in Blackbox.cpp during startup)
  1530:             FindRandomFile(pathToScan, type, true); // Apply the selected style/wallpaper...
  1531: 
  1532:             return true;
  1533:         }
  1534: 
  1535:         //====================
  1536: 
  1537:         else if (!_stricmp(token2, "Designer"))
  1538:         {
  1539:             if (!pSettings->designerModeEnabled)
  1540:             {
  1541:                 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"Designer mode is currently disabled. Enable it to allow dynamic updating of style parameters via bro@ms.");
  1542:                 return false;
  1543:             }
  1544: 
  1545:             char feedback[64];
  1546:             feedback[0] = '\0';
  1547: 
  1548:             if (!_stricmp(token3, "Select"))
  1549:             {
  1550:                 if (!_strnicmp(token4, "Toolbar", 7))
  1551:                 {
  1552:                     if (!_stricmp(token4, "Toolbar")) pSettings->selectedElement = pSettings->Toolbar;
  1553:                     else if (!_stricmp(token4, "ToolbarLabel")) pSettings->selectedElement = pSettings->ToolbarLabel;
  1554:                     else if (!_stricmp(token4, "ToolbarWindowLabel")) pSettings->selectedElement = pSettings->ToolbarWindowLabel;
  1555:                     else if (!_stricmp(token4, "ToolbarClock")) pSettings->selectedElement = pSettings->ToolbarClock;
  1556:                     else if (!_stricmp(token4, "ToolbarButton")) pSettings->selectedElement = pSettings->ToolbarButton;
  1557:                     else if (!_stricmp(token4, "ToolbarButtonPressed")) pSettings->selectedElement = pSettings->ToolbarButtonPressed;
  1558:                     else if (!_stricmp(token4, "ToolbarBorder")) pSettings->selectedElement = pSettings->ToolbarBorder;
  1559:                 }
  1560:                 else if (!_strnicmp(token4, "Menu", 4))
  1561:                 {
  1562:                     if (!_stricmp(token4, "MenuTitle")) pSettings->selectedElement = pSettings->MenuTitle;
  1563:                     else if (!_stricmp(token4, "MenuFrame")) pSettings->selectedElement = pSettings->MenuFrame;
  1564:                     else if (!_stricmp(token4, "MenuActive")) pSettings->selectedElement = pSettings->MenuActive;
  1565:                     else if (!_stricmp(token4, "MenuGrip")) pSettings->selectedElement = pSettings->MenuGrip;
  1566:                     else if (!_stricmp(token4, "MenuIndicator")) pSettings->selectedElement = pSettings->MenuIndicator;
  1567:                     else if (!_stricmp(token4, "MenuSeparator")) pSettings->selectedElement = pSettings->MenuSeparator;
  1568:                     else if (!_stricmp(token4, "MenuFrameBorder")) pSettings->selectedElement = pSettings->MenuFrameBorder;
  1569:                 }
  1570:                 else if (!_stricmp(token4, "Dock")) pSettings->selectedElement = pSettings->Dock;
  1571:                 else if (!_stricmp(token4, "DockBorder")) pSettings->selectedElement = pSettings->DockBorder;
  1572:                 else if (!_stricmp(token4, "Console")) pSettings->selectedElement = pSettings->Console;
  1573:                 else if (!_strnicmp(token4, "Window", 6))
  1574:                 {
  1575:                     if (!_strnicmp(&token4[6], "Title", 5))
  1576:                     {
  1577:                         if (!_stricmp(token4, "WindowTitleFocus")) pSettings->selectedElement = pSettings->WindowTitleFocus;
  1578:                         else if (!_stricmp(token4, "WindowTitleUnfocus")) pSettings->selectedElement = pSettings->WindowTitleUnfocus;
  1579:                     }
  1580:                     else if (!_strnicmp(&token4[6], "Label", 5))
  1581:                     {
  1582:                         if (!_stricmp(token4, "WindowLabelFocus")) pSettings->selectedElement = pSettings->WindowLabelFocus;
  1583:                         else if (!_stricmp(token4, "WindowLabelUnfocus")) pSettings->selectedElement = pSettings->WindowLabelUnfocus;
  1584:                     }
  1585:                     else if (!_strnicmp(&token4[6], "Button", 6))
  1586:                     {
  1587:                         if (!_stricmp(token4, "WindowButtonFocus")) pSettings->selectedElement = pSettings->WindowButtonFocus;
  1588:                         else if (!_stricmp(token4, "WindowButtonUnfocus")) pSettings->selectedElement = pSettings->WindowButtonUnfocus;
  1589:                         else if (!_stricmp(token4, "WindowButtonPressed")) pSettings->selectedElement = pSettings->WindowButtonPressed;
  1590:                     }
  1591:                     else if (!_strnicmp(&token4[6], "Grip", 4))
  1592:                     {
  1593:                         if (!_stricmp(token4, "WindowGripFocus")) pSettings->selectedElement = pSettings->WindowGripFocus;
  1594:                         else if (!_stricmp(token4, "WindowGripUnfocus")) pSettings->selectedElement = pSettings->WindowGripUnfocus;
  1595:                     }
  1596:                     else if (!_strnicmp(&token4[6], "Handle", 6))
  1597:                     {
  1598:                         if (!_stricmp(token4, "WindowHandleFocus")) pSettings->selectedElement = pSettings->WindowHandleFocus;
  1599:                         else if (!_stricmp(token4, "WindowHandleUnfocus")) pSettings->selectedElement = pSettings->WindowHandleUnfocus;
  1600:                     }
  1601:                 }
  1602:                 else if (!_strnicmp(token4, "Hardware", 8)) pSettings->selectedElement = pSettings->ExternalHardware;
  1603: 
  1604:                 else if (!_stricmp(token4, "Next") || !_stricmp(token4, "Previous") || strnlen_s(token4, sizeofArray(token4)) == 0)
  1605:                 {
  1606:                     if (!_stricmp(token4, "Previous"))
  1607:                     {
  1608:                         if (pSettings->selectedElement == pSettings->Toolbar) pSettings->selectedElement = pSettings->ExternalHardware;
  1609:                         else if (pSettings->selectedElement == pSettings->ToolbarBorder) pSettings->selectedElement = pSettings->Toolbar;
  1610:                         else if (pSettings->selectedElement == pSettings->ToolbarLabel) pSettings->selectedElement = pSettings->ToolbarBorder;
  1611:                         else if (pSettings->selectedElement == pSettings->ToolbarWindowLabel) pSettings->selectedElement = pSettings->ToolbarLabel;
  1612:                         else if (pSettings->selectedElement == pSettings->ToolbarClock) pSettings->selectedElement = pSettings->ToolbarWindowLabel;
  1613:                         else if (pSettings->selectedElement == pSettings->ToolbarButton) pSettings->selectedElement = pSettings->ToolbarClock;
  1614:                         else if (pSettings->selectedElement == pSettings->ToolbarButtonPressed) pSettings->selectedElement = pSettings->ToolbarButton;
  1615:                         else if (pSettings->selectedElement == pSettings->MenuTitle) pSettings->selectedElement = pSettings->ToolbarButtonPressed;
  1616:                         else if (pSettings->selectedElement == pSettings->MenuFrame) pSettings->selectedElement = pSettings->MenuTitle;
  1617:                         else if (pSettings->selectedElement == pSettings->MenuFrameBorder) pSettings->selectedElement = pSettings->MenuFrame;
  1618:                         else if (pSettings->selectedElement == pSettings->MenuActive) pSettings->selectedElement = pSettings->MenuFrameBorder;
  1619:                         else if (pSettings->selectedElement == pSettings->MenuGrip) pSettings->selectedElement = pSettings->MenuActive;
  1620:                         else if (pSettings->selectedElement == pSettings->MenuIndicator) pSettings->selectedElement = pSettings->MenuGrip;
  1621:                         else if (pSettings->selectedElement == pSettings->MenuSeparator) pSettings->selectedElement = pSettings->MenuIndicator;
  1622:                         else if (pSettings->selectedElement == pSettings->Dock) pSettings->selectedElement = pSettings->MenuSeparator;
  1623:                         else if (pSettings->selectedElement == pSettings->DockBorder) pSettings->selectedElement = pSettings->Dock;
  1624:                         else if (pSettings->selectedElement == pSettings->Console) pSettings->selectedElement = pSettings->DockBorder;
  1625: 
  1626:                         else if (pSettings->selectedElement == pSettings->WindowTitleFocus) pSettings->selectedElement = pSettings->Console;
  1627:                         else if (pSettings->selectedElement == pSettings->WindowLabelFocus) pSettings->selectedElement = pSettings->WindowTitleFocus;
  1628:                         else if (pSettings->selectedElement == pSettings->WindowButtonFocus) pSettings->selectedElement = pSettings->WindowLabelFocus;
  1629:                         else if (pSettings->selectedElement == pSettings->WindowGripFocus) pSettings->selectedElement = pSettings->WindowButtonFocus;
  1630:                         else if (pSettings->selectedElement == pSettings->WindowHandleFocus) pSettings->selectedElement = pSettings->WindowGripFocus;
  1631:                         else if (pSettings->selectedElement == pSettings->WindowButtonPressed) pSettings->selectedElement = pSettings->WindowHandleFocus;
  1632:                         else if (pSettings->selectedElement == pSettings->WindowTitleUnfocus) pSettings->selectedElement = pSettings->WindowButtonPressed;
  1633:                         else if (pSettings->selectedElement == pSettings->WindowLabelUnfocus) pSettings->selectedElement = pSettings->WindowTitleUnfocus;
  1634:                         else if (pSettings->selectedElement == pSettings->WindowButtonUnfocus) pSettings->selectedElement = pSettings->WindowLabelUnfocus;
  1635:                         else if (pSettings->selectedElement == pSettings->WindowGripUnfocus) pSettings->selectedElement = pSettings->WindowButtonUnfocus;
  1636:                         else if (pSettings->selectedElement == pSettings->WindowHandleUnfocus) pSettings->selectedElement = pSettings->WindowGripUnfocus;
  1637:                         else if (pSettings->selectedElement == pSettings->ExternalHardware) pSettings->selectedElement = pSettings->WindowHandleUnfocus;
  1638:                     }
  1639:                     else // if (!_stricmp(token4, "Next") || strnlen_s(token4, sizeofArray(token4)) == 0)
  1640:                     {
  1641:                         if (pSettings->selectedElement == pSettings->Toolbar) pSettings->selectedElement = pSettings->ToolbarBorder;
  1642:                         else if (pSettings->selectedElement == pSettings->ToolbarBorder) pSettings->selectedElement = pSettings->ToolbarLabel;
  1643:                         else if (pSettings->selectedElement == pSettings->ToolbarLabel) pSettings->selectedElement = pSettings->ToolbarWindowLabel;
  1644:                         else if (pSettings->selectedElement == pSettings->ToolbarWindowLabel) pSettings->selectedElement = pSettings->ToolbarClock;
  1645:                         else if (pSettings->selectedElement == pSettings->ToolbarClock) pSettings->selectedElement = pSettings->ToolbarButton;
  1646:                         else if (pSettings->selectedElement == pSettings->ToolbarButton) pSettings->selectedElement = pSettings->ToolbarButtonPressed;
  1647:                         else if (pSettings->selectedElement == pSettings->ToolbarButtonPressed) pSettings->selectedElement = pSettings->MenuTitle;
  1648:                         else if (pSettings->selectedElement == pSettings->MenuTitle) pSettings->selectedElement = pSettings->MenuFrame;
  1649:                         else if (pSettings->selectedElement == pSettings->MenuFrame) pSettings->selectedElement = pSettings->MenuFrameBorder;
  1650:                         else if (pSettings->selectedElement == pSettings->MenuFrameBorder) pSettings->selectedElement = pSettings->MenuActive;
  1651:                         else if (pSettings->selectedElement == pSettings->MenuActive) pSettings->selectedElement = pSettings->MenuGrip;
  1652:                         else if (pSettings->selectedElement == pSettings->MenuGrip) pSettings->selectedElement = pSettings->MenuIndicator;
  1653:                         else if (pSettings->selectedElement == pSettings->MenuIndicator) pSettings->selectedElement = pSettings->MenuSeparator;
  1654:                         else if (pSettings->selectedElement == pSettings->MenuSeparator) pSettings->selectedElement = pSettings->Dock;
  1655:                         else if (pSettings->selectedElement == pSettings->Dock) pSettings->selectedElement = pSettings->DockBorder;
  1656:                         else if (pSettings->selectedElement == pSettings->DockBorder) pSettings->selectedElement = pSettings->Console;
  1657:                         else if (pSettings->selectedElement == pSettings->Console) pSettings->selectedElement = pSettings->WindowTitleFocus;
  1658: 
  1659:                         else if (pSettings->selectedElement == pSettings->WindowTitleFocus) pSettings->selectedElement = pSettings->WindowLabelFocus;
  1660:                         else if (pSettings->selectedElement == pSettings->WindowLabelFocus) pSettings->selectedElement = pSettings->WindowButtonFocus;
  1661:                         else if (pSettings->selectedElement == pSettings->WindowButtonFocus) pSettings->selectedElement = pSettings->WindowGripFocus;
  1662:                         else if (pSettings->selectedElement == pSettings->WindowGripFocus) pSettings->selectedElement = pSettings->WindowHandleFocus;
  1663:                         else if (pSettings->selectedElement == pSettings->WindowHandleFocus) pSettings->selectedElement = pSettings->WindowButtonPressed;
  1664:                         else if (pSettings->selectedElement == pSettings->WindowButtonPressed) pSettings->selectedElement = pSettings->WindowTitleUnfocus;
  1665:                         else if (pSettings->selectedElement == pSettings->WindowTitleUnfocus) pSettings->selectedElement = pSettings->WindowLabelUnfocus;
  1666:                         else if (pSettings->selectedElement == pSettings->WindowLabelUnfocus) pSettings->selectedElement = pSettings->WindowButtonUnfocus;
  1667:                         else if (pSettings->selectedElement == pSettings->WindowButtonUnfocus) pSettings->selectedElement = pSettings->WindowGripUnfocus;
  1668:                         else if (pSettings->selectedElement == pSettings->WindowGripUnfocus) pSettings->selectedElement = pSettings->WindowHandleUnfocus;
  1669:                         else if (pSettings->selectedElement == pSettings->WindowHandleUnfocus) pSettings->selectedElement = pSettings->ExternalHardware;
  1670:                         else if (pSettings->selectedElement == pSettings->ExternalHardware) pSettings->selectedElement = pSettings->Toolbar;
  1671:                     }
  1672:                 }
  1673: 
  1674:                 if (pSettings->selectedElement == pSettings->Toolbar) strcpy_s(feedback, sizeofArray(feedback), "... Toolbar");
  1675:                 else if (pSettings->selectedElement == pSettings->ToolbarLabel) strcpy_s(feedback, sizeofArray(feedback), "... Toolbar Label");
  1676:                 else if (pSettings->selectedElement == pSettings->ToolbarWindowLabel) strcpy_s(feedback, sizeofArray(feedback), "... Toolbar WindowLabel");
  1677:                 else if (pSettings->selectedElement == pSettings->ToolbarClock) strcpy_s(feedback, sizeofArray(feedback), "... Toolbar Clock");
  1678:                 else if (pSettings->selectedElement == pSettings->ToolbarButton) strcpy_s(feedback, sizeofArray(feedback), "... Toolbar Button");
  1679:                 else if (pSettings->selectedElement == pSettings->ToolbarButtonPressed) strcpy_s(feedback, sizeofArray(feedback), "... Toolbar Button Pressed");
  1680:                 else if (pSettings->selectedElement == pSettings->ToolbarBorder) strcpy_s(feedback, sizeofArray(feedback), "... Toolbar Border");
  1681:                 else if (pSettings->selectedElement == pSettings->MenuTitle) strcpy_s(feedback, sizeofArray(feedback), "... Menu Title");
  1682:                 else if (pSettings->selectedElement == pSettings->MenuFrame) strcpy_s(feedback, sizeofArray(feedback), "... Menu Frame");
  1683:                 else if (pSettings->selectedElement == pSettings->MenuFrameBorder) strcpy_s(feedback, sizeofArray(feedback), "... Menu Frame Border");
  1684:                 else if (pSettings->selectedElement == pSettings->MenuActive) strcpy_s(feedback, sizeofArray(feedback), "... Menu Active");
  1685:                 else if (pSettings->selectedElement == pSettings->MenuGrip) strcpy_s(feedback, sizeofArray(feedback), "... Menu Grip");
  1686:                 else if (pSettings->selectedElement == pSettings->MenuIndicator) strcpy_s(feedback, sizeofArray(feedback), "... Menu Indicator");
  1687:                 else if (pSettings->selectedElement == pSettings->MenuSeparator) strcpy_s(feedback, sizeofArray(feedback), "... Menu Separator");
  1688:                 else if (pSettings->selectedElement == pSettings->Dock) strcpy_s(feedback, sizeofArray(feedback), "... Dock");
  1689:                 else if (pSettings->selectedElement == pSettings->DockBorder) strcpy_s(feedback, sizeofArray(feedback), "... Dock Border");
  1690:                 else if (pSettings->selectedElement == pSettings->Console) strcpy_s(feedback, sizeofArray(feedback), "... Console");
  1691: 
  1692:                 else if (pSettings->selectedElement == pSettings->WindowTitleFocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Title Focus");
  1693:                 else if (pSettings->selectedElement == pSettings->WindowTitleUnfocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Title Unfocus");
  1694:                 else if (pSettings->selectedElement == pSettings->WindowLabelFocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Label Focus");
  1695:                 else if (pSettings->selectedElement == pSettings->WindowLabelUnfocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Label Unfocus");
  1696:                 else if (pSettings->selectedElement == pSettings->WindowButtonFocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Button Focus");
  1697:                 else if (pSettings->selectedElement == pSettings->WindowButtonUnfocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Button Unfocus");
  1698:                 else if (pSettings->selectedElement == pSettings->WindowButtonPressed) strcpy_s(feedback, sizeofArray(feedback), "... Window Button Pressed");
  1699:                 else if (pSettings->selectedElement == pSettings->WindowGripFocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Grip Focus");
  1700:                 else if (pSettings->selectedElement == pSettings->WindowGripUnfocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Grip Unfocus");
  1701:                 else if (pSettings->selectedElement == pSettings->WindowHandleFocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Handle Focus");
  1702:                 else if (pSettings->selectedElement == pSettings->WindowHandleUnfocus) strcpy_s(feedback, sizeofArray(feedback), "... Window Handle Unfocus");
  1703:                 else if (pSettings->selectedElement == pSettings->ExternalHardware) strcpy_s(feedback, sizeofArray(feedback), "... Hardware");
  1704: 
  1705:                 if (strnlen_s(feedback, sizeofArray(feedback)) > 0)
  1706:                 {
  1707:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  1708: 
  1709:                     char broam[MAX_LINE_LENGTH];
  1710:                     sprintf_s(broam, sizeofArray(broam), "@xDesigner Feedback %s", feedback);
  1711:                     SendMessage(GetBBWnd(), BB_BROADCAST, 0, (LPARAM)broam);
  1712:                 }
  1713: 
  1714:                 return true;
  1715:             }
  1716: 
  1717:             //====================
  1718: 
  1719:             else if (!_stricmp(token3, "Modify"))
  1720:             {
  1721:                 if (!_stricmp(token4, "Appearance"))
  1722:                 {
  1723:                     if (!_stricmp(extra, "Previous"))
  1724:                     {
  1725:                         // Switch to the previous appearance type for the currently selected element...
  1726:                         if (pSettings->selectedElement == pSettings->MenuSeparator)
  1727:                         {
  1728:                             switch (pSettings->selectedElement->type)
  1729:                             {
  1730:                                 case B_SOLID: { pSettings->selectedElement->type = B_SUPERHORIZONTAL; break; }
  1731:                                 case B_HORIZONTAL: { pSettings->selectedElement->type = B_SOLID; break; }
  1732:                                 case B_MIRRORHORIZONTAL: { pSettings->selectedElement->type = B_HORIZONTAL; break; }
  1733:                                 case B_SPLITHORIZONTAL: { pSettings->selectedElement->type = B_MIRRORHORIZONTAL; break; }
  1734:                                 case B_SUPERHORIZONTAL: { pSettings->selectedElement->type = B_SPLITHORIZONTAL; break; }
  1735:                                 default: { pSettings->selectedElement->type = B_SOLID; break; }
  1736:                             }
  1737:                         }
  1738:                         else if (pSettings->selectedElement == pSettings->ToolbarBorder ||
  1739:                             pSettings->selectedElement == pSettings->MenuFrameBorder ||
  1740:                             pSettings->selectedElement == pSettings->DockBorder)
  1741:                         {
  1742:                             switch (pSettings->selectedElement->type)
  1743:                             {
  1744:                                 case B_PARENTRELATIVE: { pSettings->selectedElement->type = B_SUPERVERTICAL; break; }
  1745:                                 case B_HORIZONTAL: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1746:                                 case B_VERTICAL: { pSettings->selectedElement->type = B_HORIZONTAL; break; }
  1747:                                 case B_MIRRORHORIZONTAL: { pSettings->selectedElement->type = B_VERTICAL; break; }
  1748:                                 case B_MIRRORVERTICAL: { pSettings->selectedElement->type = B_MIRRORHORIZONTAL; break; }
  1749:                                 case B_SPLITHORIZONTAL: { pSettings->selectedElement->type = B_MIRRORVERTICAL; break; }
  1750:                                 case B_SPLITVERTICAL: { pSettings->selectedElement->type = B_SPLITHORIZONTAL; break; }
  1751:                                 case B_SUPERHORIZONTAL: { pSettings->selectedElement->type = B_SPLITVERTICAL; break; }
  1752:                                 case B_SUPERVERTICAL: { pSettings->selectedElement->type = B_SUPERHORIZONTAL; break; }
  1753:                                 default: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1754:                             }
  1755:                         }
  1756:                         else switch (pSettings->selectedElement->type)
  1757:                         {
  1758:                             case B_PARENTRELATIVE: { pSettings->selectedElement->type = B_SUPERVERTICAL; break; }
  1759:                             case B_SOLID: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1760:                             case B_HORIZONTAL: { pSettings->selectedElement->type = B_SOLID; break; }
  1761:                             case B_VERTICAL: { pSettings->selectedElement->type = B_HORIZONTAL; break; }
  1762:                             case B_DIAGONAL: { pSettings->selectedElement->type = B_VERTICAL; break; }
  1763:                             case B_CROSSDIAGONAL: { pSettings->selectedElement->type = B_DIAGONAL; break; }
  1764:                             case B_PIPECROSS: { pSettings->selectedElement->type = B_CROSSDIAGONAL; break; }
  1765:                             case B_ELLIPTIC: { pSettings->selectedElement->type = B_PIPECROSS; break; }
  1766:                             case B_RECTANGLE: { pSettings->selectedElement->type = B_ELLIPTIC; break; }
  1767:                             case B_PYRAMID: { pSettings->selectedElement->type = B_RECTANGLE; break; }
  1768:                             case B_MIRRORHORIZONTAL: { pSettings->selectedElement->type = B_PYRAMID; break; }
  1769:                             case B_MIRRORVERTICAL: { pSettings->selectedElement->type = B_MIRRORHORIZONTAL; break; }
  1770:                             case B_SPLITSOLID: { pSettings->selectedElement->type = B_MIRRORVERTICAL; break; }
  1771:                             case B_SPLITHORIZONTAL: { pSettings->selectedElement->type = B_SPLITSOLID; break; }
  1772:                             case B_SPLITVERTICAL: { pSettings->selectedElement->type = B_SPLITHORIZONTAL; break; }
  1773:                             case B_SUPERHORIZONTAL: { pSettings->selectedElement->type = B_SPLITVERTICAL; break; }
  1774:                             case B_SUPERVERTICAL: { pSettings->selectedElement->type = B_SUPERHORIZONTAL; break; }
  1775:                             default: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1776:                         }
  1777:                     }
  1778:                     else // if (!_stricmp(extra, "Next") || strnlen_s(token4, sizeofArray(token4)) == 0)
  1779:                     {
  1780:                         // Switch to the next appearance type for the currently selected element...
  1781:                         if (pSettings->selectedElement == pSettings->MenuSeparator)
  1782:                         {
  1783:                             switch (pSettings->selectedElement->type)
  1784:                             {
  1785:                                 case B_SOLID: { pSettings->selectedElement->type = B_HORIZONTAL; break; }
  1786:                                 case B_HORIZONTAL: { pSettings->selectedElement->type = B_MIRRORHORIZONTAL; break; }
  1787:                                 case B_MIRRORHORIZONTAL: { pSettings->selectedElement->type = B_SPLITHORIZONTAL; break; }
  1788:                                 case B_SPLITHORIZONTAL: { pSettings->selectedElement->type = B_SUPERHORIZONTAL; break; }
  1789:                                 case B_SUPERHORIZONTAL: { pSettings->selectedElement->type = B_SOLID; break; }
  1790:                                 default: { pSettings->selectedElement->type = B_SOLID; break; }
  1791:                             }
  1792:                         }
  1793:                         else if (pSettings->selectedElement == pSettings->ToolbarBorder ||
  1794:                             pSettings->selectedElement == pSettings->MenuFrameBorder ||
  1795:                             pSettings->selectedElement == pSettings->DockBorder)
  1796:                         {
  1797:                             switch (pSettings->selectedElement->type)
  1798:                             {
  1799:                                 case B_PARENTRELATIVE: { pSettings->selectedElement->type = B_HORIZONTAL; break; }
  1800:                                 case B_HORIZONTAL: { pSettings->selectedElement->type = B_VERTICAL; break; }
  1801:                                 case B_VERTICAL: { pSettings->selectedElement->type = B_MIRRORHORIZONTAL; break; }
  1802:                                 case B_MIRRORHORIZONTAL: { pSettings->selectedElement->type = B_MIRRORVERTICAL; break; }
  1803:                                 case B_MIRRORVERTICAL: { pSettings->selectedElement->type = B_SPLITHORIZONTAL; break; }
  1804:                                 case B_SPLITHORIZONTAL: { pSettings->selectedElement->type = B_SPLITVERTICAL; break; }
  1805:                                 case B_SPLITVERTICAL: { pSettings->selectedElement->type = B_SUPERHORIZONTAL; break; }
  1806:                                 case B_SUPERHORIZONTAL: { pSettings->selectedElement->type = B_SUPERVERTICAL; break; }
  1807:                                 case B_SUPERVERTICAL: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1808:                                 default: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1809:                             }
  1810:                         }
  1811:                         else switch (pSettings->selectedElement->type)
  1812:                         {
  1813:                             case B_PARENTRELATIVE: { pSettings->selectedElement->type = B_SOLID; break; }
  1814:                             case B_SOLID: { pSettings->selectedElement->type = B_HORIZONTAL; break; }
  1815:                             case B_HORIZONTAL: { pSettings->selectedElement->type = B_VERTICAL; break; }
  1816:                             case B_VERTICAL: { pSettings->selectedElement->type = B_DIAGONAL; break; }
  1817:                             case B_DIAGONAL: { pSettings->selectedElement->type = B_CROSSDIAGONAL; break; }
  1818:                             case B_CROSSDIAGONAL: { pSettings->selectedElement->type = B_PIPECROSS; break; }
  1819:                             case B_PIPECROSS: { pSettings->selectedElement->type = B_ELLIPTIC; break; }
  1820:                             case B_ELLIPTIC: { pSettings->selectedElement->type = B_RECTANGLE; break; }
  1821:                             case B_RECTANGLE: { pSettings->selectedElement->type = B_PYRAMID; break; }
  1822:                             case B_PYRAMID: { pSettings->selectedElement->type = B_MIRRORHORIZONTAL; break; }
  1823:                             case B_MIRRORHORIZONTAL: { pSettings->selectedElement->type = B_MIRRORVERTICAL; break; }
  1824:                             case B_MIRRORVERTICAL: { pSettings->selectedElement->type = B_SPLITSOLID; break; }
  1825:                             case B_SPLITSOLID: { pSettings->selectedElement->type = B_SPLITHORIZONTAL; break; }
  1826:                             case B_SPLITHORIZONTAL: { pSettings->selectedElement->type = B_SPLITVERTICAL; break; }
  1827:                             case B_SPLITVERTICAL: { pSettings->selectedElement->type = B_SUPERHORIZONTAL; break; }
  1828:                             case B_SUPERHORIZONTAL: { pSettings->selectedElement->type = B_SUPERVERTICAL; break; }
  1829:                             case B_SUPERVERTICAL: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1830:                             default: { pSettings->selectedElement->type = B_PARENTRELATIVE; break; }
  1831:                         }
  1832:                     }
  1833: 
  1834:                     if (pSettings->selectedElement->type == B_PARENTRELATIVE) pSettings->selectedElement->parentRelative = true;
  1835:                     else pSettings->selectedElement->parentRelative = false;
  1836: 
  1837:                     switch (pSettings->selectedElement->type)
  1838:                     {
  1839:                         case B_PARENTRELATIVE: { strcpy_s(feedback, sizeofArray(feedback), "... ParentRelative"); break; }
  1840:                         case B_SOLID: { strcpy_s(feedback, sizeofArray(feedback), "... Solid (1 color)"); break; }
  1841:                         case B_HORIZONTAL: { strcpy_s(feedback, sizeofArray(feedback), "... Horizontal (2 colors)"); break; }
  1842:                         case B_VERTICAL: { strcpy_s(feedback, sizeofArray(feedback), "... Vertical (2 colors)"); break; }
  1843:                         case B_DIAGONAL: { strcpy_s(feedback, sizeofArray(feedback), "... Diagonal (2 colors)"); break; }
  1844:                         case B_CROSSDIAGONAL: { strcpy_s(feedback, sizeofArray(feedback), "... CrossDiagonal (2 colors)"); break; }
  1845:                         case B_PIPECROSS: { strcpy_s(feedback, sizeofArray(feedback), "... Pipecross (2 colors)"); break; }
  1846:                         case B_ELLIPTIC: { strcpy_s(feedback, sizeofArray(feedback), "... Elliptic (2 colors)"); break; }
  1847:                         case B_RECTANGLE: { strcpy_s(feedback, sizeofArray(feedback), "... Rectangle (2 colors)"); break; }
  1848:                         case B_PYRAMID: { strcpy_s(feedback, sizeofArray(feedback), "... Pyramid (2 colors)"); break; }
  1849:                         case B_MIRRORHORIZONTAL: { strcpy_s(feedback, sizeofArray(feedback), "... MirrorHorizontal (2 colors)"); break; }
  1850:                         case B_MIRRORVERTICAL: { strcpy_s(feedback, sizeofArray(feedback), "... MirrorVertical (2 colors)"); break; }
  1851:                         case B_SPLITSOLID: { strcpy_s(feedback, sizeofArray(feedback), "... SplitSolid (2 colors)"); break; }
  1852:                         case B_SPLITHORIZONTAL: { strcpy_s(feedback, sizeofArray(feedback), "... SplitHorizontal (4 colors)"); break; }
  1853:                         case B_SPLITVERTICAL: { strcpy_s(feedback, sizeofArray(feedback), "... SplitVertical (4 colors)"); break; }
  1854:                         case B_SUPERHORIZONTAL: { strcpy_s(feedback, sizeofArray(feedback), "... SuperHorizontal (8 colors)"); break; }
  1855:                         case B_SUPERVERTICAL: { strcpy_s(feedback, sizeofArray(feedback), "... SuperVertical (8 colors)"); break; }
  1856:                         default: { strcpy_s(feedback, sizeofArray(feedback), "... Error: Unsupported appearance!"); break; }
  1857:                     }
  1858: 
  1859:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  1860:                 }
  1861: 
  1862:                 //====================
  1863: 
  1864:                 else if (!_stricmp(token4, "Bevel"))
  1865:                 {
  1866:                     // Switch to the next bevel type/position for the currently selected element...
  1867:                     if ((pSettings->selectedElement != pSettings->MenuSeparator) && (pSettings->selectedElement != pSettings->ToolbarBorder) &&
  1868:                         (pSettings->selectedElement != pSettings->MenuFrameBorder) && (pSettings->selectedElement != pSettings->DockBorder) &&
  1869:                         (pSettings->selectedElement != pSettings->ExternalHardware))
  1870:                     {
  1871:                         if (pSettings->selectedElement->bevelstyle == BEVEL_FLAT)
  1872:                         {
  1873:                             pSettings->selectedElement->bevelstyle = BEVEL_RAISED;
  1874:                             pSettings->selectedElement->bevelposition = BEVEL1;
  1875:                             strcpy_s(feedback, sizeofArray(feedback), "... Raised Bevel1");
  1876:                         }
  1877:                         else if (pSettings->selectedElement->bevelstyle == BEVEL_RAISED)
  1878:                         {
  1879:                             if (pSettings->selectedElement->bevelposition == BEVEL1)
  1880:                             {
  1881:                                 pSettings->selectedElement->bevelposition = BEVEL2;
  1882:                                 strcpy_s(feedback, sizeofArray(feedback), "... Raised Bevel2");
  1883:                             }
  1884:                             else
  1885:                             {
  1886:                                 pSettings->selectedElement->bevelstyle = BEVEL_SUNKEN;
  1887:                                 pSettings->selectedElement->bevelposition = BEVEL1;
  1888:                                 strcpy_s(feedback, sizeofArray(feedback), "... Sunken Bevel1");
  1889:                             }
  1890:                         }
  1891:                         else if (pSettings->selectedElement->bevelstyle == BEVEL_SUNKEN)
  1892:                         {
  1893:                             if (pSettings->selectedElement->bevelposition == BEVEL1)
  1894:                             {
  1895:                                 pSettings->selectedElement->bevelposition = BEVEL2;
  1896:                                 strcpy_s(feedback, sizeofArray(feedback), "... Sunken Bevel2");
  1897:                             }
  1898:                             else
  1899:                             {
  1900:                                 pSettings->selectedElement->bevelstyle = BEVEL_FLAT;
  1901:                                 pSettings->selectedElement->bevelposition = BEVEL1; // ...just in case later on? (most prefer B1 over B2 after all ;))
  1902:                                 strcpy_s(feedback, sizeofArray(feedback), "... Flat");
  1903:                             }
  1904:                         }
  1905: 
  1906:                         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  1907:                     }
  1908:                     else
  1909:                     {
  1910:                         pSettings->selectedElement->bevelstyle = BEVEL_FLAT;
  1911:                         strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  1912:                     }
  1913:                 }
  1914: 
  1915:                 //====================
  1916: 
  1917:                 else if (!_stricmp(token4, "Interlaced"))
  1918:                 {
  1919:                     if ((pSettings->selectedElement != pSettings->MenuSeparator) && (pSettings->selectedElement != pSettings->ToolbarBorder) &&
  1920:                         (pSettings->selectedElement != pSettings->MenuFrameBorder) && (pSettings->selectedElement != pSettings->DockBorder) &&
  1921:                         (pSettings->selectedElement != pSettings->ExternalHardware))
  1922:                     {
  1923:                         if (!pSettings->selectedElement->interlaced)
  1924:                         {
  1925:                             pSettings->selectedElement->interlaced = true;
  1926:                             strcpy_s(feedback, sizeofArray(feedback), "... Interlace enabled");
  1927:                         }
  1928:                         else
  1929:                         {
  1930:                             pSettings->selectedElement->interlaced = false;
  1931:                             strcpy_s(feedback, sizeofArray(feedback), "... Interlace disabled");
  1932:                         }
  1933: 
  1934:                         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  1935:                     }
  1936:                     else strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  1937:                 }
  1938: 
  1939:                 //====================
  1940: 
  1941:                 else if (!_stricmp(token4, "Colors"))
  1942:                 {
  1943:                     COLORREF colors[8] = { pSettings->selectedElement->Color1, pSettings->selectedElement->Color2, pSettings->selectedElement->Color3, pSettings->selectedElement->Color4, pSettings->selectedElement->Color5, pSettings->selectedElement->Color6, pSettings->selectedElement->Color7, pSettings->selectedElement->Color8 };
  1944: 
  1945:                     for (int n = 1; n <= 8; n++)
  1946:                     {
  1947:                         COLORREF* color;
  1948:                         switch (n)
  1949:                         {
  1950:                             case 1: { color = &pSettings->selectedElement->Color1; break; }
  1951:                             case 2: { color = &pSettings->selectedElement->Color2; break; }
  1952:                             case 3: { color = &pSettings->selectedElement->Color3; break; }
  1953:                             case 4: { color = &pSettings->selectedElement->Color4; break; }
  1954:                             case 5: { color = &pSettings->selectedElement->Color5; break; }
  1955:                             case 6: { color = &pSettings->selectedElement->Color6; break; }
  1956:                             case 7: { color = &pSettings->selectedElement->Color7; break; }
  1957:                             case 8: { color = &pSettings->selectedElement->Color8; break; }
  1958:                             default: return false;
  1959:                         }
  1960: 
  1961:                         if (!_stricmp(extra, "Greyscale"))
  1962:                         {
  1963:                             int greyscale = ((BYTE)GetRValue(*color) + (BYTE)GetGValue(*color) + (BYTE)GetBValue(*color)) / 3;
  1964:                             *color = RGB((BYTE)greyscale, (BYTE)greyscale, (BYTE)greyscale);
  1965:                             strcpy_s(feedback, sizeofArray(feedback), "... converted to greyscale!");
  1966:                         }
  1967:                         if (!_stricmp(extra, "Sepia"))
  1968:                         {
  1969:                             double r, g, b;
  1970:                             r = (GetRValue(*color) * 0.393) + (GetGValue(*color) * 0.769) + (GetBValue(*color) * 0.189);
  1971:                             if (r > 255) r = 255;
  1972:                             g = (GetRValue(*color) * 0.349) + (GetGValue(*color) * 0.686) + (GetBValue(*color) * 0.168);
  1973:                             if (g > 255) g = 255;
  1974:                             b = (GetRValue(*color) * 0.272) + (GetGValue(*color) * 0.534) + (GetBValue(*color) * 0.131);
  1975:                             if (b > 255) b = 255;
  1976:                             *color = RGB((BYTE)r, (BYTE)g, (BYTE)b);
  1977:                             strcpy_s(feedback, sizeofArray(feedback), "... converted to sepia!");
  1978:                         }
  1979:                         else if (!_stricmp(extra, "Darken"))
  1980:                         {
  1981:                             double r = GetRValue(*color) * 0.9;
  1982:                             double g = GetGValue(*color) * 0.9;
  1983:                             double b = GetBValue(*color) * 0.9;
  1984:                             *color = RGB((BYTE)r, (BYTE)g, (BYTE)b);
  1985:                             strcpy_s(feedback, sizeofArray(feedback), "... colors darkened!");
  1986:                         }
  1987:                         else if (!_stricmp(extra, "Lighten"))
  1988:                         {
  1989:                             bool ceilingHit = false;
  1990:                             double r = GetRValue(*color) * 1.1;
  1991:                             if (r > 255) ceilingHit = true;
  1992:                             double g = GetGValue(*color) * 1.1;
  1993:                             if (g > 255) ceilingHit = true;
  1994:                             double b = GetBValue(*color) * 1.1;
  1995:                             if (b > 255) ceilingHit = true;
  1996:                             if (!ceilingHit)
  1997:                             {
  1998:                                 *color = RGB((BYTE)r, (BYTE)g, (BYTE)b);
  1999:                                 strcpy_s(feedback, sizeofArray(feedback), "... colors lightened!");
  2000:                             }
  2001:                             else strcpy_s(feedback, sizeofArray(feedback), "... can not go further!");
  2002:                         }
  2003:                         else if (!_stricmp(extra, "Invert"))
  2004:                         {
  2005:                             BYTE r = 255 - GetRValue(*color);
  2006:                             BYTE g = 255 - GetGValue(*color);
  2007:                             BYTE b = 255 - GetBValue(*color);
  2008:                             *color = RGB((BYTE)r, (BYTE)g, (BYTE)b);
  2009:                             strcpy_s(feedback, sizeofArray(feedback), "... colors inverted!");
  2010:                         }
  2011:                         else if (!_stricmp(extra, "Flip"))
  2012:                         {
  2013:                             if ((pSettings->selectedElement->type == B_PARENTRELATIVE) || pSettings->selectedElement->parentRelative) break;
  2014:                             else if ((pSettings->selectedElement->type == B_SUPERHORIZONTAL) || (pSettings->selectedElement->type == B_SUPERVERTICAL)) *color = colors[8-n];
  2015:                             else if (((pSettings->selectedElement->type == B_SPLITHORIZONTAL) || (pSettings->selectedElement->type == B_SPLITVERTICAL)) && (n<=4)) *color = colors[4-n];
  2016:                             else if ((pSettings->selectedElement->type != B_SOLID) && (n<=2)) *color = colors[2-n];
  2017:                             else break;
  2018:                             strcpy_s(feedback, sizeofArray(feedback), "... colors flipped!");
  2019:                         }
  2020:                     }
  2021:                 }
  2022: 
  2023:                 //====================
  2024: 
  2025:                 else if (IsInString(token4, "Color"))
  2026:                 {
  2027:                     // Check if its a #RRGGBB type string...
  2028:                     if (*extra == '#') memmove(extra, extra + 1, strnlen_s(extra, sizeofArray(extra)));
  2029:                     COLORREF newColor = strtol(extra, NULL, 16);
  2030:                     newColor = RGB(GetBValue(newColor), GetGValue(newColor), GetRValue(newColor)); // Swap from RGB to BGR format...
  2031: 
  2032:                     if (!_strnicmp(token4, "Color", 5)) // -> Color1-8
  2033:                     {
  2034:                         int color = atoi(&token4[5]);
  2035:                         switch (color)
  2036:                         {
  2037:                             case 1: { pSettings->selectedElement->Color1 = newColor; break; }
  2038:                             case 2: { pSettings->selectedElement->Color2 = newColor; break; }
  2039:                             case 3: { pSettings->selectedElement->Color3 = newColor; break; }
  2040:                             case 4: { pSettings->selectedElement->Color4 = newColor; break; }
  2041:                             case 5: { pSettings->selectedElement->Color5 = newColor; break; }
  2042:                             case 6: { pSettings->selectedElement->Color6 = newColor; break; }
  2043:                             case 7: { pSettings->selectedElement->Color7 = newColor; break; }
  2044:                             case 8: { pSettings->selectedElement->Color8 = newColor; break; }
  2045:                             default: break;
  2046:                         }
  2047:                     }
  2048:                     else if (!_stricmp(token4, "TextColor")) pSettings->selectedElement->TextColor = newColor;
  2049:                     else if (!_stricmp(token4, "OutlineColor"))
  2050:                     {
  2051:                         pSettings->selectedElement->OutlineColor = newColor;
  2052:                         pSettings->selectedElement->FontOutline = true;
  2053:                     }
  2054:                     else if (!_stricmp(token4, "ShadowColor"))
  2055:                     {
  2056:                         pSettings->selectedElement->ShadowColor = newColor;
  2057:                         pSettings->selectedElement->FontShadow = true;
  2058:                     }
  2059:                     else if (!_stricmp(token4, "DisabledColor")) pSettings->selectedElement->disabledColor = newColor;
  2060:                     else if (!_stricmp(token4, "GlyphColor")) pSettings->selectedElement->BulletColor = newColor; // -> bulletColor, picColor, foregroundColor (TENTATIVE NAMING "GlyphColor")
  2061:                     else if (!_stricmp(token4, "BorderColor")) pSettings->selectedElement->borderColor = newColor;
  2062:                 }
  2063: 
  2064:                 //====================
  2065: 
  2066:                 else if (!_stricmp(token4, "MarginWidth"))
  2067:                 {
  2068:                     if ((pSettings->selectedElement != pSettings->MenuSeparator) && (pSettings->selectedElement != pSettings->ToolbarBorder) &&
  2069:                         (pSettings->selectedElement != pSettings->MenuFrameBorder) && (pSettings->selectedElement != pSettings->DockBorder) &&
  2070:                         (pSettings->selectedElement != pSettings->ExternalHardware))
  2071:                     {
  2072:                         if (!_stricmp(extra, "+")) pSettings->selectedElement->marginWidth += pSettings->scalingFactorHiDPI;
  2073:                         else if (!_stricmp(extra, "-"))
  2074:                         {
  2075:                             pSettings->selectedElement->marginWidth -= pSettings->scalingFactorHiDPI;
  2076:                             if (pSettings->selectedElement->marginWidth < 0) pSettings->selectedElement->marginWidth = 0;
  2077:                         }
  2078: 
  2079:                         sprintf_s(feedback, sizeofArray(feedback), "... %d pixels (eq)", (pSettings->selectedElement->marginWidth / pSettings->scalingFactorHiDPI));
  2080:                     }
  2081:                     else strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  2082: 
  2083: //                  SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2084:                 }
  2085: 
  2086:                 //====================
  2087: 
  2088:                 else if (!_stricmp(token4, "BorderWidth"))
  2089:                 {
  2090:                     if ((pSettings->selectedElement != pSettings->MenuSeparator) &&
  2091:                         (pSettings->selectedElement != pSettings->ExternalHardware))
  2092:                     {
  2093:                         // Redirect any gradient border BorderWidth commands to their respective "parent" elements...
  2094:                         StyleItem* styleItemPtr;
  2095:                         if (pSettings->selectedElement == pSettings->ToolbarBorder) styleItemPtr = pSettings->Toolbar;
  2096:                         else if (pSettings->selectedElement == pSettings->MenuFrameBorder) styleItemPtr = pSettings->MenuFrame;
  2097:                         else if (pSettings->selectedElement == pSettings->DockBorder) styleItemPtr = pSettings->Dock;
  2098:                         else styleItemPtr = pSettings->selectedElement;
  2099: 
  2100:                         if (!_stricmp(extra, "+")) styleItemPtr->borderWidth += pSettings->scalingFactorHiDPI;
  2101:                         else if (!_stricmp(extra, "-"))
  2102:                         {
  2103:                             styleItemPtr->borderWidth -= pSettings->scalingFactorHiDPI;
  2104:                             if (styleItemPtr->borderWidth < 0) styleItemPtr->borderWidth = 0;
  2105:                         }
  2106: 
  2107:                         if (styleItemPtr->borderWidth > 0) styleItemPtr->bordered = true;
  2108:                         else styleItemPtr->bordered = false;
  2109: 
  2110:                         sprintf_s(feedback, sizeofArray(feedback), "... %d pixels (eq)", (styleItemPtr->borderWidth / pSettings->scalingFactorHiDPI));
  2111:                     }
  2112:                     else strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  2113: 
  2114: //                  SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2115:                 }
  2116: 
  2117:                 //====================
  2118: 
  2119:                 else if (IsInString(token4, "Font"))
  2120:                 {
  2121:                     if ((pSettings->selectedElement != pSettings->ToolbarButton) && (pSettings->selectedElement != pSettings->ToolbarButtonPressed)
  2122:                         && (pSettings->selectedElement != pSettings->MenuIndicator) && (pSettings->selectedElement != pSettings->MenuSeparator)
  2123:                         && (pSettings->selectedElement != pSettings->ToolbarBorder) && (pSettings->selectedElement != pSettings->MenuFrameBorder)
  2124:                         && (pSettings->selectedElement != pSettings->DockBorder)
  2125:                         && (pSettings->selectedElement != pSettings->WindowTitleFocus) && (pSettings->selectedElement != pSettings->WindowTitleUnfocus)
  2126:                         && (pSettings->selectedElement != pSettings->WindowButtonFocus) && (pSettings->selectedElement != pSettings->WindowButtonUnfocus)
  2127:                         && (pSettings->selectedElement != pSettings->WindowButtonPressed)
  2128:                         && (pSettings->selectedElement != pSettings->WindowGripFocus) && (pSettings->selectedElement != pSettings->WindowGripUnfocus)
  2129:                         && (pSettings->selectedElement != pSettings->WindowHandleFocus) && (pSettings->selectedElement != pSettings->WindowHandleUnfocus)
  2130:                         && (pSettings->selectedElement != pSettings->ExternalHardware))
  2131:                     {
  2132:                         if (!_stricmp(token4, "Font"))
  2133:                         {
  2134:                             if (strnlen_s(extra, sizeofArray(extra)) > 0) // -> Font specified!
  2135:                             {
  2136:                                 if (strchr(extra, '\"')) StrRemoveEncap(extra);
  2137:                                 if (strchr(extra, '/')) // -> Font/Size/Weight format
  2138:                                 {
  2139:                                     ParseFontString(extra, pSettings->selectedElement);
  2140:                                     pSettings->selectedElement->FontHeight *= pSettings->scalingFactorHiDPI;
  2141:                                 }
  2142:                                 else // -> Font name only
  2143:                                 {
  2144: //                                  strncpy(pSettings->selectedElement->Font, extra, sizeof(pSettings->selectedElement->Font));
  2145:                                     strncpy_s(pSettings->selectedElement->Font, sizeof(pSettings->selectedElement->Font), extra, _TRUNCATE);
  2146:                                     pSettings->selectedElement->Font[sizeof(pSettings->selectedElement->Font) - 1] = '\0'; // Failsafe
  2147:                                 }
  2148:                             }
  2149:                             else // -> Open choose font dialog...
  2150:                             {
  2151:                                 static LOGFONT lf;
  2152:                                 ZeroMemory(&lf, sizeof(lf));
  2153:                                 strcpy_s(lf.lfFaceName, sizeofArray(lf.lfFaceName), pSettings->selectedElement->Font);
  2154:                                 lf.lfHeight = -MulDiv((pSettings->selectedElement->FontHeight / pSettings->scalingFactorHiDPI), GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
  2155:                                 lf.lfWeight = pSettings->selectedElement->FontWeight;
  2156: 
  2157:                                 CHOOSEFONT cf;
  2158:                                 ZeroMemory(&cf, sizeof(cf));
  2159:                                 cf.lStructSize = sizeof(cf);
  2160:                                 cf.hwndOwner = NULL;
  2161:                                 cf.lpLogFont = &lf;
  2162:                                 cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
  2163: 
  2164:                                 if (ChooseFont(&cf) == TRUE)
  2165:                                 {
  2166:                                     if (strnlen_s(lf.lfFaceName, sizeofArray(lf.lfFaceName)) > 0)
  2167:                                     {
  2168:                                         strcpy_s(pSettings->selectedElement->Font, sizeofArray(pSettings->selectedElement->Font), lf.lfFaceName);
  2169:                                         pSettings->selectedElement->FontHeight = cf.iPointSize / 10; // Note: iPointSize is the size of the selected font in units of *1/10* of a point... :)
  2170:                                         if ((cf.nFontType == BOLD_FONTTYPE) || (lf.lfWeight >= FW_BOLD)) pSettings->selectedElement->FontWeight = FW_BOLD;
  2171:                                         else pSettings->selectedElement->FontWeight = FW_NORMAL;
  2172: 
  2173:                                         sprintf_s(feedback, sizeofArray(feedback), "... %s/%d/", pSettings->selectedElement->Font, pSettings->selectedElement->FontHeight);
  2174:                                         if (pSettings->selectedElement->FontWeight == FW_BOLD) strcat_s(feedback, sizeofArray(feedback), "Bold");
  2175:                                         else strcat_s(feedback, sizeofArray(feedback), "Normal");
  2176:                                         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2177: 
  2178:                                         pSettings->selectedElement->FontHeight *= pSettings->scalingFactorHiDPI; // We apply the internal HiDPI scaling factor as applicable *after* displaying the selected value in "1x" style format...
  2179:                                     }
  2180:                                 }
  2181:                             }
  2182:                         }
  2183:                         else if (!_stricmp(token4, "FontHeight"))
  2184:                         {
  2185:                             if (!_stricmp(extra, "+")) pSettings->selectedElement->FontHeight += pSettings->scalingFactorHiDPI;
  2186:                             else if (!_stricmp(extra, "-"))
  2187:                             {
  2188:                                 pSettings->selectedElement->FontHeight -= pSettings->scalingFactorHiDPI;
  2189:                                 if (pSettings->selectedElement->FontHeight < pSettings->scalingFactorHiDPI) pSettings->selectedElement->FontHeight = pSettings->scalingFactorHiDPI;
  2190:                             }
  2191: 
  2192:                             sprintf_s(feedback, sizeofArray(feedback), "... %d points (eq)", (pSettings->selectedElement->FontHeight / pSettings->scalingFactorHiDPI));
  2193:                             SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2194:                         }
  2195:                         else if (!_stricmp(token4, "FontWeight"))
  2196:                         {
  2197:                             if (pSettings->selectedElement->FontWeight == FW_NORMAL)
  2198:                             {
  2199:                                 pSettings->selectedElement->FontWeight = FW_BOLD;
  2200:                                 strcpy_s(feedback, sizeofArray(feedback), "... Bold");
  2201:                             }
  2202:                             else
  2203:                             {
  2204:                                 pSettings->selectedElement->FontWeight = FW_NORMAL;
  2205:                                 strcpy_s(feedback, sizeofArray(feedback), "... Normal");
  2206:                             }
  2207: 
  2208:                             SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2209:                         }
  2210:                     }
  2211:                     else strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  2212:                 }
  2213: 
  2214:                 //====================
  2215: 
  2216:                 else if (!_stricmp(token4, "Alignment"))
  2217:                 {
  2218:                     if ((pSettings->selectedElement != pSettings->MenuSeparator) && (pSettings->selectedElement != pSettings->ToolbarBorder) &&
  2219:                         (pSettings->selectedElement != pSettings->MenuFrameBorder) && (pSettings->selectedElement != pSettings->DockBorder) &&
  2220:                         (pSettings->selectedElement != pSettings->ExternalHardware))
  2221:                     {
  2222:                         if (pSettings->selectedElement->Justify == DT_LEFT)
  2223:                         {
  2224:                             pSettings->selectedElement->Justify = DT_CENTER;
  2225:                             strcpy_s(feedback, sizeofArray(feedback), "... Center");
  2226:                         }
  2227:                         else if (pSettings->selectedElement->Justify == DT_CENTER)
  2228:                         {
  2229:                             pSettings->selectedElement->Justify = DT_RIGHT;
  2230:                             strcpy_s(feedback, sizeofArray(feedback), "... Right");
  2231:                         }
  2232:                         else // if (pSettings->selectedElement->Justify == DT_RIGHT)
  2233:                         {
  2234:                             pSettings->selectedElement->Justify = DT_LEFT;
  2235:                             strcpy_s(feedback, sizeofArray(feedback), "... Left");
  2236:                         }
  2237: 
  2238:                         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2239:                     }
  2240:                     else strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  2241:                 }
  2242: 
  2243:                 //====================
  2244: 
  2245:                 else if (!_stricmp(token4, "Outline"))
  2246:                 {
  2247:                     if ((pSettings->selectedElement != pSettings->MenuSeparator) && (pSettings->selectedElement != pSettings->ToolbarBorder) &&
  2248:                         (pSettings->selectedElement != pSettings->MenuFrameBorder) && (pSettings->selectedElement != pSettings->DockBorder) &&
  2249:                         (pSettings->selectedElement != pSettings->ExternalHardware))
  2250:                     {
  2251:                         if (!pSettings->selectedElement->FontOutline)
  2252:                         {
  2253:                             pSettings->selectedElement->FontOutline = true;
  2254:                             strcpy_s(feedback, sizeofArray(feedback), "... Outline enabled");
  2255:                         }
  2256:                         else
  2257:                         {
  2258:                             pSettings->selectedElement->FontOutline = false;
  2259:                             strcpy_s(feedback, sizeofArray(feedback), "... Outline disabled");
  2260:                         }
  2261: 
  2262:                         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2263:                     }
  2264:                     else strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  2265:                 }
  2266: 
  2267:                 //====================
  2268: 
  2269:                 else if (!_stricmp(token4, "Shadow"))
  2270:                 {
  2271:                     if ((pSettings->selectedElement != pSettings->MenuSeparator) && (pSettings->selectedElement != pSettings->ToolbarBorder) &&
  2272:                         (pSettings->selectedElement != pSettings->MenuFrameBorder) && (pSettings->selectedElement != pSettings->DockBorder) &&
  2273:                         (pSettings->selectedElement != pSettings->ExternalHardware))
  2274:                     {
  2275:                         if (!pSettings->selectedElement->FontShadow)
  2276:                         {
  2277:                             pSettings->selectedElement->FontShadow = true;
  2278:                             strcpy_s(feedback, sizeofArray(feedback), "... Shadow enabled");
  2279:                         }
  2280:                         else
  2281:                         {
  2282:                             pSettings->selectedElement->FontShadow = false;
  2283:                             strcpy_s(feedback, sizeofArray(feedback), "... Shadow disabled");
  2284:                         }
  2285: 
  2286:                         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2287:                     }
  2288:                     else strcpy_s(feedback, sizeofArray(feedback), "--- Not available ---");
  2289:                 }
  2290: 
  2291:                 //====================
  2292: 
  2293:                 else if (!_stricmp(token4, "MenuBullet"))
  2294:                 {
  2295:                     if (pSettings->menuBullet == MENU_BULLET_IMAGE) pSettings->menuBullet = MENU_BULLET_EMPTY;
  2296:                     else if (pSettings->menuBullet == MENU_BULLET_QUAD) pSettings->menuBullet = MENU_BULLET_EMPTY;
  2297:                     else pSettings->menuBullet++;
  2298: 
  2299:                     switch (pSettings->menuBullet)
  2300:                     {
  2301:                         case MENU_BULLET_EMPTY: { strcpy_s(feedback, sizeofArray(feedback), "... Empty (none)"); break; }
  2302:                         case MENU_BULLET_DIAMOND: { strcpy_s(feedback, sizeofArray(feedback), "... Diamond"); break; }
  2303:                         case MENU_BULLET_SQUARE: { strcpy_s(feedback, sizeofArray(feedback), "... Square"); break; }
  2304:                         case MENU_BULLET_TRIANGLE: { strcpy_s(feedback, sizeofArray(feedback), "...Triangle"); break; }
  2305:                         case MENU_BULLET_CIRCLE: { strcpy_s(feedback, sizeofArray(feedback), "... Circle"); break; }
  2306:                         case MENU_BULLET_TRIPLE: { strcpy_s(feedback, sizeofArray(feedback), "... Triple"); break; }
  2307:                         case MENU_BULLET_COMMENT: { strcpy_s(feedback, sizeofArray(feedback), "... Comment"); break; }
  2308:                         case MENU_BULLET_GRID: { strcpy_s(feedback, sizeofArray(feedback), "... Grid"); break; }
  2309:                         case MENU_BULLET_QUAD: { strcpy_s(feedback, sizeofArray(feedback), "... Quad"); break; }
  2310:                         default: { strcpy_s(feedback, sizeofArray(feedback), "... Error: Unsupported menu bullet type!"); break; }
  2311:                     }
  2312: 
  2313:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2314:                 }
  2315:                 else if (!_stricmp(token4, "MenuBulletPosition"))
  2316:                 {
  2317:                     if (!_stricmp(pSettings->menuBulletPosition, "Right")) strcpy_s(pSettings->menuBulletPosition, sizeofArray(pSettings->menuBulletPosition), "Left");
  2318:                     else strcpy_s(pSettings->menuBulletPosition, sizeofArray(pSettings->menuBulletPosition), "Right");
  2319:                     sprintf_s(feedback, sizeofArray(feedback), "... %s", pSettings->menuBulletPosition);
  2320:                     SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)feedback);
  2321:                 }
  2322: 
  2323:                 //====================
  2324: 
  2325:                 // Send any feedback on the modify command back to the xDesignerGUI plugin as well... (nb. same feedback as displayed in the console)
  2326:                 if (strnlen_s(feedback, sizeofArray(feedback)) > 0)
  2327:                 {
  2328:                     char broam[MAX_LINE_LENGTH];
  2329:                     sprintf_s(broam, sizeofArray(broam), "@xDesigner Feedback %s", feedback);
  2330:                     SendMessage(GetBBWnd(), BB_BROADCAST, 0, (LPARAM)broam);
  2331:                 }
  2332: 
  2333:                 //====================
  2334: 
  2335:                  // Update the cached appearance *string* for the selected element...
  2336:                 // (nb. not included in the StyleItem definition but potentially used by
  2337:                 //  e.g. plugins calling ReadString, so needs to reflect the latest changes too)
  2338:                 pSettings->UpdateAppearanceString(pSettings->selectedElement);
  2339: 
  2340:                 if (pSettings->selectedElement == pSettings->MenuTitle || pSettings->selectedElement == pSettings->MenuFrame ||
  2341:                     pSettings->selectedElement == pSettings->MenuActive || pSettings->selectedElement == pSettings->MenuGrip ||
  2342:                     pSettings->selectedElement == pSettings->MenuIndicator || pSettings->selectedElement == pSettings->MenuSeparator ||
  2343:                     pSettings->selectedElement == pSettings->MenuFrameBorder ||
  2344:                     !_stricmp(token4, "MenuBullet") || !_stricmp(token4, "MenuBulletPosition")) // Note: We need to check the Menu if's first as we have some non-selectedElement checks here...
  2345:                 {
  2346:                     if (pMenuCommon)
  2347:                     {
  2348:                         pMenuCommon->Configure();
  2349:                         SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_MENU, 0); // Note: Using BB_REDRAWGUI here; we do not want/need to trigger a full BB_RECONFIGURE for Designer mode single style param changes
  2350:                     }
  2351:                 }
  2352:                 else if (pSettings->selectedElement == pSettings->Toolbar || pSettings->selectedElement == pSettings->ToolbarLabel ||
  2353:                          pSettings->selectedElement == pSettings->ToolbarWindowLabel || pSettings->selectedElement == pSettings->ToolbarClock ||
  2354:                          pSettings->selectedElement == pSettings->ToolbarButton || pSettings->selectedElement == pSettings->ToolbarButtonPressed ||
  2355:                          pSettings->selectedElement == pSettings->ToolbarBorder)
  2356:                 {
  2357:                     pSettings->DeriveTaskbarStyle(); // Note: The taskbar style parameters are derived from other elements, and hence they need to be updated on changes too...
  2358:                     if (pToolbar) pToolbar->UpdatePosition();
  2359:                     SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_TOOLBAR, 0); // Signal BB_REDRAWGUI to any other listening subscribers...
  2360:                 }
  2361:                 else if (pSettings->selectedElement == pSettings->Dock || pSettings->selectedElement == pSettings->DockBorder)
  2362:                 {
  2363:                     if (pDock) pDock->UpdateDockWindow();
  2364:                     SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_DOCK, 0); // Signal BB_REDRAWGUI to any other listening subscribers...
  2365:                 }
  2366:                 else if (pSettings->selectedElement == pSettings->Console)
  2367:                 {
  2368:                     if (pConsole) pConsole->UpdatePosition();
  2369:                 }
  2370:                 else if (pSettings->selectedElement == pSettings->WindowTitleFocus || pSettings->selectedElement == pSettings->WindowTitleUnfocus ||
  2371:                          pSettings->selectedElement == pSettings->WindowLabelFocus || pSettings->selectedElement == pSettings->WindowLabelUnfocus ||
  2372:                          pSettings->selectedElement == pSettings->WindowButtonFocus || pSettings->selectedElement == pSettings->WindowButtonUnfocus || pSettings->selectedElement == pSettings->WindowButtonPressed ||
  2373:                          pSettings->selectedElement == pSettings->WindowGripFocus || pSettings->selectedElement == pSettings->WindowGripUnfocus ||
  2374:                          pSettings->selectedElement == pSettings->WindowHandleFocus || pSettings->selectedElement == pSettings->WindowHandleUnfocus)
  2375:                 {
  2376:                     SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_WINDOW, 0); // Signal BB_REDRAWGUI to any other listening subscribers...
  2377:                 }
  2378:                 else if (pSettings->selectedElement == pSettings->ExternalHardware)
  2379:                 {
  2380:                     SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_HARDWARE, 0); // Signal BB_REDRAWGUI to any other listening subscribers...
  2381:                 }
  2382: 
  2383:                 return true;
  2384:             }
  2385: 
  2386:             //====================
  2387: 
  2388:             else if (!_stricmp(token3, "Copy"))
  2389:             {
  2390:                 StyleItem* source = NULL;
  2391:                 StyleItem* destination = NULL;
  2392:                 StyleItem* ptr;
  2393:                 char srcdest[MAX_LINE_LENGTH];
  2394: 
  2395:                 for (int n=1; n<=2; n++)
  2396:                 {
  2397:                     if (n == 1) strcpy_s(srcdest, sizeofArray(srcdest), token4);
  2398:                     else strcpy_s(srcdest, sizeofArray(srcdest), extra);
  2399: 
  2400:                     if (!_strnicmp(srcdest, "Toolbar", 7))
  2401:                     {
  2402:                         if (!_stricmp(srcdest, "Toolbar")) ptr = pSettings->Toolbar;
  2403:                         else if (!_stricmp(srcdest, "ToolbarLabel")) ptr = pSettings->ToolbarLabel;
  2404:                         else if (!_stricmp(srcdest, "ToolbarWindowLabel")) ptr = pSettings->ToolbarWindowLabel;
  2405:                         else if (!_stricmp(srcdest, "ToolbarClock")) ptr = pSettings->ToolbarClock;
  2406:                         else if (!_stricmp(srcdest, "ToolbarButton")) ptr = pSettings->ToolbarButton;
  2407:                         else if (!_stricmp(srcdest, "ToolbarButtonPressed")) ptr = pSettings->ToolbarButtonPressed;
  2408:                         else if (!_stricmp(srcdest, "ToolbarBorder")) ptr = pSettings->ToolbarBorder;
  2409:                     }
  2410:                     else if (!_strnicmp(srcdest, "Menu", 4))
  2411:                     {
  2412:                         if (!_stricmp(srcdest, "MenuTitle")) ptr = pSettings->MenuTitle;
  2413:                         else if (!_stricmp(srcdest, "MenuFrame")) ptr = pSettings->MenuFrame;
  2414:                         else if (!_stricmp(srcdest, "MenuActive")) ptr = pSettings->MenuActive;
  2415:                         else if (!_stricmp(srcdest, "MenuGrip")) ptr = pSettings->MenuGrip;
  2416:                         else if (!_stricmp(srcdest, "MenuIndicator")) ptr = pSettings->MenuIndicator;
  2417:                         else if (!_stricmp(srcdest, "MenuSeparator")) ptr = pSettings->MenuSeparator;
  2418:                         else if (!_stricmp(srcdest, "MenuFrameBorder")) ptr = pSettings->MenuFrameBorder;
  2419:                     }
  2420:                     else if (!_stricmp(srcdest, "Dock")) ptr = pSettings->Dock;
  2421:                     else if (!_stricmp(srcdest, "DockBorder")) ptr = pSettings->DockBorder;
  2422:                     else if (!_stricmp(srcdest, "Console")) ptr = pSettings->Console;
  2423:                     else if (!_strnicmp(srcdest, "Window", 6))
  2424:                     {
  2425:                         if (!_strnicmp(&srcdest[6], "Title", 5))
  2426:                         {
  2427:                             if (!_stricmp(srcdest, "WindowTitleFocus")) ptr = pSettings->WindowTitleFocus;
  2428:                             else if (!_stricmp(srcdest, "WindowTitleUnfocus")) ptr = pSettings->WindowTitleUnfocus;
  2429:                         }
  2430:                         else if (!_strnicmp(&srcdest[6], "Label", 5))
  2431:                         {
  2432:                             if (!_stricmp(srcdest, "WindowLabelFocus")) ptr = pSettings->WindowLabelFocus;
  2433:                             else if (!_stricmp(srcdest, "WindowLabelUnfocus")) ptr = pSettings->WindowLabelUnfocus;
  2434:                         }
  2435:                         else if (!_strnicmp(&srcdest[6], "Button", 6))
  2436:                         {
  2437:                             if (!_stricmp(srcdest, "WindowButtonFocus")) ptr = pSettings->WindowButtonFocus;
  2438:                             else if (!_stricmp(srcdest, "WindowButtonUnfocus")) ptr = pSettings->WindowButtonUnfocus;
  2439:                             else if (!_stricmp(srcdest, "WindowButtonPressed")) ptr = pSettings->WindowButtonPressed;
  2440:                         }
  2441:                         else if (!_strnicmp(&srcdest[6], "Grip", 4))
  2442:                         {
  2443:                             if (!_stricmp(srcdest, "WindowGripFocus")) ptr = pSettings->WindowGripFocus;
  2444:                             else if (!_stricmp(srcdest, "WindowGripUnfocus")) ptr = pSettings->WindowGripUnfocus;
  2445:                         }
  2446:                         else if (!_strnicmp(&srcdest[6], "Handle", 6))
  2447:                         {
  2448:                             if (!_stricmp(srcdest, "WindowHandleFocus")) ptr = pSettings->WindowHandleFocus;
  2449:                             else if (!_stricmp(srcdest, "WindowHandleUnfocus")) ptr = pSettings->WindowHandleUnfocus;
  2450:                         }
  2451:                     }
  2452:                     else if (!_stricmp(srcdest, "Hardware")) ptr = pSettings->ExternalHardware;
  2453:                     else return false; // Failsafe
  2454: 
  2455:                     if (n == 1) source = ptr;
  2456:                     else destination = ptr;
  2457:                 }
  2458: 
  2459:                 // Copy from the source element to the destination element... (and select the latter for further editing)
  2460:                 CopyMemory(destination, source, sizeof(StyleItem));
  2461:                 pSettings->selectedElement = destination;
  2462: 
  2463:                 // Update all UI elements... (because that's way easier than complex source/destination checking ;))
  2464:                 if (pToolbar) pToolbar->UpdatePosition();
  2465:                 if (pMenuCommon)
  2466:                 {
  2467:                     pMenuCommon->Configure();
  2468:                     SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_MENU, 0);
  2469:                 }
  2470:                 if (pDock) pDock->UpdateDockWindow();
  2471:                 if (pConsole) pConsole->UpdatePosition();
  2472:                 SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_WINDOW, 0);
  2473: 
  2474:                 SendMessage(GetBBWnd(), BB_BROADCAST, 0, (LPARAM)"@xDesigner Feedback ... copied!");
  2475:             }
  2476: 
  2477:             //====================
  2478: 
  2479:             else if (!_stricmp(token3, "Save"))
  2480:             {
  2481:                 pSettings->WriteStyle();
  2482:                 SendMessage(GetBBWnd(), BB_BROADCAST, 0, (LPARAM)"@xDesigner Feedback ... saved!");
  2483:             }
  2484:         }
  2485: 
  2486:         //====================
  2487: 
  2488:         else if (!_stricmp(token2, "Reconfigure"))
  2489:         {
  2490:             PostMessage(GetBBWnd(), BB_SETSTYLE, 0, 0); // -> Reload current style
  2491:             return true;
  2492:         }
  2493: 
  2494:         else if (!_stricmp(token2, "Restart"))
  2495:         {
  2496:             PostMessage(GetBBWnd(), BB_RESTART, 0, 0);
  2497:             return true;
  2498:         }
  2499: 
  2500:         else if (!_stricmp(token2, "PausedRestart"))
  2501:         {
  2502:             // Note: BB_RESTART WPARAM set to 1 -> Paused restart! (xoblite only for now)
  2503:             PostMessage(GetBBWnd(), BB_RESTART, 1, 0);
  2504:             return true;
  2505:         }
  2506: 
  2507:         //====================
  2508: 
  2509:         else if (!_stricmp(token2, "MinimizeAll"))
  2510:         {
  2511:             pTaskbar->MinimizeAllWindows();
  2512:             return true;
  2513:         }
  2514:         else if (!_stricmp(token2, "RestoreAll"))
  2515:         {
  2516:             pTaskbar->RestoreAllWindows();
  2517:             return true;
  2518:         }
  2519: 
  2520:         //====================
  2521: 
  2522:         else if (!_stricmp(token2, "Explorer")) // New more flexible syntax
  2523:         {
  2524:             if (!_stricmp(token3, "Toggle")) ToggleExplorer();
  2525:             else if (!_stricmp(token3, "Hide") && !pSettings->explorerHidden) ToggleExplorer();
  2526:             else if (!_stricmp(token3, "Show") && pSettings->explorerHidden) ToggleExplorer();
  2527: 
  2528:             return true;
  2529:         }
  2530: 
  2531:         else if (!_stricmp(token2, "ToggleExplorer")) // Legacy syntax (kept for backwards compatibility only)
  2532:         {
  2533:             ToggleExplorer();
  2534:             return true;
  2535:         }
  2536: 
  2537:         else if (!_stricmp(token2, "EmptyRecycleBin"))
  2538:         {
  2539:             SHEmptyRecycleBin(NULL, NULL, 0);
  2540:             return true;
  2541:         }
  2542: 
  2543:         //====================
  2544: 
  2545:         else if (!_stricmp(token2, "Statistics"))
  2546:         {
  2547:             char msg[255];
  2548:             sprintf_s(msg, sizeofArray(msg), "xoblite says: \"Since launch, you have changed theme %d time%s, style %d time%s, and wallpaper %d time%s.\"", pSettings->Statistics.changedTheme, ((pSettings->Statistics.changedTheme != 1) ? "s" : ""), pSettings->Statistics.changedStyle, ((pSettings->Statistics.changedStyle != 1) ? "s" : ""), pSettings->Statistics.changedWallpaper, ((pSettings->Statistics.changedWallpaper != 1) ? "s" : ""));
  2549:             SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_SHELL_MESSAGE, (LPARAM)msg);
  2550:             sprintf_s(msg, sizeofArray(msg), "\"You have also used hotkeys %d time%s, and (through various actions) triggered %d bro@m%s.\"", pSettings->Statistics.usedAHotkey, ((pSettings->Statistics.usedAHotkey != 1) ? "s" : ""), pSettings->Statistics.executedBroams, ((pSettings->Statistics.executedBroams != 1) ? "s" : ""));
  2551:             SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_PLAIN_MESSAGE, (LPARAM)msg);
  2552:             return true;
  2553:         }
  2554: 
  2555:         //====================
  2556: 
  2557:         else if (!_stricmp(token2, "Quit"))
  2558:         {
  2559:             if (!_stricmp(token3, "<Yes>")) PostMessage(GetBBWnd(), BB_QUIT, 0, 0);
  2560:             else SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"Are you sure you want to quit?", (LPARAM)"@xoblite Quit <Yes>");
  2561:             return true;
  2562:         }
  2563: 
  2564:         //====================
  2565: 
  2566:         else if (!_stricmp(token2, "System"))
  2567:         {
  2568:             if (!_stricmp(token3, "Shutdown")) PostMessage(GetBBWnd(), BB_SHUTDOWN, 0, 1); // Setting LPARAM to 1 -> Skip the normal "yes/no" dialog (xoblite only)
  2569:             else if (!_stricmp(token3, "Reboot")) PostMessage(GetBBWnd(), BB_SHUTDOWN, 1, 1);
  2570:             else if (!_stricmp(token3, "LogOff")) PostMessage(GetBBWnd(), BB_SHUTDOWN, 2, 1);
  2571:             else if (!_stricmp(token3, "Hibernate")) PostMessage(GetBBWnd(), BB_SHUTDOWN, 3, 1);
  2572:             else if (!_stricmp(token3, "Standby")) PostMessage(GetBBWnd(), BB_SHUTDOWN, 4, 1);
  2573:             return true;
  2574:         }
  2575:     }
  2576: 
  2577:     //====================
  2578: 
  2579:     else if (!_strnicmp(broam, "@Script", 7))
  2580:     {
  2581:         if (!pSettings->disableScriptSupport)
  2582:         {
  2583:             SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)broam); // Display the @Script bro@m in the console...
  2584: 
  2585:             char token1[MAX_LINE_LENGTH], script[MAX_LINE_LENGTH];
  2586:             LPSTR tokens[1];
  2587:             tokens[0] = token1;
  2588: 
  2589:             token1[0] = script[0] = '\0';
  2590:             BBTokenize(broam, tokens, 1, script);
  2591: 
  2592:             // Remove encapsulating [] brackets and execute the script...
  2593:             script[strnlen_s(script, sizeofArray(script)) - 1] = '\0';
  2594:             _beginthread(ExecuteScript, 0, &script[1]);
  2595:         }
  2596:         else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"@Script support is currently disabled.");
  2597: 
  2598:         return true;
  2599:     }
  2600: 
  2601:     //====================
  2602: 
  2603:     else if (!_strnicmp(broam, "@Callback", 9))
  2604:     {
  2605:         // Edit a generic string, and when ready execute the specified callback broam...
  2606: 
  2607:         char token1[MAX_LINE_LENGTH], token2[MAX_LINE_LENGTH], token3[MAX_LINE_LENGTH], extra[MAX_LINE_LENGTH];
  2608:         LPSTR tokens[4];
  2609:         tokens[0] = token1;
  2610:         tokens[1] = token2;
  2611:         tokens[2] = token3;
  2612:         token1[0] = token2[0] = token3[0] = extra[0] = '\0';
  2613:         BBTokenize(broam, tokens, 3, extra);
  2614: 
  2615:         if ((token2[0] == '@') && strnlen_s(token3, sizeofArray(token3))) // ...expecting a two-parameter callback broam in @xxxxx yyyyy format! (this should be sufficient for most if not all use cases)
  2616:         {
  2617:             char command[MAX_LINE_LENGTH];
  2618:             sprintf_s(command, sizeofArray(command), "%s %s", token2, token3);
  2619:             CreateRunBox(hMainInstance, command, extra); // Callback broam -> @xxxxx yyyyy <edited string>
  2620:             return false; // Suppress the pre-editing @Callback <...> bro@m from being displayed in the console...
  2621:         }
  2622:     }
  2623: 
  2624:     //====================
  2625: 
  2626:     else if (!_strnicmp(broam, "@GoToURL", 8))
  2627:     {
  2628:         char token1[MAX_LINE_LENGTH], extra[MAX_LINE_LENGTH];
  2629:         LPSTR tokens[1];
  2630:         tokens[0] = token1;
  2631:         token1[0] = extra[0] = '\0';
  2632:         BBTokenize(broam, tokens, 1, extra);
  2633:         BBSmartExecute(extra);
  2634:         return false; // Suppress internal @GoToURL bro@ms from being displayed in the console...
  2635:     }
  2636: 
  2637:     //====================
  2638: 
  2639:     else if (!_strnicmp(broam, "@BBShowPlugins", 14) || !_strnicmp(broam, "@BBHidePlugins", 14)) return false; // Suppress the "silent" internal @BBShowPlugins/@BBHidePlugins typically triggered by calling @xoblite Plugins Toggle...
  2640:     else if (!_strnicmp(broam, "@xDesigner Feedback", 19)) return false; // Suppress xDesignerGUI feedback bro@ms from being displayed in the console...
  2641:     else if (!_strnicmp(broam, "@xWebViewer Bookmark", 20) || !_strnicmp(broam, "@xWebViewer URL", 15)) return false; // Suppress xWebViewer bookmark+URL bro@ms from being displayed in the console...
  2642:     else if (!_strnicmp(broam, "@", 1))
  2643:     {
  2644:         SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)broam); // Display all other bro@ms in the console...
  2645: 
  2646:         if (IsInString(broam, "@xDesignerGUI") && !pSettings->designerModeEnabled)
  2647:         {
  2648:             SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"Designer mode is disabled. Please enable it to use the @xDesignerGUI bro@ms.");
  2649:         }
  2650:     }
  2651:     else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)broam); // Debug failsafe (e.g. non-broam, non-terminated, etc) -> Display message as is but with ERROR flag set...
  2652: 
  2653:     //====================
  2654: 
  2655:     return false;
  2656: }
  2657: 
  2658: //===========================================================================
  2659: // Function: ExecuteScript
  2660: // Purpose: Provides built-in support for @Script command scripting
  2661: //===========================================================================
  2662: 
  2663: void ExecuteScript(void *param)
  2664: {
  2665:     char script[MAX_LINE_LENGTH], cmd[MAX_LINE_LENGTH];
  2666:     strcpy_s(script, sizeofArray(script), (LPSTR)param);
  2667: 
  2668:     while (strnlen_s(script, sizeofArray(script)))
  2669:     {
  2670:         strcpy_s(script, sizeofArray(script), Tokenize(script, cmd, "|"));
  2671:         if (pConsole) pConsole->BlockMessage(cmd); // Block individual items of an @Script being echoed in the Console...
  2672:         BBSmartExecute(cmd);
  2673:     }
  2674: 
  2675:     _endthread();
  2676: }
  2677: 
  2678: //===========================================================================
  2679: // Function: FindRandomFile
  2680: // Purpose: Support functions to the @xoblite Random <> bro@ms (see above)
  2681: //===========================================================================
  2682: 
  2683: bool FindRandomFile(LPSTR folder, int type, bool applyRandom)
  2684: {
  2685:     char thisFolder[MAX_PATH];
  2686:     char subFolder[MAX_PATH];
  2687:     long handle;
  2688:     _finddata_t found;
  2689: 
  2690: //  strncpy(thisFolder, folder, MAX_PATH - 1);
  2691:     strncpy_s(thisFolder, sizeof(thisFolder), folder, _TRUNCATE);
  2692:     if (thisFolder[strnlen_s(thisFolder, sizeofArray(thisFolder))] != '\\') strcat_s(thisFolder, sizeofArray(thisFolder), "\\");
  2693:     strcat_s(thisFolder, sizeofArray(thisFolder), "*");
  2694: 
  2695:     handle = _findfirst(thisFolder, &found);
  2696: 
  2697:     if (handle != -1)
  2698:     {
  2699:         do
  2700:         {
  2701:             if (strcmp(found.name, ".") == 0 || strcmp(found.name, "..") == 0 || (found.attrib & _A_HIDDEN))
  2702:             {
  2703:                 // Skip hidden files...
  2704:                 continue;
  2705:             }
  2706: 
  2707:             if (found.attrib & _A_SUBDIR)
  2708:             {
  2709:                 // Scan through subfolders too...
  2710: //              strncpy(subFolder, thisFolder, MAX_PATH - 1);
  2711:                 strncpy_s(subFolder, sizeof(subFolder), thisFolder, _TRUNCATE);
  2712:                 subFolder[strnlen_s(subFolder, sizeofArray(subFolder)) - 1] = '\0'; // Remove the * wildcard...
  2713:                 strcat_s(subFolder, sizeofArray(subFolder), found.name);
  2714:                 if (FindRandomFile(subFolder, type, applyRandom)) break;
  2715:             }
  2716:             else
  2717:             {
  2718:                 if (type == BROAM_RANDOM_STYLE)
  2719:                 {
  2720:                     // Skip any .3dc colour scheme files in styles folders...
  2721:                     if (IsInString(found.name, ".3dc")) continue;
  2722:                 }
  2723:                 else // BROAM_RANDOM_WALLPAPER
  2724:                 {
  2725:                     // We allow only JPG/JPEG, PNG, and BMP files as wallpaper images...
  2726:                     if (!IsInString(found.name, ".jpg") && !IsInString(found.name, ".jpeg") && !IsInString(found.name, ".png") && !IsInString(found.name, ".bmp")) continue;
  2727:                 }
  2728: 
  2729:                 if (applyRandom)
  2730:                 {
  2731:                     currentFile++;
  2732:                     if (currentFile == randomFile)
  2733:                     {
  2734: //                      strncpy(pathToFile, thisFolder, MAX_PATH - 1);
  2735:                         strncpy_s(pathToFile, sizeof(pathToFile), thisFolder, _TRUNCATE);
  2736:                         pathToFile[strnlen_s(pathToFile, sizeofArray(pathToFile)) - 1] = '\0'; // Remove the * wildcard...
  2737:                         strcat_s(pathToFile, sizeofArray(pathToFile), found.name);
  2738: 
  2739:                         if (type == BROAM_RANDOM_STYLE)
  2740:                         {
  2741:                             PostMessage(GetBBWnd(), BB_SETSTYLE, 0, (LPARAM)pathToFile); // Set randomly selected style...
  2742:                             // pSettings->Statistics.changedStyle++; // Note: We do this under BB_SETSTYLE in Blackbox.cpp for all style changes instead!
  2743:                         }
  2744:                         else // BROAM_RANDOM_WALLPAPER
  2745:                         {
  2746:                             // Set randomly selected wallpaper...
  2747:                             pWallpaper->SetWallpaper(pathToFile, "stretch");
  2748: /*
  2749:                             // ...and copy a matching rootCommand to the clipboard for
  2750:                             // possibly updating of a style in case it was a good match! =]
  2751:                             char rootCmd[MAX_LINE_LENGTH];
  2752:                             if (IsInString(pathToFile, pSettings->SF_currentThemePath)) sprintf_s(rootCmd, sizeofArray(rootCmd), "rootCommand: bsetbg -full \"$CurrentTheme$%s\"", &pathToFile[strnlen_s(pSettings->SF_currentThemePath, sizeofArray(pSettings->SF_currentThemePath))]);
  2753:                             else if (IsInString(pathToFile, pSettings->SF_blackboxPath)) sprintf_s(rootCmd, sizeofArray(rootCmd), "rootCommand: bsetbg -full \"%s\"", &pathToFile[strnlen_s(pSettings->SF_blackboxPath, sizeofArray(pSettings->SF_blackboxPath))+1]);
  2754:                             else sprintf_s(rootCmd, sizeofArray(rootCmd), "rootCommand: bsetbg -full \"%s\"", pathToFile);
  2755:                             CopyStringToClipboard(rootCmd);
  2756: 
  2757:                             strcpy_s(pSettings->rootCommand, sizeofArray(pSettings->rootCommand), &rootCmd[13]); // Finally, remember the manually applied wallpaper as the "last applied" rootCommand in case Designer mode wants to Save it later on...
  2758: */
  2759:                             pSettings->Statistics.changedWallpaper++; // Update statistics...
  2760:                         }
  2761: 
  2762:                         return true;
  2763:                     }
  2764:                 }
  2765:                 else numberOfFiles++;
  2766:             }
  2767:         } while (_findnext(handle, &found) == 0);
  2768:     }
  2769: 
  2770:     _findclose(handle);
  2771: 
  2772:     return false;
  2773: }
  2774: 
  2775: //===========================================================================
  2776: // Function: ToggleExplorer/HideExplorer/ShowExplorer/ExplorerEnumWindowsProc
  2777: // Purpose: Functions related to the optional hiding of the Explorer taskbar
  2778: //===========================================================================
  2779: 
  2780: vector<HWND> ExplorerWndList;
  2781: //RECT origWorkArea;
  2782: 
  2783: void ToggleExplorer()
  2784: {
  2785:     if (!pSettings->underExplorer) return;
  2786: 
  2787:     if (!pSettings->explorerHidden) HideExplorer(false);
  2788:     else ShowExplorer();
  2789: 
  2790:     bool savedWriteProtection = pSettings->writeProtection;
  2791:     pSettings->writeProtection = false;
  2792:     WriteBool(pSettings->xobrcDefaultFile, "xoblite.explorer.hidden:", pSettings->explorerHidden);
  2793:     pSettings->writeProtection = savedWriteProtection;
  2794: 
  2795:     // Update core shell elements...
  2796:     if (pDesktop) pDesktop->UpdateDesktopWindow();
  2797:     if (pToolbar) pToolbar->UpdatePosition();
  2798:     if (pConsole) pConsole->UpdatePosition();
  2799:     if (pDock) pDock->UpdatePosition();
  2800: 
  2801:     // Notify plugins that the desktop work area has changed...
  2802:     SendMessage(GetBBWnd(), BB_REDRAWGUI, BBRG_DESKTOP, 0);
  2803: 
  2804:     PlaySoundFX(SFX_TOGGLE_ELEMENT);
  2805: 
  2806: //  if (pSettings->explorerHidden) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"Explorer taskbar hidden.");
  2807: //  else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"Explorer taskbar shown.");
  2808: }
  2809: 
  2810: //====================
  2811: 
  2812: void HideExplorer(bool hideOnStartup)
  2813: {
  2814:     KillTimer(GetBBWnd(), CHECK_EXPLORER_HIDDEN_TIMER);
  2815: 
  2816:     if (!pSettings->explorerHidden || hideOnStartup)
  2817:     {
  2818:         if (FindWindow("Shell_TrayWnd", "") == NULL) return;
  2819: /*
  2820:         // Save the current/original desktop work area before the Explorer taskbar is hidden...
  2821:         SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&origWorkArea, 0);
  2822: */
  2823:         // Enable taskbar auto-hide... (nb. this will prevent it from still taking up desktop work area when forcibly/truly hidden)
  2824:         APPBARDATA abd;
  2825:         ZeroMemory(&abd, sizeof(abd));
  2826:         abd.cbSize = sizeof(abd);
  2827:         abd.lParam = ABS_AUTOHIDE;
  2828:         SHAppBarMessage(ABM_SETSTATE, &abd);
  2829:         // SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd);
  2830: 
  2831:         // Hide applicable Explorer shell elements... (e.g. taskbar including the system tray, etc)
  2832:         ExplorerWndList.clear();
  2833:         EnumWindows(ExplorerEnumWindowsProc, 0);
  2834: 
  2835:         // Set a timer for every 2 seconds to check whether they have gone visible again... (see also WM_TIMER handling in Blackbox.cpp)
  2836:         SetTimer(GetBBWnd(), CHECK_EXPLORER_HIDDEN_TIMER, 2000, (TIMERPROC)NULL);
  2837: 
  2838:         pSettings->explorerHidden = true;
  2839: /*
  2840:         // Finally, we set a new desktop work area to use when the Explorer taskbar is hidden...
  2841:         RECT newWorkArea;
  2842:         int ScreenX = GetSystemMetrics(SM_XVIRTUALSCREEN);
  2843:         int ScreenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
  2844:         int ScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
  2845:         int ScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
  2846:         SetRect(&newWorkArea, ScreenX, ScreenY, ScreenX+ScreenWidth, ScreenY+ScreenHeight);
  2847:         SystemParametersInfo(SPI_SETWORKAREA, 0, (PVOID)&newWorkArea, SPIF_SENDCHANGE);
  2848:         // SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&newWorkArea, SPIF_SENDCHANGE); // (...is this really needed? Just in case...)
  2849: */
  2850:     }
  2851: }
  2852: 
  2853: //====================
  2854: 
  2855: void ShowExplorer()
  2856: {
  2857:     KillTimer(GetBBWnd(), CHECK_EXPLORER_HIDDEN_TIMER);
  2858: 
  2859:     if (pSettings->explorerHidden)
  2860:     {
  2861: /*
  2862:         // Restore the original desktop work area... (see HideExplorer() above)
  2863:         SystemParametersInfo(SPI_SETWORKAREA, 0, (PVOID)&origWorkArea, SPIF_SENDCHANGE);
  2864:         // SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&origWorkArea, SPIF_SENDCHANGE); // (...is this really needed? Just in case...)
  2865: */
  2866:         // Show previously hidden Explorer shell elements...
  2867:         while (ExplorerWndList.size())
  2868:         {
  2869:             ShowWindow(ExplorerWndList.back(), SW_SHOWNOACTIVATE);
  2870:             ExplorerWndList.pop_back();
  2871:         }
  2872: 
  2873:         // Disable taskbar auto-hide... (nb. maybe we could somehow have saved the previous state here, but that's arguably a minor thing)
  2874:         APPBARDATA abd;
  2875:         ZeroMemory(&abd, sizeof(abd));
  2876:         abd.cbSize = sizeof(abd);
  2877:         abd.lParam = ABS_ALWAYSONTOP;
  2878:         SHAppBarMessage(ABM_SETSTATE, &abd);
  2879:         // SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd);
  2880: 
  2881:         pSettings->explorerHidden = false;
  2882:     }
  2883: }
  2884: 
  2885: //====================
  2886: 
  2887: char enumClassName[MAX_LINE_LENGTH], enumWindowTitle[MAX_LINE_LENGTH];
  2888: 
  2889: BOOL CALLBACK ExplorerEnumWindowsProc(HWND hwnd, LPARAM lParam)
  2890: {
  2891: //  if (IsWindowVisible(hwnd))
  2892:     {
  2893:         GetClassName(hwnd, enumClassName, sizeof(enumClassName));
  2894: 
  2895:         if (!_stricmp(enumClassName, "Shell_TrayWnd") || !_stricmp(enumClassName, "Shell_SecondaryTrayWnd"))
  2896:         {
  2897: //          GetWindowText(hwnd, enumWindowTitle, sizeof(enumWindowTitle));
  2898: //          if (!_stricmp(enumWindowTitle, ""))
  2899:             {
  2900:                 ShowWindow(hwnd, SW_HIDE);
  2901:                 ExplorerWndList.push_back(hwnd);
  2902:             }
  2903:         }
  2904:         else if (!_stricmp(enumClassName, "Button"))
  2905:         {
  2906:             GetWindowText(hwnd, enumWindowTitle, sizeof(enumWindowTitle));
  2907:             if (!_stricmp(enumWindowTitle, "Start")) // -> The Start button in Windows Vista/7 [...iirc?]
  2908:             {
  2909:                 ShowWindow(hwnd, SW_HIDE);
  2910:                 ExplorerWndList.push_back(hwnd);
  2911:             }
  2912:         }
  2913: /*
  2914:         else if (!_stricmp(enumClassName, "Progman"))
  2915:         {
  2916:             // ##### Note: This part commented out because for xoblite bb5 onwards we do not
  2917:             // want to hide the desktop window etc -> Kept for legacy reference only... #####
  2918:             GetWindowText(hwnd, enumWindowTitle, sizeof(enumWindowTitle));
  2919:             if (!_stricmp(enumWindowTitle, "Program Manager"))
  2920:             {
  2921:                 ShowWindow(hwnd, SW_HIDE);
  2922:                 ExplorerWndList.push_back(hwnd);
  2923:             }
  2924:         }
  2925: */
  2926: /*
  2927:         else if (!_stricmp(enumClassName, "Progman"))
  2928:         {
  2929:             GetWindowText(hwnd, enumWindowTitle, sizeof(enumWindowTitle));
  2930:             if (!_stricmp(enumWindowTitle, "Program Manager"))
  2931:             {
  2932:                 HWND desktopIconsWindow = FindWindowEx(hwnd, NULL, "SHELLDLL_DefView", "");
  2933:                 if (desktopIconsWindow != NULL)
  2934:                 {
  2935:                     desktopIconsWindow = FindWindowEx(desktopIconsWindow, NULL, "SysListView32", "FolderView");
  2936:                     if (desktopIconsWindow != NULL)
  2937:                     {
  2938:                         ShowWindow(desktopIconsWindow, SW_HIDE);
  2939:                         ExplorerWndList.push_back(desktopIconsWindow);
  2940:                     }
  2941:                 }
  2942:             }
  2943:         }
  2944: */
  2945:         else if (!_stricmp(enumClassName, "BaseBar"))
  2946:         {
  2947:             ShowWindow(hwnd, SW_HIDE);
  2948:             ExplorerWndList.push_back(hwnd);
  2949:         }
  2950:     }
  2951: 
  2952:     return true;
  2953: }
  2954: 
  2955: //===========================================================================
  2956: 
  2957: HWND runBoxWindow = NULL;
  2958: HFONT runBoxFont = NULL;
  2959: char runBoxCommand[MAX_LINE_LENGTH] = "\0";
  2960: char runBoxString[MAX_LINE_LENGTH] = "@xoblite ";
  2961: 
  2962: void CreateRunBox(HINSTANCE hMainInstance, LPSTR commandString, LPSTR initString)
  2963: {
  2964:     if (commandString != NULL) strcpy_s(runBoxCommand, sizeofArray(runBoxCommand), commandString);
  2965:     else runBoxCommand[0] = '\0';
  2966: 
  2967:     if (!runBoxWindow)
  2968:     {
  2969:         RECT workArea;
  2970:         ZeroMemory(&workArea, sizeof(workArea));
  2971:         SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
  2972: 
  2973:         int editboxWidth = (workArea.right - workArea.left) / 2;
  2974:         int editboxHeight = 15 * pSettings->scalingFactorHiDPI; // Using a fixed font size of 15 pixels times the HiDPI scaling factor... (Segoe UI)
  2975:         editboxHeight += 12; // Add vertical padding to allow for a WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE sunken double border (see extended window styles below)
  2976:         int editboxX = editboxWidth / 2;
  2977:         int editboxY = ((workArea.bottom - workArea.top) / 2) - (editboxHeight / 2);
  2978: 
  2979:         runBoxWindow = CreateWindowEx(
  2980:             WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE,  // window style
  2981:             "EDIT",                                                                     // window class
  2982:             NULL,                                                                       // window name
  2983:             WS_POPUP | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,                            // window parameters
  2984:             editboxX,                                                                   // x position
  2985:             editboxY,                                                                   // y position
  2986:             editboxWidth,                                                               // window width
  2987:             editboxHeight,                                                              // window height
  2988:             GetBBWnd(),                                                                 // parent window
  2989:             NULL,                                                                       // no menu
  2990:             hMainInstance,                                                              // hInstance
  2991:             NULL                                                                        // no window creation data
  2992:         );
  2993: 
  2994:         if (!runBoxWindow)
  2995:         {
  2996:             MessageBox(0, "Error creating run box window!", "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
  2997:             Log("xoblite", "Error creating run box window!");
  2998:             runBoxWindow = NULL;
  2999:         }
  3000:         else
  3001:         {
  3002:             if (runBoxFont) DeleteObject(runBoxFont);
  3003:             int runBoxFontSize = 15 * pSettings->scalingFactorHiDPI;
  3004:             runBoxFont = CreateFont(runBoxFontSize, 0, 0, 0, FW_BOLD, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Segoe UI");
  3005: 
  3006:             SendMessage(runBoxWindow, (UINT)WM_SETFONT, (WPARAM)runBoxFont, TRUE);
  3007:             SendMessage(runBoxWindow, (UINT)EM_SETLIMITTEXT, (WPARAM)MAX_LINE_LENGTH, 0); // Allow maximum 4096 characters in the edit control
  3008:             if (strlen(initString) > 0) SendMessage(runBoxWindow, WM_SETTEXT, 0, (LPARAM)initString); // -> Init string specified
  3009:             else SendMessage(runBoxWindow, WM_SETTEXT, 0, (LPARAM)runBoxString); // -> Init string not specified -> Use the last run box history entry
  3010:             SendMessage(runBoxWindow, EM_SETSEL, (WPARAM)0, (LPARAM)-1); // Select all text in the edit control
  3011: 
  3012:             // Add a subclass to the edit window to be able to respond to the Return/Enter and Escape keys (not visible to the parent WndProc) being pressed...
  3013:             SetWindowSubclass(runBoxWindow, RunBoxWindowSubclassProc, 0, 0);
  3014: 
  3015:             ShowWindow(runBoxWindow, SW_SHOW);
  3016:             SetWindowPos(runBoxWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
  3017:             SetForegroundWindow(runBoxWindow);
  3018: 
  3019:             PlaySoundFX(SFX_TOGGLE_ELEMENT);
  3020:         }
  3021:     }
  3022:     else DestroyRunBox();
  3023: }
  3024: 
  3025: //====================
  3026: 
  3027: void DestroyRunBox()
  3028: {
  3029:     if (runBoxWindow)
  3030:     {
  3031:         ShowWindow(runBoxWindow, SW_HIDE);
  3032:         RemoveWindowSubclass(runBoxWindow, RunBoxWindowSubclassProc, 0);
  3033:         DestroyWindow(runBoxWindow);
  3034:         runBoxWindow = NULL;
  3035:     }
  3036: 
  3037:     if (runBoxFont) DeleteObject(runBoxFont);
  3038: }
  3039: 
  3040: //====================
  3041: 
  3042: LRESULT CALLBACK RunBoxWindowSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
  3043: {
  3044:     if (runBoxWindow && (message == WM_KEYDOWN))
  3045:     {
  3046:         if (wParam == VK_RETURN)
  3047:         {
  3048:             // The user has pressed the Return/Enter key -> Execute the command entered in the run box, or send the applicable post-editing callback broam...
  3049:             if (strnlen_s(runBoxCommand, sizeofArray(runBoxCommand)))
  3050:             {
  3051:                 char editedString[MAX_LINE_LENGTH], callback[MAX_LINE_LENGTH];
  3052:                 SendMessage(runBoxWindow, WM_GETTEXT, MAX_LINE_LENGTH, (LPARAM)&editedString); // Fetch the edited string from the run box... (nb. *not* added to run box history)
  3053:                 ShowWindow(runBoxWindow, SW_HIDE); // Hide the run box to let the focus go back to the previously active task first...
  3054:                 sprintf_s(callback, sizeofArray(callback), "%s %s", runBoxCommand, editedString);
  3055:                 BBSmartExecute(callback); // Execute the post-editing callback broam... (with command+parameters depending on the prior input)
  3056:             }
  3057:             else
  3058:             {
  3059:                 SendMessage(runBoxWindow, WM_GETTEXT, MAX_LINE_LENGTH, (LPARAM)&runBoxString); // Fetch the command string from the run box... (nb. added to run box history)
  3060:                 ShowWindow(runBoxWindow, SW_HIDE); // Hide the run box to let the focus go back to the previously active task first...
  3061:                 BBSmartExecute(runBoxString); // Execute the command... (this could be a bro@m, an @Script, a regular command, a URL, a ? <searchstring>, etc, see BBSmartExecute() in BBApi.cpp)
  3062:             }
  3063: //          PlaySoundFX(SFX_MENU_CLICK);
  3064: 
  3065:             // ...and then close the run box...
  3066:             DestroyRunBox();
  3067:         }
  3068:         else if (wParam == VK_ESCAPE)
  3069:         {
  3070:             // The user has pressed the Escape key -> Close the run box *without* executing any entered command...
  3071:             DestroyRunBox();
  3072:         }
  3073:     }
  3074:     
  3075:     return DefSubclassProc(hwnd, message, wParam, lParam);
  3076: }
  3077: 
  3078: //===========================================================================
  3079: