/[rtss_sdk]/trunk/Samples/SharedMemory/RTSSSharedMemorySample/RTSSSharedMemorySampleDlg.cpp
ViewVC logotype

Contents of /trunk/Samples/SharedMemory/RTSSSharedMemorySample/RTSSSharedMemorySampleDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Aug 8 11:41:35 2014 UTC (5 years, 1 month ago) by william
File size: 14887 byte(s)
initial commit of RTSS SDK (from 6.1.0.7305)
Available from: http://www.guru3d.com/files-details/rtss-rivatuner-statistics-server-download.html
1 // RTSSSharedMemorySampleDlg.cpp : implementation file
2 //
3 // created by Unwinder
4 /////////////////////////////////////////////////////////////////////////////
5 #include "stdafx.h"
6 #include "RTSSSharedMemory.h"
7 #include "RTSSSharedMemorySample.h"
8 #include "RTSSSharedMemorySampleDlg.h"
9 #include "GroupedString.h"
10 /////////////////////////////////////////////////////////////////////////////
11 #include <shlwapi.h>
12 #include <float.h>
13 #include <io.h>
14 /////////////////////////////////////////////////////////////////////////////
15 #ifdef _DEBUG
16 #define new DEBUG_NEW
17 #undef THIS_FILE
18 static char THIS_FILE[] = __FILE__;
19 #endif
20 /////////////////////////////////////////////////////////////////////////////
21 // CAboutDlg dialog used for App About
22 /////////////////////////////////////////////////////////////////////////////
23 class CAboutDlg : public CDialog
24 {
25 public:
26 CAboutDlg();
27
28 // Dialog Data
29 //{{AFX_DATA(CAboutDlg)
30 enum { IDD = IDD_ABOUTBOX };
31 //}}AFX_DATA
32
33 // ClassWizard generated virtual function overrides
34 //{{AFX_VIRTUAL(CAboutDlg)
35 protected:
36 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
37 //}}AFX_VIRTUAL
38
39 // Implementation
40 protected:
41 //{{AFX_MSG(CAboutDlg)
42 //}}AFX_MSG
43 DECLARE_MESSAGE_MAP()
44 };
45 /////////////////////////////////////////////////////////////////////////////
46 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
47 {
48 //{{AFX_DATA_INIT(CAboutDlg)
49 //}}AFX_DATA_INIT
50 }
51 /////////////////////////////////////////////////////////////////////////////
52 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
53 {
54 CDialog::DoDataExchange(pDX);
55 //{{AFX_DATA_MAP(CAboutDlg)
56 //}}AFX_DATA_MAP
57 }
58 /////////////////////////////////////////////////////////////////////////////
59 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
60 //{{AFX_MSG_MAP(CAboutDlg)
61 // No message handlers
62 //}}AFX_MSG_MAP
63 END_MESSAGE_MAP()
64 /////////////////////////////////////////////////////////////////////////////
65 // CRTSSSharedMemorySampleDlg dialog
66 /////////////////////////////////////////////////////////////////////////////
67 CRTSSSharedMemorySampleDlg::CRTSSSharedMemorySampleDlg(CWnd* pParent /*=NULL*/)
68 : CDialog(CRTSSSharedMemorySampleDlg::IDD, pParent)
69 {
70 //{{AFX_DATA_INIT(CRTSSSharedMemorySampleDlg)
71 //}}AFX_DATA_INIT
72 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
73
74 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
75
76 m_dwNumberOfProcessors = 0;
77 m_pNtQuerySystemInformation = NULL;
78 m_strStatus = "";
79 m_strInstallPath = "";
80
81 m_bMultiLineOutput = TRUE;
82 m_bConnected = FALSE;
83 }
84 /////////////////////////////////////////////////////////////////////////////
85 void CRTSSSharedMemorySampleDlg::DoDataExchange(CDataExchange* pDX)
86 {
87 CDialog::DoDataExchange(pDX);
88 //{{AFX_DATA_MAP(CRTSSSharedMemorySampleDlg)
89 //}}AFX_DATA_MAP
90 }
91 /////////////////////////////////////////////////////////////////////////////
92 BEGIN_MESSAGE_MAP(CRTSSSharedMemorySampleDlg, CDialog)
93 //{{AFX_MSG_MAP(CRTSSSharedMemorySampleDlg)
94 ON_WM_SYSCOMMAND()
95 ON_WM_PAINT()
96 ON_WM_QUERYDRAGICON()
97 ON_WM_TIMER()
98 ON_WM_DESTROY()
99 //}}AFX_MSG_MAP
100 END_MESSAGE_MAP()
101 /////////////////////////////////////////////////////////////////////////////
102 // CRTSSSharedMemorySampleDlg message handlers
103 /////////////////////////////////////////////////////////////////////////////
104 BOOL CRTSSSharedMemorySampleDlg::OnInitDialog()
105 {
106 CDialog::OnInitDialog();
107
108 // Add "About..." menu item to system menu.
109
110 // IDM_ABOUTBOX must be in the system command range.
111 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
112 ASSERT(IDM_ABOUTBOX < 0xF000);
113
114 CMenu* pSysMenu = GetSystemMenu(FALSE);
115 if (pSysMenu != NULL)
116 {
117 CString strAboutMenu;
118 strAboutMenu.LoadString(IDS_ABOUTBOX);
119 if (!strAboutMenu.IsEmpty())
120 {
121 pSysMenu->AppendMenu(MF_SEPARATOR);
122 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
123 }
124 }
125
126 // Set the icon for this dialog. The framework does this automatically
127 // when the application's main window is not a dialog
128 SetIcon(m_hIcon, TRUE); // Set big icon
129
130
131 CWnd* pPlaceholder = GetDlgItem(IDC_PLACEHOLDER);
132
133 if (pPlaceholder)
134 {
135 CRect rect;
136 pPlaceholder->GetClientRect(&rect);
137
138 if (!m_richEditCtrl.Create(WS_VISIBLE|ES_READONLY|ES_MULTILINE|ES_AUTOHSCROLL|WS_HSCROLL|ES_AUTOVSCROLL|WS_VSCROLL, rect, this, 0))
139 return FALSE;
140
141 m_font.CreateFont(-11, 0, 0, 0, FW_REGULAR, 0, 0, 0, BALTIC_CHARSET, 0, 0, 0, 0, "Courier New");
142 m_richEditCtrl.SetFont(&m_font);
143 }
144
145 //init CPU usage calculation related variables
146
147 SYSTEM_INFO info;
148 GetSystemInfo(&info);
149
150 m_dwNumberOfProcessors = info.dwNumberOfProcessors;
151 m_pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("NTDLL"), "NtQuerySystemInformation");
152
153 for (DWORD dwCpu=0; dwCpu<MAX_CPU; dwCpu++)
154 {
155 m_idleTime[dwCpu].QuadPart = 0;
156 m_fltUsage[dwCpu] = FLT_MAX;
157 m_dwTickCount[dwCpu] = 0;
158 }
159
160 //init timer
161
162 m_nTimerID = SetTimer(0x1234, 1000, NULL);
163
164 Refresh();
165
166 return TRUE; // return TRUE unless you set the focus to a control
167 }
168 /////////////////////////////////////////////////////////////////////////////
169 void CRTSSSharedMemorySampleDlg::OnSysCommand(UINT nID, LPARAM lParam)
170 {
171 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
172 {
173 CAboutDlg dlgAbout;
174 dlgAbout.DoModal();
175 }
176 else
177 {
178 CDialog::OnSysCommand(nID, lParam);
179 }
180 }
181 /////////////////////////////////////////////////////////////////////////////
182 // If you add a minimize button to your dialog, you will need the code below
183 // to draw the icon. For MFC applications using the document/view model,
184 // this is automatically done for you by the framework.
185 /////////////////////////////////////////////////////////////////////////////
186 void CRTSSSharedMemorySampleDlg::OnPaint()
187 {
188 if (IsIconic())
189 {
190 CPaintDC dc(this); // device context for painting
191
192 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
193
194 // Center icon in client rectangle
195 int cxIcon = GetSystemMetrics(SM_CXICON);
196 int cyIcon = GetSystemMetrics(SM_CYICON);
197 CRect rect;
198 GetClientRect(&rect);
199 int x = (rect.Width() - cxIcon + 1) / 2;
200 int y = (rect.Height() - cyIcon + 1) / 2;
201
202 // Draw the icon
203 dc.DrawIcon(x, y, m_hIcon);
204 }
205 else
206 {
207 CDialog::OnPaint();
208 }
209 }
210 /////////////////////////////////////////////////////////////////////////////
211 // The system calls this to obtain the cursor to display while the user drags
212 // the minimized window.
213 /////////////////////////////////////////////////////////////////////////////
214 HCURSOR CRTSSSharedMemorySampleDlg::OnQueryDragIcon()
215 {
216 return (HCURSOR) m_hIcon;
217 }
218 /////////////////////////////////////////////////////////////////////////////
219 // we'll update sample's window on timer once per second
220 /////////////////////////////////////////////////////////////////////////////
221 void CRTSSSharedMemorySampleDlg::OnTimer(UINT nIDEvent)
222 {
223 Refresh();
224
225 CDialog::OnTimer(nIDEvent);
226 }
227 /////////////////////////////////////////////////////////////////////////////
228 void CRTSSSharedMemorySampleDlg::OnDestroy()
229 {
230 if (m_nTimerID)
231 KillTimer(m_nTimerID);
232
233 m_nTimerID = NULL;
234
235 MSG msg;
236 while (PeekMessage(&msg, m_hWnd, WM_TIMER, WM_TIMER, PM_REMOVE));
237
238 ReleaseOSD();
239
240 CDialog::OnDestroy();
241 }
242 /////////////////////////////////////////////////////////////////////////////
243 BOOL CRTSSSharedMemorySampleDlg::UpdateOSD(LPCSTR lpText)
244 {
245 BOOL bResult = FALSE;
246
247 HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "RTSSSharedMemoryV2");
248
249 if (hMapFile)
250 {
251 LPVOID pMapAddr = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
252 LPRTSS_SHARED_MEMORY pMem = (LPRTSS_SHARED_MEMORY)pMapAddr;
253
254 if (pMem)
255 {
256 if ((pMem->dwSignature == 'RTSS') &&
257 (pMem->dwVersion >= 0x00020000))
258 {
259 for (DWORD dwPass=0; dwPass<2; dwPass++)
260 //1st pass : find previously captured OSD slot
261 //2nd pass : otherwise find the first unused OSD slot and capture it
262 {
263 for (DWORD dwEntry=1; dwEntry<pMem->dwOSDArrSize; dwEntry++)
264 //allow primary OSD clients (i.e. EVGA Precision / MSI Afterburner) to use the first slot exclusively, so third party
265 //applications start scanning the slots from the second one
266 {
267 RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_OSD_ENTRY pEntry = (RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_OSD_ENTRY)((LPBYTE)pMem + pMem->dwOSDArrOffset + dwEntry * pMem->dwOSDEntrySize);
268
269 if (dwPass)
270 {
271 if (!strlen(pEntry->szOSDOwner))
272 strcpy(pEntry->szOSDOwner, "RTSSSharedMemorySample");
273 }
274
275 if (!strcmp(pEntry->szOSDOwner, "RTSSSharedMemorySample"))
276 {
277 if (pMem->dwVersion >= 0x00020007)
278 //use extended text slot for v2.7 and higher shared memory, it allows displaying 4096 symbols
279 //instead of 256 for regular text slot
280 strncpy(pEntry->szOSDEx, lpText, sizeof(pEntry->szOSDEx) - 1);
281 else
282 strncpy(pEntry->szOSD, lpText, sizeof(pEntry->szOSD) - 1);
283
284 pMem->dwOSDFrame++;
285
286 bResult = TRUE;
287
288 break;
289 }
290 }
291
292 if (bResult)
293 break;
294 }
295 }
296
297 UnmapViewOfFile(pMapAddr);
298 }
299
300 CloseHandle(hMapFile);
301 }
302
303 return bResult;
304 }
305 /////////////////////////////////////////////////////////////////////////////
306 void CRTSSSharedMemorySampleDlg::ReleaseOSD()
307 {
308 HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "RTSSSharedMemoryV2");
309
310 if (hMapFile)
311 {
312 LPVOID pMapAddr = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
313
314 LPRTSS_SHARED_MEMORY pMem = (LPRTSS_SHARED_MEMORY)pMapAddr;
315
316 if (pMem)
317 {
318 if ((pMem->dwSignature == 'RTSS') &&
319 (pMem->dwVersion >= 0x00020000))
320 {
321 for (DWORD dwEntry=1; dwEntry<pMem->dwOSDArrSize; dwEntry++)
322 {
323 RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_OSD_ENTRY pEntry = (RTSS_SHARED_MEMORY::LPRTSS_SHARED_MEMORY_OSD_ENTRY)((LPBYTE)pMem + pMem->dwOSDArrOffset + dwEntry * pMem->dwOSDEntrySize);
324
325 if (!strcmp(pEntry->szOSDOwner, "RTSSSharedMemorySample"))
326 {
327 memset(pEntry, 0, pMem->dwOSDEntrySize);
328 pMem->dwOSDFrame++;
329 }
330 }
331 }
332
333 UnmapViewOfFile(pMapAddr);
334 }
335
336 CloseHandle(hMapFile);
337 }
338 }
339 /////////////////////////////////////////////////////////////////////////////
340 float CRTSSSharedMemorySampleDlg::CalcCpuUsage(DWORD dwCpu)
341 {
342 //validate NtQuerySystemInformation pointer and return FLT_MAX on error
343
344 if (!m_pNtQuerySystemInformation)
345 return FLT_MAX;
346
347 //validate specified CPU index and return FLT_MAX on error
348
349 if (dwCpu >= m_dwNumberOfProcessors)
350 return FLT_MAX;
351
352 DWORD dwTickCount = GetTickCount();
353 //get standard timer tick count
354
355 if (dwTickCount - m_dwTickCount[dwCpu] >= 1000)
356 //update usage once per second
357 {
358 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[MAX_CPU];
359
360 if (SUCCEEDED(m_pNtQuerySystemInformation(SystemProcessorPerformanceInformation, &info, sizeof(info), NULL)))
361 //query CPU usage
362 {
363 if (m_idleTime[dwCpu].QuadPart)
364 //ensure that this function was already called at least once
365 //and we have the previous idle time value
366 {
367 m_fltUsage[dwCpu] = 100.0f - 0.01f * (info[dwCpu].IdleTime.QuadPart - m_idleTime[dwCpu].QuadPart) / (dwTickCount - m_dwTickCount[dwCpu]);
368 //calculate new CPU usage value by estimating amount of time
369 //CPU was in idle during the last second
370
371 //clip calculated CPU usage to [0-100] range to filter calculation non-ideality
372
373 if (m_fltUsage[dwCpu] < 0.0f)
374 m_fltUsage[dwCpu] = 0.0f;
375
376 if (m_fltUsage[dwCpu] > 100.0f)
377 m_fltUsage[dwCpu] = 100.0f;
378 }
379
380 m_idleTime[dwCpu] = info[dwCpu].IdleTime;
381 //save new idle time for specified CPU
382 m_dwTickCount[dwCpu] = dwTickCount;
383 //save new tick count for specified CPU
384 }
385 }
386
387 return m_fltUsage[dwCpu];
388 }
389 /////////////////////////////////////////////////////////////////////////////
390 void CRTSSSharedMemorySampleDlg::Refresh()
391 {
392 //init RivaTuner Statistics Server installation path
393
394 if (m_strInstallPath.IsEmpty())
395 {
396 HKEY hKey;
397
398 if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Unwinder\\RTSS", &hKey))
399 {
400 char buf[MAX_PATH];
401
402 DWORD dwSize = MAX_PATH;
403 DWORD dwType;
404
405 if (ERROR_SUCCESS == RegQueryValueEx(hKey, "InstallPath", 0, &dwType, (LPBYTE)buf, &dwSize))
406 {
407 if (dwType == REG_SZ)
408 m_strInstallPath = buf;
409 }
410
411 RegCloseKey(hKey);
412 }
413 }
414
415 //validate RivaTuner Statistics Server installation path
416
417 if (_taccess(m_strInstallPath, 0))
418 m_strInstallPath = "";
419
420 CGroupedString groupedString(sizeof(RTSS_SHARED_MEMORY::RTSS_SHARED_MEMORY_OSD_ENTRY().szOSD) - 1);
421 // RivaTuner based products use similar CGroupedString object for convenient OSD text formatting and length control
422 // You may use it to format your OSD similar to RivaTuner's one or just use your own routines to format OSD text
423
424 for (DWORD dwCpu=0; dwCpu<m_dwNumberOfProcessors; dwCpu++)
425 {
426 float fltUsage = CalcCpuUsage(dwCpu);
427
428 if (fltUsage != FLT_MAX)
429 {
430 CString strValue;
431 strValue.Format("%.0f %%", fltUsage);
432
433 CString strGroup;
434 if ((m_dwNumberOfProcessors > 1) && m_bMultiLineOutput)
435 strGroup.Format("CPU%d", dwCpu + 1);
436 else
437 strGroup.Format("CPU", dwCpu + 1);
438
439 groupedString.Add(strValue, strGroup, "\n");
440 }
441 }
442
443 BOOL bTruncated = FALSE;
444
445 CString strOSD = groupedString.Get(bTruncated);
446
447 if (!strOSD.IsEmpty())
448 {
449 BOOL bResult = UpdateOSD(strOSD);
450
451 m_bConnected = bResult;
452
453 if (bResult)
454 {
455 m_strStatus = "The following text is being forwarded to OSD:\n\n" + strOSD;
456
457 if (bTruncated)
458 m_strStatus += "\n\nWarning!\nThe text is too long to be displayed in OSD, some info has been truncated!";
459
460 m_strStatus += "\n\nHints:\n-Press <Space> to toggle multi-line OSD text formatting";
461
462 }
463 else
464 {
465
466 if (m_strInstallPath.IsEmpty())
467 m_strStatus = "Failed to connect to RTSS shared memory!\n\nHints:\n-Install RivaTuner Statistics Server";
468 else
469 m_strStatus = "Failed to connect to RTSS shared memory!\n\nHints:\n-Press <Space> to start RivaTuner Statistics Server";
470 }
471
472 m_richEditCtrl.SetWindowText(m_strStatus);
473 }
474 }
475 /////////////////////////////////////////////////////////////////////////////
476
477 BOOL CRTSSSharedMemorySampleDlg::PreTranslateMessage(MSG* pMsg)
478 {
479 if (pMsg->message == WM_KEYDOWN)
480 {
481 switch (pMsg->wParam)
482 {
483 case ' ':
484 if (m_bConnected)
485 {
486 m_bMultiLineOutput = !m_bMultiLineOutput;
487 Refresh();
488 }
489 else
490 {
491 if (!m_strInstallPath.IsEmpty())
492 ShellExecute(GetSafeHwnd(), "open", m_strInstallPath, NULL, NULL, SW_SHOWNORMAL);
493 }
494 break;
495 }
496 }
497
498 return CDialog::PreTranslateMessage(pMsg);
499 }

  ViewVC Help
Powered by ViewVC 1.1.22