PPH_STRING PhGetTreeNewText( __in HWND TreeNewHandle, __reserved ULONG Reserved ) { PH_STRING_BUILDER stringBuilder; PULONG displayToId; ULONG rows; ULONG columns; ULONG i; ULONG j; PhMapDisplayIndexTreeNew(TreeNewHandle, &displayToId, NULL, &columns); rows = TreeNew_GetFlatNodeCount(TreeNewHandle); PhInitializeStringBuilder(&stringBuilder, 0x100); for (i = 0; i < rows; i++) { PH_TREENEW_GET_CELL_TEXT getCellText; getCellText.Node = TreeNew_GetFlatNode(TreeNewHandle, i); assert(getCellText.Node); if (!getCellText.Node->Selected) continue; for (j = 0; j < columns; j++) { getCellText.Id = displayToId[j]; PhInitializeEmptyStringRef(&getCellText.Text); TreeNew_GetCellText(TreeNewHandle, &getCellText); PhAppendStringBuilderEx(&stringBuilder, getCellText.Text.Buffer, getCellText.Text.Length); PhAppendStringBuilder2(&stringBuilder, L", "); } // Remove the trailing comma and space. if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 2, 2); PhAppendStringBuilder2(&stringBuilder, L"\r\n"); } PhFree(displayToId); return PhFinalStringBuilderString(&stringBuilder); }
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]); } }
PPH_LIST PhGetGenericTreeNewLines( __in HWND TreeNewHandle, __in ULONG Mode ) { PH_AUTO_POOL autoPool; PPH_LIST lines; ULONG rows; ULONG columns; ULONG numberOfNodes; PULONG displayToId; PWSTR *displayToText; PPH_STRING **table; ULONG i; ULONG j; PhInitializeAutoPool(&autoPool); numberOfNodes = TreeNew_GetFlatNodeCount(TreeNewHandle); rows = numberOfNodes + 1; PhMapDisplayIndexTreeNew(TreeNewHandle, &displayToId, &displayToText, &columns); PhaCreateTextTable(&table, rows, columns); for (i = 0; i < columns; i++) table[0][i] = PhaCreateString(displayToText[i]); for (i = 0; i < numberOfNodes; i++) { PPH_TREENEW_NODE node; node = TreeNew_GetFlatNode(TreeNewHandle, i); if (node) { for (j = 0; j < columns; j++) { PH_TREENEW_GET_CELL_TEXT getCellText; getCellText.Node = node; getCellText.Id = displayToId[j]; PhInitializeEmptyStringRef(&getCellText.Text); TreeNew_GetCellText(TreeNewHandle, &getCellText); table[i + 1][j] = PhaCreateStringEx(getCellText.Text.Buffer, getCellText.Text.Length); } } else { for (j = 0; j < columns; j++) { table[i + 1][j] = PHA_DEREFERENCE(PhReferenceEmptyString()); } } } PhFree(displayToText); PhFree(displayToId); lines = PhaFormatTextTable(table, rows, columns, Mode); PhDeleteAutoPool(&autoPool); return lines; }
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. windowPoint.x = GET_X_LPARAM(lParam); windowPoint.y = GET_Y_LPARAM(lParam); // Get the position of the inserted button. GetWindowRect(hWnd, &windowRect); 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. windowPoint.x = GET_X_LPARAM(lParam); windowPoint.y = GET_Y_LPARAM(lParam); // Get the position of the inserted button. GetWindowRect(hWnd, &windowRect); 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. windowPoint.x = GET_X_LPARAM(lParam); windowPoint.y = GET_Y_LPARAM(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); // 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. windowPoint.x = GET_X_LPARAM(lParam); windowPoint.y = GET_Y_LPARAM(lParam); // 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)) { if (!context->Hot) { TRACKMOUSEEVENT trackMouseEvent = { sizeof(TRACKMOUSEEVENT) }; trackMouseEvent.dwFlags = TME_LEAVE | TME_NONCLIENT; trackMouseEvent.hwndTrack = hWnd; 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. windowPoint.x = GET_X_LPARAM(lParam); windowPoint.y = GET_Y_LPARAM(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); // 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); }