/* * 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 . */ #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); }