コード例 #1
0
ファイル: gpuprprp.c プロジェクト: andyvand/ProcessHacker
static VOID GpuPropUpdateGraphs(
    _In_ PET_GPU_CONTEXT Context
    )
{
    Context->GpuGraphState.Valid = FALSE;
    Context->GpuGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->GpuGraphHandle, 1);
    Graph_Draw(Context->GpuGraphHandle);
    Graph_UpdateTooltip(Context->GpuGraphHandle);
    InvalidateRect(Context->GpuGraphHandle, NULL, FALSE);

    Context->MemoryGraphState.Valid = FALSE;
    Context->MemoryGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->MemGraphHandle, 1);
    Graph_Draw(Context->MemGraphHandle);
    Graph_UpdateTooltip(Context->MemGraphHandle);
    InvalidateRect(Context->MemGraphHandle, NULL, FALSE);

    Context->MemorySharedGraphState.Valid = FALSE;
    Context->MemorySharedGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->SharedGraphHandle, 1);
    Graph_Draw(Context->SharedGraphHandle);
    Graph_UpdateTooltip(Context->SharedGraphHandle);
    InvalidateRect(Context->SharedGraphHandle, NULL, FALSE);
}
コード例 #2
0
ファイル: gpugraph.c プロジェクト: simon734/processhacker2
VOID NvGpuUpdateGraphs(
    VOID
    )
{
    GpuGraphState.Valid = FALSE;
    GpuGraphState.TooltipIndex = -1;
    Graph_MoveGrid(GpuGraphHandle, 1);
    Graph_Draw(GpuGraphHandle);
    Graph_UpdateTooltip(GpuGraphHandle);
    InvalidateRect(GpuGraphHandle, NULL, FALSE);

    MemGraphState.Valid = FALSE;
    MemGraphState.TooltipIndex = -1;
    Graph_MoveGrid(MemGraphHandle, 1);
    Graph_Draw(MemGraphHandle);
    Graph_UpdateTooltip(MemGraphHandle);
    InvalidateRect(MemGraphHandle, NULL, FALSE);

    SharedGraphState.Valid = FALSE;
    SharedGraphState.TooltipIndex = -1;
    Graph_MoveGrid(SharedGraphHandle, 1);
    Graph_Draw(SharedGraphHandle);
    Graph_UpdateTooltip(SharedGraphHandle);
    InvalidateRect(SharedGraphHandle, NULL, FALSE);

    BusGraphState.Valid = FALSE;
    BusGraphState.TooltipIndex = -1;
    Graph_MoveGrid(BusGraphHandle, 1);
    Graph_Draw(BusGraphHandle);
    Graph_UpdateTooltip(BusGraphHandle);
    InvalidateRect(BusGraphHandle, NULL, FALSE);
}
コード例 #3
0
ファイル: gpusys.c プロジェクト: john-peterson/processhacker
VOID EtpUpdateGpuGraphs(
    VOID
    )
{
    GpuGraphState.Valid = FALSE;
    GpuGraphState.TooltipIndex = -1;
    Graph_MoveGrid(GpuGraphHandle, 1);
    Graph_Draw(GpuGraphHandle);
    Graph_UpdateTooltip(GpuGraphHandle);
    InvalidateRect(GpuGraphHandle, NULL, FALSE);

    DedicatedGraphState.Valid = FALSE;
    DedicatedGraphState.TooltipIndex = -1;
    Graph_MoveGrid(DedicatedGraphHandle, 1);
    Graph_Draw(DedicatedGraphHandle);
    Graph_UpdateTooltip(DedicatedGraphHandle);
    InvalidateRect(DedicatedGraphHandle, NULL, FALSE);

    SharedGraphState.Valid = FALSE;
    SharedGraphState.TooltipIndex = -1;
    Graph_MoveGrid(SharedGraphHandle, 1);
    Graph_Draw(SharedGraphHandle);
    Graph_UpdateTooltip(SharedGraphHandle);
    InvalidateRect(SharedGraphHandle, NULL, FALSE);
}
コード例 #4
0
static VOID NvGpuUpdateGraphs(
    _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context
    )
{
    Context->GpuGraphState.Valid = FALSE;
    Context->GpuGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->GpuGraphHandle, 1);
    Graph_Draw(Context->GpuGraphHandle);
    Graph_UpdateTooltip(Context->GpuGraphHandle);
    InvalidateRect(Context->GpuGraphHandle, NULL, FALSE);

    Context->MemGraphState.Valid = FALSE;
    Context->MemGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->MemGraphHandle, 1);
    Graph_Draw(Context->MemGraphHandle);
    Graph_UpdateTooltip(Context->MemGraphHandle);
    InvalidateRect(Context->MemGraphHandle, NULL, FALSE);

    Context->SharedGraphState.Valid = FALSE;
    Context->SharedGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->SharedGraphHandle, 1);
    Graph_Draw(Context->SharedGraphHandle);
    Graph_UpdateTooltip(Context->SharedGraphHandle);
    InvalidateRect(Context->SharedGraphHandle, NULL, FALSE);

    Context->BusGraphState.Valid = FALSE;
    Context->BusGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->BusGraphHandle, 1);
    Graph_Draw(Context->BusGraphHandle);
    Graph_UpdateTooltip(Context->BusGraphHandle);
    InvalidateRect(Context->BusGraphHandle, NULL, FALSE);
}
コード例 #5
0
ファイル: etwprprp.c プロジェクト: PKRoma/ProcessHacker
VOID EtwDiskNetworkUpdateGraphs(
    _In_ PET_DISKNET_CONTEXT Context
    )
{
    Context->DiskGraphState.Valid = FALSE;
    Context->DiskGraphState.TooltipIndex = ULONG_MAX;
    Graph_MoveGrid(Context->DiskGraphHandle, 1);
    Graph_Draw(Context->DiskGraphHandle);
    Graph_UpdateTooltip(Context->DiskGraphHandle);
    InvalidateRect(Context->DiskGraphHandle, NULL, FALSE);

    Context->NetworkGraphState.Valid = FALSE;
    Context->NetworkGraphState.TooltipIndex = ULONG_MAX;
    Graph_MoveGrid(Context->NetworkGraphHandle, 1);
    Graph_Draw(Context->NetworkGraphHandle);
    Graph_UpdateTooltip(Context->NetworkGraphHandle);
    InvalidateRect(Context->NetworkGraphHandle, NULL, FALSE);
}
コード例 #6
0
ファイル: sysscmem.c プロジェクト: poizan42/processhacker2
VOID PhSipUpdateMemoryGraphs(
    VOID
    )
{
    CommitGraphState.Valid = FALSE;
    CommitGraphState.TooltipIndex = -1;
    Graph_MoveGrid(CommitGraphHandle, 1);
    Graph_Draw(CommitGraphHandle);
    Graph_UpdateTooltip(CommitGraphHandle);
    InvalidateRect(CommitGraphHandle, NULL, FALSE);

    PhysicalGraphState.Valid = FALSE;
    PhysicalGraphState.TooltipIndex = -1;
    Graph_MoveGrid(PhysicalGraphHandle, 1);
    Graph_Draw(PhysicalGraphHandle);
    Graph_UpdateTooltip(PhysicalGraphHandle);
    InvalidateRect(PhysicalGraphHandle, NULL, FALSE);
}
コード例 #7
0
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);
    }
}
コード例 #8
0
ファイル: ping.c プロジェクト: lei720/processhacker2
static VOID PhNetworkPingUpdateGraph(
    _In_ PNETWORK_OUTPUT_CONTEXT Context
    )
{
    Context->PingGraphState.Valid = FALSE;
    Context->PingGraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->PingGraphHandle, 1);
    Graph_Draw(Context->PingGraphHandle);
    Graph_UpdateTooltip(Context->PingGraphHandle);
    InvalidateRect(Context->PingGraphHandle, NULL, FALSE);
}
コード例 #9
0
ファイル: graph.c プロジェクト: xiaowei0516/processhacker
static VOID NetAdapterUpdateGraphs(
    _Inout_ PPH_NETADAPTER_SYSINFO_CONTEXT Context
    )
{
    Context->GraphState.Valid = FALSE;
    Context->GraphState.TooltipIndex = -1;
    Graph_MoveGrid(Context->GraphHandle, 1);
    Graph_Draw(Context->GraphHandle);
    Graph_UpdateTooltip(Context->GraphHandle);
    InvalidateRect(Context->GraphHandle, NULL, FALSE);
}
コード例 #10
0
VOID PhSipUpdateCpuGraphs(
    VOID
    )
{
    ULONG i;

    CpuGraphState.Valid = FALSE;
    CpuGraphState.TooltipIndex = -1;
    Graph_MoveGrid(CpuGraphHandle, 1);
    Graph_Draw(CpuGraphHandle);
    Graph_UpdateTooltip(CpuGraphHandle);
    InvalidateRect(CpuGraphHandle, NULL, FALSE);

    for (i = 0; i < NumberOfProcessors; i++)
    {
        CpusGraphState[i].Valid = FALSE;
        CpusGraphState[i].TooltipIndex = -1;
        Graph_MoveGrid(CpusGraphHandle[i], 1);
        Graph_Draw(CpusGraphHandle[i]);
        Graph_UpdateTooltip(CpusGraphHandle[i]);
        InvalidateRect(CpusGraphHandle[i], NULL, FALSE);
    }
}
コード例 #11
0
ファイル: gpunodes.c プロジェクト: lei720/processhacker2
INT_PTR CALLBACK EtpGpuNodesDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            ULONG i;
            HFONT font;
            PPH_STRING nodeString;
            RECT labelRect;
            RECT tempRect;
            ULONG numberOfRows;
            ULONG numberOfColumns;

            WindowHandle = hwndDlg;
            PhCenterWindow(hwndDlg, GetParent(hwndDlg));

            PhInitializeLayoutManager(&LayoutManager, hwndDlg);
            PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
            LayoutMargin = PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_LAYOUT), NULL, PH_ANCHOR_ALL)->Margin;

            PhRegisterCallback(&PhProcessesUpdatedEvent, ProcessesUpdatedCallback, NULL, &ProcessesUpdatedCallbackRegistration);

            GraphHandle = PhAllocate(sizeof(HWND) * EtGpuTotalNodeCount);
            CheckBoxHandle = PhAllocate(sizeof(HWND) * EtGpuTotalNodeCount);
            GraphState = PhAllocate(sizeof(PH_GRAPH_STATE) * EtGpuTotalNodeCount);

            font = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);

            for (i = 0; i < EtGpuTotalNodeCount; i++)
            {
                nodeString = PhFormatString(L"Node %lu", i);

                GraphHandle[i] = CreateWindow(
                    PH_GRAPH_CLASSNAME,
                    NULL,
                    WS_VISIBLE | WS_CHILD | WS_BORDER,
                    0,
                    0,
                    3,
                    3,
                    hwndDlg,
                    NULL,
                    NULL,
                    NULL
                    );
                Graph_SetTooltip(GraphHandle[i], TRUE);
                CheckBoxHandle[i] = CreateWindow(
                    WC_BUTTON,
                    nodeString->Buffer,
                    WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX,
                    0,
                    0,
                    3,
                    3,
                    hwndDlg,
                    NULL,
                    NULL,
                    NULL
                    );
                SendMessage(CheckBoxHandle[i], WM_SETFONT, (WPARAM)font, FALSE);
                PhInitializeGraphState(&GraphState[i]);

                PhDereferenceObject(nodeString);
            }

            // Calculate the minimum size.

            numberOfRows = (ULONG)sqrt(EtGpuTotalNodeCount);
            numberOfColumns = (EtGpuTotalNodeCount + numberOfRows - 1) / numberOfRows;

            MinimumSize.left = 0;
            MinimumSize.top = 0;
            MinimumSize.right = 45;
            MinimumSize.bottom = 60;
            MapDialogRect(hwndDlg, &MinimumSize);
            MinimumSize.right += (MinimumSize.right + GRAPH_PADDING) * numberOfColumns;
            MinimumSize.bottom += (MinimumSize.bottom + GRAPH_PADDING) * numberOfRows;

            GetWindowRect(GetDlgItem(hwndDlg, IDC_INSTRUCTION), &labelRect);
            MapWindowPoints(NULL, hwndDlg, (POINT *)&labelRect, 2);
            labelRect.right += GetSystemMetrics(SM_CXFRAME) * 2;

            tempRect.left = 0;
            tempRect.top = 0;
            tempRect.right = 7;
            tempRect.bottom = 0;
            MapDialogRect(hwndDlg, &tempRect);
            labelRect.right += tempRect.right;

            if (MinimumSize.right < labelRect.right)
                MinimumSize.right = labelRect.right;

            SetWindowPos(hwndDlg, NULL, 0, 0, MinimumSize.right, MinimumSize.bottom, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);

            EtpLoadNodeBitMap();
        }
        break;
    case WM_DESTROY:
        {
            ULONG i;

            EtpSaveNodeBitMap();

            PhUnregisterCallback(&PhProcessesUpdatedEvent, &ProcessesUpdatedCallbackRegistration);

            for (i = 0; i < EtGpuTotalNodeCount; i++)
            {
                PhDeleteGraphState(&GraphState[i]);
            }

            PhFree(GraphHandle);
            PhFree(CheckBoxHandle);
            PhFree(GraphState);

            PhDeleteLayoutManager(&LayoutManager);
        }
        break;
    case WM_SIZE:
        {
            HDWP deferHandle;
            RECT clientRect;
            RECT checkBoxRect;
            ULONG numberOfRows = (ULONG)sqrt(EtGpuTotalNodeCount);
            ULONG numberOfColumns = (EtGpuTotalNodeCount + numberOfRows - 1) / numberOfRows;
            ULONG numberOfYPaddings = numberOfRows - 1;
            ULONG numberOfXPaddings = numberOfColumns - 1;
            ULONG cellHeight;
            ULONG y;
            ULONG cellWidth;
            ULONG x;
            ULONG i;

            PhLayoutManagerLayout(&LayoutManager);

            deferHandle = BeginDeferWindowPos(EtGpuTotalNodeCount * 2);

            GetClientRect(hwndDlg, &clientRect);
            GetClientRect(GetDlgItem(hwndDlg, IDC_EXAMPLE), &checkBoxRect);
            cellHeight = (clientRect.bottom - LayoutMargin.top - LayoutMargin.bottom - GRAPH_PADDING * numberOfYPaddings) / numberOfRows;
            y = LayoutMargin.top;
            i = 0;

            for (ULONG row = 0; row < numberOfRows; ++row)
            {
                // Give the last row the remaining space; the height we calculated might be off by a few
                // pixels due to integer division.
                if (row == numberOfRows - 1)
                    cellHeight = clientRect.bottom - LayoutMargin.bottom - y;

                cellWidth = (clientRect.right - LayoutMargin.left - LayoutMargin.right - GRAPH_PADDING * numberOfXPaddings) / numberOfColumns;
                x = LayoutMargin.left;

                for (ULONG column = 0; column < numberOfColumns; column++)
                {
                    // Give the last cell the remaining space; the width we calculated might be off by a few
                    // pixels due to integer division.
                    if (column == numberOfColumns - 1)
                        cellWidth = clientRect.right - LayoutMargin.right - x;

                    if (i < EtGpuTotalNodeCount)
                    {
                        deferHandle = DeferWindowPos(
                            deferHandle,
                            GraphHandle[i],
                            NULL,
                            x,
                            y,
                            cellWidth,
                            cellHeight - checkBoxRect.bottom - CHECKBOX_PADDING,
                            SWP_NOACTIVATE | SWP_NOZORDER
                            );
                        deferHandle = DeferWindowPos(
                            deferHandle,
                            CheckBoxHandle[i],
                            NULL,
                            x,
                            y + cellHeight - checkBoxRect.bottom,
                            cellWidth,
                            checkBoxRect.bottom,
                            SWP_NOACTIVATE | SWP_NOZORDER
                            );
                        i++;
                    }
                    x += cellWidth + GRAPH_PADDING;
                }

                y += cellHeight + GRAPH_PADDING;
            }

            EndDeferWindowPos(deferHandle);
        }
        break;
    case WM_SIZING:
        {
            PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDCANCEL:
            case IDOK:
                {
                    EndDialog(hwndDlg, IDOK);
                }
                break;
            }
        }
        break;
    case WM_NOTIFY:
        {
            NMHDR *header = (NMHDR *)lParam;
            ULONG i;

            switch (header->code)
            {
            case GCN_GETDRAWINFO:
                {
                    PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header;
                    PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;

                    drawInfo->Flags = PH_GRAPH_USE_GRID;
                    SysInfoParameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);

                    for (i = 0; i < EtGpuTotalNodeCount; i++)
                    {
                        if (header->hwndFrom == GraphHandle[i])
                        {
                            PhGraphStateGetDrawInfo(
                                &GraphState[i],
                                getDrawInfo,
                                EtGpuNodesHistory[i].Count
                                );

                            if (!GraphState[i].Valid)
                            {
                                PhCopyCircularBuffer_FLOAT(&EtGpuNodesHistory[i], GraphState[i].Data1, drawInfo->LineDataCount);
                                GraphState[i].Valid = TRUE;
                            }

                            break;
                        }
                    }
                }
                break;
            case GCN_GETTOOLTIPTEXT:
                {
                    PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)header;

                    if (getTooltipText->Index < getTooltipText->TotalCount)
                    {
                        for (i = 0; i < EtGpuTotalNodeCount; i++)
                        {
                            if (header->hwndFrom == GraphHandle[i])
                            {
                                if (GraphState[i].TooltipIndex != getTooltipText->Index)
                                {
                                    FLOAT gpu;
                                    ULONG adapterIndex;
                                    PPH_STRING adapterDescription;

                                    gpu = PhGetItemCircularBuffer_FLOAT(&EtGpuNodesHistory[i], getTooltipText->Index);
                                    adapterIndex = EtGetGpuAdapterIndexFromNodeIndex(i);

                                    if (adapterIndex != -1)
                                    {
                                        adapterDescription = EtGetGpuAdapterDescription(adapterIndex);

                                        if (adapterDescription && adapterDescription->Length == 0)
                                            PhClearReference(&adapterDescription);

                                        if (!adapterDescription)
                                            adapterDescription = PhFormatString(L"Adapter %lu", adapterIndex);
                                    }
                                    else
                                    {
                                        adapterDescription = PhCreateString(L"Unknown Adapter");
                                    }

                                    PhMoveReference(&GraphState[i].TooltipText, PhFormatString(
                                        L"Node %lu on %s\n%.2f%%\n%s",
                                        i,
                                        adapterDescription->Buffer,
                                        gpu * 100,
                                        ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
                                        ));
                                    PhDereferenceObject(adapterDescription);
                                }

                                getTooltipText->Text = GraphState[i].TooltipText->sr;

                                break;
                            }
                        }
                    }
                }
                break;
            }
        }
        break;
    case UPDATE_MSG:
        {
            ULONG i;

            for (i = 0; i < EtGpuTotalNodeCount; i++)
            {
                GraphState[i].Valid = FALSE;
                GraphState[i].TooltipIndex = -1;
                Graph_MoveGrid(GraphHandle[i], 1);
                Graph_Draw(GraphHandle[i]);
                Graph_UpdateTooltip(GraphHandle[i]);
                InvalidateRect(GraphHandle[i], NULL, FALSE);
            }
        }
        break;
    }

    return FALSE;
}
コード例 #12
0
ファイル: output.c プロジェクト: john-peterson/processhacker
INT_PTR CALLBACK MainWndProc(
    __in HWND hwndDlg,
    __in UINT uMsg,
    __in WPARAM wParam,
    __in LPARAM lParam
    )
{
    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            // Add the Graphics card name to the Window Title.
            //PPH_STRING gpuname = GetDriverName();
            //PPH_STRING title = PhFormatString(L"Graphics Information (%s)", gpuname->Buffer);

            //SetWindowText(hwndDlg, title->Buffer);  

            //PhDereferenceObject(gpuname);
            //PhDereferenceObject(title);

            // We have already set the group boxes to have WS_EX_TRANSPARENT to fix
            // the drawing issue that arises when using WS_CLIPCHILDREN. However
            // in removing the flicker from the graphs the group boxes will now flicker.
            // It's a good tradeoff since no one stares at the group boxes.
            PhSetWindowStyle(hwndDlg, WS_CLIPCHILDREN, WS_CLIPCHILDREN);
         
            PhCenterWindow(hwndDlg, PhMainWndHandle);
            
            PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg);
  
            PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
            PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);

            PhLoadWindowPlacementFromSetting(SETTING_NAME_GFX_WINDOW_POSITION, SETTING_NAME_GFX_WINDOW_SIZE, hwndDlg);

            PhInitializeGraphState(&GpuGraphState);
            PhInitializeGraphState(&CoreGraphState);
            PhInitializeGraphState(&MemGraphState);

            // TEMP
            if (GpuHistory.Count == 0)
            {
                PhInitializeCircularBuffer_FLOAT(&GpuHistory, PhGetIntegerSetting(L"SampleCount"));
                PhInitializeCircularBuffer_FLOAT(&CoreHistory, PhGetIntegerSetting(L"SampleCount"));
                PhInitializeCircularBuffer_ULONG(&MemHistory, PhGetIntegerSetting(L"SampleCount"));
            }

            GpuGraphHandle = CreateWindow(
                PH_GRAPH_CLASSNAME,
                NULL,
                WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
                0,
                0,
                3,
                3,
                hwndDlg,
                (HMENU)110,
                PluginInstance->DllBase,
                NULL
                );
            Graph_SetTooltip(GpuGraphHandle, TRUE);
            BringWindowToTop(GpuGraphHandle);
     
            CoreGraphHandle = CreateWindow(
                PH_GRAPH_CLASSNAME,
                NULL,
                WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
                0,
                0,
                3,
                3,
                hwndDlg,
                (HMENU)111,
                PluginInstance->DllBase,
                NULL
                );
            Graph_SetTooltip(CoreGraphHandle, TRUE);
            BringWindowToTop(CoreGraphHandle);

            MemGraphHandle = CreateWindow(
                PH_GRAPH_CLASSNAME,
                NULL,
                WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
                0,
                0,
                3,
                3,
                hwndDlg,
                (HMENU)109,
                PluginInstance->DllBase,
                NULL
                );
            Graph_SetTooltip(MemGraphHandle, TRUE);
            BringWindowToTop(MemGraphHandle);
      
            PhRegisterCallback(
				PhGetGeneralCallback(GeneralCallbackProcessesUpdated),
				GfxUpdateHandler,
				NULL,
				&ProcessesUpdatedRegistration
				);
        }
        break;
    case WM_DESTROY:
        {     
            // Unregister our callbacks.
            PhUnregisterCallback(&PhProcessesUpdatedEvent, &ProcessesUpdatedRegistration);

            // Save our settings.
            PhSetIntegerSetting(SETTING_NAME_GFX_ALWAYS_ON_TOP, AlwaysOnTop);
            PhSaveWindowPlacementToSetting(SETTING_NAME_GFX_WINDOW_POSITION, SETTING_NAME_GFX_WINDOW_SIZE, hwndDlg);

            // Reset our Window Management.
            PhDeleteLayoutManager(&WindowLayoutManager);

            // TEMP commented out.
            // Clear our buffers.
            //PhDeleteCircularBuffer_FLOAT(&GpuHistory);
            //PhDeleteCircularBuffer_ULONG(&MemHistory);

            // Clear our state.
            PhDeleteGraphState(&GpuGraphState);
            PhDeleteGraphState(&MemGraphState);

            // Quit.
            PostQuitMessage(0);
        }
        break;
    case WM_NOTIFY:
        {
            LPNMHDR header = (LPNMHDR)lParam;

            switch (header->code)
            {
            case GCN_GETDRAWINFO:
                {
                    PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header;
                    PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;

                    if (header->hwndFrom == GpuGraphHandle)
                    {
                        if (PhGetIntegerSetting(L"GraphShowText"))
                        {
                            HDC hdc;

                            PhSwapReference2(
                                &GpuGraphState.TooltipText,
                                PhFormatString(
                                L"%.0f%%",
                                CurrentGpuUsage * 100
                                ));

                            hdc = Graph_GetBufferedContext(GpuGraphHandle);
                            SelectObject(hdc, PhApplicationFont);
                            PhSetGraphText(hdc, drawInfo, &GpuGraphState.TooltipText->sr,
                                &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
                        }
                        else
                        {
                            drawInfo->Text.Buffer = NULL;
                        }

                        drawInfo->Flags = PH_GRAPH_USE_GRID;
                        drawInfo->LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel");
                        //drawInfo->LineColor2 = PhGetIntegerSetting(L"ColorCpuUser");
                        drawInfo->LineBackColor1 = PhHalveColorBrightness(drawInfo->LineColor1);
                        //drawInfo->LineBackColor2 = PhHalveColorBrightness(drawInfo->LineColor2);

                        PhGraphStateGetDrawInfo(
                            &GpuGraphState,
                            getDrawInfo,
                            GpuHistory.Count
                            );

                        if (!GpuGraphState.Valid)
                        {
                            PhCopyCircularBuffer_FLOAT(
                                &GpuHistory, 
                                getDrawInfo->DrawInfo->LineData1, 
                                getDrawInfo->DrawInfo->LineDataCount
                                );

                            GpuGraphState.Valid = TRUE;
                        }
                    }
                    else if (header->hwndFrom == MemGraphHandle)
                    {
                        if (PhGetIntegerSetting(L"GraphShowText"))
                        {
                            HDC hdc;

                            PhSwapReference2(&MemGraphState.TooltipText,
                                PhFormatString(
                                L"%s / %s (%.2f%%)",
                                PhaFormatSize(UInt32x32To64(CurrentMemUsage, 1024), -1)->Buffer,
                                PhaFormatSize(UInt32x32To64(MaxMemUsage, 1024), -1)->Buffer,
                                (FLOAT)CurrentMemUsage / MaxMemUsage * 100
                                ));

                            hdc = Graph_GetBufferedContext(MemGraphHandle);
                            SelectObject(hdc, PhApplicationFont);
                            PhSetGraphText(
                                hdc, 
                                drawInfo, 
                                &MemGraphState.TooltipText->sr,  
                                &NormalGraphTextMargin, 
                                &NormalGraphTextPadding, 
                                PH_ALIGN_TOP | PH_ALIGN_LEFT
                                );
                        }
                        else
                        {
                            drawInfo->Text.Buffer = NULL;
                        }

                        drawInfo->Flags = PH_GRAPH_USE_GRID;
                        drawInfo->LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel");
                        //drawInfo->LineColor2 = PhGetIntegerSetting(L"ColorCpuUser");
                        drawInfo->LineBackColor1 = PhHalveColorBrightness(drawInfo->LineColor1);
                        //drawInfo->LineBackColor2 = PhHalveColorBrightness(drawInfo->LineColor2);

                        PhGraphStateGetDrawInfo(
                            &MemGraphState,
                            getDrawInfo,
                            MemHistory.Count
                            );

                        if (!MemGraphState.Valid)
                        {
                            ULONG i = 0;

                            for (i = 0; i < drawInfo->LineDataCount; i++)
                            {
                                MemGraphState.Data1[i] =
                                    (FLOAT)PhGetItemCircularBuffer_ULONG(&MemHistory, i);
                            }

                            // Scale the data.
                            PhxfDivideSingle2U(
                                MemGraphState.Data1,
                                (FLOAT)MaxMemUsage,
                                drawInfo->LineDataCount
                                );

                            MemGraphState.Valid = TRUE;
                        }
                    }
                    else if (header->hwndFrom == CoreGraphHandle)
                    {
                        if (PhGetIntegerSetting(L"GraphShowText"))
                        {
                            HDC hdc;

                            PhSwapReference2(
                                &CoreGraphState.TooltipText,
                                PhFormatString(
                                L"%.0f%%",
                                CurrentCoreUsage * 100
                                ));

                            hdc = Graph_GetBufferedContext(CoreGraphHandle);
                            SelectObject(hdc, PhApplicationFont);
                            PhSetGraphText(hdc, drawInfo, &CoreGraphState.TooltipText->sr,
                                &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
                        }
                        else
                        {
                            drawInfo->Text.Buffer = NULL;
                        }

                        drawInfo->Flags = PH_GRAPH_USE_GRID;
                        drawInfo->LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel");
                        //drawInfo->LineColor2 = PhGetIntegerSetting(L"ColorCpuUser");
                        drawInfo->LineBackColor1 = PhHalveColorBrightness(drawInfo->LineColor1);
                        //drawInfo->LineBackColor2 = PhHalveColorBrightness(drawInfo->LineColor2);

                        PhGraphStateGetDrawInfo(
                            &CoreGraphState,
                            getDrawInfo,
                            CoreHistory.Count
                            );

                        if (!CoreGraphState.Valid)
                        {
                            PhCopyCircularBuffer_FLOAT(
                                &CoreHistory, 
                                getDrawInfo->DrawInfo->LineData1, 
                                getDrawInfo->DrawInfo->LineDataCount
                                );

                            CoreGraphState.Valid = TRUE;
                        }
                    }
                }
                break;
            case GCN_GETTOOLTIPTEXT:
                {
                    PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam;

                    if (getTooltipText->Index < getTooltipText->TotalCount)
                    {
                        if (header->hwndFrom == GpuGraphHandle)
                        {
                            if (GpuGraphState.TooltipIndex != getTooltipText->Index)
                            {
                                FLOAT usage;

                                usage = PhGetItemCircularBuffer_FLOAT(&GpuHistory, getTooltipText->Index);

                                PhSwapReference2(&GpuGraphState.TooltipText, PhFormatString(
                                    L"%.0f%%",
                                    usage * 100
                                    ));
                            }

                            getTooltipText->Text = GpuGraphState.TooltipText->sr;
                        }
                        else if (header->hwndFrom == MemGraphHandle)
                        {
                            if (MemGraphState.TooltipIndex != getTooltipText->Index)
                            {
                                ULONG usage;

                                usage = PhGetItemCircularBuffer_ULONG(&MemHistory, getTooltipText->Index);

                                PhSwapReference2(&MemGraphState.TooltipText,
                                    PhFormatString(
                                    L"%s / %s (%.2f%%)",
                                    PhaFormatSize(UInt32x32To64(usage, 1024), -1)->Buffer,
                                    PhaFormatSize(UInt32x32To64(MaxMemUsage, 1024), -1)->Buffer,
                                    (FLOAT)usage / MaxMemUsage * 100
                                    ));
                            }

                            getTooltipText->Text = MemGraphState.TooltipText->sr;
                        }
                        else if (header->hwndFrom == CoreGraphHandle)
                        {
                            if (CoreGraphState.TooltipIndex != getTooltipText->Index)
                            {
                                FLOAT usage;

                                usage = PhGetItemCircularBuffer_FLOAT(&CoreHistory, getTooltipText->Index);

                                PhSwapReference2(&CoreGraphState.TooltipText, 
                                    PhFormatString(
                                    L"%.0f%%",
                                    usage * 100
                                    ));
                            }

                            getTooltipText->Text = CoreGraphState.TooltipText->sr;
                        }
                    }
                }
                break;
            case GCN_MOUSEEVENT:
                {
                    PPH_GRAPH_MOUSEEVENT mouseEvent = (PPH_GRAPH_MOUSEEVENT)lParam;

                    if (mouseEvent->Message == WM_LBUTTONDBLCLK)
                    {
                        if (header->hwndFrom == GpuGraphHandle)
                        {
                            PhShowInformation(hwndDlg, L"Double clicked!");
                        }
                    }
                }
                break;
            }
        }
        break;
    case WM_SHOWWINDOW:
        {
            RECT margin;

            GfxPanelWindowHandle = CreateDialog(
                PluginInstance->DllBase,
                MAKEINTRESOURCE(IDD_SYSGFX_PANEL),
                hwndDlg,
                MainPanelDlgProc
                );

            SetWindowPos(
                GfxPanelWindowHandle, 
                NULL, 
                10, 0, 0, 0,
                SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOSIZE | SWP_NOZORDER
                );

            ShowWindow(GfxPanelWindowHandle, SW_SHOW);

            AlwaysOnTop = (BOOLEAN)PhGetIntegerSetting(SETTING_NAME_GFX_ALWAYS_ON_TOP);
            Button_SetCheck(GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), AlwaysOnTop ? BST_CHECKED : BST_UNCHECKED);
            GfxSetAlwaysOnTop();

            margin.left = 0;
            margin.top = 0;
            margin.right = 0;
            margin.bottom = 25;
            MapDialogRect(hwndDlg, &margin);

            PhAddLayoutItemEx(
                &WindowLayoutManager, 
                GfxPanelWindowHandle, 
                NULL, 
                PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT, 
                margin
                );

            SendMessage(hwndDlg, WM_SIZE, 0, 0);
            SendMessage(hwndDlg, WM_GFX_UPDATE, 0, 0);
        }
        break;
    case WM_SIZE:
        {                      
            HDWP deferHandle;
            HWND cpuGroupBox = GetDlgItem(hwndDlg, IDC_GROUPCONTROLLER);
            HWND diskGroupBox = GetDlgItem(hwndDlg, IDC_GROUPGPU);
            HWND networkGroupBox = GetDlgItem(hwndDlg, IDC_GROUPMEM);
            RECT clientRect;
            RECT panelRect;
            RECT margin = { 13, 13, 13, 13 };
            RECT innerMargin = { 10, 20, 10, 10 };
            LONG between = 3;
            LONG width;
            LONG height;

            PhLayoutManagerLayout(&WindowLayoutManager);

            GpuGraphState.Valid = FALSE;
            MemGraphState.Valid = FALSE;

            GetClientRect(hwndDlg, &clientRect);
            // Limit the rectangle bottom to the top of the panel.
            GetWindowRect(GfxPanelWindowHandle, &panelRect);
            MapWindowPoints(NULL, hwndDlg, (POINT *)&panelRect, 2);
            clientRect.bottom = panelRect.top;

            width = clientRect.right - margin.left - margin.right;
            height = (clientRect.bottom - margin.top - margin.bottom - between * 2) / 3;

            deferHandle = BeginDeferWindowPos(6);

            deferHandle = DeferWindowPos(deferHandle, diskGroupBox, NULL, margin.left, margin.top,  width, height, SWP_NOACTIVATE | SWP_NOZORDER);
            deferHandle = DeferWindowPos(
                deferHandle,
                GpuGraphHandle,
                NULL,
                margin.left + innerMargin.left,
                margin.top + innerMargin.top,
                width - innerMargin.left - innerMargin.right,
                height - innerMargin.top - innerMargin.bottom,
                SWP_NOACTIVATE | SWP_NOZORDER
                );

            deferHandle = DeferWindowPos(deferHandle, networkGroupBox, NULL, margin.left, margin.top + height + between, width, height, SWP_NOACTIVATE | SWP_NOZORDER);
            deferHandle = DeferWindowPos(
                deferHandle,
                MemGraphHandle,
                NULL,
                margin.left + innerMargin.left,
                margin.top + height + between + innerMargin.top,
                width - innerMargin.left - innerMargin.right,
                height - innerMargin.top - innerMargin.bottom,
                SWP_NOACTIVATE | SWP_NOZORDER
                );

            deferHandle = DeferWindowPos(deferHandle, cpuGroupBox, NULL, margin.left, margin.top + (height + between) * 2, width, height, SWP_NOACTIVATE | SWP_NOZORDER);
            deferHandle = DeferWindowPos(
                deferHandle,
                CoreGraphHandle,
                NULL,
                margin.left + innerMargin.left,
                margin.top + (height + between) * 2 + innerMargin.top,
                width - innerMargin.left - innerMargin.right,
                height - innerMargin.top - innerMargin.bottom,
                SWP_NOACTIVATE | SWP_NOZORDER
                );

            EndDeferWindowPos(deferHandle);
        }
        break;

    case WM_SIZING:
        {
            PhResizingMinimumSize((PRECT)lParam, wParam, 500, 400);
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDCANCEL:
            case IDOK:
                DestroyWindow(hwndDlg);
                break;
            case IDC_ALWAYSONTOP:
                {
                    AlwaysOnTop = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ALWAYSONTOP)) == BST_CHECKED;
                    GfxSetAlwaysOnTop();
                }
                break;
            }
        }
        break;
    case WM_GFX_ACTIVATE:
        {
            if (IsIconic(hwndDlg))
                ShowWindow(hwndDlg, SW_RESTORE);
            else
                ShowWindow(hwndDlg, SW_SHOW);

            SetForegroundWindow(hwndDlg);
        }
        break;
    case WM_GFX_UPDATE:
        {
            GetGfxUsages();
            GetGfxTemp();
            GetGfxClockSpeeds();

            GpuGraphState.Valid = FALSE;
            GpuGraphState.TooltipIndex = -1;
            Graph_MoveGrid(GpuGraphHandle, 1);
            Graph_Draw(GpuGraphHandle);
            Graph_UpdateTooltip(GpuGraphHandle);
            InvalidateRect(GpuGraphHandle, NULL, FALSE);

            CoreGraphState.Valid = FALSE;
            CoreGraphState.TooltipIndex = -1;
            Graph_MoveGrid(CoreGraphHandle, 1);
            Graph_Draw(CoreGraphHandle);
            Graph_UpdateTooltip(CoreGraphHandle);
            InvalidateRect(CoreGraphHandle, NULL, FALSE);

            MemGraphState.Valid = FALSE;
            MemGraphState.TooltipIndex = -1;
            Graph_MoveGrid(MemGraphHandle, 1);
            Graph_Draw(MemGraphHandle);
            Graph_UpdateTooltip(MemGraphHandle);
            InvalidateRect(MemGraphHandle, NULL, FALSE);

            SendMessage(GfxPanelWindowHandle, WM_GFX_PANEL_UPDATE, 0, 0);
        }
        break;
    }

    return FALSE;
}