go my file uploader

This commit is contained in:
AirDog46
2025-05-13 19:45:22 +03:00
commit c5fab8aa94
708 changed files with 343216 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
2.4
* Added 32x32 icons for high DPI displays
* Fixed status bar crash
2.3
* Added Auto-hide main menu
* Added CPU, Memory and IO graphs to main window
* Added Right-click menu on the Toolbar
* Added Toolbar customize dialog
* Added Statusbar customize dialog
2.2
* Added Modern Toolbar theme
* Added portable Toolbar customization
* Added Toolbar power menu (ported from PH1.x)
* Fixed Toolbar DPI scaling issues
2.1
* Fixed Auto-hide Searchbox (Ctrl+K to show)
2.0
* Added Toolbar customization
* Added Rebar Chevron support
* Added Auto-hide Searchbox
* Fixed searching multiple processes
1.9
* Added PNG images
* Fixed search box fonts
* Fixed plugin settings state (disable/enable)
* Updated Searchbox UI
* Updated Searchbox commands
* Updated plugin settings
1.8
* Added search box
1.7
* Added option to configure Toolbar display style.
1.6
* Fixed Always on Top being reset when using Find Window
* Fixed Esc key when using Find Window
1.5
* Added Find Window and Kill
1.4
* Added option to resolve ghost windows to the hung windows
they represent
1.3
* Fixed layout problems
1.2
* Added options
* Status bar panel widths are more stable
1.1
* Fixed hanging when using Find Window on hung programs
* Fixed status bar with no selected parts
1.0
* Initial release

View File

@@ -0,0 +1,294 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (Australia) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,4,0,0
PRODUCTVERSION 2,4,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "0c0904b0"
BEGIN
VALUE "CompanyName", "dmex"
VALUE "FileDescription", "ToolStatus plugin for Process Hacker"
VALUE "FileVersion", "2.4"
VALUE "InternalName", "ToolStatus"
VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
VALUE "OriginalFilename", "ToolStatus.dll"
VALUE "ProductName", "ToolStatus plugin for Process Hacker"
VALUE "ProductVersion", "2.4"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0xc09, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_OPTIONS DIALOGEX 0, 0, 191, 103
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Options"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "Enable toolbar",IDC_ENABLE_TOOLBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,62,10
CONTROL "Enable status bar",IDC_ENABLE_STATUSBAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,19,72,10
CONTROL "Resolve ghost windows to hung windows",IDC_RESOLVEGHOSTWINDOWS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,32,152,10
CONTROL "Auto-hide main menu (Alt or F10 key toggle)",IDC_ENABLE_AUTOHIDE_MENU,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,44,157,10
DEFPUSHBUTTON "OK",IDOK,79,82,50,14
PUSHBUTTON "Cancel",IDCANCEL,133,82,50,14
LTEXT "Note: Right-click the toolbar on the main window to customize the icons and graphs.",IDC_STATIC,7,59,157,18
END
IDD_CUSTOMIZE_TB DIALOGEX 0, 0, 369, 191
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Customize Toolbar"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "Available toolbar buttons:",IDC_STATIC,7,7,85,8
LISTBOX IDC_AVAILABLE,7,18,122,117,LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Add >",IDC_ADD,133,50,50,14
PUSHBUTTON "< Remove",IDC_REMOVE,133,68,50,14
LTEXT "Current toolbar buttons:",IDC_STATIC,188,7,81,8
LISTBOX IDC_CURRENT,187,18,122,117,LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Move up",IDC_MOVEUP,312,18,50,14
PUSHBUTTON "Move down",IDC_MOVEDOWN,312,36,50,14
LTEXT "Text options:",IDC_STATIC,7,142,44,8
COMBOBOX IDC_TEXTOPTIONS,56,139,123,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Search box:",IDC_STATIC,7,158,45,8
COMBOBOX IDC_SEARCHOPTIONS,56,155,123,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Enable modern icons",IDC_ENABLE_MODERN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,188,141,83,10
CONTROL "Auto-hide main menu (Alt or F10 key toggle)",IDC_ENABLE_AUTOHIDE_MENU,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,188,154,157,10
PUSHBUTTON "Reset",IDC_RESET,258,170,50,14
DEFPUSHBUTTON "Close",IDCANCEL,312,170,50,14
LTEXT "Theme:",IDC_STATIC,7,174,45,8,NOT WS_VISIBLE
COMBOBOX IDC_THEMEOPTIONS,56,171,123,30,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
END
IDD_CUSTOMIZE_SB DIALOGEX 0, 0, 373, 142
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Customize Status Bar"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "Available status bar entries:",-1,7,7,91,8
LISTBOX IDC_AVAILABLE,7,18,122,117,LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Add >",IDC_ADD,133,50,50,14
PUSHBUTTON "< Remove",IDC_REMOVE,133,68,50,14
LTEXT "Current status bar entries:",-1,188,7,87,8
LISTBOX IDC_CURRENT,187,18,122,117,LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Move up",IDC_MOVEUP,316,18,50,14
PUSHBUTTON "Move down",IDC_MOVEDOWN,316,36,50,14
PUSHBUTTON "Reset",IDC_RESET,316,103,50,14
DEFPUSHBUTTON "Close",IDCANCEL,316,121,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_OPTIONS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 184
TOPMARGIN, 7
BOTTOMMARGIN, 96
END
IDD_CUSTOMIZE_TB, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 362
TOPMARGIN, 7
BOTTOMMARGIN, 184
END
IDD_CUSTOMIZE_SB, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 366
TOPMARGIN, 7
BOTTOMMARGIN, 135
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_MAINWND_ACCEL ACCELERATORS
BEGIN
"K", ID_SEARCH, VIRTKEY, CONTROL, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// PNG
//
IDB_SEARCH_ACTIVE PNG "resources\\active_search.png"
IDB_SEARCH_INACTIVE PNG "resources\\inactive_search.png"
IDB_APPLICATION_GET_MODERN PNG "resources\\application_get_modern.png"
IDB_APPLICATION_GO_MODERN PNG "resources\\application_go_modern.png"
IDB_APPLICATION_MODERN PNG "resources\\application_modern.png"
IDB_ARROW_REFRESH_MODERN PNG "resources\\arrow_refresh_modern.png"
IDB_CHART_LINE_MODERN PNG "resources\\chart_line_modern.png"
IDB_COG_EDIT_MODERN PNG "resources\\cog_edit_modern.png"
IDB_CROSS_MODERN PNG "resources\\cross_modern.png"
IDB_FIND_MODERN PNG "resources\\find_modern.png"
IDB_POWER_MODERN PNG "resources\\lightbulb_off_modern.png"
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_SEARCH_ACTIVE_BMP BITMAP "resources\\active_search.bmp"
IDB_SEARCH_INACTIVE_BMP BITMAP "resources\\inactive_search.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_OPTIONS AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_CUSTOMIZE_TB AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_CUSTOMIZE_SB AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ARROW_REFRESH ICON "resources\\arrow_refresh.ico"
IDI_COG_EDIT ICON "resources\\cog_edit.ico"
IDI_FIND ICON "resources\\find.ico"
IDI_CHART_LINE ICON "resources\\chart_line.ico"
IDI_TBAPPLICATION ICON "resources\\application.ico"
IDI_APPLICATION_GO ICON "resources\\application_go.ico"
IDI_CROSS ICON "resources\\cross.ico"
IDI_APPLICATION_GET ICON "resources\\application_get.ico"
IDI_LIGHTBULB_OFF ICON "resources\\lightbulb_off.ico"
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{60B43533-C75E-4741-9E19-C4D581BEF51C}</ProjectGuid>
<RootNamespace>ToolStatus</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>ToolStatus</ProjectName>
<WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\Plugins.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug64</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<AdditionalDependencies>WindowsCodecs.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<AdditionalDependencies>WindowsCodecs.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Link>
<AdditionalDependencies>WindowsCodecs.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>WindowsCodecs.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="customizesb.c" />
<ClCompile Include="customizetb.c" />
<ClCompile Include="graph.c" />
<ClCompile Include="main.c" />
<ClCompile Include="searchbox.c" />
<ClCompile Include="options.c" />
<ClCompile Include="filter.c" />
<ClCompile Include="statusbar.c" />
<ClCompile Include="toolbar.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
<ClInclude Include="toolstatus.h" />
</ItemGroup>
<ItemGroup>
<None Include="CHANGELOG.txt" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ToolStatus.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="resources\active_search.bmp" />
<Image Include="resources\active_search.png" />
<Image Include="resources\application.ico" />
<Image Include="resources\application_get.ico" />
<Image Include="resources\application_get_modern.png" />
<Image Include="resources\application_go.ico" />
<Image Include="resources\application_go_modern.png" />
<Image Include="resources\application_modern.png" />
<Image Include="resources\arrow_refresh.ico" />
<Image Include="resources\arrow_refresh_modern.png" />
<Image Include="resources\chart_line.ico" />
<Image Include="resources\chart_line_modern.png" />
<Image Include="resources\cog_edit.ico" />
<Image Include="resources\cog_edit_modern.png" />
<Image Include="resources\cross.ico" />
<Image Include="resources\cross_modern.png" />
<Image Include="resources\find.ico" />
<Image Include="resources\find_modern.png" />
<Image Include="resources\inactive_search.bmp" />
<Image Include="resources\inactive_search.png" />
<Image Include="resources\lightbulb_off.ico" />
<Image Include="resources\lightbulb_off_modern.png" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="Resource Files\Images">
<UniqueIdentifier>{6b19a091-ecf3-43f6-8756-eabd86ca6db7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="options.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="statusbar.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="filter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="searchbox.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="toolbar.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="graph.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="customizetb.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="customizesb.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="toolstatus.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CHANGELOG.txt" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ToolStatus.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="resources\active_search.bmp">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\active_search.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\application_get_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\application_go_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\application_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\arrow_refresh_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\chart_line_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\cog_edit_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\cross_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\find_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\inactive_search.bmp">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\inactive_search.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\lightbulb_off_modern.png">
<Filter>Resource Files\Images</Filter>
</Image>
<Image Include="resources\application.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\application_get.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\application_go.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\arrow_refresh.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\lightbulb_off.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\find.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\cross.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\cog_edit.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resources\chart_line.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,679 @@
/*
* Process Hacker ToolStatus -
* Statusbar Customize Dialog
*
* Copyright (C) 2015-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"
#include "commonutil.h"
BOOLEAN CustomizeStatusBarItemExists(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IdCommand
)
{
INT buttonIndex = 0;
INT buttonCount = 0;
buttonCount = ListBox_GetCount(Context->CurrentListHandle);
if (buttonCount == LB_ERR)
return FALSE;
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, buttonIndex);
if (itemContext == NULL)
continue;
if (itemContext->IdCommand == IdCommand)
return TRUE;
}
return FALSE;
}
VOID CustomizeInsertStatusBarItem(
_In_ INT Index,
_In_ PBUTTON_CONTEXT ItemContext
)
{
PSTATUSBAR_ITEM statusItem;
statusItem = PhAllocate(sizeof(STATUSBAR_ITEM));
memset(statusItem, 0, sizeof(STATUSBAR_ITEM));
statusItem->Id = ItemContext->IdCommand;
PhInsertItemList(StatusBarItemList, Index, statusItem);
StatusBarUpdate(TRUE);
}
VOID CustomizeAddStatusBarItem(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IndexAvail,
_In_ INT IndexTo
)
{
INT count;
PBUTTON_CONTEXT itemContext;
count = ListBox_GetCount(Context->AvailableListHandle);
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->AvailableListHandle, IndexAvail);
if (count == LB_ERR)
return;
if (itemContext == NULL)
return;
if (!itemContext->IsVirtual)
{
// remove from 'available' list
ListBox_DeleteString(Context->AvailableListHandle, IndexAvail);
if (IndexAvail == count - 1)
{
ListBox_SetCurSel(Context->AvailableListHandle, IndexAvail - 1);
}
else
{
ListBox_SetCurSel(Context->AvailableListHandle, IndexAvail);
}
// insert into 'current' list
ListBox_InsertItemData(Context->CurrentListHandle, IndexTo, itemContext);
CustomizeInsertStatusBarItem(IndexTo, itemContext);
}
SendMessage(Context->DialogHandle, WM_COMMAND, MAKEWPARAM(IDC_AVAILABLE, LBN_SELCHANGE), 0);
}
VOID CustomizeRemoveStatusBarItem(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IndexFrom
)
{
PBUTTON_CONTEXT itemContext;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, IndexFrom);
if (itemContext == NULL)
return;
ListBox_DeleteString(Context->CurrentListHandle, IndexFrom);
ListBox_SetCurSel(Context->CurrentListHandle, IndexFrom);
PhRemoveItemList(StatusBarItemList, IndexFrom);
if (!itemContext->IsVirtual)
{
INT count;
count = ListBox_GetCount(Context->AvailableListHandle);
if (count == LB_ERR)
count = 1;
// insert into 'available' list
ListBox_InsertItemData(Context->AvailableListHandle, count - 1, itemContext);
}
SendMessage(Context->DialogHandle, WM_COMMAND, MAKEWPARAM(IDC_CURRENT, LBN_SELCHANGE), 0);
StatusBarUpdate(TRUE);
}
VOID CustomizeMoveStatusBarItem(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IndexFrom,
_In_ INT IndexTo
)
{
INT count;
PBUTTON_CONTEXT itemContext;
if (IndexFrom == IndexTo)
return;
count = ListBox_GetCount(Context->CurrentListHandle);
if (count == LB_ERR)
return;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, IndexFrom);
if (itemContext == NULL)
return;
ListBox_DeleteString(Context->CurrentListHandle, IndexFrom);
ListBox_InsertItemData(Context->CurrentListHandle, IndexTo, itemContext);
ListBox_SetCurSel(Context->CurrentListHandle, IndexTo);
if (IndexTo <= 0)
{
Button_Enable(Context->MoveUpButtonHandle, FALSE);
}
else
{
Button_Enable(Context->MoveUpButtonHandle, TRUE);
}
// last item is always separator
if (IndexTo >= (count - 2))
{
Button_Enable(Context->MoveDownButtonHandle, FALSE);
}
else
{
Button_Enable(Context->MoveDownButtonHandle, TRUE);
}
PhRemoveItemList(StatusBarItemList, IndexFrom);
CustomizeInsertStatusBarItem(IndexTo, itemContext);
}
VOID CustomizeFreeStatusBarItems(
_In_ PCUSTOMIZE_CONTEXT Context
)
{
INT buttonIndex = 0;
INT buttonCount = 0;
buttonCount = ListBox_GetCount(Context->CurrentListHandle);
if (buttonCount != LB_ERR)
{
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
if (itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, buttonIndex))
{
PhFree(itemContext);
}
}
}
buttonCount = ListBox_GetCount(Context->AvailableListHandle);
if (buttonCount != LB_ERR)
{
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
if (itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->AvailableListHandle, buttonIndex))
{
PhFree(itemContext);
}
}
}
}
VOID CustomizeLoadStatusBarItems(
_In_ PCUSTOMIZE_CONTEXT Context
)
{
ULONG buttonIndex;
PBUTTON_CONTEXT itemContext;
CustomizeFreeStatusBarItems(Context);
ListBox_ResetContent(Context->AvailableListHandle);
ListBox_ResetContent(Context->CurrentListHandle);
for (buttonIndex = 0; buttonIndex < StatusBarItemList->Count; buttonIndex++)
{
PSTATUSBAR_ITEM statusItem;
statusItem = StatusBarItemList->Items[buttonIndex];
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IdCommand = statusItem->Id;
ListBox_AddItemData(Context->CurrentListHandle, itemContext);
}
for (buttonIndex = 0; buttonIndex < MAX_STATUSBAR_ITEMS; buttonIndex++)
{
ULONG buttonId = StatusBarItems[buttonIndex];
if (CustomizeStatusBarItemExists(Context, buttonId))
continue;
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IdCommand = buttonId;
ListBox_AddItemData(Context->AvailableListHandle, itemContext);
}
// Append separator to the last 'current list' position
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IsVirtual = TRUE;
buttonIndex = ListBox_AddItemData(Context->CurrentListHandle, itemContext);
ListBox_SetCurSel(Context->CurrentListHandle, buttonIndex);
ListBox_SetTopIndex(Context->CurrentListHandle, buttonIndex);
// Append separator to the last 'available list' position
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IsVirtual = TRUE;
buttonIndex = ListBox_AddItemData(Context->AvailableListHandle, itemContext);
ListBox_SetCurSel(Context->AvailableListHandle, buttonIndex);
ListBox_SetTopIndex(Context->AvailableListHandle, 0); // NOTE: This is intentional.
// Disable buttons
Button_Enable(Context->MoveUpButtonHandle, FALSE);
Button_Enable(Context->MoveDownButtonHandle, FALSE);
Button_Enable(Context->AddButtonHandle, FALSE);
Button_Enable(Context->RemoveButtonHandle, FALSE);
}
INT_PTR CALLBACK CustomizeStatusBarDialogProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
PCUSTOMIZE_CONTEXT context = NULL;
if (uMsg == WM_INITDIALOG)
{
context = (PCUSTOMIZE_CONTEXT)PhAllocate(sizeof(CUSTOMIZE_CONTEXT));
memset(context, 0, sizeof(CUSTOMIZE_CONTEXT));
SetProp(hwndDlg, L"Context", (HANDLE)context);
}
else
{
context = (PCUSTOMIZE_CONTEXT)GetProp(hwndDlg, L"Context");
if (uMsg == WM_NCDESTROY)
{
RemoveProp(hwndDlg, L"Context");
PhFree(context);
}
}
if (context == NULL)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
PhCenterWindow(hwndDlg, PhMainWndHandle);
context->DialogHandle = hwndDlg;
context->AvailableListHandle = GetDlgItem(hwndDlg, IDC_AVAILABLE);
context->CurrentListHandle = GetDlgItem(hwndDlg, IDC_CURRENT);
context->MoveUpButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEUP);
context->MoveDownButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEDOWN);
context->AddButtonHandle = GetDlgItem(hwndDlg, IDC_ADD);
context->RemoveButtonHandle = GetDlgItem(hwndDlg, IDC_REMOVE);
context->FontHandle = CommonDuplicateFont((HFONT)SendMessage(StatusBarHandle, WM_GETFONT, 0, 0));
ListBox_SetItemHeight(context->AvailableListHandle, 0, PhMultiplyDivide(22, PhGlobalDpi, 96)); // BitmapHeight
ListBox_SetItemHeight(context->CurrentListHandle, 0, PhMultiplyDivide(22, PhGlobalDpi, 96)); // BitmapHeight
CustomizeLoadStatusBarItems(context);
SendMessage(context->DialogHandle, WM_NEXTDLGCTL, (WPARAM)context->CurrentListHandle, TRUE);
}
return TRUE;
case WM_DESTROY:
{
StatusBarSaveSettings();
CustomizeFreeStatusBarItems(context);
if (context->FontHandle)
{
DeleteObject(context->FontHandle);
}
}
break;
case WM_COMMAND:
{
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDC_AVAILABLE:
{
switch (GET_WM_COMMAND_CMD(wParam, lParam))
{
case LBN_SELCHANGE:
{
INT count;
INT index;
count = ListBox_GetCount(context->AvailableListHandle);
index = ListBox_GetCurSel(context->AvailableListHandle);
if (count == LB_ERR)
break;
if (index == LB_ERR)
break;
if (index == (count - 1))
{
Button_Enable(context->AddButtonHandle, FALSE);
}
else
{
Button_Enable(context->AddButtonHandle, TRUE);
}
}
break;
case LBN_DBLCLK:
{
INT count;
INT index;
INT indexto;
count = ListBox_GetCount(context->AvailableListHandle);
index = ListBox_GetCurSel(context->AvailableListHandle);
indexto = ListBox_GetCurSel(context->CurrentListHandle);
if (count == LB_ERR)
break;
if (index == LB_ERR)
break;
if (indexto == LB_ERR)
break;
if (index == (count - 1))
{
// virtual separator
break;
}
CustomizeAddStatusBarItem(context, index, indexto);
}
break;
}
}
break;
case IDC_CURRENT:
{
switch (GET_WM_COMMAND_CMD(wParam, lParam))
{
case LBN_SELCHANGE:
{
INT count;
INT index;
PBUTTON_CONTEXT itemContext;
count = ListBox_GetCount(context->CurrentListHandle);
index = ListBox_GetCurSel(context->CurrentListHandle);
if (count == LB_ERR)
break;
if (index == LB_ERR)
break;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(context->CurrentListHandle, index);
if (itemContext == NULL)
break;
if (index == 0 && count == 2)
{
// first and last item
Button_Enable(context->MoveUpButtonHandle, FALSE);
Button_Enable(context->MoveDownButtonHandle, FALSE);
}
else if (index == (count - 1))
{
// last item (virtual separator)
Button_Enable(context->MoveUpButtonHandle, FALSE);
Button_Enable(context->MoveDownButtonHandle, FALSE);
}
else if (index == (count - 2))
{
// second last item (last non-virtual item)
Button_Enable(context->MoveUpButtonHandle, TRUE);
Button_Enable(context->MoveDownButtonHandle, FALSE);
}
else if (index == 0)
{
// first item
Button_Enable(context->MoveUpButtonHandle, FALSE);
Button_Enable(context->MoveDownButtonHandle, TRUE);
}
else
{
Button_Enable(context->MoveUpButtonHandle, TRUE);
Button_Enable(context->MoveDownButtonHandle, TRUE);
}
Button_Enable(context->RemoveButtonHandle, !itemContext->IsVirtual);
}
break;
case LBN_DBLCLK:
{
INT count;
INT index;
count = ListBox_GetCount(context->CurrentListHandle);
index = ListBox_GetCurSel(context->CurrentListHandle);
if (count == LB_ERR)
break;
if (index == LB_ERR)
break;
if (index == (count - 1))
{
// virtual separator
break;
}
CustomizeRemoveStatusBarItem(context, index);
}
break;
}
}
break;
case IDC_ADD:
{
INT index;
INT indexto;
index = ListBox_GetCurSel(context->AvailableListHandle);
indexto = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
if (indexto == LB_ERR)
break;
CustomizeAddStatusBarItem(context, index, indexto);
}
break;
case IDC_REMOVE:
{
INT index;
index = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
CustomizeRemoveStatusBarItem(context, index);
}
break;
case IDC_MOVEUP:
{
INT index;
index = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
CustomizeMoveStatusBarItem(context, index, index - 1);
}
break;
case IDC_MOVEDOWN:
{
INT index;
index = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
CustomizeMoveStatusBarItem(context, index, index + 1);
}
break;
case IDC_RESET:
{
// Reset to default settings.
StatusBarResetSettings();
// Save as the new defaults.
StatusBarSaveSettings();
StatusBarUpdate(TRUE);
CustomizeLoadStatusBarItems(context);
}
break;
case IDCANCEL:
{
EndDialog(hwndDlg, FALSE);
}
break;
}
}
break;
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT drawInfo = (LPDRAWITEMSTRUCT)lParam;
if (drawInfo->CtlID == IDC_AVAILABLE || drawInfo->CtlID == IDC_CURRENT)
{
HDC bufferDc;
HBITMAP bufferBitmap;
HBITMAP oldBufferBitmap;
PBUTTON_CONTEXT itemContext;
RECT bufferRect =
{
0, 0,
drawInfo->rcItem.right - drawInfo->rcItem.left,
drawInfo->rcItem.bottom - drawInfo->rcItem.top
};
BOOLEAN isSelected = (drawInfo->itemState & ODS_SELECTED) == ODS_SELECTED;
BOOLEAN isFocused = (drawInfo->itemState & ODS_FOCUS) == ODS_FOCUS;
if (drawInfo->itemID == LB_ERR)
break;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(drawInfo->hwndItem, drawInfo->itemID);
if (itemContext == NULL)
break;
bufferDc = CreateCompatibleDC(drawInfo->hDC);
bufferBitmap = CreateCompatibleBitmap(drawInfo->hDC, bufferRect.right, bufferRect.bottom);
oldBufferBitmap = SelectBitmap(bufferDc, bufferBitmap);
SelectFont(bufferDc, context->FontHandle);
SetBkMode(bufferDc, TRANSPARENT);
FillRect(bufferDc, &bufferRect, GetSysColorBrush(isFocused ? COLOR_HIGHLIGHT : COLOR_WINDOW));
if (isSelected)
{
FrameRect(bufferDc, &bufferRect, isFocused ? GetStockBrush(BLACK_BRUSH) : GetSysColorBrush(COLOR_HIGHLIGHT));
}
else
{
FrameRect(bufferDc, &bufferRect, isFocused ? GetStockBrush(BLACK_BRUSH) : GetSysColorBrush(COLOR_HIGHLIGHTTEXT));
}
if (!itemContext->IsVirtual)
{
SetTextColor(bufferDc, GetSysColor(isFocused ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
bufferRect.left += 5;
DrawText(
bufferDc,
StatusBarGetText(itemContext->IdCommand),
-1,
&bufferRect,
DT_LEFT | DT_VCENTER | DT_SINGLELINE
);
}
BitBlt(
drawInfo->hDC,
drawInfo->rcItem.left,
drawInfo->rcItem.top,
drawInfo->rcItem.right,
drawInfo->rcItem.bottom,
bufferDc,
0,
0,
SRCCOPY
);
SelectBitmap(bufferDc, oldBufferBitmap);
DeleteBitmap(bufferBitmap);
DeleteDC(bufferDc);
return TRUE;
}
}
break;
}
return FALSE;
}
VOID StatusBarShowCustomizeDialog(
VOID
)
{
DialogBox(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_CUSTOMIZE_SB),
PhMainWndHandle,
CustomizeStatusBarDialogProc
);
}

View File

@@ -0,0 +1,983 @@
/*
* Process Hacker ToolStatus -
* Toolbar Customize Dialog
*
* Copyright (C) 2015-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"
#include "commonutil.h"
static PWSTR CustomizeTextOptionsStrings[] =
{
L"No text labels",
L"Selective text",
L"Show text labels"
};
static PWSTR CustomizeSearchDisplayStrings[] =
{
L"Always show",
L"Hide when inactive (Ctrl+K)",
// L"Auto-hide"
};
static PWSTR CustomizeThemeOptionsStrings[] =
{
L"None",
L"Black",
L"Blue"
};
BOOLEAN CustomizeToolbarItemExists(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IdCommand
)
{
INT buttonIndex = 0;
INT buttonCount = 0;
buttonCount = ListBox_GetCount(Context->CurrentListHandle);
if (buttonCount == LB_ERR)
return FALSE;
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, buttonIndex);
if (itemContext == NULL)
continue;
if (itemContext->IdCommand == IdCommand)
return TRUE;
}
return FALSE;
}
VOID CustomizeInsertToolbarButton(
_In_ INT Index,
_In_ PBUTTON_CONTEXT ItemContext
)
{
TBBUTTON button;
memset(&button, 0, sizeof(TBBUTTON));
button.idCommand = ItemContext->IdCommand;
button.iBitmap = I_IMAGECALLBACK;
button.fsState = TBSTATE_ENABLED;
button.fsStyle = ItemContext->IsSeparator ? BTNS_SEP : BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT;
button.iString = (INT_PTR)ToolbarGetText(ItemContext->IdCommand);
SendMessage(ToolBarHandle, TB_INSERTBUTTON, Index, (LPARAM)&button);
}
VOID CustomizeAddToolbarItem(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IndexAvail,
_In_ INT IndexTo
)
{
INT count;
PBUTTON_CONTEXT itemContext;
count = ListBox_GetCount(Context->AvailableListHandle);
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->AvailableListHandle, IndexAvail);
if (count == LB_ERR)
return;
if (itemContext == NULL)
return;
if (IndexAvail != 0) // index 0 is separator
{
// remove from 'available' list
ListBox_DeleteString(Context->AvailableListHandle, IndexAvail);
if (IndexAvail == count - 1)
{
ListBox_SetCurSel(Context->AvailableListHandle, IndexAvail - 1);
}
else
{
ListBox_SetCurSel(Context->AvailableListHandle, IndexAvail);
}
}
else
{
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IsSeparator = TRUE;
itemContext->IsRemovable = TRUE;
}
// insert into 'current' list
ListBox_InsertItemData(Context->CurrentListHandle, IndexTo, itemContext);
CustomizeInsertToolbarButton(IndexTo, itemContext);
}
VOID CustomizeRemoveToolbarItem(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IndexFrom
)
{
PBUTTON_CONTEXT itemContext;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, IndexFrom);
if (itemContext == NULL)
return;
ListBox_DeleteString(Context->CurrentListHandle, IndexFrom);
ListBox_SetCurSel(Context->CurrentListHandle, IndexFrom);
SendMessage(ToolBarHandle, TB_DELETEBUTTON, IndexFrom, 0);
if (itemContext->IsSeparator)
{
PhFree(itemContext);
}
else
{
// insert into 'available' list
ListBox_AddItemData(Context->AvailableListHandle, itemContext);
}
SendMessage(Context->DialogHandle, WM_COMMAND, MAKEWPARAM(IDC_CURRENT, LBN_SELCHANGE), 0);
}
VOID CustomizeMoveToolbarItem(
_In_ PCUSTOMIZE_CONTEXT Context,
_In_ INT IndexFrom,
_In_ INT IndexTo
)
{
INT count;
PBUTTON_CONTEXT itemContext;
if (IndexFrom == IndexTo)
return;
count = ListBox_GetCount(Context->CurrentListHandle);
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, IndexFrom);
if (count == LB_ERR)
return;
if (itemContext == NULL)
return;
ListBox_DeleteString(Context->CurrentListHandle, IndexFrom);
ListBox_InsertItemData(Context->CurrentListHandle, IndexTo, itemContext);
ListBox_SetCurSel(Context->CurrentListHandle, IndexTo);
if (IndexTo <= 0)
{
Button_Enable(Context->MoveUpButtonHandle, FALSE);
}
else
{
Button_Enable(Context->MoveUpButtonHandle, TRUE);
}
// last item is always separator
if (IndexTo >= (count - 2))
{
Button_Enable(Context->MoveDownButtonHandle, FALSE);
}
else
{
Button_Enable(Context->MoveDownButtonHandle, TRUE);
}
SendMessage(ToolBarHandle, TB_DELETEBUTTON, IndexFrom, 0);
CustomizeInsertToolbarButton(IndexTo, itemContext);
}
VOID CustomizeFreeToolbarItems(
_In_ PCUSTOMIZE_CONTEXT Context
)
{
INT buttonIndex = 0;
INT buttonCount = 0;
buttonCount = ListBox_GetCount(Context->CurrentListHandle);
if (buttonCount != LB_ERR)
{
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
if (itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, buttonIndex))
{
PhFree(itemContext);
}
}
}
buttonCount = ListBox_GetCount(Context->AvailableListHandle);
if (buttonCount != LB_ERR)
{
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
if (itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->AvailableListHandle, buttonIndex))
{
PhFree(itemContext);
}
}
}
}
VOID CustomizeLoadToolbarItems(
_In_ PCUSTOMIZE_CONTEXT Context
)
{
INT buttonIndex = 0;
INT buttonCount = 0;
PBUTTON_CONTEXT itemContext;
CustomizeFreeToolbarItems(Context);
ListBox_ResetContent(Context->AvailableListHandle);
ListBox_ResetContent(Context->CurrentListHandle);
buttonCount = (INT)SendMessage(ToolBarHandle, TB_BUTTONCOUNT, 0, 0);
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
TBBUTTON button;
memset(&button, 0, sizeof(TBBUTTON));
if (SendMessage(ToolBarHandle, TB_GETBUTTON, buttonIndex, (LPARAM)&button))
{
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IsVirtual = FALSE;
itemContext->IsRemovable = TRUE;
itemContext->IdCommand = button.idCommand;
if (button.fsStyle & BTNS_SEP)
{
itemContext->IsSeparator = TRUE;
}
else
{
HBITMAP buttonImage;
if (buttonImage = ToolbarGetImage(button.idCommand))
{
itemContext->IdBitmap = ImageList_Add(
Context->ImageListHandle,
buttonImage,
NULL
);
DeleteObject(buttonImage);
}
}
ListBox_AddItemData(Context->CurrentListHandle, itemContext);
}
}
for (buttonIndex = 0; buttonIndex < MAX_TOOLBAR_ITEMS; buttonIndex++)
{
HBITMAP buttonImage;
TBBUTTON button = ToolbarButtons[buttonIndex];
if (button.idCommand == 0)
continue;
if (CustomizeToolbarItemExists(Context, button.idCommand))
continue;
// HACK and violation of abstraction.
// Don't show the 'Show Details for All Processes' button on XP.
if (!WINDOWS_HAS_UAC && button.idCommand == PHAPP_ID_HACKER_SHOWDETAILSFORALLPROCESSES)
{
continue;
}
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IsRemovable = TRUE;
itemContext->IdCommand = button.idCommand;
if (buttonImage = ToolbarGetImage(button.idCommand))
{
itemContext->IdBitmap = ImageList_Add(
Context->ImageListHandle,
buttonImage,
NULL
);
DeleteObject(buttonImage);
}
ListBox_AddItemData(Context->AvailableListHandle, itemContext);
}
// Append separator to the last 'current list' position
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IsSeparator = TRUE;
itemContext->IsVirtual = TRUE;
itemContext->IsRemovable = FALSE;
buttonIndex = ListBox_AddItemData(Context->CurrentListHandle, itemContext);
ListBox_SetCurSel(Context->CurrentListHandle, buttonIndex);
ListBox_SetTopIndex(Context->CurrentListHandle, buttonIndex);
// Insert separator into first 'available list' position
itemContext = PhAllocate(sizeof(BUTTON_CONTEXT));
memset(itemContext, 0, sizeof(BUTTON_CONTEXT));
itemContext->IsSeparator = TRUE;
itemContext->IsVirtual = FALSE;
itemContext->IsRemovable = FALSE;
buttonIndex = ListBox_InsertItemData(Context->AvailableListHandle, 0, itemContext);
ListBox_SetCurSel(Context->AvailableListHandle, buttonIndex);
ListBox_SetTopIndex(Context->AvailableListHandle, buttonIndex);
// Disable buttons
Button_Enable(Context->MoveUpButtonHandle, FALSE);
Button_Enable(Context->MoveDownButtonHandle, FALSE);
Button_Enable(Context->RemoveButtonHandle, FALSE);
}
VOID CustomizeLoadToolbarSettings(
_In_ PCUSTOMIZE_CONTEXT Context
)
{
HWND toolbarCombo = GetDlgItem(Context->DialogHandle, IDC_TEXTOPTIONS);
HWND searchboxCombo = GetDlgItem(Context->DialogHandle, IDC_SEARCHOPTIONS);
HWND themeCombo = GetDlgItem(Context->DialogHandle, IDC_THEMEOPTIONS);
PhAddComboBoxStrings(
toolbarCombo,
CustomizeTextOptionsStrings,
ARRAYSIZE(CustomizeTextOptionsStrings)
);
PhAddComboBoxStrings(
searchboxCombo,
CustomizeSearchDisplayStrings,
ARRAYSIZE(CustomizeSearchDisplayStrings)
);
PhAddComboBoxStrings(
themeCombo,
CustomizeThemeOptionsStrings,
ARRAYSIZE(CustomizeThemeOptionsStrings)
);
ComboBox_SetCurSel(toolbarCombo, PhGetIntegerSetting(SETTING_NAME_TOOLBARDISPLAYSTYLE));
ComboBox_SetCurSel(searchboxCombo, PhGetIntegerSetting(SETTING_NAME_SEARCHBOXDISPLAYMODE));
ComboBox_SetCurSel(themeCombo, PhGetIntegerSetting(SETTING_NAME_TOOLBAR_THEME));
Button_SetCheck(GetDlgItem(Context->DialogHandle, IDC_ENABLE_MODERN),
ToolStatusConfig.ModernIcons ? BST_CHECKED : BST_UNCHECKED);
Button_SetCheck(GetDlgItem(Context->DialogHandle, IDC_ENABLE_AUTOHIDE_MENU),
ToolStatusConfig.AutoHideMenu ? BST_CHECKED : BST_UNCHECKED);
if (!ToolStatusConfig.SearchBoxEnabled)
{
ComboBox_Enable(searchboxCombo, FALSE);
}
if (WindowsVersion <= WINDOWS_VISTA)
{
ComboBox_Enable(themeCombo, FALSE);
}
}
VOID CustomizeResetImages(
_In_ PCUSTOMIZE_CONTEXT Context
)
{
INT buttonIndex = 0;
INT buttonCount = 0;
buttonCount = ListBox_GetCount(Context->CurrentListHandle);
if (buttonCount != LB_ERR)
{
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
HBITMAP buttonImage;
if (itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->CurrentListHandle, buttonIndex))
{
if (buttonImage = ToolbarGetImage(itemContext->IdCommand))
{
ImageList_Replace(
Context->ImageListHandle,
itemContext->IdBitmap,
buttonImage,
NULL
);
DeleteObject(buttonImage);
}
}
}
}
buttonCount = ListBox_GetCount(Context->AvailableListHandle);
if (buttonCount != LB_ERR)
{
for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++)
{
PBUTTON_CONTEXT itemContext;
HBITMAP buttonImage;
if (itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(Context->AvailableListHandle, buttonIndex))
{
if (buttonImage = ToolbarGetImage(itemContext->IdCommand))
{
ImageList_Replace(
Context->ImageListHandle,
itemContext->IdBitmap,
buttonImage,
NULL
);
DeleteObject(buttonImage);
}
}
}
}
InvalidateRect(Context->AvailableListHandle, NULL, TRUE);
InvalidateRect(Context->CurrentListHandle, NULL, TRUE);
}
VOID CustomizeResetToolbarImages(
VOID
)
{
// Reset the image cache with the new icons.
// TODO: Move function to Toolbar.c
for (INT i = 0; i < ARRAYSIZE(ToolbarButtons); i++)
{
if (ToolbarButtons[i].iBitmap != I_IMAGECALLBACK)
{
HBITMAP buttonImage;
if (buttonImage = ToolbarGetImage(ToolbarButtons[i].idCommand))
{
ImageList_Replace(
ToolBarImageList,
ToolbarButtons[i].iBitmap,
buttonImage,
NULL
);
DeleteObject(buttonImage);
}
}
}
}
INT_PTR CALLBACK CustomizeToolbarDialogProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
PCUSTOMIZE_CONTEXT context = NULL;
if (uMsg == WM_INITDIALOG)
{
context = (PCUSTOMIZE_CONTEXT)PhAllocate(sizeof(CUSTOMIZE_CONTEXT));
memset(context, 0, sizeof(CUSTOMIZE_CONTEXT));
SetProp(hwndDlg, L"Context", (HANDLE)context);
}
else
{
context = (PCUSTOMIZE_CONTEXT)GetProp(hwndDlg, L"Context");
if (uMsg == WM_NCDESTROY)
{
RemoveProp(hwndDlg, L"Context");
PhFree(context);
}
}
if (context == NULL)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
PhCenterWindow(hwndDlg, PhMainWndHandle);
context->DialogHandle = hwndDlg;
context->AvailableListHandle = GetDlgItem(hwndDlg, IDC_AVAILABLE);
context->CurrentListHandle = GetDlgItem(hwndDlg, IDC_CURRENT);
context->MoveUpButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEUP);
context->MoveDownButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEDOWN);
context->AddButtonHandle = GetDlgItem(hwndDlg, IDC_ADD);
context->RemoveButtonHandle = GetDlgItem(hwndDlg, IDC_REMOVE);
context->BitmapWidth = GetSystemMetrics(SM_CYSMICON) + 4;
context->FontHandle = CommonDuplicateFont((HFONT)SendMessage(ToolBarHandle, WM_GETFONT, 0, 0));
context->ImageListHandle = ImageList_Create(
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
ILC_COLOR32 | ILC_MASK,
0,
0
);
ListBox_SetItemHeight(context->AvailableListHandle, 0, context->BitmapWidth); // BitmapHeight
ListBox_SetItemHeight(context->CurrentListHandle, 0, context->BitmapWidth); // BitmapHeight
CustomizeLoadToolbarItems(context);
CustomizeLoadToolbarSettings(context);
SendMessage(context->DialogHandle, WM_NEXTDLGCTL, (WPARAM)context->CurrentListHandle, TRUE);
}
return TRUE;
case WM_DESTROY:
{
ToolbarSaveButtonSettings();
ToolbarLoadSettings();
CustomizeFreeToolbarItems(context);
if (context->ImageListHandle)
{
ImageList_Destroy(context->ImageListHandle);
}
if (context->FontHandle)
{
DeleteObject(context->FontHandle);
}
}
break;
case WM_COMMAND:
{
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDC_AVAILABLE:
{
switch (GET_WM_COMMAND_CMD(wParam, lParam))
{
case LBN_DBLCLK:
{
INT index;
INT indexto;
index = ListBox_GetCurSel(context->AvailableListHandle);
indexto = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
if (indexto == LB_ERR)
break;
CustomizeAddToolbarItem(context, index, indexto);
}
break;
}
}
break;
case IDC_CURRENT:
{
switch (GET_WM_COMMAND_CMD(wParam, lParam))
{
case LBN_SELCHANGE:
{
INT count;
INT index;
PBUTTON_CONTEXT itemContext;
count = ListBox_GetCount(context->CurrentListHandle);
index = ListBox_GetCurSel(context->CurrentListHandle);
if (count == LB_ERR)
break;
if (index == LB_ERR)
break;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(context->CurrentListHandle, index);
if (itemContext == NULL)
break;
if (index == 0 && count == 2)
{
// first and last item
Button_Enable(context->MoveUpButtonHandle, FALSE);
Button_Enable(context->MoveDownButtonHandle, FALSE);
}
else if (index == (count - 1))
{
// last item (virtual separator)
Button_Enable(context->MoveUpButtonHandle, FALSE);
Button_Enable(context->MoveDownButtonHandle, FALSE);
}
else if (index == (count - 2))
{
// second last item (last non-virtual item)
Button_Enable(context->MoveUpButtonHandle, TRUE);
Button_Enable(context->MoveDownButtonHandle, FALSE);
}
else if (index == 0)
{
// first item
Button_Enable(context->MoveUpButtonHandle, FALSE);
Button_Enable(context->MoveDownButtonHandle, TRUE);
}
else
{
Button_Enable(context->MoveUpButtonHandle, TRUE);
Button_Enable(context->MoveDownButtonHandle, TRUE);
}
Button_Enable(context->RemoveButtonHandle, itemContext->IsRemovable);
}
break;
case LBN_DBLCLK:
{
INT count;
INT index;
count = ListBox_GetCount(context->CurrentListHandle);
index = ListBox_GetCurSel(context->CurrentListHandle);
if (count == LB_ERR)
break;
if (index == LB_ERR)
break;
if (index == (count - 1))
{
// virtual separator
break;
}
CustomizeRemoveToolbarItem(context, index);
}
break;
}
}
break;
case IDC_ADD:
{
INT index;
INT indexto;
index = ListBox_GetCurSel(context->AvailableListHandle);
indexto = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
if (indexto == LB_ERR)
break;
CustomizeAddToolbarItem(context, index, indexto);
}
break;
case IDC_REMOVE:
{
INT index;
index = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
CustomizeRemoveToolbarItem(context, index);
}
break;
case IDC_MOVEUP:
{
INT index;
index = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
CustomizeMoveToolbarItem(context, index, index - 1);
}
break;
case IDC_MOVEDOWN:
{
INT index;
index = ListBox_GetCurSel(context->CurrentListHandle);
if (index == LB_ERR)
break;
CustomizeMoveToolbarItem(context, index, index + 1);
}
break;
case IDC_RESET:
{
// Reset the Toolbar buttons to default settings.
ToolbarResetSettings();
// Re-load the settings.
ToolbarLoadSettings();
// Save as the new defaults.
ToolbarSaveButtonSettings();
CustomizeLoadToolbarItems(context);
}
break;
case IDC_TEXTOPTIONS:
{
if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
{
PhSetIntegerSetting(SETTING_NAME_TOOLBARDISPLAYSTYLE,
(DisplayStyle = (TOOLBAR_DISPLAY_STYLE)ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam))));
ToolbarLoadSettings();
}
}
break;
case IDC_SEARCHOPTIONS:
{
if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
{
PhSetIntegerSetting(SETTING_NAME_SEARCHBOXDISPLAYMODE,
(SearchBoxDisplayMode = (SEARCHBOX_DISPLAY_MODE)ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam))));
ToolbarLoadSettings();
}
}
break;
case IDC_THEMEOPTIONS:
{
if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
{
PhSetIntegerSetting(SETTING_NAME_TOOLBAR_THEME,
(ToolBarTheme = (TOOLBAR_THEME)ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam))));
switch (ToolBarTheme)
{
case TOOLBAR_THEME_NONE:
{
SendMessage(RebarHandle, RB_SETWINDOWTHEME, 0, (LPARAM)L"");
SendMessage(ToolBarHandle, TB_SETWINDOWTHEME, 0, (LPARAM)L"");
}
break;
case TOOLBAR_THEME_BLACK:
{
SendMessage(RebarHandle, RB_SETWINDOWTHEME, 0, (LPARAM)L"Media");
SendMessage(ToolBarHandle, TB_SETWINDOWTHEME, 0, (LPARAM)L"Media");
}
break;
case TOOLBAR_THEME_BLUE:
{
SendMessage(RebarHandle, RB_SETWINDOWTHEME, 0, (LPARAM)L"Communications");
SendMessage(ToolBarHandle, TB_SETWINDOWTHEME, 0, (LPARAM)L"Communications");
}
break;
}
}
}
break;
case IDC_ENABLE_MODERN:
{
if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED)
{
ToolStatusConfig.ModernIcons = Button_GetCheck(GET_WM_COMMAND_HWND(wParam, lParam)) == BST_CHECKED;
PhSetIntegerSetting(SETTING_NAME_TOOLSTATUS_CONFIG, ToolStatusConfig.Flags);
ToolbarLoadSettings();
CustomizeResetImages(context);
CustomizeResetToolbarImages();
//CustomizeLoadItems(context);
}
}
break;
case IDC_ENABLE_AUTOHIDE_MENU:
{
if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED)
{
ToolStatusConfig.AutoHideMenu = !ToolStatusConfig.AutoHideMenu;
PhSetIntegerSetting(SETTING_NAME_TOOLSTATUS_CONFIG, ToolStatusConfig.Flags);
if (ToolStatusConfig.AutoHideMenu)
{
SetMenu(PhMainWndHandle, NULL);
}
else
{
SetMenu(PhMainWndHandle, MainMenu);
DrawMenuBar(PhMainWndHandle);
}
}
}
break;
case IDCANCEL:
{
EndDialog(hwndDlg, FALSE);
}
break;
}
}
break;
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT drawInfo = (LPDRAWITEMSTRUCT)lParam;
if (drawInfo->CtlID == IDC_AVAILABLE || drawInfo->CtlID == IDC_CURRENT)
{
HDC bufferDc;
HBITMAP bufferBitmap;
HBITMAP oldBufferBitmap;
PBUTTON_CONTEXT itemContext;
RECT bufferRect =
{
0, 0,
drawInfo->rcItem.right - drawInfo->rcItem.left,
drawInfo->rcItem.bottom - drawInfo->rcItem.top
};
BOOLEAN isSelected = (drawInfo->itemState & ODS_SELECTED) == ODS_SELECTED;
BOOLEAN isFocused = (drawInfo->itemState & ODS_FOCUS) == ODS_FOCUS;
if (drawInfo->itemID == LB_ERR)
break;
itemContext = (PBUTTON_CONTEXT)ListBox_GetItemData(drawInfo->hwndItem, drawInfo->itemID);
if (itemContext == NULL)
break;
bufferDc = CreateCompatibleDC(drawInfo->hDC);
bufferBitmap = CreateCompatibleBitmap(drawInfo->hDC, bufferRect.right, bufferRect.bottom);
oldBufferBitmap = SelectBitmap(bufferDc, bufferBitmap);
SelectFont(bufferDc, context->FontHandle);
SetBkMode(bufferDc, TRANSPARENT);
FillRect(bufferDc, &bufferRect, GetSysColorBrush(isFocused ? COLOR_HIGHLIGHT : COLOR_WINDOW));
if (isSelected)
{
FrameRect(bufferDc, &bufferRect, isFocused ? GetStockBrush(BLACK_BRUSH) : GetSysColorBrush(COLOR_HIGHLIGHT));
}
else
{
FrameRect(bufferDc, &bufferRect, isFocused ? GetStockBrush(BLACK_BRUSH) : GetSysColorBrush(COLOR_HIGHLIGHTTEXT));
}
if (itemContext->IsVirtual)
{
SetTextColor(bufferDc, GetSysColor(COLOR_GRAYTEXT));
}
else
{
SetTextColor(bufferDc, GetSysColor(isFocused ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
}
if (!itemContext->IsSeparator)
{
ImageList_Draw(
context->ImageListHandle,
itemContext->IdBitmap,
bufferDc,
bufferRect.left + 2,
bufferRect.top + 2,
ILD_NORMAL
);
}
bufferRect.left += context->BitmapWidth; //+ 2;
if (itemContext->IdCommand != 0)
{
DrawText(
bufferDc,
ToolbarGetText(itemContext->IdCommand),
-1,
&bufferRect,
DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOCLIP
);
}
else
{
DrawText(
bufferDc,
L"Separator",
-1,
&bufferRect,
DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOCLIP
);
}
BitBlt(
drawInfo->hDC,
drawInfo->rcItem.left,
drawInfo->rcItem.top,
drawInfo->rcItem.right,
drawInfo->rcItem.bottom,
bufferDc,
0,
0,
SRCCOPY
);
SelectBitmap(bufferDc, oldBufferBitmap);
DeleteBitmap(bufferBitmap);
DeleteDC(bufferDc);
return TRUE;
}
}
break;
}
return FALSE;
}
VOID ToolBarShowCustomizeDialog(
VOID
)
{
DialogBox(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_CUSTOMIZE_TB),
PhMainWndHandle,
CustomizeToolbarDialogProc
);
}

467
plugins/ToolStatus/filter.c Normal file
View File

@@ -0,0 +1,467 @@
/*
* Process Hacker ToolStatus -
* search filter callbacks
*
* Copyright (C) 2011-2015 dmex
* Copyright (C) 2010-2013 wj32
*
* 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"
#include <verify.h>
BOOLEAN WordMatchStringRef(
_In_ PPH_STRINGREF Text
)
{
PH_STRINGREF part;
PH_STRINGREF remainingPart;
remainingPart = SearchboxText->sr;
while (remainingPart.Length != 0)
{
PhSplitStringRefAtChar(&remainingPart, '|', &part, &remainingPart);
if (part.Length != 0)
{
if (PhFindStringInStringRef(Text, &part, TRUE) != -1)
return TRUE;
}
}
return FALSE;
}
BOOLEAN WordMatchStringZ(
_In_ PWSTR Text
)
{
PH_STRINGREF text;
PhInitializeStringRef(&text, Text);
return WordMatchStringRef(&text);
}
BOOLEAN ProcessTreeFilterCallback(
_In_ PPH_TREENEW_NODE Node,
_In_opt_ PVOID Context
)
{
PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE)Node;
if (PhIsNullOrEmptyString(SearchboxText))
return TRUE;
if (!PhIsNullOrEmptyString(processNode->ProcessItem->ProcessName))
{
if (WordMatchStringRef(&processNode->ProcessItem->ProcessName->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->FileName))
{
if (WordMatchStringRef(&processNode->ProcessItem->FileName->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->CommandLine))
{
if (WordMatchStringRef(&processNode->ProcessItem->CommandLine->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.CompanyName))
{
if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.CompanyName->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.FileDescription))
{
if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.FileDescription->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.FileVersion))
{
if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.FileVersion->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.ProductName))
{
if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.ProductName->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->UserName))
{
if (WordMatchStringRef(&processNode->ProcessItem->UserName->sr))
return TRUE;
}
if (processNode->ProcessItem->IntegrityString)
{
if (WordMatchStringZ(processNode->ProcessItem->IntegrityString))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->JobName))
{
if (WordMatchStringRef(&processNode->ProcessItem->JobName->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->VerifySignerName))
{
if (WordMatchStringRef(&processNode->ProcessItem->VerifySignerName->sr))
return TRUE;
}
if (processNode->ProcessItem->ProcessIdString[0] != 0)
{
if (WordMatchStringZ(processNode->ProcessItem->ProcessIdString))
return TRUE;
}
if (processNode->ProcessItem->ParentProcessIdString[0] != 0)
{
if (WordMatchStringZ(processNode->ProcessItem->ParentProcessIdString))
return TRUE;
}
if (processNode->ProcessItem->SessionIdString[0] != 0)
{
if (WordMatchStringZ(processNode->ProcessItem->SessionIdString))
return TRUE;
}
if (!PhIsNullOrEmptyString(processNode->ProcessItem->PackageFullName))
{
if (WordMatchStringRef(&processNode->ProcessItem->PackageFullName->sr))
return TRUE;
}
if (WordMatchStringZ(PhGetProcessPriorityClassString(processNode->ProcessItem->PriorityClass)))
{
return TRUE;
}
if (processNode->ProcessItem->VerifyResult != VrUnknown)
{
switch (processNode->ProcessItem->VerifyResult)
{
case VrNoSignature:
if (WordMatchStringZ(L"NoSignature"))
return TRUE;
break;
case VrTrusted:
if (WordMatchStringZ(L"Trusted"))
return TRUE;
break;
case VrExpired:
if (WordMatchStringZ(L"Expired"))
return TRUE;
break;
case VrRevoked:
if (WordMatchStringZ(L"Revoked"))
return TRUE;
break;
case VrDistrust:
if (WordMatchStringZ(L"Distrust"))
return TRUE;
break;
case VrSecuritySettings:
if (WordMatchStringZ(L"SecuritySettings"))
return TRUE;
break;
case VrBadSignature:
if (WordMatchStringZ(L"BadSignature"))
return TRUE;
break;
default:
if (WordMatchStringZ(L"Unknown"))
return TRUE;
break;
}
}
if (WINDOWS_HAS_UAC && processNode->ProcessItem->ElevationType != TokenElevationTypeDefault)
{
switch (processNode->ProcessItem->ElevationType)
{
case TokenElevationTypeLimited:
if (WordMatchStringZ(L"Limited"))
return TRUE;
break;
case TokenElevationTypeFull:
if (WordMatchStringZ(L"Full"))
return TRUE;
break;
default:
if (WordMatchStringZ(L"Unknown"))
return TRUE;
break;
}
}
if (WordMatchStringZ(L"UpdateIsDotNet") && processNode->ProcessItem->UpdateIsDotNet)
{
return TRUE;
}
if (WordMatchStringZ(L"IsBeingDebugged") && processNode->ProcessItem->IsBeingDebugged)
{
return TRUE;
}
if (WordMatchStringZ(L"IsDotNet") && processNode->ProcessItem->IsDotNet)
{
return TRUE;
}
if (WordMatchStringZ(L"IsElevated") && processNode->ProcessItem->IsElevated)
{
return TRUE;
}
if (WordMatchStringZ(L"IsInJob") && processNode->ProcessItem->IsInJob)
{
return TRUE;
}
if (WordMatchStringZ(L"IsInSignificantJob") && processNode->ProcessItem->IsInSignificantJob)
{
return TRUE;
}
if (WordMatchStringZ(L"IsPacked") && processNode->ProcessItem->IsPacked)
{
return TRUE;
}
if (WordMatchStringZ(L"IsSuspended") && processNode->ProcessItem->IsSuspended)
{
return TRUE;
}
if (WordMatchStringZ(L"IsWow64") && processNode->ProcessItem->IsWow64)
{
return TRUE;
}
if (WordMatchStringZ(L"IsImmersive") && processNode->ProcessItem->IsImmersive)
{
return TRUE;
}
if (processNode->ProcessItem->ServiceList && processNode->ProcessItem->ServiceList->Count != 0)
{
ULONG enumerationKey = 0;
PPH_SERVICE_ITEM serviceItem;
PPH_LIST serviceList;
ULONG i;
BOOLEAN matched = FALSE;
// Copy the service list so we can search it.
serviceList = PhCreateList(processNode->ProcessItem->ServiceList->Count);
PhAcquireQueuedLockShared(&processNode->ProcessItem->ServiceListLock);
while (PhEnumPointerList(
processNode->ProcessItem->ServiceList,
&enumerationKey,
&serviceItem
))
{
PhReferenceObject(serviceItem);
PhAddItemList(serviceList, serviceItem);
}
PhReleaseQueuedLockShared(&processNode->ProcessItem->ServiceListLock);
for (i = 0; i < serviceList->Count; i++)
{
serviceItem = serviceList->Items[i];
if (!PhIsNullOrEmptyString(serviceItem->Name))
{
if (WordMatchStringRef(&serviceItem->Name->sr))
{
matched = TRUE;
break;
}
}
if (!PhIsNullOrEmptyString(serviceItem->DisplayName))
{
if (WordMatchStringRef(&serviceItem->DisplayName->sr))
{
matched = TRUE;
break;
}
}
if (serviceItem->ProcessId)
{
WCHAR processIdString[PH_INT32_STR_LEN_1];
PhPrintUInt32(processIdString, HandleToUlong(serviceItem->ProcessId));
if (WordMatchStringZ(processIdString))
{
matched = TRUE;
break;
}
}
}
PhDereferenceObjects(serviceList->Items, serviceList->Count);
PhDereferenceObject(serviceList);
if (matched)
return TRUE;
}
return FALSE;
}
BOOLEAN ServiceTreeFilterCallback(
_In_ PPH_TREENEW_NODE Node,
_In_opt_ PVOID Context
)
{
PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)Node;
if (PhIsNullOrEmptyString(SearchboxText))
return TRUE;
if (WordMatchStringZ(PhGetServiceTypeString(serviceNode->ServiceItem->Type)))
return TRUE;
if (WordMatchStringZ(PhGetServiceStateString(serviceNode->ServiceItem->State)))
return TRUE;
if (WordMatchStringZ(PhGetServiceStartTypeString(serviceNode->ServiceItem->StartType)))
return TRUE;
if (WordMatchStringZ(PhGetServiceErrorControlString(serviceNode->ServiceItem->ErrorControl)))
return TRUE;
if (!PhIsNullOrEmptyString(serviceNode->ServiceItem->Name))
{
if (WordMatchStringRef(&serviceNode->ServiceItem->Name->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(serviceNode->ServiceItem->DisplayName))
{
if (WordMatchStringRef(&serviceNode->ServiceItem->DisplayName->sr))
return TRUE;
}
if (serviceNode->ServiceItem->ProcessId)
{
WCHAR processIdString[PH_INT32_STR_LEN_1];
PhPrintUInt32(processIdString, HandleToUlong(serviceNode->ServiceItem->ProcessId));
if (WordMatchStringZ(processIdString))
return TRUE;
}
return FALSE;
}
BOOLEAN NetworkTreeFilterCallback(
_In_ PPH_TREENEW_NODE Node,
_In_opt_ PVOID Context
)
{
PPH_NETWORK_NODE networkNode = (PPH_NETWORK_NODE)Node;
if (PhIsNullOrEmptyString(SearchboxText))
return TRUE;
if (!PhIsNullOrEmptyString(networkNode->NetworkItem->ProcessName))
{
if (WordMatchStringRef(&networkNode->NetworkItem->ProcessName->sr))
return TRUE;
}
if (!PhIsNullOrEmptyString(networkNode->NetworkItem->OwnerName))
{
if (WordMatchStringRef(&networkNode->NetworkItem->OwnerName->sr))
return TRUE;
}
if (networkNode->NetworkItem->LocalAddressString[0] != 0)
{
if (WordMatchStringZ(networkNode->NetworkItem->LocalAddressString))
return TRUE;
}
if (networkNode->NetworkItem->LocalPortString[0] != 0)
{
if (WordMatchStringZ(networkNode->NetworkItem->LocalPortString))
return TRUE;
}
if (!PhIsNullOrEmptyString(networkNode->NetworkItem->LocalHostString))
{
if (WordMatchStringRef(&networkNode->NetworkItem->LocalHostString->sr))
return TRUE;
}
if (networkNode->NetworkItem->RemoteAddressString[0] != 0)
{
if (WordMatchStringZ(networkNode->NetworkItem->RemoteAddressString))
return TRUE;
}
if (networkNode->NetworkItem->RemotePortString[0] != 0)
{
if (WordMatchStringZ(networkNode->NetworkItem->RemotePortString))
return TRUE;
}
if (!PhIsNullOrEmptyString(networkNode->NetworkItem->RemoteHostString))
{
if (WordMatchStringRef(&networkNode->NetworkItem->RemoteHostString->sr))
return TRUE;
}
if (WordMatchStringZ(PhGetProtocolTypeName(networkNode->NetworkItem->ProtocolType)))
return TRUE;
if ((networkNode->NetworkItem->ProtocolType & PH_TCP_PROTOCOL_TYPE) &&
WordMatchStringZ(PhGetTcpStateName(networkNode->NetworkItem->State)))
return TRUE;
if (networkNode->NetworkItem->ProcessId)
{
WCHAR processIdString[PH_INT32_STR_LEN_1];
PhPrintUInt32(processIdString, HandleToUlong(networkNode->NetworkItem->ProcessId));
if (WordMatchStringZ(processIdString))
return TRUE;
}
return FALSE;
}

662
plugins/ToolStatus/graph.c Normal file
View File

@@ -0,0 +1,662 @@
/*
* Process Hacker ToolStatus -
* Toolbar Graph Bands
*
* Copyright (C) 2015-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"
HWND CpuGraphHandle = NULL;
HWND MemGraphHandle = NULL;
HWND CommitGraphHandle = NULL;
HWND IoGraphHandle = NULL;
static PH_GRAPH_STATE CpuGraphState;
static PH_GRAPH_STATE MemGraphState;
static PH_GRAPH_STATE CommitGraphState;
static PH_GRAPH_STATE IoGraphState;
VOID ToolbarCreateGraphs(VOID)
{
UINT height = (UINT)SendMessage(RebarHandle, RB_GETROWHEIGHT, 0, 0);
if (ToolStatusConfig.CpuGraphEnabled && !CpuGraphHandle)
{
CpuGraphHandle = CreateWindow(
PH_GRAPH_CLASSNAME,
NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER,
0,
0,
0,
0,
PhMainWndHandle,
NULL,
NULL,
NULL
);
Graph_SetTooltip(CpuGraphHandle, TRUE);
PhInitializeGraphState(&CpuGraphState);
}
if (ToolStatusConfig.MemGraphEnabled && !MemGraphHandle)
{
MemGraphHandle = CreateWindow(
PH_GRAPH_CLASSNAME,
NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER,
0,
0,
0,
0,
PhMainWndHandle,
NULL,
NULL,
NULL
);
Graph_SetTooltip(MemGraphHandle, TRUE);
PhInitializeGraphState(&MemGraphState);
}
if (ToolStatusConfig.CommitGraphEnabled && !CommitGraphHandle)
{
CommitGraphHandle = CreateWindow(
PH_GRAPH_CLASSNAME,
NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER,
0,
0,
0,
0,
PhMainWndHandle,
NULL,
NULL,
NULL
);
Graph_SetTooltip(CommitGraphHandle, TRUE);
PhInitializeGraphState(&CommitGraphState);
}
if (ToolStatusConfig.IoGraphEnabled && !IoGraphHandle)
{
IoGraphHandle = CreateWindow(
PH_GRAPH_CLASSNAME,
NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER,
0,
0,
0,
0,
PhMainWndHandle,
NULL,
NULL,
NULL
);
Graph_SetTooltip(IoGraphHandle, TRUE);
PhInitializeGraphState(&IoGraphState);
}
if (ToolStatusConfig.CpuGraphEnabled)
{
if (!RebarBandExists(REBAR_BAND_ID_CPUGRAPH))
RebarBandInsert(REBAR_BAND_ID_CPUGRAPH, CpuGraphHandle, 145, height); // 85
if (CpuGraphHandle && !IsWindowVisible(CpuGraphHandle))
ShowWindow(CpuGraphHandle, SW_SHOW);
}
else
{
if (RebarBandExists(REBAR_BAND_ID_CPUGRAPH))
RebarBandRemove(REBAR_BAND_ID_CPUGRAPH);
if (CpuGraphHandle)
{
PhDeleteGraphState(&CpuGraphState);
DestroyWindow(CpuGraphHandle);
CpuGraphHandle = NULL;
}
}
if (ToolStatusConfig.MemGraphEnabled)
{
if (!RebarBandExists(REBAR_BAND_ID_MEMGRAPH))
RebarBandInsert(REBAR_BAND_ID_MEMGRAPH, MemGraphHandle, 145, height); // 85
if (MemGraphHandle && !IsWindowVisible(MemGraphHandle))
{
ShowWindow(MemGraphHandle, SW_SHOW);
}
}
else
{
if (RebarBandExists(REBAR_BAND_ID_MEMGRAPH))
RebarBandRemove(REBAR_BAND_ID_MEMGRAPH);
if (MemGraphHandle)
{
PhDeleteGraphState(&MemGraphState);
DestroyWindow(MemGraphHandle);
MemGraphHandle = NULL;
}
}
if (ToolStatusConfig.CommitGraphEnabled)
{
if (!RebarBandExists(REBAR_BAND_ID_COMMITGRAPH))
RebarBandInsert(REBAR_BAND_ID_COMMITGRAPH, CommitGraphHandle, 145, height); // 85
if (CommitGraphHandle && !IsWindowVisible(CommitGraphHandle))
{
ShowWindow(CommitGraphHandle, SW_SHOW);
}
}
else
{
if (RebarBandExists(REBAR_BAND_ID_COMMITGRAPH))
RebarBandRemove(REBAR_BAND_ID_COMMITGRAPH);
if (CommitGraphHandle)
{
PhDeleteGraphState(&CommitGraphState);
DestroyWindow(CommitGraphHandle);
CommitGraphHandle = NULL;
}
}
if (ToolStatusConfig.IoGraphEnabled)
{
if (!RebarBandExists(REBAR_BAND_ID_IOGRAPH))
RebarBandInsert(REBAR_BAND_ID_IOGRAPH, IoGraphHandle, 145, height); // 85
if (IoGraphHandle && !IsWindowVisible(IoGraphHandle))
{
ShowWindow(IoGraphHandle, SW_SHOW);
}
}
else
{
if (RebarBandExists(REBAR_BAND_ID_IOGRAPH))
RebarBandRemove(REBAR_BAND_ID_IOGRAPH);
if (IoGraphHandle)
{
PhDeleteGraphState(&IoGraphState);
DestroyWindow(IoGraphHandle);
IoGraphHandle = NULL;
}
}
}
VOID ToolbarUpdateGraphs(VOID)
{
if (ToolStatusConfig.CpuGraphEnabled && CpuGraphHandle)
{
CpuGraphState.Valid = FALSE;
CpuGraphState.TooltipIndex = -1;
Graph_MoveGrid(CpuGraphHandle, 1);
Graph_Draw(CpuGraphHandle);
Graph_UpdateTooltip(CpuGraphHandle);
InvalidateRect(CpuGraphHandle, NULL, FALSE);
}
if (ToolStatusConfig.MemGraphEnabled && MemGraphHandle)
{
MemGraphState.Valid = FALSE;
MemGraphState.TooltipIndex = -1;
Graph_MoveGrid(MemGraphHandle, 1);
Graph_Draw(MemGraphHandle);
Graph_UpdateTooltip(MemGraphHandle);
InvalidateRect(MemGraphHandle, NULL, FALSE);
}
if (ToolStatusConfig.CommitGraphEnabled && CommitGraphHandle)
{
CommitGraphState.Valid = FALSE;
CommitGraphState.TooltipIndex = -1;
Graph_MoveGrid(CommitGraphHandle, 1);
Graph_Draw(CommitGraphHandle);
Graph_UpdateTooltip(CommitGraphHandle);
InvalidateRect(CommitGraphHandle, NULL, FALSE);
}
if (ToolStatusConfig.IoGraphEnabled && IoGraphHandle)
{
IoGraphState.Valid = FALSE;
IoGraphState.TooltipIndex = -1;
Graph_MoveGrid(IoGraphHandle, 1);
Graph_Draw(IoGraphHandle);
Graph_UpdateTooltip(IoGraphHandle);
InvalidateRect(IoGraphHandle, NULL, FALSE);
}
}
//
// BEGIN copied from ProcessHacker/sysinfo.c
//
static PPH_PROCESS_RECORD PhSipReferenceMaxCpuRecord(
_In_ LONG Index
)
{
LARGE_INTEGER time;
LONG maxProcessIdLong;
HANDLE maxProcessId;
// Find the process record for the max. CPU process for the particular time.
maxProcessIdLong = PhGetItemCircularBuffer_ULONG(SystemStatistics.MaxCpuHistory, Index);
if (!maxProcessIdLong)
return NULL;
// This must be treated as a signed integer to handle Interrupts correctly.
maxProcessId = LongToHandle(maxProcessIdLong);
// Note that the time we get has its components beyond seconds cleared.
// For example:
// * At 2.5 seconds a process is started.
// * At 2.75 seconds our process provider is fired, and the process is determined
// to have 75% CPU usage, which happens to be the maximum CPU usage.
// * However the 2.75 seconds is recorded as 2 seconds due to
// RtlTimeToSecondsSince1980.
// * If we call PhFindProcessRecord, it cannot find the process because it was
// started at 2.5 seconds, not 2 seconds or older.
//
// This mean we must add one second minus one tick (100ns) to the time, giving us
// 2.9999999 seconds. This will then make sure we find the process.
PhGetStatisticsTime(NULL, Index, &time);
time.QuadPart += PH_TICKS_PER_SEC - 1;
return PhFindProcessRecord(maxProcessId, &time);
}
static PPH_STRING PhSipGetMaxCpuString(
_In_ LONG Index
)
{
PPH_PROCESS_RECORD maxProcessRecord;
FLOAT maxCpuUsage;
PPH_STRING maxUsageString = NULL;
if (maxProcessRecord = PhSipReferenceMaxCpuRecord(Index))
{
// We found the process record, so now we construct the max. usage string.
maxCpuUsage = PhGetItemCircularBuffer_FLOAT(SystemStatistics.MaxCpuUsageHistory, Index);
// Make sure we don't try to display the PID of DPCs or Interrupts.
if (!PH_IS_FAKE_PROCESS_ID(maxProcessRecord->ProcessId))
{
maxUsageString = PhaFormatString(
L"\n%s (%u): %.2f%%",
maxProcessRecord->ProcessName->Buffer,
HandleToUlong(maxProcessRecord->ProcessId),
maxCpuUsage * 100
);
}
else
{
maxUsageString = PhaFormatString(
L"\n%s: %.2f%%",
maxProcessRecord->ProcessName->Buffer,
maxCpuUsage * 100
);
}
PhDereferenceProcessRecord(maxProcessRecord);
}
return maxUsageString;
}
static PPH_PROCESS_RECORD PhSipReferenceMaxIoRecord(
_In_ LONG Index
)
{
LARGE_INTEGER time;
ULONG maxProcessId;
// Find the process record for the max. I/O process for the particular time.
maxProcessId = PhGetItemCircularBuffer_ULONG(SystemStatistics.MaxIoHistory, Index);
if (!maxProcessId)
return NULL;
// See above for the explanation.
PhGetStatisticsTime(NULL, Index, &time);
time.QuadPart += PH_TICKS_PER_SEC - 1;
return PhFindProcessRecord(UlongToHandle(maxProcessId), &time);
}
static PPH_STRING PhSipGetMaxIoString(
_In_ LONG Index
)
{
PPH_PROCESS_RECORD maxProcessRecord;
ULONG64 maxIoReadOther;
ULONG64 maxIoWrite;
PPH_STRING maxUsageString = NULL;
if (maxProcessRecord = PhSipReferenceMaxIoRecord(Index))
{
// We found the process record, so now we construct the max. usage string.
maxIoReadOther = PhGetItemCircularBuffer_ULONG64(SystemStatistics.MaxIoReadOtherHistory, Index);
maxIoWrite = PhGetItemCircularBuffer_ULONG64(SystemStatistics.MaxIoWriteHistory, Index);
if (!PH_IS_FAKE_PROCESS_ID(maxProcessRecord->ProcessId))
{
maxUsageString = PhaFormatString(
L"\n%s (%u): R+O: %s, W: %s",
maxProcessRecord->ProcessName->Buffer,
HandleToUlong(maxProcessRecord->ProcessId),
PhaFormatSize(maxIoReadOther, -1)->Buffer,
PhaFormatSize(maxIoWrite, -1)->Buffer
);
}
else
{
maxUsageString = PhaFormatString(
L"\n%s: R+O: %s, W: %s",
maxProcessRecord->ProcessName->Buffer,
PhaFormatSize(maxIoReadOther, -1)->Buffer,
PhaFormatSize(maxIoWrite, -1)->Buffer
);
}
PhDereferenceProcessRecord(maxProcessRecord);
}
return maxUsageString;
}
//
// END copied from ProcessHacker/sysinfo.c
//
VOID ToolbarUpdateGraphsInfo(LPNMHDR Header)
{
switch (Header->code)
{
case GCN_GETDRAWINFO:
{
if (ToolStatusConfig.CpuGraphEnabled && Header->hwndFrom == CpuGraphHandle)
{
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_LINE_2;
PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), PhGetIntegerSetting(L"ColorCpuUser"));
if (ProcessesUpdatedCount < 2)
return;
PhGraphStateGetDrawInfo(&CpuGraphState, getDrawInfo, SystemStatistics.CpuUserHistory->Count);
if (!CpuGraphState.Valid)
{
PhCopyCircularBuffer_FLOAT(SystemStatistics.CpuKernelHistory,
CpuGraphState.Data1, drawInfo->LineDataCount);
PhCopyCircularBuffer_FLOAT(SystemStatistics.CpuUserHistory,
CpuGraphState.Data2, drawInfo->LineDataCount);
CpuGraphState.Valid = TRUE;
}
}
else if (ToolStatusConfig.MemGraphEnabled && Header->hwndFrom == MemGraphHandle)
{
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
drawInfo->Flags = PH_GRAPH_USE_GRID_X;
PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorPhysical"), 0);
if (ProcessesUpdatedCount < 2)
return;
PhGraphStateGetDrawInfo(&MemGraphState, getDrawInfo, SystemStatistics.PhysicalHistory->Count);
if (!MemGraphState.Valid)
{
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
{
MemGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(SystemStatistics.PhysicalHistory, i);
}
PhDivideSinglesBySingle(
MemGraphState.Data1,
(FLOAT)PhSystemBasicInformation.NumberOfPhysicalPages,
drawInfo->LineDataCount
);
MemGraphState.Valid = TRUE;
}
}
else if (ToolStatusConfig.CommitGraphEnabled && Header->hwndFrom == CommitGraphHandle)
{
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
drawInfo->Flags = PH_GRAPH_USE_GRID_X;
PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorPrivate"), 0);
if (ProcessesUpdatedCount < 2)
return;
PhGraphStateGetDrawInfo(&CommitGraphState, getDrawInfo, SystemStatistics.CommitHistory->Count);
if (!CommitGraphState.Valid)
{
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
{
CommitGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(SystemStatistics.CommitHistory, i);
}
PhDivideSinglesBySingle(
CommitGraphState.Data1,
(FLOAT)SystemStatistics.Performance->CommitLimit,
drawInfo->LineDataCount
);
CommitGraphState.Valid = TRUE;
}
}
else if (ToolStatusConfig.IoGraphEnabled && Header->hwndFrom == IoGraphHandle)
{
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_LINE_2;
PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite"));
if (ProcessesUpdatedCount < 2)
return;
PhGraphStateGetDrawInfo(&IoGraphState, getDrawInfo, SystemStatistics.IoReadHistory->Count);
if (!IoGraphState.Valid)
{
FLOAT max = 1024 * 1024; // minimum scaling of 1 MB.
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
{
IoGraphState.Data1[i] =
(FLOAT)PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoReadHistory, i) +
(FLOAT)PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoOtherHistory, i);
IoGraphState.Data2[i] =
(FLOAT)PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoWriteHistory, i);
if (max < IoGraphState.Data1[i] + IoGraphState.Data2[i])
max = IoGraphState.Data1[i] + IoGraphState.Data2[i];
}
PhDivideSinglesBySingle(IoGraphState.Data1, max, drawInfo->LineDataCount);
PhDivideSinglesBySingle(IoGraphState.Data2, max, drawInfo->LineDataCount);
IoGraphState.Valid = TRUE;
}
}
}
break;
case GCN_GETTOOLTIPTEXT:
{
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
if (getTooltipText->Index < getTooltipText->TotalCount)
{
if (ToolStatusConfig.CpuGraphEnabled && Header->hwndFrom == CpuGraphHandle)
{
if (CpuGraphState.TooltipIndex != getTooltipText->Index)
{
FLOAT cpuKernel;
FLOAT cpuUser;
cpuKernel = PhGetItemCircularBuffer_FLOAT(SystemStatistics.CpuKernelHistory, getTooltipText->Index);
cpuUser = PhGetItemCircularBuffer_FLOAT(SystemStatistics.CpuUserHistory, getTooltipText->Index);
PhMoveReference(&CpuGraphState.TooltipText, PhFormatString(
L"%.2f%%%s\n%s",
(cpuKernel + cpuUser) * 100,
PhGetStringOrEmpty(PhSipGetMaxCpuString(getTooltipText->Index)),
PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer
));
}
getTooltipText->Text = CpuGraphState.TooltipText->sr;
}
else if (ToolStatusConfig.MemGraphEnabled && Header->hwndFrom == MemGraphHandle)
{
ULONG physicalUsage;
physicalUsage = PhGetItemCircularBuffer_ULONG(SystemStatistics.PhysicalHistory, getTooltipText->Index);
PhMoveReference(&MemGraphState.TooltipText, PhFormatString(
L"Physical memory: %s\n%s",
PhaFormatSize(UInt32x32To64(physicalUsage, PAGE_SIZE), -1)->Buffer,
PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer
));
getTooltipText->Text = MemGraphState.TooltipText->sr;
}
else if (ToolStatusConfig.CommitGraphEnabled && Header->hwndFrom == CommitGraphHandle)
{
ULONG commitUsage;
commitUsage = PhGetItemCircularBuffer_ULONG(SystemStatistics.CommitHistory, getTooltipText->Index);
PhMoveReference(&CommitGraphState.TooltipText, PhFormatString(
L"Commit charge: %s\n%s",
PhaFormatSize(UInt32x32To64(commitUsage, PAGE_SIZE), -1)->Buffer,
PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer
));
getTooltipText->Text = CommitGraphState.TooltipText->sr;
}
else if (ToolStatusConfig.IoGraphEnabled && Header->hwndFrom == IoGraphHandle)
{
ULONG64 ioRead;
ULONG64 ioWrite;
ULONG64 ioOther;
ioRead = PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoReadHistory, getTooltipText->Index);
ioWrite = PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoWriteHistory, getTooltipText->Index);
ioOther = PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoOtherHistory, getTooltipText->Index);
PhMoveReference(&IoGraphState.TooltipText, PhFormatString(
L"R: %s\nW: %s\nO: %s%s\n%s",
PhaFormatSize(ioRead, -1)->Buffer,
PhaFormatSize(ioWrite, -1)->Buffer,
PhaFormatSize(ioOther, -1)->Buffer,
PhGetStringOrEmpty(PhSipGetMaxIoString(getTooltipText->Index)),
PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer
));
getTooltipText->Text = IoGraphState.TooltipText->sr;
}
}
}
break;
case GCN_MOUSEEVENT:
{
PPH_GRAPH_MOUSEEVENT mouseEvent = (PPH_GRAPH_MOUSEEVENT)Header;
PPH_PROCESS_RECORD record = NULL;
if (ToolStatusConfig.CpuGraphEnabled && Header->hwndFrom == CpuGraphHandle)
{
if (mouseEvent->Message == WM_RBUTTONUP)
{
ShowCustomizeMenu();
}
else
{
if (mouseEvent->Message == WM_LBUTTONDBLCLK && mouseEvent->Index < mouseEvent->TotalCount)
{
record = PhSipReferenceMaxCpuRecord(mouseEvent->Index);
}
if (record)
{
PhShowProcessRecordDialog(PhMainWndHandle, record);
PhDereferenceProcessRecord(record);
}
}
}
else if (ToolStatusConfig.MemGraphEnabled && Header->hwndFrom == MemGraphHandle)
{
if (mouseEvent->Message == WM_RBUTTONUP)
{
ShowCustomizeMenu();
}
}
else if (ToolStatusConfig.CommitGraphEnabled && Header->hwndFrom == CommitGraphHandle)
{
if (mouseEvent->Message == WM_RBUTTONUP)
{
ShowCustomizeMenu();
}
}
else if (ToolStatusConfig.IoGraphEnabled && Header->hwndFrom == IoGraphHandle)
{
if (mouseEvent->Message == WM_RBUTTONUP)
{
ShowCustomizeMenu();
}
else
{
if (mouseEvent->Message == WM_LBUTTONDBLCLK && mouseEvent->Index < mouseEvent->TotalCount)
{
record = PhSipReferenceMaxIoRecord(mouseEvent->Index);
}
if (record)
{
PhShowProcessRecordDialog(PhMainWndHandle, record);
PhDereferenceProcessRecord(record);
}
}
}
}
break;
}
}

1421
plugins/ToolStatus/main.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,101 @@
/*
* Process Hacker ToolStatus -
* Plugin Options
*
* Copyright (C) 2011-2016 dmex
* Copyright (C) 2010-2013 wj32
*
* 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"
INT_PTR CALLBACK OptionsDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLE_TOOLBAR),
ToolStatusConfig.ToolBarEnabled ? BST_CHECKED : BST_UNCHECKED);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLE_STATUSBAR),
ToolStatusConfig.StatusBarEnabled ? BST_CHECKED : BST_UNCHECKED);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_RESOLVEGHOSTWINDOWS),
ToolStatusConfig.ResolveGhostWindows ? BST_CHECKED : BST_UNCHECKED);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLE_AUTOHIDE_MENU),
ToolStatusConfig.AutoHideMenu ? BST_CHECKED : BST_UNCHECKED);
}
break;
case WM_COMMAND:
{
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDCANCEL:
EndDialog(hwndDlg, IDCANCEL);
break;
case IDOK:
{
ToolStatusConfig.ToolBarEnabled = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLE_TOOLBAR)) == BST_CHECKED;
ToolStatusConfig.StatusBarEnabled = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLE_STATUSBAR)) == BST_CHECKED;
ToolStatusConfig.ResolveGhostWindows = Button_GetCheck(GetDlgItem(hwndDlg, IDC_RESOLVEGHOSTWINDOWS)) == BST_CHECKED;
ToolStatusConfig.AutoHideMenu = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLE_AUTOHIDE_MENU)) == BST_CHECKED;
PhSetIntegerSetting(SETTING_NAME_TOOLSTATUS_CONFIG, ToolStatusConfig.Flags);
ToolbarLoadSettings();
if (ToolStatusConfig.AutoHideMenu)
{
SetMenu(PhMainWndHandle, NULL);
}
else
{
SetMenu(PhMainWndHandle, MainMenu);
DrawMenuBar(PhMainWndHandle);
}
EndDialog(hwndDlg, IDOK);
}
break;
}
}
break;
}
return FALSE;
}
VOID ShowOptionsDialog(
_In_opt_ HWND Parent
)
{
DialogBox(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_OPTIONS),
Parent,
OptionsDlgProc
);
}

View File

@@ -0,0 +1,57 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ToolStatus.rc
//
#define IDD_OPTIONS 102
#define IDR_MAINWND_ACCEL 103
#define IDB_SEARCH_ACTIVE 104
#define IDB_SEARCH_ACTIVE_BMP 119
#define IDB_SEARCH_INACTIVE 120
#define IDB_SEARCH_INACTIVE_BMP 121
#define IDB_APPLICATION_GET_MODERN 126
#define IDB_APPLICATION_GO_MODERN 127
#define IDB_APPLICATION_MODERN 128
#define IDB_ARROW_REFRESH_MODERN 129
#define IDB_CHART_LINE_MODERN 130
#define IDB_COG_EDIT_MODERN 131
#define IDB_CROSS_MODERN 132
#define IDB_FIND_MODERN 133
#define IDB_POWER_MODERN 134
#define IDD_CUSTOMIZE_TB 135
#define IDD_CUSTOMIZE_SB 136
#define IDI_ARROW_REFRESH 137
#define IDI_COG_EDIT 138
#define IDI_FIND 139
#define IDI_CHART_LINE 140
#define IDI_TBAPPLICATION 141
#define IDI_APPLICATION_GO 142
#define IDI_CROSS 143
#define IDI_APPLICATION_GET 144
#define IDI_LIGHTBULB_OFF 145
#define IDC_ENABLE_TOOLBAR 1001
#define IDC_ENABLE_MODERN 1002
#define IDC_ENABLE_STATUSBAR 1003
#define IDC_RESOLVEGHOSTWINDOWS 1004
#define IDC_AVAILABLE 1005
#define IDC_ADD 1006
#define IDC_REMOVE 1007
#define IDC_CURRENT 1008
#define IDC_SEARCHOPTIONS 1009
#define IDC_TEXTOPTIONS 1010
#define IDC_MOVEUP 1011
#define IDC_MOVEDOWN 1012
#define IDC_THEMEOPTIONS 1013
#define IDC_RESET 1014
#define IDC_ENABLE_AUTOHIDE_MENU 1015
#define ID_SEARCH 40011
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 146
#define _APS_NEXT_COMMAND_VALUE 40016
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 11010
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

View File

@@ -0,0 +1,739 @@
/*
* Process Hacker -
* Subclassed Edit control
*
* Copyright (C) 2012-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"
#include "commonutil.h"
#include <uxtheme.h>
#include <vssym32.h>
VOID NcAreaFreeTheme(
_Inout_ PEDIT_CONTEXT Context
)
{
if (Context->BrushNormal)
DeleteObject(Context->BrushNormal);
if (Context->BrushHot)
DeleteObject(Context->BrushHot);
if (Context->BrushPushed)
DeleteObject(Context->BrushPushed);
}
VOID NcAreaInitializeFont(
_Inout_ PEDIT_CONTEXT Context
)
{
// Cleanup existing font handle.
if (Context->WindowFont)
DeleteObject(Context->WindowFont);
Context->WindowFont = CommonDuplicateFont((HFONT)SendMessage(ToolBarHandle, WM_GETFONT, 0, 0));
SendMessage(Context->WindowHandle, WM_SETFONT, (WPARAM)Context->WindowFont, TRUE);
}
VOID NcAreaInitializeTheme(
_Inout_ PEDIT_CONTEXT Context
)
{
Context->CXWidth = PhMultiplyDivide(19, PhGlobalDpi, 96);
Context->BrushNormal = GetSysColorBrush(COLOR_WINDOW);
Context->BrushHot = CreateSolidBrush(RGB(205, 232, 255));
Context->BrushPushed = CreateSolidBrush(RGB(153, 209, 255));
if (IsThemeActive())
{
HTHEME themeDataHandle;
if (themeDataHandle = OpenThemeData(Context->WindowHandle, VSCLASS_EDIT))
{
//IsThemePartDefined_I(themeDataHandle, EP_EDITBORDER_NOSCROLL, EPSHV_NORMAL);
if (!SUCCEEDED(GetThemeInt(
themeDataHandle,
EP_EDITBORDER_NOSCROLL,
EPSHV_NORMAL,
TMT_BORDERSIZE,
&Context->CXBorder
)))
{
Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
}
CloseThemeData(themeDataHandle);
}
else
{
Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
}
}
else
{
Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
}
}
VOID NcAreaInitializeImageList(
_Inout_ PEDIT_CONTEXT Context
)
{
HBITMAP bitmapActive = NULL;
HBITMAP bitmapInactive = NULL;
Context->ImageWidth = GetSystemMetrics(SM_CXSMICON) + 4;
Context->ImageHeight = GetSystemMetrics(SM_CYSMICON) + 4;
Context->ImageList = ImageList_Create(32, 32, ILC_COLOR32, 2, 2);
ImageList_SetImageCount(Context->ImageList, 2);
// Add the images to the imagelist
if (bitmapActive = LoadImageFromResources(Context->ImageWidth, Context->ImageHeight, MAKEINTRESOURCE(IDB_SEARCH_ACTIVE)))
{
ImageList_Replace(Context->ImageList, 0, bitmapActive, NULL);
DeleteObject(bitmapActive);
}
else
{
PhSetImageListBitmap(Context->ImageList, 0, PluginInstance->DllBase, MAKEINTRESOURCE(IDB_SEARCH_ACTIVE_BMP));
}
if (bitmapInactive = LoadImageFromResources(Context->ImageWidth, Context->ImageHeight, MAKEINTRESOURCE(IDB_SEARCH_INACTIVE)))
{
ImageList_Replace(Context->ImageList, 1, bitmapInactive, NULL);
DeleteObject(bitmapInactive);
}
else
{
PhSetImageListBitmap(Context->ImageList, 1, PluginInstance->DllBase, MAKEINTRESOURCE(IDB_SEARCH_INACTIVE_BMP));
}
}
VOID NcAreaGetButtonRect(
_Inout_ PEDIT_CONTEXT Context,
_Inout_ PRECT ButtonRect
)
{
ButtonRect->left = (ButtonRect->right - Context->CXWidth) - Context->CXBorder - 1; // offset left border by 1
ButtonRect->bottom -= Context->CXBorder;
ButtonRect->right -= Context->CXBorder;
ButtonRect->top += Context->CXBorder;
}
VOID NcAreaDrawButton(
_Inout_ PEDIT_CONTEXT Context,
_In_ RECT ButtonRect
)
{
HDC hdc;
HDC bufferDc;
HBITMAP bufferBitmap;
HBITMAP oldBufferBitmap;
RECT bufferRect =
{
0, 0,
ButtonRect.right - ButtonRect.left,
ButtonRect.bottom - ButtonRect.top
};
if (!(hdc = GetWindowDC(Context->WindowHandle)))
return;
bufferDc = CreateCompatibleDC(hdc);
bufferBitmap = CreateCompatibleBitmap(hdc, bufferRect.right, bufferRect.bottom);
oldBufferBitmap = SelectObject(bufferDc, bufferBitmap);
if (Context->Pushed)
{
FillRect(bufferDc, &bufferRect, Context->BrushPushed);
//FrameRect(bufferDc, &bufferRect, CreateSolidBrush(RGB(0xff, 0, 0)));
}
else if (Context->Hot)
{
FillRect(bufferDc, &bufferRect, Context->BrushHot);
//FrameRect(bufferDc, &bufferRect, CreateSolidBrush(RGB(38, 160, 218)));
}
else
{
FillRect(bufferDc, &bufferRect, Context->BrushNormal);
}
// Draw the image centered within the rect.
if (SearchboxText->Length > 0)
{
ImageList_Draw(
Context->ImageList,
0,
bufferDc,
bufferRect.left + ((bufferRect.right - bufferRect.left) - Context->ImageWidth) / 2,
bufferRect.top + ((bufferRect.bottom - bufferRect.top) - Context->ImageHeight) / 2,
ILD_NORMAL | ILD_TRANSPARENT
);
}
else
{
ImageList_Draw(
Context->ImageList,
1,
bufferDc,
bufferRect.left + ((bufferRect.right - bufferRect.left) - (Context->ImageWidth - 2)) / 2, // (ImageWidth - 2) offset left by two
bufferRect.top + ((bufferRect.bottom - bufferRect.top) - (Context->ImageHeight - 2)) / 2, // (ImageHeight - 2) offset top by one
ILD_NORMAL | ILD_TRANSPARENT
);
}
BitBlt(hdc, ButtonRect.left, ButtonRect.top, ButtonRect.right, ButtonRect.bottom, bufferDc, 0, 0, SRCCOPY);
SelectObject(bufferDc, oldBufferBitmap);
DeleteObject(bufferBitmap);
DeleteDC(bufferDc);
ReleaseDC(Context->WindowHandle, hdc);
}
LRESULT CALLBACK NcAreaWndSubclassProc(
_In_ HWND hWnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ UINT_PTR uIdSubclass,
_In_ ULONG_PTR dwRefData
)
{
PEDIT_CONTEXT context;
context = (PEDIT_CONTEXT)GetProp(hWnd, L"EditSubclassContext");
switch (uMsg)
{
case WM_NCDESTROY:
{
NcAreaFreeTheme(context);
if (context->ImageList)
ImageList_Destroy(context->ImageList);
if (context->WindowFont)
DeleteObject(context->WindowFont);
RemoveWindowSubclass(hWnd, NcAreaWndSubclassProc, uIdSubclass);
RemoveProp(hWnd, L"EditSubclassContext");
PhFree(context);
}
break;
case WM_ERASEBKGND:
return 1;
case WM_NCCALCSIZE:
{
LPNCCALCSIZE_PARAMS ncCalcSize = (NCCALCSIZE_PARAMS*)lParam;
// Let Windows handle the non-client defaults.
DefSubclassProc(hWnd, uMsg, wParam, lParam);
// Deflate the client area to accommodate the custom button.
ncCalcSize->rgrc[0].right -= context->CXWidth;
}
return 0;
case WM_NCPAINT:
{
RECT windowRect;
// Let Windows handle the non-client defaults.
DefSubclassProc(hWnd, uMsg, wParam, lParam);
// Get the screen coordinates of the window.
GetWindowRect(hWnd, &windowRect);
// Adjust the coordinates (start from 0,0).
OffsetRect(&windowRect, -windowRect.left, -windowRect.top);
// Get the position of the inserted button.
NcAreaGetButtonRect(context, &windowRect);
// Draw the button.
NcAreaDrawButton(context, windowRect);
}
return 0;
case WM_NCHITTEST:
{
POINT windowPoint;
RECT windowRect;
// Get the screen coordinates of the mouse.
if (!GetCursorPos(&windowPoint))
break;
// Get the screen coordinates of the window.
GetWindowRect(hWnd, &windowRect);
// Get the position of the inserted button.
NcAreaGetButtonRect(context, &windowRect);
// Check that the mouse is within the inserted button.
if (PtInRect(&windowRect, windowPoint))
{
return HTBORDER;
}
}
break;
case WM_NCLBUTTONDOWN:
{
POINT windowPoint;
RECT windowRect;
// Get the screen coordinates of the mouse.
if (!GetCursorPos(&windowPoint))
break;
// Get the screen coordinates of the window.
GetWindowRect(hWnd, &windowRect);
// Get the position of the inserted button.
NcAreaGetButtonRect(context, &windowRect);
// Check that the mouse is within the inserted button.
if (PtInRect(&windowRect, windowPoint))
{
context->Pushed = TRUE;
SetCapture(hWnd);
RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
}
}
break;
case WM_LBUTTONUP:
{
POINT windowPoint;
RECT windowRect;
// Get the screen coordinates of the mouse.
if (!GetCursorPos(&windowPoint))
break;
// Get the screen coordinates of the window.
GetWindowRect(hWnd, &windowRect);
// Get the position of the inserted button.
NcAreaGetButtonRect(context, &windowRect);
// Check that the mouse is within the inserted button.
if (PtInRect(&windowRect, windowPoint))
{
// Forward click notification.
SendMessage(PhMainWndHandle, WM_COMMAND, MAKEWPARAM(context->CommandID, BN_CLICKED), 0);
}
if (GetCapture() == hWnd)
{
context->Pushed = FALSE;
ReleaseCapture();
}
RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
}
break;
case WM_KEYDOWN:
{
if (wParam == '\t' || wParam == '\r')
{
HWND tnHandle;
tnHandle = GetCurrentTreeNewHandle();
if (tnHandle)
{
SetFocus(tnHandle);
if (wParam == '\r')
{
if (TreeNew_GetFlatNodeCount(tnHandle) > 0)
{
TreeNew_DeselectRange(tnHandle, 0, -1);
TreeNew_SelectRange(tnHandle, 0, 0);
TreeNew_SetFocusNode(tnHandle, TreeNew_GetFlatNode(tnHandle, 0));
TreeNew_SetMarkNode(tnHandle, TreeNew_GetFlatNode(tnHandle, 0));
}
}
}
else
{
PTOOLSTATUS_TAB_INFO tabInfo;
if ((tabInfo = FindTabInfo(SelectedTabIndex)) && tabInfo->ActivateContent)
tabInfo->ActivateContent(wParam == '\r');
}
return FALSE;
}
// Handle CTRL+A below Vista.
if (WindowsVersion < WINDOWS_VISTA && (GetKeyState(VK_CONTROL) & VK_LCONTROL) && wParam == 'A')
{
Edit_SetSel(hWnd, 0, -1);
return FALSE;
}
}
break;
case WM_CHAR:
if (wParam == '\t' || wParam == '\r')
return FALSE;
break;
case WM_CUT:
case WM_CLEAR:
case WM_PASTE:
case WM_UNDO:
case WM_KEYUP:
case WM_SETTEXT:
case WM_KILLFOCUS:
RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
break;
case WM_SETTINGCHANGE:
case WM_SYSCOLORCHANGE:
case WM_THEMECHANGED:
{
NcAreaFreeTheme(context);
NcAreaInitializeTheme(context);
NcAreaInitializeFont(context);
// Reset the client area margins.
SendMessage(hWnd, EM_SETMARGINS, EC_LEFTMARGIN, MAKELPARAM(0, 0));
// Force the edit control to update its non-client area.
RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
//SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
}
break;
case WM_SETFOCUS:
{
if (SearchBoxDisplayMode != SEARCHBOX_DISPLAY_MODE_HIDEINACTIVE)
break;
if (!RebarBandExists(REBAR_BAND_ID_SEARCHBOX))
{
UINT height = (UINT)SendMessage(RebarHandle, RB_GETROWHEIGHT, 0, 0);
RebarBandInsert(REBAR_BAND_ID_SEARCHBOX, SearchboxHandle, PhMultiplyDivide(180, PhGlobalDpi, 96), height - 2);
}
}
break;
case WM_NCMOUSEMOVE:
{
POINT windowPoint;
RECT windowRect;
// Get the screen coordinates of the mouse.
if (!GetCursorPos(&windowPoint))
break;
// Get the screen coordinates of the window.
GetWindowRect(hWnd, &windowRect);
// Get the position of the inserted button.
NcAreaGetButtonRect(context, &windowRect);
// Check that the mouse is within the inserted button.
if (PtInRect(&windowRect, windowPoint) && !context->Hot)
{
TRACKMOUSEEVENT trackMouseEvent;
trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
trackMouseEvent.dwFlags = TME_LEAVE | TME_NONCLIENT;
trackMouseEvent.hwndTrack = hWnd;
trackMouseEvent.dwHoverTime = 0;
context->Hot = TRUE;
RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
TrackMouseEvent(&trackMouseEvent);
}
}
break;
case WM_NCMOUSELEAVE:
{
if (context->Hot)
{
context->Hot = FALSE;
RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
}
}
break;
case WM_MOUSEMOVE:
{
if ((wParam & MK_LBUTTON) && GetCapture() == hWnd)
{
POINT windowPoint;
RECT windowRect;
// Get the screen coordinates of the mouse.
if (!GetCursorPos(&windowPoint))
break;
// Get the screen coordinates of the window.
GetWindowRect(hWnd, &windowRect);
// Get the position of the inserted button.
NcAreaGetButtonRect(context, &windowRect);
// Check that the mouse is within the inserted button.
context->Pushed = PtInRect(&windowRect, windowPoint);
RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
}
}
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
HBITMAP LoadImageFromResources(
_In_ UINT Width,
_In_ UINT Height,
_In_ PCWSTR Name
)
{
UINT width = 0;
UINT height = 0;
UINT frameCount = 0;
BOOLEAN isSuccess = FALSE;
ULONG resourceLength = 0;
HGLOBAL resourceHandle = NULL;
HRSRC resourceHandleSource = NULL;
WICInProcPointer resourceBuffer = NULL;
HDC screenHdc = NULL;
HDC bufferDc = NULL;
BITMAPINFO bitmapInfo = { 0 };
HBITMAP bitmapHandle = NULL;
PBYTE bitmapBuffer = NULL;
IWICStream* wicStream = NULL;
IWICBitmapSource* wicBitmapSource = NULL;
IWICBitmapDecoder* wicDecoder = NULL;
IWICBitmapFrameDecode* wicFrame = NULL;
IWICImagingFactory* wicFactory = NULL;
IWICBitmapScaler* wicScaler = NULL;
WICPixelFormatGUID pixelFormat;
WICRect rect = { 0, 0, Width, Height };
__try
{
// Create the ImagingFactory
if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory)))
__leave;
// Find the resource
if ((resourceHandleSource = FindResource(PluginInstance->DllBase, Name, L"PNG")) == NULL)
__leave;
// Get the resource length
resourceLength = SizeofResource(PluginInstance->DllBase, resourceHandleSource);
// Load the resource
if ((resourceHandle = LoadResource(PluginInstance->DllBase, resourceHandleSource)) == NULL)
__leave;
if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL)
__leave;
// Create the Stream
if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream)))
__leave;
// Initialize the Stream from Memory
if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength)))
__leave;
if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder)))
__leave;
if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad)))
__leave;
// Get the Frame count
if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1)
__leave;
// Get the Frame
if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame)))
__leave;
// Get the WicFrame image format
if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat)))
__leave;
// Check if the image format is supported:
if (IsEqualGUID(&pixelFormat, &GUID_WICPixelFormat32bppRGBA)) // GUID_WICPixelFormat32bppPBGRA
{
wicBitmapSource = (IWICBitmapSource*)wicFrame;
}
else
{
IWICFormatConverter* wicFormatConverter = NULL;
if (FAILED(IWICImagingFactory_CreateFormatConverter(wicFactory, &wicFormatConverter)))
__leave;
if (FAILED(IWICFormatConverter_Initialize(
wicFormatConverter,
(IWICBitmapSource*)wicFrame,
&GUID_WICPixelFormat32bppBGRA,
WICBitmapDitherTypeNone,
NULL,
0.0,
WICBitmapPaletteTypeCustom
)))
{
IWICFormatConverter_Release(wicFormatConverter);
__leave;
}
// Convert the image to the correct format:
IWICFormatConverter_QueryInterface(wicFormatConverter, &IID_IWICBitmapSource, &wicBitmapSource);
// Cleanup the converter.
IWICFormatConverter_Release(wicFormatConverter);
// Dispose the old frame now that the converted frame is in wicBitmapSource.
IWICBitmapFrameDecode_Release(wicFrame);
}
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = rect.Width;
bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height);
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
screenHdc = GetDC(NULL);
bufferDc = CreateCompatibleDC(screenHdc);
bitmapHandle = CreateDIBSection(screenHdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0);
// Check if it's the same rect as the requested size.
//if (width != rect.Width || height != rect.Height)
if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler)))
__leave;
if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant)))
__leave;
if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, bitmapBuffer)))
__leave;
isSuccess = TRUE;
}
__finally
{
// Cleanup resources in the same order they were created.
if (wicScaler)
{
IWICBitmapScaler_Release(wicScaler);
}
if (bufferDc)
{
DeleteDC(bufferDc);
}
if (screenHdc)
{
ReleaseDC(NULL, screenHdc);
}
if (wicBitmapSource)
{
IWICBitmapSource_Release(wicBitmapSource);
}
if (wicStream)
{
IWICStream_Release(wicStream);
}
if (wicDecoder)
{
IWICBitmapDecoder_Release(wicDecoder);
}
if (wicFactory)
{
IWICImagingFactory_Release(wicFactory);
}
if (resourceHandle)
{
FreeResource(resourceHandle);
}
}
return bitmapHandle;
}
HWND CreateSearchControl(
_In_ UINT CommandID
)
{
PEDIT_CONTEXT context;
context = (PEDIT_CONTEXT)PhAllocate(sizeof(EDIT_CONTEXT));
memset(context, 0, sizeof(EDIT_CONTEXT));
context->CommandID = CommandID;
// Create the SearchBox window.
context->WindowHandle = CreateWindowEx(
WS_EX_CLIENTEDGE,
WC_EDIT,
NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | ES_LEFT | ES_AUTOHSCROLL | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
RebarHandle,
NULL,
NULL,
NULL
);
// TODO: Why does the Edit control require WS_VISIBLE to be correctly initialized under some conditions?
// For now just call ShowWindow with SW_HIDE instead of removing the WS_VISIBLE style passed to CreateWindowEx.
if (SearchBoxDisplayMode == SEARCHBOX_DISPLAY_MODE_HIDEINACTIVE)
{
ShowWindow(SearchboxHandle, SW_HIDE);
}
//NcAreaInitializeTheme(context);
NcAreaInitializeImageList(context);
// Set initial text
Edit_SetCueBannerText(context->WindowHandle, L"Search Processes (Ctrl+K)");
// Set our window context data.
SetProp(context->WindowHandle, L"EditSubclassContext", (HANDLE)context);
// Subclass the Edit control window procedure.
SetWindowSubclass(context->WindowHandle, NcAreaWndSubclassProc, 0, (ULONG_PTR)context);
// Initialize the theme parameters.
SendMessage(context->WindowHandle, WM_THEMECHANGED, 0, 0);
return context->WindowHandle;
}

View File

@@ -0,0 +1,584 @@
/*
* Process Hacker ToolStatus -
* statusbar main
*
* Copyright (C) 2011-2016 dmex
* Copyright (C) 2010-2013 wj32
*
* 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"
HWND StatusBarHandle = NULL;
ULONG ProcessesUpdatedCount = 0;
ULONG StatusBarMaxWidths[MAX_STATUSBAR_ITEMS];
// Note: no lock is needed because we only ever modify the list on this same thread.
PPH_LIST StatusBarItemList = NULL;
ULONG StatusBarItems[MAX_STATUSBAR_ITEMS] =
{
// Default items (displayed)
{ ID_STATUS_CPUUSAGE },
{ ID_STATUS_PHYSICALMEMORY },
{ ID_STATUS_NUMBEROFPROCESSES },
// Available items (hidden)
{ ID_STATUS_COMMITCHARGE },
{ ID_STATUS_FREEMEMORY },
{ ID_STATUS_NUMBEROFTHREADS },
{ ID_STATUS_NUMBEROFHANDLES },
{ ID_STATUS_NUMBEROFVISIBLEITEMS, },
{ ID_STATUS_NUMBEROFSELECTEDITEMS, },
{ ID_STATUS_INTERVALSTATUS },
{ ID_STATUS_IO_RO },
{ ID_STATUS_IO_W },
{ ID_STATUS_MAX_CPU_PROCESS },
{ ID_STATUS_MAX_IO_PROCESS },
};
VOID StatusBarLoadDefault(
VOID
)
{
ULONG i;
if (!StatusBarItemList)
StatusBarItemList = PhCreateList(MAX_DEFAULT_STATUSBAR_ITEMS);
for (i = 0; i < MAX_DEFAULT_STATUSBAR_ITEMS; i++)
{
PSTATUSBAR_ITEM statusItem;
statusItem = PhAllocate(sizeof(STATUSBAR_ITEM));
memset(statusItem, 0, sizeof(STATUSBAR_ITEM));
statusItem->Id = StatusBarItems[i];
PhAddItemList(StatusBarItemList, statusItem);
}
}
VOID StatusBarLoadSettings(
VOID
)
{
ULONG64 buttonCount = 0;
PPH_STRING settingsString;
PH_STRINGREF remaining;
PH_STRINGREF part;
settingsString = PhaGetStringSetting(SETTING_NAME_STATUSBAR_CONFIG);
remaining = settingsString->sr;
if (remaining.Length == 0)
{
// Load default settings
StatusBarLoadDefault();
return;
}
// Query the number of buttons to insert
if (!PhSplitStringRefAtChar(&remaining, '|', &part, &remaining))
{
// Load default settings
StatusBarLoadDefault();
return;
}
if (!PhStringToInteger64(&part, 10, &buttonCount))
{
// Load default settings
StatusBarLoadDefault();
return;
}
StatusBarItemList = PhCreateList((ULONG)buttonCount);
for (ULONG i = 0; i < (ULONG)buttonCount; i++)
{
PH_STRINGREF idPart;
ULONG64 idInteger;
if (remaining.Length == 0)
break;
PhSplitStringRefAtChar(&remaining, '|', &idPart, &remaining);
if (PhStringToInteger64(&idPart, 10, &idInteger))
{
PSTATUSBAR_ITEM statusItem;
statusItem = PhAllocate(sizeof(STATUSBAR_ITEM));
memset(statusItem, 0, sizeof(STATUSBAR_ITEM));
statusItem->Id = (ULONG)idInteger;
PhInsertItemList(StatusBarItemList, i, statusItem);
}
}
}
VOID StatusBarSaveSettings(
VOID
)
{
ULONG buttonIndex = 0;
PPH_STRING settingsString;
PH_STRING_BUILDER stringBuilder;
PhInitializeStringBuilder(&stringBuilder, 100);
PhAppendFormatStringBuilder(
&stringBuilder,
L"%lu|",
StatusBarItemList->Count
);
for (buttonIndex = 0; buttonIndex < StatusBarItemList->Count; buttonIndex++)
{
PSTATUSBAR_ITEM statusItem = StatusBarItemList->Items[buttonIndex];
PhAppendFormatStringBuilder(
&stringBuilder,
L"%lu|",
statusItem->Id
);
}
if (stringBuilder.String->Length != 0)
PhRemoveEndStringBuilder(&stringBuilder, 1);
settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder));
PhSetStringSetting2(SETTING_NAME_STATUSBAR_CONFIG, &settingsString->sr);
}
VOID StatusBarResetSettings(
VOID
)
{
for (ULONG i = 0; i < StatusBarItemList->Count; i++)
{
PhFree(StatusBarItemList->Items[i]);
}
PhClearList(StatusBarItemList);
StatusBarLoadDefault();
}
PWSTR StatusBarGetText(
_In_ ULONG CommandID
)
{
switch (CommandID)
{
case ID_STATUS_CPUUSAGE:
return L"CPU usage";
case ID_STATUS_PHYSICALMEMORY:
return L"Physical memory";
case ID_STATUS_NUMBEROFPROCESSES:
return L"Number of processes";
case ID_STATUS_COMMITCHARGE:
return L"Commit charge";
case ID_STATUS_FREEMEMORY:
return L"Free physical memory";
case ID_STATUS_NUMBEROFTHREADS:
return L"Number of threads";
case ID_STATUS_NUMBEROFHANDLES:
return L"Number of handles";
case ID_STATUS_NUMBEROFVISIBLEITEMS:
return L"Number of visible items";
case ID_STATUS_NUMBEROFSELECTEDITEMS:
return L"Number of selected items";
case ID_STATUS_INTERVALSTATUS:
return L"Interval status";
case ID_STATUS_IO_RO:
return L"I/O read+other";
case ID_STATUS_IO_W:
return L"I/O write";
case ID_STATUS_MAX_CPU_PROCESS:
return L"Max. CPU process";
case ID_STATUS_MAX_IO_PROCESS:
return L"Max. I/O process";
}
return L"ERROR";
}
VOID StatusBarShowMenu(
VOID
)
{
PPH_EMENU menu;
PPH_EMENU_ITEM selectedItem;
POINT cursorPos;
GetCursorPos(&cursorPos);
menu = PhCreateEMenu();
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, COMMAND_ID_ENABLE_SEARCHBOX, L"Customize...", NULL, NULL), -1);
selectedItem = PhShowEMenu(
menu,
PhMainWndHandle,
PH_EMENU_SHOW_LEFTRIGHT,
PH_ALIGN_LEFT | PH_ALIGN_BOTTOM,
cursorPos.x,
cursorPos.y
);
if (selectedItem && selectedItem->Id != -1)
{
StatusBarShowCustomizeDialog();
StatusBarUpdate(TRUE);
}
PhDestroyEMenu(menu);
}
VOID StatusBarUpdate(
_In_ BOOLEAN ResetMaxWidths
)
{
static ULONG64 lastTickCount = 0;
ULONG count;
ULONG i;
HDC hdc;
BOOLEAN resetMaxWidths = FALSE;
PPH_STRING text[MAX_STATUSBAR_ITEMS];
ULONG widths[MAX_STATUSBAR_ITEMS];
if (ProcessesUpdatedCount < 2)
return;
if (ResetMaxWidths)
resetMaxWidths = TRUE;
if (!StatusBarItemList || StatusBarItemList->Count == 0)
{
// The status bar doesn't cope well with 0 parts.
widths[0] = -1;
SendMessage(StatusBarHandle, SB_SETPARTS, 1, (LPARAM)widths);
SendMessage(StatusBarHandle, SB_SETTEXT, 0, (LPARAM)L"");
return;
}
hdc = GetDC(StatusBarHandle);
SelectObject(hdc, (HFONT)SendMessage(StatusBarHandle, WM_GETFONT, 0, 0));
// Reset max. widths for Max. CPU Process and Max. I/O Process parts once in a while.
{
LARGE_INTEGER tickCount;
PhQuerySystemTime(&tickCount);
if (tickCount.QuadPart - lastTickCount >= 10 * PH_TICKS_PER_SEC)
{
resetMaxWidths = TRUE;
lastTickCount = tickCount.QuadPart;
}
}
count = 0;
for (i = 0; i < StatusBarItemList->Count; i++)
{
SIZE size;
ULONG width;
PSTATUSBAR_ITEM statusItem;
statusItem = StatusBarItemList->Items[i];
switch (statusItem->Id)
{
case ID_STATUS_CPUUSAGE:
{
text[count] = PhFormatString(
L"CPU Usage: %.2f%%",
(SystemStatistics.CpuKernelUsage + SystemStatistics.CpuUserUsage) * 100
);
}
break;
case ID_STATUS_COMMITCHARGE:
{
ULONG commitUsage = SystemStatistics.Performance->CommittedPages;
FLOAT commitFraction = (FLOAT)commitUsage / SystemStatistics.Performance->CommitLimit * 100;
text[count] = PhFormatString(
L"Commit charge: %s (%.2f%%)",
PhaFormatSize(UInt32x32To64(commitUsage, PAGE_SIZE), -1)->Buffer,
commitFraction
);
}
break;
case ID_STATUS_PHYSICALMEMORY:
{
ULONG physicalUsage = PhSystemBasicInformation.NumberOfPhysicalPages - SystemStatistics.Performance->AvailablePages;
FLOAT physicalFraction = (FLOAT)physicalUsage / PhSystemBasicInformation.NumberOfPhysicalPages * 100;
text[count] = PhFormatString(
L"Physical memory: %s (%.2f%%)",
PhaFormatSize(UInt32x32To64(physicalUsage, PAGE_SIZE), -1)->Buffer,
physicalFraction
);
}
break;
case ID_STATUS_FREEMEMORY:
{
ULONG physicalFree = SystemStatistics.Performance->AvailablePages;
FLOAT physicalFreeFraction = (FLOAT)physicalFree / PhSystemBasicInformation.NumberOfPhysicalPages * 100;
text[count] = PhFormatString(
L"Free memory: %s (%.2f%%)",
PhaFormatSize(UInt32x32To64(physicalFree, PAGE_SIZE), -1)->Buffer,
physicalFreeFraction
);
}
break;
case ID_STATUS_NUMBEROFPROCESSES:
{
text[count] = PhConcatStrings2(
L"Processes: ",
PhaFormatUInt64(SystemStatistics.NumberOfProcesses, TRUE)->Buffer
);
}
break;
case ID_STATUS_NUMBEROFTHREADS:
{
text[count] = PhConcatStrings2(
L"Threads: ",
PhaFormatUInt64(SystemStatistics.NumberOfThreads, TRUE)->Buffer
);
}
break;
case ID_STATUS_NUMBEROFHANDLES:
{
text[count] = PhConcatStrings2(
L"Handles: ",
PhaFormatUInt64(SystemStatistics.NumberOfHandles, TRUE)->Buffer
);
}
break;
case ID_STATUS_IO_RO:
{
text[count] = PhConcatStrings2(
L"I/O R+O: ",
PhaFormatSize(SystemStatistics.IoReadDelta.Delta + SystemStatistics.IoOtherDelta.Delta, -1)->Buffer
);
}
break;
case ID_STATUS_IO_W:
{
text[count] = PhConcatStrings2(
L"I/O W: ",
PhaFormatSize(SystemStatistics.IoWriteDelta.Delta, -1)->Buffer
);
}
break;
case ID_STATUS_MAX_CPU_PROCESS:
{
PPH_PROCESS_ITEM processItem;
if (SystemStatistics.MaxCpuProcessId && (processItem = PhReferenceProcessItem(SystemStatistics.MaxCpuProcessId)))
{
if (!PH_IS_FAKE_PROCESS_ID(processItem->ProcessId))
{
text[count] = PhFormatString(
L"%s (%lu): %.2f%%",
processItem->ProcessName->Buffer,
HandleToUlong(processItem->ProcessId),
processItem->CpuUsage * 100
);
}
else
{
text[count] = PhFormatString(
L"%s: %.2f%%",
processItem->ProcessName->Buffer,
processItem->CpuUsage * 100
);
}
PhDereferenceObject(processItem);
}
else
{
text[count] = PhCreateString(L"-");
}
}
break;
case ID_STATUS_MAX_IO_PROCESS:
{
PPH_PROCESS_ITEM processItem;
if (SystemStatistics.MaxIoProcessId && (processItem = PhReferenceProcessItem(SystemStatistics.MaxIoProcessId)))
{
if (!PH_IS_FAKE_PROCESS_ID(processItem->ProcessId))
{
text[count] = PhFormatString(
L"%s (%lu): %s",
processItem->ProcessName->Buffer,
HandleToUlong(processItem->ProcessId),
PhaFormatSize(processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta, -1)->Buffer
);
}
else
{
text[count] = PhFormatString(
L"%s: %s",
processItem->ProcessName->Buffer,
PhaFormatSize(processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta, -1)->Buffer
);
}
PhDereferenceObject(processItem);
}
else
{
text[count] = PhCreateString(L"-");
}
}
break;
case ID_STATUS_NUMBEROFVISIBLEITEMS:
{
HWND tnHandle = NULL;
tnHandle = GetCurrentTreeNewHandle();
if (tnHandle)
{
ULONG visibleCount = 0;
visibleCount = TreeNew_GetFlatNodeCount(tnHandle);
text[count] = PhFormatString(
L"Visible: %lu",
visibleCount
);
}
else
{
text[count] = PhCreateString(
L"Visible: N/A"
);
}
}
break;
case ID_STATUS_NUMBEROFSELECTEDITEMS:
{
HWND tnHandle = NULL;
tnHandle = GetCurrentTreeNewHandle();
if (tnHandle)
{
ULONG visibleCount = 0;
ULONG selectedCount = 0;
visibleCount = TreeNew_GetFlatNodeCount(tnHandle);
for (ULONG i = 0; i < visibleCount; i++)
{
if (TreeNew_GetFlatNode(tnHandle, i)->Selected)
selectedCount++;
}
text[count] = PhFormatString(
L"Selected: %lu",
selectedCount
);
}
else
{
text[count] = PhCreateString(
L"Selected: N/A"
);
}
}
break;
case ID_STATUS_INTERVALSTATUS:
{
ULONG interval;
interval = PhGetIntegerSetting(L"UpdateInterval");
if (UpdateAutomatically)
{
switch (interval)
{
case 500:
text[count] = PhCreateString(L"Interval: Fast");
break;
case 1000:
text[count] = PhCreateString(L"Interval: Normal");
break;
case 2000:
text[count] = PhCreateString(L"Interval: Below normal");
break;
case 5000:
text[count] = PhCreateString(L"Interval: Slow");
break;
case 10000:
text[count] = PhCreateString(L"Interval: Very slow");
break;
}
}
else
{
text[count] = PhCreateString(L"Interval: Paused");
}
}
break;
}
if (resetMaxWidths)
StatusBarMaxWidths[count] = 0;
if (!GetTextExtentPoint32(hdc, text[count]->Buffer, (ULONG)text[count]->Length / sizeof(WCHAR), &size))
size.cx = 200;
if (count != 0)
widths[count] = widths[count - 1];
else
widths[count] = 0;
width = size.cx + 10;
if (width <= StatusBarMaxWidths[count])
{
width = StatusBarMaxWidths[count];
}
else
{
StatusBarMaxWidths[count] = width;
}
widths[count] += width;
count++;
}
ReleaseDC(StatusBarHandle, hdc);
SendMessage(StatusBarHandle, SB_SETPARTS, count, (LPARAM)widths);
for (i = 0; i < count; i++)
{
SendMessage(StatusBarHandle, SB_SETTEXT, i, (LPARAM)text[i]->Buffer);
PhDereferenceObject(text[i]);
}
}

View File

@@ -0,0 +1,899 @@
/*
* 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);
}

View File

@@ -0,0 +1,409 @@
/*
* Process Hacker ToolStatus -
* toolstatus header
*
* Copyright (C) 2011-2016 dmex
* Copyright (C) 2010-2013 wj32
*
* 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/>.
*/
#ifndef _TOOLSTATUS_H
#define _TOOLSTATUS_H
#define CINTERFACE
#define COBJMACROS
#define INITGUID
#include <phdk.h>
#include <phappresource.h>
#include <windowsx.h>
#include <Wincodec.h>
#include <toolstatusintf.h>
#include "resource.h"
#define PLUGIN_NAME TOOLSTATUS_PLUGIN_NAME
#define SETTING_NAME_TOOLSTATUS_CONFIG (PLUGIN_NAME L".Config")
#define SETTING_NAME_REBAR_CONFIG (PLUGIN_NAME L".RebarConfig")
#define SETTING_NAME_TOOLBAR_CONFIG (PLUGIN_NAME L".ToolbarConfig")
#define SETTING_NAME_STATUSBAR_CONFIG (PLUGIN_NAME L".StatusbarConfig")
#define SETTING_NAME_TOOLBAR_THEME (PLUGIN_NAME L".ToolbarTheme")
#define SETTING_NAME_TOOLBARDISPLAYSTYLE (PLUGIN_NAME L".ToolbarDisplayStyle")
#define SETTING_NAME_SEARCHBOXDISPLAYMODE (PLUGIN_NAME L".SearchBoxDisplayMode")
#define MAX_DEFAULT_TOOLBAR_ITEMS 9
#define MAX_DEFAULT_STATUSBAR_ITEMS 3
#define MAX_TOOLBAR_ITEMS 12
#define MAX_STATUSBAR_ITEMS 14
#define ID_SEARCH_CLEAR (WM_APP + 1)
#define TIDC_FINDWINDOW (WM_APP + 2)
#define TIDC_FINDWINDOWTHREAD (WM_APP + 3)
#define TIDC_FINDWINDOWKILL (WM_APP + 4)
#define TIDC_POWERMENUDROPDOWN (WM_APP + 5)
typedef enum _TOOLBAR_DISPLAY_STYLE
{
TOOLBAR_DISPLAY_STYLE_IMAGEONLY,
TOOLBAR_DISPLAY_STYLE_SELECTIVETEXT,
TOOLBAR_DISPLAY_STYLE_ALLTEXT
} TOOLBAR_DISPLAY_STYLE;
typedef enum _TOOLBAR_COMMAND_ID
{
COMMAND_ID_ENABLE_MENU = 1,
COMMAND_ID_ENABLE_SEARCHBOX,
COMMAND_ID_ENABLE_CPU_GRAPH,
COMMAND_ID_ENABLE_MEMORY_GRAPH,
COMMAND_ID_ENABLE_COMMIT_GRAPH,
COMMAND_ID_ENABLE_IO_GRAPH,
COMMAND_ID_TOOLBAR_LOCKUNLOCK,
COMMAND_ID_TOOLBAR_CUSTOMIZE,
} TOOLBAR_COMMAND_ID;
typedef enum _TOOLBAR_THEME
{
TOOLBAR_THEME_NONE,
TOOLBAR_THEME_BLACK,
TOOLBAR_THEME_BLUE
} TOOLBAR_THEME;
typedef enum _SEARCHBOX_DISPLAY_MODE
{
SEARCHBOX_DISPLAY_MODE_ALWAYSSHOW,
SEARCHBOX_DISPLAY_MODE_HIDEINACTIVE,
//SEARCHBOX_DISPLAY_MODE_AUTOHIDE
} SEARCHBOX_DISPLAY_MODE;
typedef enum _REBAR_BAND_ID
{
REBAR_BAND_ID_TOOLBAR,
REBAR_BAND_ID_SEARCHBOX,
REBAR_BAND_ID_CPUGRAPH,
REBAR_BAND_ID_MEMGRAPH,
REBAR_BAND_ID_COMMITGRAPH,
REBAR_BAND_ID_IOGRAPH
} REBAR_BAND;
typedef enum _REBAR_DISPLAY_LOCATION
{
REBAR_DISPLAY_LOCATION_TOP,
REBAR_DISPLAY_LOCATION_LEFT,
REBAR_DISPLAY_LOCATION_BOTTOM,
REBAR_DISPLAY_LOCATION_RIGHT,
} REBAR_DISPLAY_LOCATION;
typedef union _TOOLSTATUS_CONFIG
{
ULONG Flags;
struct
{
ULONG ToolBarEnabled : 1;
ULONG SearchBoxEnabled : 1;
ULONG StatusBarEnabled : 1;
ULONG ToolBarLocked : 1;
ULONG ResolveGhostWindows : 1;
ULONG ModernIcons : 1;
ULONG AutoHideMenu : 1;
ULONG CpuGraphEnabled : 1;
ULONG MemGraphEnabled : 1;
ULONG CommitGraphEnabled : 1;
ULONG IoGraphEnabled : 1;
ULONG Spare : 21;
};
} TOOLSTATUS_CONFIG;
extern TOOLSTATUS_CONFIG ToolStatusConfig;
extern HWND ProcessTreeNewHandle;
extern HWND ServiceTreeNewHandle;
extern HWND NetworkTreeNewHandle;
extern INT SelectedTabIndex;
extern BOOLEAN UpdateAutomatically;
extern BOOLEAN UpdateGraphs;
extern TOOLBAR_THEME ToolBarTheme;
extern TOOLBAR_DISPLAY_STYLE DisplayStyle;
extern SEARCHBOX_DISPLAY_MODE SearchBoxDisplayMode;
extern REBAR_DISPLAY_LOCATION RebarDisplayLocation;
extern HWND RebarHandle;
extern HWND ToolBarHandle;
extern HWND SearchboxHandle;
extern HMENU MainMenu;
extern HACCEL AcceleratorTable;
extern PPH_STRING SearchboxText;
extern PH_PLUGIN_SYSTEM_STATISTICS SystemStatistics;
extern HIMAGELIST ToolBarImageList;
extern TBBUTTON ToolbarButtons[MAX_TOOLBAR_ITEMS];
extern PPH_PLUGIN PluginInstance;
extern PPH_TN_FILTER_ENTRY ProcessTreeFilterEntry;
extern PPH_TN_FILTER_ENTRY ServiceTreeFilterEntry;
extern PPH_TN_FILTER_ENTRY NetworkTreeFilterEntry;
PTOOLSTATUS_TAB_INFO FindTabInfo(
_In_ INT TabIndex
);
// toolbar.c
typedef HRESULT (WINAPI *_LoadIconMetric)(
_In_ HINSTANCE hinst,
_In_ PCWSTR pszName,
_In_ int lims,
_Out_ HICON *phico
);
VOID RebarBandInsert(
_In_ UINT BandID,
_In_ HWND HwndChild,
_In_ UINT cyMinChild,
_In_ UINT cxMinChild
);
VOID RebarBandRemove(
_In_ UINT BandID
);
BOOLEAN RebarBandExists(
_In_ UINT BandID
);
VOID ToolbarLoadSettings(
VOID
);
VOID ToolbarResetSettings(
VOID
);
PWSTR ToolbarGetText(
_In_ INT CommandID
);
HBITMAP ToolbarGetImage(
_In_ INT CommandID
);
VOID ToolbarLoadButtonSettings(
VOID
);
VOID ToolbarSaveButtonSettings(
VOID
);
VOID ReBarLoadLayoutSettings(
VOID
);
VOID ReBarSaveLayoutSettings(
VOID
);
// main.c
HWND GetCurrentTreeNewHandle(
VOID
);
VOID ShowCustomizeMenu(
VOID
);
// options.c
VOID ShowOptionsDialog(
_In_opt_ HWND Parent
);
// filter.c
BOOLEAN WordMatchStringRef(
_In_ PPH_STRINGREF Text
);
BOOLEAN ProcessTreeFilterCallback(
_In_ PPH_TREENEW_NODE Node,
_In_opt_ PVOID Context
);
BOOLEAN ServiceTreeFilterCallback(
_In_ PPH_TREENEW_NODE Node,
_In_opt_ PVOID Context
);
BOOLEAN NetworkTreeFilterCallback(
_In_ PPH_TREENEW_NODE Node,
_In_opt_ PVOID Context
);
// searchbox.c
HWND CreateSearchControl(
_In_ UINT CmdId
);
typedef struct _EDIT_CONTEXT
{
UINT CommandID;
LONG CXWidth;
INT CXBorder;
INT ImageWidth;
INT ImageHeight;
HWND WindowHandle;
HFONT WindowFont;
HIMAGELIST ImageList;
HBRUSH BrushNormal;
HBRUSH BrushPushed;
HBRUSH BrushHot;
//COLORREF BackgroundColorRef;
union
{
ULONG Flags;
struct
{
ULONG Hot : 1;
ULONG Pushed : 1;
ULONG Spare : 30;
};
};
} EDIT_CONTEXT, *PEDIT_CONTEXT;
HBITMAP LoadImageFromResources(
_In_ UINT Width,
_In_ UINT Height,
_In_ PCWSTR Name
);
// graph.c
extern HWND CpuGraphHandle;
extern HWND MemGraphHandle;
extern HWND CommitGraphHandle;
extern HWND IoGraphHandle;
VOID ToolbarCreateGraphs(VOID);
VOID ToolbarUpdateGraphs(VOID);
VOID ToolbarUpdateGraphsInfo(LPNMHDR Header);
// statusbar.c
typedef struct _STATUSBAR_ITEM
{
ULONG Id;
} STATUSBAR_ITEM, *PSTATUSBAR_ITEM;
extern ULONG ProcessesUpdatedCount;
extern HWND StatusBarHandle;
extern PPH_LIST StatusBarItemList;
extern ULONG StatusBarItems[MAX_STATUSBAR_ITEMS];
VOID StatusBarLoadSettings(
VOID
);
VOID StatusBarSaveSettings(
VOID
);
VOID StatusBarResetSettings(
VOID
);
PWSTR StatusBarGetText(
_In_ ULONG CommandID
);
VOID StatusBarUpdate(
_In_ BOOLEAN ResetMaxWidths
);
VOID StatusBarShowMenu(
VOID
);
// customizetb.c
VOID ToolBarShowCustomizeDialog(
VOID
);
// customizesb.c
typedef enum _ID_STATUS
{
ID_STATUS_NONE,
ID_STATUS_CPUUSAGE,
ID_STATUS_COMMITCHARGE,
ID_STATUS_PHYSICALMEMORY,
ID_STATUS_NUMBEROFPROCESSES,
ID_STATUS_NUMBEROFTHREADS,
ID_STATUS_NUMBEROFHANDLES,
ID_STATUS_IO_RO,
ID_STATUS_IO_W,
ID_STATUS_MAX_CPU_PROCESS,
ID_STATUS_MAX_IO_PROCESS,
ID_STATUS_NUMBEROFVISIBLEITEMS,
ID_STATUS_NUMBEROFSELECTEDITEMS,
ID_STATUS_INTERVALSTATUS,
ID_STATUS_FREEMEMORY
} ID_STATUS;
VOID StatusBarShowCustomizeDialog(
VOID
);
// Shared by customizetb.c and customizesb.c
typedef struct _BUTTON_CONTEXT
{
INT IdCommand;
INT IdBitmap;
union
{
ULONG Flags;
struct
{
ULONG IsVirtual : 1;
ULONG IsRemovable : 1;
ULONG IsSeparator : 1;
ULONG Spare : 29;
};
};
} BUTTON_CONTEXT, *PBUTTON_CONTEXT;
typedef struct _CUSTOMIZE_CONTEXT
{
HWND DialogHandle;
HWND AvailableListHandle;
HWND CurrentListHandle;
HWND MoveUpButtonHandle;
HWND MoveDownButtonHandle;
HWND AddButtonHandle;
HWND RemoveButtonHandle;
INT BitmapWidth;
HFONT FontHandle;
HIMAGELIST ImageListHandle;
} CUSTOMIZE_CONTEXT, *PCUSTOMIZE_CONTEXT;
#endif