Wat wilde ik, ik wil een programma wat zich in de startbalk nestelt (zoals een widget) links van de icon tray, rechts op het startmenu. Het programma moet een aantal statistieken laten zien (internet snelheid, hdd snelheid, cpu en mem gebruik)quote:TrafficMonitor / XMeters is een lichte systeemmonitor voor Windows die real-time netwerk-, CPU-, geheugen-, schijf- en GPU-gebruik toont via taakbalk- of bureaubladwidgets, met aanpasbare meters en waarschuwingen.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | using System; using System.Drawing; using System.Linq; using System.Windows.Forms; using System.Net.NetworkInformation; using System.Diagnostics; using System.Runtime.InteropServices; using System.Collections.Generic; namespace TaskbarMonitor { public partial class Form1 : Form { // Metrics private float cpuUsage = 0; private float memUsage = 0; private float uploadAvg = 0; private float downloadAvg = 0; private float diskReadAvg = 0; private float diskWriteAvg = 0; private PerformanceCounter cpuCounter; private PerformanceCounter memCounter; private PerformanceCounter diskReadCounter; private PerformanceCounter diskWriteCounter; private long prevBytesSent = 0; private long prevBytesReceived = 0; // Rolling queues for averaging private Queue<float> uploadSamples = new Queue<float>(); private Queue<float> downloadSamples = new Queue<float>(); private Queue<float> readSamples = new Queue<float>(); private Queue<float> writeSamples = new Queue<float>(); private const int sampleInterval = 100; // 100 ms private const int samplesToAverage = 10; // average over 1 second private System.Windows.Forms.Timer refreshTimer; private System.Windows.Forms.Timer topMostTimer; private Color textColor = Color.White; // Celbreedtes: icoon, waarde, icoon, waarde, icoon, waarde private readonly int[] cellWidths = { 15, 60, 15, 60, 25, 49 }; // pixels public Form1() { InitializeComponent(); this.FormBorderStyle = FormBorderStyle.None; this.ShowInTaskbar = false; this.TopMost = true; this.BackColor = Color.Black; // use solid background for stable clicks this.StartPosition = FormStartPosition.Manual; this.Load += Form1_Load; cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); memCounter = new PerformanceCounter("Memory", "% Committed Bytes In Use"); diskReadCounter = new PerformanceCounter("PhysicalDisk", "Disk Read Bytes/sec", "_Total"); diskWriteCounter = new PerformanceCounter("PhysicalDisk", "Disk Write Bytes/sec", "_Total"); } protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; int WS_EX_TOPMOST = 0x00000008; int WS_EX_TOOLWINDOW = 0x00000080; // hide from Alt+Tab cp.ExStyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW; return cp; } } private void Form1_Load(object? sender, EventArgs e) { Rectangle taskbarRect = GetTaskbarBounds(); Rectangle trayRect = GetTrayBounds(); int width = cellWidths.Sum(); int height = taskbarRect.Height; int x = trayRect.Left - width; int y = taskbarRect.Top; this.Location = new Point(x, y); this.Size = new Size(width, height); this.TopMost = true; // Force TopMost continuously topMostTimer = new System.Windows.Forms.Timer(); topMostTimer.Interval = 500; topMostTimer.Tick += (s, ev) => this.TopMost = true; topMostTimer.Start(); // Initial network snapshot prevBytesSent = NetworkInterface.GetAllNetworkInterfaces() .Where(n => n.OperationalStatus == OperationalStatus.Up) .Sum(n => n.GetIPv4Statistics().BytesSent); prevBytesReceived = NetworkInterface.GetAllNetworkInterfaces() .Where(n => n.OperationalStatus == OperationalStatus.Up) .Sum(n => n.GetIPv4Statistics().BytesReceived); // Refresh timer refreshTimer = new System.Windows.Forms.Timer(); refreshTimer.Interval = sampleInterval; refreshTimer.Tick += RefreshTimer_Tick; refreshTimer.Start(); } private void RefreshTimer_Tick(object? sender, EventArgs e) { long totalSent = NetworkInterface.GetAllNetworkInterfaces() .Where(n => n.OperationalStatus == OperationalStatus.Up) .Sum(n => n.GetIPv4Statistics().BytesSent); long totalReceived = NetworkInterface.GetAllNetworkInterfaces() .Where(n => n.OperationalStatus == OperationalStatus.Up) .Sum(n => n.GetIPv4Statistics().BytesReceived); float deltaUpload = (totalSent - prevBytesSent) / (float)sampleInterval * 1000f; float deltaDownload = (totalReceived - prevBytesReceived) / (float)sampleInterval * 1000f; prevBytesSent = totalSent; prevBytesReceived = totalReceived; EnqueueSample(uploadSamples, deltaUpload); EnqueueSample(downloadSamples, deltaDownload); uploadAvg = uploadSamples.Average(); downloadAvg = downloadSamples.Average(); float readCurrent = diskReadCounter.NextValue(); float writeCurrent = diskWriteCounter.NextValue(); EnqueueSample(readSamples, readCurrent); EnqueueSample(writeSamples, writeCurrent); diskReadAvg = readSamples.Average(); diskWriteAvg = writeSamples.Average(); cpuUsage = cpuCounter.NextValue(); memUsage = memCounter.NextValue(); this.Invalidate(); } private void EnqueueSample(Queue<float> queue, float value) { queue.Enqueue(value); if (queue.Count > samplesToAverage) queue.Dequeue(); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; Font font = new Font("Segoe UI", 9, FontStyle.Regular); string FormatSpeed(float speed) { float value; string unit; if (speed < 1024) { value = speed; unit = "B/s"; } else if (speed < 1024 * 1024) { value = speed / 1024f; unit = "K/s"; } else if (speed < 1024 * 1024 * 1024) { value = speed / (1024f * 1024f); unit = "M/s"; } else { value = speed / (1024f * 1024f * 1024f); unit = "G/s"; } return (value >= 100f) ? $"{Math.Floor(value)}{unit}" : $"{value:F1}{unit}"; } string[] row1Labels = { "↑", "R", "CPU" }; string[] row1Values = { FormatSpeed(uploadAvg), FormatSpeed(diskReadAvg), $"{cpuUsage:F0}%" }; string[] row2Labels = { "↓", "W", "MEM" }; string[] row2Values = { FormatSpeed(downloadAvg), FormatSpeed(diskWriteAvg), $"{memUsage:F0}%" }; float y = 10; float lineHeight = g.MeasureString("Test", font).Height; void DrawRow(string[] labels, string[] values) { float x = 0; for (int i = 0; i < 3; i++) { g.DrawString(labels[i], font, new SolidBrush(textColor), x, y); x += cellWidths[i * 2]; SizeF textSize = g.MeasureString(values[i], font); float valueX = x + cellWidths[i * 2 + 1] - textSize.Width; g.DrawString(values[i], font, new SolidBrush(textColor), valueX, y); x += cellWidths[i * 2 + 1]; } } DrawRow(row1Labels, row1Values); y += lineHeight; DrawRow(row2Labels, row2Values); } protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (e.Button == MouseButtons.Left) { try { Process.Start(new ProcessStartInfo("taskmgr.exe") { UseShellExecute = true }); } catch { } this.TopMost = true; // ensure still on top } else if (e.Button == MouseButtons.Right) { if (refreshTimer != null) { refreshTimer.Stop(); refreshTimer.Dispose(); } if (topMostTimer != null) { topMostTimer.Stop(); topMostTimer.Dispose(); } this.Close(); Application.Exit(); } } // --- Taskbar --- [DllImport("shell32.dll", CallingConvention = CallingConvention.StdCall)] static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA pData); const int ABM_GETTASKBARPOS = 0x00000005; [StructLayout(LayoutKind.Sequential)] struct APPBARDATA { public int cbSize; public IntPtr hWnd; public uint uCallbackMessage; public uint uEdge; public RECT rc; public int lParam; } [StructLayout(LayoutKind.Sequential)] struct RECT { public int left, top, right, bottom; } private Rectangle GetTaskbarBounds() { APPBARDATA data = new APPBARDATA(); data.cbSize = Marshal.SizeOf(data); SHAppBarMessage(ABM_GETTASKBARPOS, ref data); RECT r = data.rc; return new Rectangle(r.left, r.top, r.right - r.left, r.bottom - r.top); } [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string? lpszWindow); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); private Rectangle GetTrayBounds() { IntPtr trayWnd = FindWindow("Shell_TrayWnd", null); if (trayWnd == IntPtr.Zero) return Rectangle.Empty; IntPtr trayNotify = FindWindowEx(trayWnd, IntPtr.Zero, "TrayNotifyWnd", null); if (trayNotify == IntPtr.Zero) return Rectangle.Empty; if (GetWindowRect(trayNotify, out RECT r)) return new Rectangle(r.left, r.top, r.right - r.left, r.bottom - r.top); return Rectangle.Empty; } } } |
Hartsikke fijn dat je het progje deelt; Top!quote:Het programma moet een aantal statistieken laten zien (internet snelheid, hdd snelheid, cpu en mem gebruik)
Correct, maar dan moet ik taakbeheer standaard open hebben. Nu zie ik deze statistieken altijd!quote:Op zaterdag 28 februari 2026 17:30 schreef gepromoveerT het volgende:
[..]
Hartsikke fijn dat je het progje deelt; Top!
Die statistieken kan je overigens ook verkrijgen met Taakbeheer/Prestaties, wat overigens niks afdoet aan jouw werkt.
Ook top. Vroeger had Nvidia zo'n progje. Overigens... Taakbeheer aan de taakbalk vastzettenquote:Op zaterdag 28 februari 2026 18:45 schreef Chandler het volgende:
[..]
Correct, maar dan moet ik taakbeheer standaard open hebben. Nu zie ik deze statistieken altijd!
Ga het hierna verder uitbouwen naar daadwerkelijke cloud omgevingen. Nu draait het nog allemaal lokaal.quote:A local Delta Lake medallion architecture pipeline built with PySpark and delta-spark, running in Docker. Ingests retail sales CSV files and processes them through bronze, silver, and gold layers.
Built as a portfolio project to demonstrate modern data lakehouse patterns — designed to be extended to cloud storage (ADLS, S3) or Databricks with minimal changes.
|
|
| Forum Opties | |
|---|---|
| Forumhop: | |
| Hop naar: | |