2025-05-13 19:45:22 +03:00

899 lines
27 KiB
C

/*
* Process Hacker ToolStatus -
* main toolbar
*
* Copyright (C) 2011-2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "toolstatus.h"
HIMAGELIST ToolBarImageList = NULL;
TBBUTTON ToolbarButtons[MAX_TOOLBAR_ITEMS] =
{
// Default toolbar buttons (displayed)
{ I_IMAGECALLBACK, PHAPP_ID_VIEW_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
{ I_IMAGECALLBACK, PHAPP_ID_HACKER_OPTIONS, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
{ 0, 0, 0, BTNS_SEP, { 0 }, 0, 0 },
{ I_IMAGECALLBACK, PHAPP_ID_HACKER_FINDHANDLESORDLLS, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
{ I_IMAGECALLBACK, PHAPP_ID_VIEW_SYSTEMINFORMATION, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
{ 0, 0, 0, BTNS_SEP, { 0 }, 0, 0 },
{ I_IMAGECALLBACK, TIDC_FINDWINDOW, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
{ I_IMAGECALLBACK, TIDC_FINDWINDOWTHREAD, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
{ I_IMAGECALLBACK, TIDC_FINDWINDOWKILL, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
// Available toolbar buttons (hidden)
{ I_IMAGECALLBACK, PHAPP_ID_VIEW_ALWAYSONTOP, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT, { 0 }, 0, 0 },
{ I_IMAGECALLBACK, TIDC_POWERMENUDROPDOWN, TBSTATE_ENABLED, BTNS_WHOLEDROPDOWN | BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT,{ 0 }, 0, 0 },
{ I_IMAGECALLBACK, PHAPP_ID_HACKER_SHOWDETAILSFORALLPROCESSES, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT,{ 0 }, 0, 0 },
};
VOID RebarBandInsert(
_In_ UINT BandID,
_In_ HWND HwndChild,
_In_ UINT cxMinChild,
_In_ UINT cyMinChild
)
{
REBARBANDINFO rebarBandInfo =
{
REBARBANDINFO_V6_SIZE,
RBBIM_STYLE | RBBIM_ID | RBBIM_CHILD | RBBIM_CHILDSIZE,
RBBS_USECHEVRON // RBBS_NOGRIPPER | RBBS_HIDETITLE | RBBS_TOPALIGN
};
rebarBandInfo.wID = BandID;
rebarBandInfo.hwndChild = HwndChild;
rebarBandInfo.cxMinChild = cxMinChild;
rebarBandInfo.cyMinChild = cyMinChild;
if (BandID == REBAR_BAND_ID_SEARCHBOX)
{
rebarBandInfo.fStyle |= RBBS_FIXEDSIZE;
}
if (ToolStatusConfig.ToolBarLocked)
{
rebarBandInfo.fStyle |= RBBS_NOGRIPPER;
}
SendMessage(RebarHandle, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rebarBandInfo);
}
VOID RebarBandRemove(
_In_ UINT BandID
)
{
UINT index = (UINT)SendMessage(RebarHandle, RB_IDTOINDEX, (WPARAM)BandID, 0);
if (index == -1)
return;
SendMessage(RebarHandle, RB_DELETEBAND, (WPARAM)index, 0);
}
BOOLEAN RebarBandExists(
_In_ UINT BandID
)
{
UINT index = (UINT)SendMessage(RebarHandle, RB_IDTOINDEX, (WPARAM)BandID, 0);
if (index != -1)
return TRUE;
return FALSE;
}
VOID RebarLoadSettings(
VOID
)
{
// Initialize the Toolbar Imagelist.
if (ToolStatusConfig.ToolBarEnabled && !ToolBarImageList)
{
ToolBarImageList = ImageList_Create(
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
ILC_COLOR32,
0,
0
);
}
// Initialize the Rebar and Toolbar controls.
if (ToolStatusConfig.ToolBarEnabled && !RebarHandle)
{
REBARINFO rebarInfo = { sizeof(REBARINFO) };
ULONG toolbarButtonSize;
// Create the ReBar window.
RebarHandle = CreateWindowEx(
WS_EX_TOOLWINDOW,
REBARCLASSNAME,
NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CCS_NODIVIDER | CCS_TOP | RBS_VARHEIGHT | RBS_AUTOSIZE, // CCS_NOPARENTALIGN | RBS_FIXEDORDER
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
PhMainWndHandle,
NULL,
NULL,
NULL
);
// Set the toolbar info with no imagelist.
SendMessage(RebarHandle, RB_SETBARINFO, 0, (LPARAM)&rebarInfo);
// Create the ToolBar window.
ToolBarHandle = CreateWindowEx(
0,
TOOLBARCLASSNAME,
NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER | TBSTYLE_FLAT | TBSTYLE_LIST | TBSTYLE_TRANSPARENT | TBSTYLE_TOOLTIPS | TBSTYLE_AUTOSIZE, // TBSTYLE_CUSTOMERASE TBSTYLE_ALTDRAG
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
RebarHandle,
NULL,
NULL,
NULL
);
// Set the toolbar struct size.
SendMessage(ToolBarHandle, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
// Set the toolbar extended toolbar styles.
SendMessage(ToolBarHandle, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DOUBLEBUFFER | TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_HIDECLIPPEDBUTTONS);
// Configure the toolbar imagelist.
SendMessage(ToolBarHandle, TB_SETIMAGELIST, 0, (LPARAM)ToolBarImageList);
// Add the buttons to the toolbar.
ToolbarLoadButtonSettings();
// Resize the toolbar.
SendMessage(ToolBarHandle, TB_AUTOSIZE, 0, 0);
// Query the toolbar width and height.
//SendMessage(ToolBarHandle, TB_GETMAXSIZE, 0, (LPARAM)&toolbarSize);
toolbarButtonSize = (ULONG)SendMessage(ToolBarHandle, TB_GETBUTTONSIZE, 0, 0);
// Enable theming
switch (ToolBarTheme)
{
case TOOLBAR_THEME_BLACK:
{
SendMessage(RebarHandle, RB_SETWINDOWTHEME, 0, (LPARAM)L"Media"); //Media/Communications/BrowserTabBar/Help
SendMessage(ToolBarHandle, TB_SETWINDOWTHEME, 0, (LPARAM)L"Media"); //Media/Communications/BrowserTabBar/Help
}
break;
case TOOLBAR_THEME_BLUE:
{
SendMessage(RebarHandle, RB_SETWINDOWTHEME, 0, (LPARAM)L"Communications");
SendMessage(ToolBarHandle, TB_SETWINDOWTHEME, 0, (LPARAM)L"Communications");
}
break;
}
// Inset the toolbar into the rebar control.
RebarBandInsert(REBAR_BAND_ID_TOOLBAR, ToolBarHandle, LOWORD(toolbarButtonSize), HIWORD(toolbarButtonSize));
}
// Initialize the Searchbox and TreeNewFilters.
if (ToolStatusConfig.SearchBoxEnabled && !SearchboxHandle)
{
SearchboxText = PhReferenceEmptyString();
ProcessTreeFilterEntry = PhAddTreeNewFilter(PhGetFilterSupportProcessTreeList(), (PPH_TN_FILTER_FUNCTION)ProcessTreeFilterCallback, NULL);
ServiceTreeFilterEntry = PhAddTreeNewFilter(PhGetFilterSupportServiceTreeList(), (PPH_TN_FILTER_FUNCTION)ServiceTreeFilterCallback, NULL);
NetworkTreeFilterEntry = PhAddTreeNewFilter(PhGetFilterSupportNetworkTreeList(), (PPH_TN_FILTER_FUNCTION)NetworkTreeFilterCallback, NULL);
// Create the Searchbox control.
SearchboxHandle = CreateSearchControl(ID_SEARCH_CLEAR);
}
// Initialize the Statusbar control.
if (ToolStatusConfig.StatusBarEnabled && !StatusBarHandle)
{
// Create the StatusBar window.
StatusBarHandle = CreateWindowEx(
0,
STATUSCLASSNAME,
NULL,
WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
PhMainWndHandle,
NULL,
NULL,
NULL
);
}
// Hide or show controls (Note: don't unload or remove at runtime).
if (ToolStatusConfig.ToolBarEnabled)
{
if (RebarHandle && !IsWindowVisible(RebarHandle))
ShowWindow(RebarHandle, SW_SHOW);
}
else
{
if (RebarHandle && IsWindowVisible(RebarHandle))
ShowWindow(RebarHandle, SW_HIDE);
}
if (ToolStatusConfig.SearchBoxEnabled && RebarHandle && SearchboxHandle)
{
UINT height = (UINT)SendMessage(RebarHandle, RB_GETROWHEIGHT, 0, 0);
// Add the Searchbox band into the rebar control.
if (!RebarBandExists(REBAR_BAND_ID_SEARCHBOX))
RebarBandInsert(REBAR_BAND_ID_SEARCHBOX, SearchboxHandle, PhMultiplyDivide(180, PhGlobalDpi, 96), height - 2);
if (!IsWindowVisible(SearchboxHandle))
ShowWindow(SearchboxHandle, SW_SHOW);
if (SearchBoxDisplayMode == SEARCHBOX_DISPLAY_MODE_HIDEINACTIVE)
{
if (RebarBandExists(REBAR_BAND_ID_SEARCHBOX))
RebarBandRemove(REBAR_BAND_ID_SEARCHBOX);
}
}
else
{
// Remove the Searchbox band from the rebar control.
if (RebarBandExists(REBAR_BAND_ID_SEARCHBOX))
RebarBandRemove(REBAR_BAND_ID_SEARCHBOX);
if (SearchboxHandle)
{
// Clear search text and reset search filters.
SetFocus(SearchboxHandle);
Static_SetText(SearchboxHandle, L"");
if (IsWindowVisible(SearchboxHandle))
ShowWindow(SearchboxHandle, SW_HIDE);
}
}
if (ToolStatusConfig.StatusBarEnabled)
{
if (StatusBarHandle && !IsWindowVisible(StatusBarHandle))
ShowWindow(StatusBarHandle, SW_SHOW);
}
else
{
if (StatusBarHandle && IsWindowVisible(StatusBarHandle))
ShowWindow(StatusBarHandle, SW_HIDE);
}
ToolbarCreateGraphs();
}
VOID ToolbarLoadSettings(
VOID
)
{
RebarLoadSettings();
if (ToolStatusConfig.ToolBarEnabled && ToolBarHandle)
{
INT index = 0;
INT buttonCount = 0;
buttonCount = (INT)SendMessage(ToolBarHandle, TB_BUTTONCOUNT, 0, 0);
for (index = 0; index < buttonCount; index++)
{
TBBUTTONINFO buttonInfo =
{
sizeof(TBBUTTONINFO),
TBIF_BYINDEX | TBIF_STYLE | TBIF_COMMAND | TBIF_STATE
};
// Get settings for first button
if (SendMessage(ToolBarHandle, TB_GETBUTTONINFO, index, (LPARAM)&buttonInfo) == -1)
break;
// Skip separator buttons
if (buttonInfo.fsStyle == BTNS_SEP)
continue;
// Add the button text
buttonInfo.dwMask |= TBIF_TEXT;
buttonInfo.pszText = ToolbarGetText(buttonInfo.idCommand);
switch (DisplayStyle)
{
case TOOLBAR_DISPLAY_STYLE_IMAGEONLY:
buttonInfo.fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE;
break;
case TOOLBAR_DISPLAY_STYLE_SELECTIVETEXT:
{
switch (buttonInfo.idCommand)
{
case PHAPP_ID_VIEW_REFRESH:
case PHAPP_ID_HACKER_OPTIONS:
case PHAPP_ID_HACKER_FINDHANDLESORDLLS:
case PHAPP_ID_VIEW_SYSTEMINFORMATION:
buttonInfo.fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT;
break;
default:
buttonInfo.fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE;
break;
}
}
break;
case TOOLBAR_DISPLAY_STYLE_ALLTEXT:
buttonInfo.fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT;
break;
}
switch (buttonInfo.idCommand)
{
case PHAPP_ID_HACKER_SHOWDETAILSFORALLPROCESSES:
{
if (WINDOWS_HAS_UAC && PhGetOwnTokenAttributes().Elevated)
{
buttonInfo.fsState |= TBSTATE_HIDDEN;
}
}
break;
case PHAPP_ID_VIEW_ALWAYSONTOP:
{
// Set the pressed state
if (PhGetIntegerSetting(L"MainWindowAlwaysOnTop"))
{
buttonInfo.fsState |= TBSTATE_PRESSED;
}
}
break;
case TIDC_POWERMENUDROPDOWN:
{
buttonInfo.fsStyle |= BTNS_WHOLEDROPDOWN;
}
break;
}
// Set updated button info
SendMessage(ToolBarHandle, TB_SETBUTTONINFO, index, (LPARAM)&buttonInfo);
}
// Resize the toolbar
SendMessage(ToolBarHandle, TB_AUTOSIZE, 0, 0);
}
if (ToolStatusConfig.ToolBarEnabled && RebarHandle && ToolBarHandle)
{
UINT index;
REBARBANDINFO rebarBandInfo =
{
REBARBANDINFO_V6_SIZE,
RBBIM_IDEALSIZE
};
index = (UINT)SendMessage(RebarHandle, RB_IDTOINDEX, (WPARAM)REBAR_BAND_ID_TOOLBAR, 0);
// Get settings for Rebar band.
if (SendMessage(RebarHandle, RB_GETBANDINFO, index, (LPARAM)&rebarBandInfo) != -1)
{
SIZE idealWidth;
// Reset the cxIdeal for the Chevron
SendMessage(ToolBarHandle, TB_GETIDEALSIZE, FALSE, (LPARAM)&idealWidth);
rebarBandInfo.cxIdeal = idealWidth.cx;
SendMessage(RebarHandle, RB_SETBANDINFO, index, (LPARAM)&rebarBandInfo);
}
}
// Invoke the LayoutPaddingCallback.
SendMessage(PhMainWndHandle, WM_SIZE, 0, 0);
}
VOID ToolbarResetSettings(
VOID
)
{
// Remove all buttons.
INT buttonCount = (INT)SendMessage(ToolBarHandle, TB_BUTTONCOUNT, 0, 0);
while (buttonCount--)
SendMessage(ToolBarHandle, TB_DELETEBUTTON, (WPARAM)buttonCount, 0);
// Add the default buttons.
SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons);
}
PWSTR ToolbarGetText(
_In_ INT CommandID
)
{
switch (CommandID)
{
case PHAPP_ID_VIEW_REFRESH:
return L"Refresh";
case PHAPP_ID_HACKER_OPTIONS:
return L"Options";
case PHAPP_ID_HACKER_FINDHANDLESORDLLS:
return L"Find handles or DLLs";
case PHAPP_ID_VIEW_SYSTEMINFORMATION:
return L"System information";
case TIDC_FINDWINDOW:
return L"Find window";
case TIDC_FINDWINDOWTHREAD:
return L"Find window and thread";
case TIDC_FINDWINDOWKILL:
return L"Find window and kill";
case PHAPP_ID_VIEW_ALWAYSONTOP:
return L"Always on top";
case TIDC_POWERMENUDROPDOWN:
return L"Computer";
case PHAPP_ID_HACKER_SHOWDETAILSFORALLPROCESSES:
return L"Show details for all processes";
}
return L"ERROR";
}
HBITMAP ToolbarLoadImageFromIcon(
_In_ ULONG Width,
_In_ ULONG Height,
_In_ PWSTR Name
)
{
HICON icon = PhLoadIcon(PluginInstance->DllBase, Name, 0, Width, Height);
HBITMAP bitmap = PhIconToBitmap(icon, Width, Height);
DestroyIcon(icon);
return bitmap;
}
HBITMAP ToolbarGetImage(
_In_ INT CommandID
)
{
static INT cx = 0;
static INT cy = 0;
if (!cx)
{
cx = GetSystemMetrics(SM_CXSMICON);
}
if (!cy)
{
cy = GetSystemMetrics(SM_CYSMICON);
}
switch (CommandID)
{
case PHAPP_ID_VIEW_REFRESH:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_ARROW_REFRESH_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_ARROW_REFRESH));
}
return toolbarBitmap;
}
break;
case PHAPP_ID_HACKER_OPTIONS:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_COG_EDIT_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_COG_EDIT));
}
return toolbarBitmap;
}
break;
case PHAPP_ID_HACKER_FINDHANDLESORDLLS:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_FIND_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_FIND));
}
return toolbarBitmap;
}
break;
case PHAPP_ID_VIEW_SYSTEMINFORMATION:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_CHART_LINE_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_CHART_LINE));
}
return toolbarBitmap;
}
break;
case TIDC_FINDWINDOW:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_APPLICATION_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_TBAPPLICATION));
}
return toolbarBitmap;
}
break;
case TIDC_FINDWINDOWTHREAD:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_APPLICATION_GO_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_APPLICATION_GO));
}
return toolbarBitmap;
}
break;
case TIDC_FINDWINDOWKILL:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_CROSS_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_CROSS));
}
return toolbarBitmap;
}
break;
case PHAPP_ID_VIEW_ALWAYSONTOP:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_APPLICATION_GET_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_APPLICATION_GET));
}
return toolbarBitmap;
}
break;
case TIDC_POWERMENUDROPDOWN:
{
HBITMAP toolbarBitmap = NULL;
if (ToolStatusConfig.ModernIcons)
{
toolbarBitmap = LoadImageFromResources(cx, cy, MAKEINTRESOURCE(IDB_POWER_MODERN));
}
else
{
toolbarBitmap = ToolbarLoadImageFromIcon(cx, cy, MAKEINTRESOURCE(IDI_LIGHTBULB_OFF));
}
return toolbarBitmap;
}
break;
case PHAPP_ID_HACKER_SHOWDETAILSFORALLPROCESSES:
{
HBITMAP toolbarBitmap = NULL;
HICON shieldIcon = NULL;
if (shieldIcon = PhLoadIcon(NULL, IDI_SHIELD, PH_LOAD_ICON_SIZE_SMALL | PH_LOAD_ICON_STRICT, 0, 0))
{
toolbarBitmap = PhIconToBitmap(
shieldIcon,
cx,
cy
);
DestroyIcon(shieldIcon);
}
return toolbarBitmap;
}
break;
}
return NULL;
}
VOID ToolbarLoadButtonSettings(
VOID
)
{
INT buttonCount;
ULONG64 countInteger;
PPH_STRING settingsString;
PTBBUTTON buttonArray;
PH_STRINGREF remaining;
PH_STRINGREF part;
settingsString = PhaGetStringSetting(SETTING_NAME_TOOLBAR_CONFIG);
remaining = settingsString->sr;
if (remaining.Length == 0)
{
// Load default settings
SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons);
return;
}
// Query the number of buttons to insert
if (!PhSplitStringRefAtChar(&remaining, '|', &part, &remaining))
{
// Load default settings
SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons);
return;
}
if (!PhStringToInteger64(&part, 10, &countInteger))
{
// Load default settings
SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons);
return;
}
buttonCount = (INT)countInteger;
// Allocate the button array
buttonArray = PhAllocate(buttonCount * sizeof(TBBUTTON));
memset(buttonArray, 0, buttonCount * sizeof(TBBUTTON));
for (INT index = 0; index < buttonCount; index++)
{
ULONG64 commandInteger;
PH_STRINGREF commandIdPart;
if (remaining.Length == 0)
break;
PhSplitStringRefAtChar(&remaining, '|', &commandIdPart, &remaining);
PhStringToInteger64(&commandIdPart, 10, &commandInteger);
buttonArray[index].idCommand = (INT)commandInteger;
//buttonArray[index].iBitmap = I_IMAGECALLBACK;
buttonArray[index].fsState = TBSTATE_ENABLED;
if (commandInteger)
{
buttonArray[index].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE;
}
else
{
buttonArray[index].fsStyle = BTNS_SEP;
}
// Pre-cache the image in the Toolbar array on startup.
for (INT i = 0; i < ARRAYSIZE(ToolbarButtons); i++)
{
if (ToolbarButtons[i].idCommand == buttonArray[index].idCommand)
{
HBITMAP buttonImage;
buttonImage = ToolbarGetImage(ToolbarButtons[i].idCommand);
// Add the image, cache the value in the ToolbarButtons array, set the bitmap index.
buttonArray[index].iBitmap = ToolbarButtons[i].iBitmap = ImageList_Add(
ToolBarImageList,
buttonImage,
NULL
);
DeleteObject(buttonImage);
break;
}
}
}
SendMessage(ToolBarHandle, TB_ADDBUTTONS, buttonCount, (LPARAM)buttonArray);
PhFree(buttonArray);
}
VOID ToolbarSaveButtonSettings(
VOID
)
{
INT buttonIndex = 0;
INT buttonCount = 0;
PPH_STRING settingsString;
PH_STRING_BUILDER stringBuilder;
PhInitializeStringBuilder(&stringBuilder, 100);
buttonCount = (INT)SendMessage(ToolBarHandle, TB_BUTTONCOUNT, 0, 0);
PhAppendFormatStringBuilder(
&stringBuilder,
L"%d|",
buttonCount
);
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
TBBUTTONINFO buttonInfo =
{
sizeof(TBBUTTONINFO),
TBIF_BYINDEX | TBIF_IMAGE | TBIF_STYLE | TBIF_COMMAND
};
// Get button information.
if (SendMessage(ToolBarHandle, TB_GETBUTTONINFO, buttonIndex, (LPARAM)&buttonInfo) == -1)
break;
PhAppendFormatStringBuilder(
&stringBuilder,
L"%d|",
buttonInfo.idCommand
);
}
if (stringBuilder.String->Length != 0)
PhRemoveEndStringBuilder(&stringBuilder, 1);
settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder));
PhSetStringSetting2(SETTING_NAME_TOOLBAR_CONFIG, &settingsString->sr);
}
VOID ReBarLoadLayoutSettings(
VOID
)
{
UINT bandIndex = 0;
UINT bandCount = 0;
PPH_STRING settingsString;
PH_STRINGREF remaining;
settingsString = PhGetStringSetting(SETTING_NAME_REBAR_CONFIG);
remaining = settingsString->sr;
if (remaining.Length == 0)
return;
bandCount = (UINT)SendMessage(RebarHandle, RB_GETBANDCOUNT, 0, 0);
for (bandIndex = 0; bandIndex < bandCount; bandIndex++)
{
PH_STRINGREF idPart;
PH_STRINGREF cxPart;
PH_STRINGREF stylePart;
ULONG64 idInteger;
ULONG64 cxInteger;
ULONG64 styleInteger;
UINT oldBandIndex;
REBARBANDINFO rebarBandInfo =
{
REBARBANDINFO_V6_SIZE,
RBBIM_STYLE | RBBIM_SIZE
};
if (remaining.Length == 0)
break;
PhSplitStringRefAtChar(&remaining, '|', &idPart, &remaining);
PhSplitStringRefAtChar(&remaining, '|', &cxPart, &remaining);
PhSplitStringRefAtChar(&remaining, '|', &stylePart, &remaining);
PhStringToInteger64(&idPart, 10, &idInteger);
PhStringToInteger64(&cxPart, 10, &cxInteger);
PhStringToInteger64(&stylePart, 10, &styleInteger);
if ((oldBandIndex = (UINT)SendMessage(RebarHandle, RB_IDTOINDEX, (UINT)idInteger, 0)) == -1)
break;
if (oldBandIndex != bandIndex)
{
SendMessage(RebarHandle, RB_MOVEBAND, oldBandIndex, bandIndex);
}
if (SendMessage(RebarHandle, RB_GETBANDINFO, bandIndex, (LPARAM)&rebarBandInfo))
{
if (idInteger == REBAR_BAND_ID_SEARCHBOX)
{
rebarBandInfo.fStyle |= RBBS_FIXEDSIZE;
}
rebarBandInfo.cx = (UINT)cxInteger;
rebarBandInfo.fStyle |= (UINT)styleInteger;
SendMessage(RebarHandle, RB_SETBANDINFO, bandIndex, (LPARAM)&rebarBandInfo);
}
}
}
VOID ReBarSaveLayoutSettings(
VOID
)
{
UINT bandIndex = 0;
UINT bandCount = 0;
PPH_STRING settingsString;
PH_STRING_BUILDER stringBuilder;
PhInitializeStringBuilder(&stringBuilder, 100);
bandCount = (UINT)SendMessage(RebarHandle, RB_GETBANDCOUNT, 0, 0);
for (bandIndex = 0; bandIndex < bandCount; bandIndex++)
{
REBARBANDINFO rebarBandInfo =
{
REBARBANDINFO_V6_SIZE,
RBBIM_STYLE | RBBIM_SIZE | RBBIM_ID
};
SendMessage(RebarHandle, RB_GETBANDINFO, bandIndex, (LPARAM)&rebarBandInfo);
if (rebarBandInfo.fStyle & RBBS_GRIPPERALWAYS)
{
rebarBandInfo.fStyle &= ~RBBS_GRIPPERALWAYS;
}
if (rebarBandInfo.fStyle & RBBS_NOGRIPPER)
{
rebarBandInfo.fStyle &= ~RBBS_NOGRIPPER;
}
if (rebarBandInfo.fStyle & RBBS_FIXEDSIZE)
{
rebarBandInfo.fStyle &= ~RBBS_FIXEDSIZE;
}
PhAppendFormatStringBuilder(
&stringBuilder,
L"%u|%u|%u|",
rebarBandInfo.wID,
rebarBandInfo.cx,
rebarBandInfo.fStyle
);
}
if (stringBuilder.String->Length != 0)
PhRemoveEndStringBuilder(&stringBuilder, 1);
settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder));
PhSetStringSetting2(SETTING_NAME_REBAR_CONFIG, &settingsString->sr);
}