INT_PTR CALLBACK WepWindowsPageProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PWINDOWS_CONTEXT context; LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { context->TreeNewHandle = GetDlgItem(hwndDlg, IDC_LIST); context->SearchBoxHandle = GetDlgItem(hwndDlg, IDC_SEARCHEDIT); PhCreateSearchControl(hwndDlg, context->SearchBoxHandle, L"Search Windows (Ctrl+K)"); WeInitializeWindowTree(hwndDlg, context->TreeNewHandle, &context->TreeContext); PhRegisterDialog(hwndDlg); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SEARCHEDIT), NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LIST), NULL, PH_ANCHOR_ALL); WepRefreshWindows(context); } break; case WM_SHOWWINDOW: { if (PhBeginPropPageLayout(hwndDlg, propPageContext)) PhEndPropPageLayout(hwndDlg, propPageContext); } break; case WM_DESTROY: { PhDeleteLayoutManager(&context->LayoutManager); PhUnregisterDialog(hwndDlg); WeDeleteWindowTree(&context->TreeContext); WepDeleteWindowSelector(&context->Selector); PhFree(context); } break; case WM_COMMAND: { switch (GET_WM_COMMAND_CMD(wParam, lParam)) { case EN_CHANGE: { PPH_STRING newSearchboxText; if (GET_WM_COMMAND_HWND(wParam, lParam) != context->SearchBoxHandle) break; newSearchboxText = PH_AUTO(PhGetWindowText(context->SearchBoxHandle)); if (!PhEqualString(context->TreeContext.SearchboxText, newSearchboxText, FALSE)) { PhSwapReference(&context->TreeContext.SearchboxText, newSearchboxText); if (!PhIsNullOrEmptyString(context->TreeContext.SearchboxText)) WeExpandAllWindowNodes(&context->TreeContext, TRUE); PhApplyTreeNewFilters(&context->TreeContext.FilterSupport); TreeNew_NodesStructured(context->TreeNewHandle); // PhInvokeCallback(&SearchChangedEvent, SearchboxText); } } break; } switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_REFRESH: WepRefreshWindows(context); break; case ID_SHOWCONTEXTMENU: { PPH_TREENEW_CONTEXT_MENU contextMenuEvent = (PPH_TREENEW_CONTEXT_MENU)lParam; PWE_WINDOW_NODE *windows; ULONG numberOfWindows; PPH_EMENU menu; PPH_EMENU selectedItem; WeGetSelectedWindowNodes( &context->TreeContext, &windows, &numberOfWindows ); if (numberOfWindows != 0) { menu = PhCreateEMenu(); PhLoadResourceEMenuItem(menu, PluginInstance->DllBase, MAKEINTRESOURCE(IDR_WINDOW), 0); PhInsertCopyCellEMenuItem(menu, ID_WINDOW_COPY, context->TreeNewHandle, contextMenuEvent->Column); PhSetFlagsEMenuItem(menu, ID_WINDOW_PROPERTIES, PH_EMENU_DEFAULT, PH_EMENU_DEFAULT); if (numberOfWindows == 1) { WINDOWPLACEMENT placement = { sizeof(placement) }; BYTE alpha; ULONG flags; ULONG i; ULONG id; // State GetWindowPlacement(windows[0]->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) PhSetFlagsEMenuItem(menu, ID_WINDOW_MINIMIZE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); else if (placement.showCmd == SW_MAXIMIZE) PhSetFlagsEMenuItem(menu, ID_WINDOW_MAXIMIZE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); else if (placement.showCmd == SW_NORMAL) PhSetFlagsEMenuItem(menu, ID_WINDOW_RESTORE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); // Visible PhSetFlagsEMenuItem(menu, ID_WINDOW_VISIBLE, PH_EMENU_CHECKED, (GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_VISIBLE) ? PH_EMENU_CHECKED : 0); // Enabled PhSetFlagsEMenuItem(menu, ID_WINDOW_ENABLED, PH_EMENU_CHECKED, !(GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_DISABLED) ? PH_EMENU_CHECKED : 0); // Always on Top PhSetFlagsEMenuItem(menu, ID_WINDOW_ALWAYSONTOP, PH_EMENU_CHECKED, (GetWindowLong(windows[0]->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST) ? PH_EMENU_CHECKED : 0); // Opacity if (GetLayeredWindowAttributes(windows[0]->WindowHandle, NULL, &alpha, &flags)) { if (!(flags & LWA_ALPHA)) alpha = 255; } else { alpha = 255; } if (alpha == 255) { id = ID_OPACITY_OPAQUE; } else { id = 0; // Due to integer division, we cannot use simple arithmetic to calculate which menu item to check. for (i = 0; i < 10; i++) { if (alpha == (BYTE)(255 * (i + 1) / 10)) { id = ID_OPACITY_10 + i; break; } } } if (id != 0) { PhSetFlagsEMenuItem(menu, id, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK); } } else { PhSetFlagsAllEMenuItems(menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); PhSetFlagsEMenuItem(menu, ID_WINDOW_COPY, PH_EMENU_DISABLED, 0); } selectedItem = PhShowEMenu( menu, hwndDlg, PH_EMENU_SHOW_SEND_COMMAND | PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, contextMenuEvent->Location.x, contextMenuEvent->Location.y ); if (selectedItem && selectedItem->Id != -1) { BOOLEAN handled = FALSE; handled = PhHandleCopyCellEMenuItem(selectedItem); } PhDestroyEMenu(menu); } } break; case ID_WINDOW_BRINGTOFRONT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { WINDOWPLACEMENT placement = { sizeof(placement) }; GetWindowPlacement(selectedNode->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); else SetForegroundWindow(selectedNode->WindowHandle); } } break; case ID_WINDOW_RESTORE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); } } break; case ID_WINDOW_MINIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MINIMIZE); } } break; case ID_WINDOW_MAXIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MAXIMIZE); } } break; case ID_WINDOW_CLOSE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { PostMessage(selectedNode->WindowHandle, WM_CLOSE, 0, 0); } } break; case ID_WINDOW_VISIBLE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (IsWindowVisible(selectedNode->WindowHandle)) { selectedNode->WindowVisible = FALSE; ShowWindowAsync(selectedNode->WindowHandle, SW_HIDE); } else { selectedNode->WindowVisible = TRUE; ShowWindowAsync(selectedNode->WindowHandle, SW_SHOW); } PhInvalidateTreeNewNode(&selectedNode->Node, TN_CACHE_COLOR); TreeNew_InvalidateNode(context->TreeNewHandle, &selectedNode->Node); } } break; case ID_WINDOW_ENABLED: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { EnableWindow(selectedNode->WindowHandle, !IsWindowEnabled(selectedNode->WindowHandle)); } } break; case ID_WINDOW_ALWAYSONTOP: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { LOGICAL topMost; topMost = GetWindowLong(selectedNode->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST; SetWindowPos(selectedNode->WindowHandle, topMost ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } } break; case ID_OPACITY_10: case ID_OPACITY_20: case ID_OPACITY_30: case ID_OPACITY_40: case ID_OPACITY_50: case ID_OPACITY_60: case ID_OPACITY_70: case ID_OPACITY_80: case ID_OPACITY_90: case ID_OPACITY_OPAQUE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ULONG opacity; opacity = ((ULONG)LOWORD(wParam) - ID_OPACITY_10) + 1; if (opacity == 10) { // Remove the WS_EX_LAYERED bit since it is not needed. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, 0); RedrawWindow(selectedNode->WindowHandle, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } else { // Add the WS_EX_LAYERED bit so opacity will work. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, WS_EX_LAYERED); SetLayeredWindowAttributes(selectedNode->WindowHandle, 0, (BYTE)(255 * opacity / 10), LWA_ALPHA); } } } break; case ID_WINDOW_HIGHLIGHT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (context->HighlightingWindow) { if (context->HighlightingWindowCount & 1) WeInvertWindowBorder(context->HighlightingWindow); } context->HighlightingWindow = selectedNode->WindowHandle; context->HighlightingWindowCount = 10; SetTimer(hwndDlg, 9, 100, NULL); } } break; case ID_WINDOW_GOTOTHREAD: { PWE_WINDOW_NODE selectedNode; PPH_PROCESS_ITEM processItem; PPH_PROCESS_PROPCONTEXT propContext; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (processItem = PhReferenceProcessItem(selectedNode->ClientId.UniqueProcess)) { if (propContext = PhCreateProcessPropContext(WE_PhMainWndHandle, processItem)) { PhSetSelectThreadIdProcessPropContext(propContext, selectedNode->ClientId.UniqueThread); PhShowProcessProperties(propContext); PhDereferenceObject(propContext); } PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"The process does not exist."); } } } break; case ID_WINDOW_PROPERTIES: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) WeShowWindowProperties(hwndDlg, selectedNode->WindowHandle); } break; case ID_WINDOW_COPY: { PPH_STRING text; text = PhGetTreeNewText(context->TreeNewHandle, 0); PhSetClipboardString(hwndDlg, &text->sr); PhDereferenceObject(text); } break; } } break; case WM_TIMER: { switch (wParam) { case 9: { WeInvertWindowBorder(context->HighlightingWindow); if (--context->HighlightingWindowCount == 0) KillTimer(hwndDlg, 9); } break; } } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_QUERYINITIALFOCUS: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LPARAM)GetDlgItem(hwndDlg, IDC_REFRESH)); return TRUE; } } break; } return FALSE; }
VOID RebarLoadSettings( VOID ) { if (ToolStatusConfig.ToolBarEnabled && !ToolBarImageList) { ToolBarImageSize.cx = GetSystemMetrics(SM_CXSMICON); ToolBarImageSize.cy = GetSystemMetrics(SM_CYSMICON); ToolBarImageList = ImageList_Create(ToolBarImageSize.cx, ToolBarImageSize.cy, ILC_COLOR32, 0, 0); HFONT newFont; if (newFont = ToolStatusGetTreeWindowFont()) { if (ToolStatusWindowFont) DeleteObject(ToolStatusWindowFont); ToolStatusWindowFont = newFont; } } if (ToolStatusConfig.ToolBarEnabled && !RebarHandle) { RebarHandle = CreateWindowEx( WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CCS_NODIVIDER | CCS_TOP | RBS_VARHEIGHT | RBS_AUTOSIZE, // CCS_NOPARENTALIGN CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, PhMainWndHandle, NULL, NULL, NULL ); ToolBarHandle = CreateWindowEx( 0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CCS_NOPARENTALIGN | CCS_NODIVIDER | TBSTYLE_FLAT | TBSTYLE_LIST | TBSTYLE_TRANSPARENT | TBSTYLE_TOOLTIPS | TBSTYLE_AUTOSIZE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, RebarHandle, NULL, NULL, NULL ); // Set the rebar info with no imagelist. SendMessage(RebarHandle, RB_SETBARINFO, 0, (LPARAM)&(REBARINFO){ sizeof(REBARINFO) }); // 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(); SendMessage(ToolBarHandle, WM_SETFONT, (WPARAM)ToolStatusWindowFont, FALSE); // Resize the toolbar. SendMessage(ToolBarHandle, TB_AUTOSIZE, 0, 0); // Inset the toolbar into the rebar control. ULONG toolbarButtonSize = (ULONG)SendMessage(ToolBarHandle, TB_GETBUTTONSIZE, 0, 0); RebarBandInsert(REBAR_BAND_ID_TOOLBAR, ToolBarHandle, LOWORD(toolbarButtonSize), HIWORD(toolbarButtonSize)); } if (ToolStatusConfig.SearchBoxEnabled && !SearchboxHandle) { SearchboxText = PhReferenceEmptyString(); ProcessTreeFilterEntry = PhAddTreeNewFilter(PhGetFilterSupportProcessTreeList(), ProcessTreeFilterCallback, NULL); ServiceTreeFilterEntry = PhAddTreeNewFilter(PhGetFilterSupportServiceTreeList(), ServiceTreeFilterCallback, NULL); NetworkTreeFilterEntry = PhAddTreeNewFilter(PhGetFilterSupportNetworkTreeList(), NetworkTreeFilterCallback, NULL); if (SearchboxHandle = 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 )) { PhCreateSearchControl(RebarHandle, SearchboxHandle, L"Search Processes (Ctrl+K)"); } } if (ToolStatusConfig.StatusBarEnabled && !StatusBarHandle) { 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 ); if (StatusBarHandle && PhGetIntegerSetting(L"EnableThemeSupport")) { PhInitializeWindowThemeStatusBar(StatusBarHandle); } } // 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, PH_SCALE_DPI(180), height); 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); } }