File: SWINTRAC\M_DEVICE.CPP
1 // m_device.cpp
2 // (C) 1993,1994 by Heiko Damerow
3 // MPG AG "Röntgenbeugung an Schichtstrukturen"
4
5 #include "utils\u_utils.h"
6 #include "winresrc\rc_def.h" // Ressourcen-IDs
7 #pragma hdrstop
8
9 #include "swintrac\m_dlg.h" // für TCounterWindow
10 #include "detecuse\detecuse.h"
11
12 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
13
14 TCounterWindow *TCounterWindow::s_Singleton= 0;
15
16 //******************************************************************************
17 //******** Anwender-Schnittstelle **********************************************
18 //******** Methoden für das Zähler-Fenster *************************************
19 TCounterWindow::TCounterWindow(HINSTANCE aInstance, TDetector *detectorParam) : TMDIWindow(aInstance), IField(0, 0.0) // 31.04.2004 MEMCORRECT (verwende IField), hMemG(0)
20 {
21 if ( detectorParam == 0 )
22 Sensor= TDetectorManager::DetectorManager().GetDetector();
23 else
24 Sensor= detectorParam;
25
26 Sensor->SetCounterWnd(NULL);
27 if ( s_Singleton ) _FREEOBJ(s_Singleton);
28 s_Singleton= this;
29
30 // Aussehen des Fensters festlegen
31 bShowAsDigital= TRUE;
32 bQuiteOpen= FALSE;
33 eScaleType= sLinear;
34 bAnalogSwitchOn= TRUE;
35 bWindowWillBeOpen= TRUE;
36 bWriteLogFile= FALSE;
37 fData= 100.0;
38 fThickness= 10.0;
39 fHight= 200.0;
40 // Größe der Historien-Schlange
41 nBarCount= 40;
42 nIdx= -1;
43 fMaxIntensity= 14000.1f;
44 hBrushRed= CreateSolidBrush(RGB(255, 0, 0));
45 hBrushWhite= CreateSolidBrush(RGB(0, 0, 0));
46 hBrushBlack= CreateSolidBrush(RGB(255, 255, 255));
47 hBrushOC= CreateSolidBrush(RGB(0, 255, 127));
48 hPen= CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
49 strcpy(FontName, "");
50
51 //! erstellen der Menüeintraege
52 hHoleMenu= LoadMenu(GetMainInstance(), MAKEINTRESOURCE(menu_Counter));
53 // Fix für PopupMenüs aus Ressourcen (Dummy Popup)
54 TheMenu= GetSubMenu(hHoleMenu, 0);
55 };
56
57 TCounterWindow::~TCounterWindow()
58 {
59 char buf[MaxString];
60 RECT rc, rcm;
61
62 if (bQuiteOpen)
63 {
64 Sensor->MeasureStop();
65 Sensor->SetCounterWnd(NULL);
66 }
67
68 GetWindowRect(GetFrameHandle(), &rcm);
69 GetWindowRect(GetHandle(), &rc);
70 sprintf(buf, "%d", rc.left - rcm.left - 4);
71 WritePrivateProfileString("Counter", "xo", buf, GetCFile());
72 sprintf(buf, "%d", rc.top - rcm.top - 42);
73 WritePrivateProfileString("Counter", "yo", buf, GetCFile());
74 sprintf(buf, "%d", rc.right - rc.left);
75 WritePrivateProfileString("Counter", "dx", buf, GetCFile());
76 sprintf(buf, "%d", rc.bottom - rc.top);
77 WritePrivateProfileString("Counter", "dy", buf, GetCFile());
78 DeleteObject(hBrushWhite);
79 DeleteObject(hBrushRed);
80 DeleteObject(hBrushBlack);
81 DeleteObject(hBrushOC);
82 DeleteObject(hPen);
83
84 s_Singleton= 0;
85
86 /* 31.04.2004 MEMCORRECT (verwende IField) if ( hMemG ) HeapFree(GetProcessHeap(),0,hMemG);
87 hMemG= 0;*/
88 };
89
90 BOOL TCounterWindow::CanOpen(void)
91 {
92 char buf[MaxString];
93
94 if (!TMDIWindow::CanOpen())
95 return FALSE;
96
97 if (Sensor->GetCounterWnd())
98 {
99 sprintf(buf, "Es ist bereits ein darstellendes Fenster geöffnet!");
100 MessageBox((LPSTR)buf, "Fehler", MBINFO);
101 return FALSE;
102 }
103
104 return TRUE;
105 };
106
107 void TCounterWindow::OnCreate()
108 {
109 int value;
110
111 bQuiteOpen= TRUE;
112 Sensor->MeasureStop();
113 Sensor->SetCounterWnd( GetHandle() );
114 Sensor->SetParameters();
115 Sensor->MeasureStart();
116 GetPrivateProfileString( "Counter", "font", "Times New Roman", FontName,
117 MaxString, GetCFile());
118 nBarCount= GetPrivateProfileInt("Counter", "BarNumber", 40, GetCFile());
119
120 WndRect.left= GetPrivateProfileInt("Counter", "xo", 500, GetCFile());
121 WndRect.top= GetPrivateProfileInt("Counter", "yo", 400, GetCFile());
122 value= GetPrivateProfileInt("Counter", "dx", 170, GetCFile());
123 WndRect.right= WndRect.left + value;
124 value= GetPrivateProfileInt("Counter", "dy", 50, GetCFile());
125 WndRect.bottom= WndRect.top + value;
126
127
128 // 31.04.2004 MEMCORRECT (verwende IField) hMemG= (HGLOBAL)HeapAlloc(GetProcessHeap(),0,nBarCount * sizeof(float));
129 IField.SetCount( nBarCount );
130
131
132 SetWindowPos( GetHandle(), NULL, WndRect.left, WndRect.top,
133 WndRect.right - WndRect.left, WndRect.bottom - WndRect.top, SWP_NOZORDER );
134 SetTitle();
135 };
136
137 void TCounterWindow::OnSize(WPARAM, LPARAM)
138 {
139 char buf[MaxString];
140
141 if (bWindowWillBeOpen)
142 bWindowWillBeOpen= FALSE;
143 else
144 GetWindowRect(GetHandle(), &WndRect);
145
146 GetClientRect(GetHandle(), &ClientRect);
147
148 sprintf(buf, "%d", nBarCount);
149
150 WritePrivateProfileString("Counter", "BarNumber", buf, GetCFile());
151 };
152
153 BOOL TCounterWindow::SetTitle()
154 {
155 strcpy(m_Title, "Zähler: ");
156 strcat(m_Title, Sensor->GetCharacteristic());
157 return TMDIWindow::SetTitle();
158 };
159
160 LRESULT TCounterWindow::OnCommand(WPARAM wParam, LPARAM lParam)
161 {
162 TModalDlg *dlg;
163 WPARAM Cmd;
164 Cmd= GET_WM_COMMAND_ID(wParam, lParam);
165 switch (Cmd)
166 {
167 case cm_ShowCounterParam:
168 dlg= new TCounterShowParamDlg(this);
169 if ( dlg ) dlg->ExecuteDialog(GetHandle());
170 _FREEOBJ(dlg);
171 return 0l;
172
173 case cm_Logging:
174 SetupLogging();
175 return 0l;
176
177 case cm_ShowDigital:
178 bShowAsDigital= TRUE;
179 return 0l;
180
181 case cm_ShowAnalog:
182 bShowAsDigital= FALSE;
183 return 0l;
184 }
185 return TMDIWindow::OnCommand(wParam, lParam);
186 }
187
188 void TCounterWindow::CounterSetRequest(LPARAM)
189 {
190 float temp= 0;
191 int res= Sensor->GetIntegral(temp);
192 if ( (res==R_OK) || (res==R_SoftOverflow) ) ShowCounterSetRequest(temp);
193 else ShowCounterSetRequest(fData); // bei Hardoverflow
194 };
195
196 void TCounterWindow::ShowCounterSetRequest(float aIntegral)
197 {
198 FILE *hFile;
199 char buf[MaxString];
200 fData= aIntegral;
201
202 if (bWriteLogFile)
203 {
204 sprintf(buf, "device%d.log", Sensor->GetId());
205 hFile= fopen(buf, "at");
206 sprintf(buf, "%.3f\n", fData);
207 fwrite(buf, 1, strlen(buf), hFile);
208 fclose(hFile);
209 }
210
211 if (bShowAsDigital)
212 UpdateWnd();
213 else
214 UpdateWnd( ptPaintPoint );
215
216 if (!Sensor->GetControlWnd())
217 Sensor->MeasureStart();
218 };
219
220 void TCounterWindow::SetupLogging(void)
221 {
222 FILE *hFile;
223 char buf[MaxString];
224
225 SYSTEMTIME t;
226
227 bWriteLogFile= !bWriteLogFile;
228
229 if (bWriteLogFile)
230 {
231 GetLocalTime(&t);
232 sprintf(buf, "device%d.log", Sensor->GetId());
233 hFile= fopen(buf, "at");
234 sprintf(buf, "Logging Detector%d starts at %02i.%02i.%i %2d:%02d\n",
235 Sensor->GetId(), t.wDay, t.wMonth, t.wYear, t.wHour, t.wMinute);
236 fwrite(buf, 1, strlen(buf), hFile);
237 fclose(hFile);
238 }
239 };
240
241 void TCounterWindow::OnPopupMenuInit(WPARAM, LPARAM lParam)
242 {
243 TDetectorManager::DetectorManager().SetDetector(Sensor);
244 CheckMenuItem(TheMenu, cm_ShowDigital, bShowAsDigital ? MF_CHECKED : MF_UNCHECKED);
245 CheckMenuItem(TheMenu, cm_ShowAnalog, bShowAsDigital ? MF_UNCHECKED : MF_CHECKED);
246 CheckMenuItem(TheMenu, cm_Logging, bWriteLogFile ? MF_CHECKED : MF_UNCHECKED);
247 };
248
249 void TCounterWindow::OnFocus(void)
250 {
251 TDetectorManager::DetectorManager().SetDetector(Sensor);
252 };
253
254 void TCounterWindow::OnLButtonDown(WPARAM, LPARAM)
255 {};
256
257 void TCounterWindow::DoPaint(HDC hdc, PAINTSTRUCT *)
258 {
259 char buf[MaxString];
260 HDC hMemDC;
261 HBITMAP hOldBitmap, hBitmap;
262 HFONT hOldFont, hFont;
263 int yp, xp;
264 int xclient, yclient, i;
265 LOGFONT lf;
266 SIZE size;
267 POINT point;
268
269 if (!WholeWnd()) {
270 if (bShowAsDigital) return;
271
272 // Definition des logischen Zeichen-Fensters
273 SetMapMode(hdc, MM_ANISOTROPIC);
274
275 // Koordinatenursprung setzen
276 SetWindowExtEx(hdc, ClientRect.right - ClientRect.left, ClientRect.bottom - ClientRect.top, &size);
277 SetWindowOrgEx(hdc, 0, 0, &point);
278 SetViewportExtEx(hdc, ClientRect.right - ClientRect.left, -(ClientRect.bottom - ClientRect.top), &size);
279 SetViewportOrgEx(hdc, 0, ClientRect.bottom - ClientRect.top, &point);
280
281
282 // 31.04.2004 MEMCORRECT (verwende IField) IField= (HPFLOAT)GlobalLock(hMemG);
283
284 SelectObject(hdc, hPen);
285 SelectObject(hdc, hBrushRed);
286 if (nIdx >= 0) Rectangle(hdc, nIdx*fThickness, IField[nIdx]*fHight, (nIdx + 1)*fThickness, 0);
287 if (++nIdx >= nBarCount) nIdx= 0;
288
289 IField[nIdx]= fData;
290
291 // Zeichnen des letzten Wertes als Säule in schwarz
292 SelectObject(hdc, hBrushBlack);
293
294 Rectangle(hdc, nIdx*fThickness, ClientRect.bottom - ClientRect.top, (nIdx + 2)*fThickness, IField[nIdx]*fHight);
295 SelectObject(hdc, hBrushWhite);
296 Rectangle(hdc, nIdx*fThickness, IField[nIdx]*fHight, (nIdx + 2)*fThickness, 0);
297 sprintf(buf, "Intensität: %.1f", IField[nIdx]);
298 SetInfo(buf);
299
300
301 // 31.04.2004 MEMCORRECT (verwende IField) GlobalUnlock(hMemG);
302
303
304 return;
305 }
306
307 if (bShowAsDigital) {
308 bAnalogSwitchOn= TRUE;
309 xclient= ClientRect.right - ClientRect.left;
310 yclient= ClientRect.bottom - ClientRect.top;
311 SetMapMode(hdc, MM_TEXT);
312
313 // MemDC erzeugen und auswählen
314 hMemDC= CreateCompatibleDC(hdc);
315 hBitmap= CreateCompatibleBitmap(hdc, xclient, yclient);
316 hOldBitmap= (HBITMAP)SelectObject(hMemDC, hBitmap);
317
318 // auszugebende Zeichenkette erstellen
319 if (fabs(fData) > 10000) sprintf(buf, "%.0f", fData);
320 else if (fabs(fData) > 1000) sprintf(buf, "%.1f", fData);
321 else sprintf(buf, "%.2f", fData);
322
323 //Schriftskalierung berechnen (neu Kullmann+Reinecker)
324 GetTextExtentPoint(hMemDC, buf, strlen(buf), &size);
325 float scaleX= (float)xclient / max(1.0f, (float)size.cx); // DIV0 verhindern
326 float scaleY= (float)yclient / max(1.0f, (float)size.cy); // DIV0 verhindern
327
328 // Font erstellen und auswählen
329 memset(&lf, 0, sizeof(LOGFONT));
330 lf.lfHeight= (int) ( size.cy*min(scaleX, scaleY) ); // neu Kullmann+Reinecker: yclient ersetzt durch Skalierung
331 lf.lfWidth= 0;
332 lf.lfWeight= 200;
333 lf.lfUnderline= FALSE;
334 strcpy(lf.lfFaceName, FontName);
335 hFont= CreateFontIndirect(&lf);
336 hOldFont= (HFONT)SelectObject(hMemDC, hFont);
337
338 // Zeichnen der Daten
339 GetTextExtentPoint(hMemDC, buf, strlen(buf), &size);
340 xp= xclient - size.cx; // horizontal rechtsbündig
341 yp= yclient / 2 - size.cy / 2; // vertikal zentiert
342 TextOut(hMemDC, xp, yp, (LPSTR)buf, strlen(buf));
343 BitBlt(hdc, xp, yp, size.cx, size.cy, hMemDC, xp, yp, SRCCOPY); // PatBlt(hMemDC,0,0,xclient,yclient,WHITENESS);
344
345 // DC wiederherstellen
346 SelectObject(hMemDC, hOldFont);
347 DeleteObject(hFont);
348 SelectObject(hMemDC, hOldBitmap);
349 DeleteObject(hBitmap);
350 DeleteDC(hMemDC);
351 } else { // !bShowAsDigital
352 // 31.04.2004 MEMCORRECT (verwende IField) IField= (HPFLOAT)GlobalLock(hMemG);
353
354
355 if (bAnalogSwitchOn) {
356 for (nIdx= 0;nIdx < nBarCount; nIdx++) IField[nIdx]= 0.0;
357 nIdx= -1;
358 bAnalogSwitchOn= FALSE;
359 fHight= (ClientRect.bottom - ClientRect.top) / fMaxIntensity * 0.9;
360 };
361
362 fThickness= (ClientRect.right - ClientRect.left) / nBarCount;
363 SetMapMode(hdc, MM_ANISOTROPIC);
364 SetWindowExtEx( hdc, ClientRect.right - ClientRect.left, ClientRect.bottom - ClientRect.top, &size);
365 SetWindowOrgEx(hdc, 0, 0, &point);
366 SetViewportExtEx( hdc, ClientRect.right - ClientRect.left, -(ClientRect.bottom - ClientRect.top), &size);
367 SetViewportOrgEx(hdc, 0, ClientRect.bottom - ClientRect.top, &point);
368
369 // Zeichnen der aktuellen Werte in Rot
370 SelectObject(hdc, hPen);
371 SelectObject(hdc, hBrushRed);
372 for (i= 0;i < nBarCount;i++) Rectangle(hdc, i*fThickness, 0, (i + 1)*fThickness, IField[i]*fHight);
373
374
375 // 31.04.2004 MEMCORRECT (verwende IField) GlobalUnlock(hMemG);
376 }
377 };
378
379 //******************************************************************************
380 TCounterShowParamDlg::TCounterShowParamDlg(TCounterWindow *cwnd)
381 : TModalDlg("CounterShowParam", GetMainInstance() )
382 {
383 CounterWnd= cwnd;
384 };
385
386
387 BOOL TCounterShowParamDlg::Dlg_OnInit(HWND hwnd, HWND hwndCtl, LPARAM lParam)
388 {
389 char buf[MaxString];
390
391 SetFocus(GetDlgItem(GetHandle(), IDOK));
392 CheckDlgButton(GetHandle(), id_ShowAsLog, (CounterWnd->eScaleType == sLogarithmic));
393 sprintf(buf, "%.1f", CounterWnd->fMaxIntensity);
394 SetDlgItemText(GetHandle(), id_MaxIntensity, (LPSTR)buf);
395 sprintf(buf, "%u", CounterWnd->nBarCount);
396 SetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf);
397 return TRUE;
398 };
399
400 BOOL TCounterShowParamDlg::CanClose(void)
401 {
402 float value_f;
403 short value_s;
404 char buf[MaxString];
405
406 if (!IsDlgButtonChecked(GetHandle(), id_ShowAsLog))
407 CounterWnd->eScaleType= sLinear;
408 else
409 CounterWnd->eScaleType= sLogarithmic;
410
411 GetDlgItemText(GetHandle(), id_MaxIntensity, (LPSTR)buf, 10);
412
413 value_f= atof(buf);
414
415 if ((value_f < 2e5) && (value_f > 0.0))
416 CounterWnd->fMaxIntensity= value_f;
417 else
418 {
419 CounterWnd->fMaxIntensity= 2.6e4;
420 sprintf(buf, "%.1f", CounterWnd->fMaxIntensity);
421 SetDlgItemText(GetHandle(), id_MaxIntensity, (LPSTR)buf);
422 return FALSE;
423 }
424
425 GetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf, 10);
426 value_s= (short)atoi(buf);
427
428 if (CounterWnd->nBarCount == value_s)
429 return TRUE;
430
431 if ((value_s < 140) && (value_s > 0))
432 {
433 CounterWnd->nBarCount= value_s;
434 // Änderung des belegten Speichers notwendig
435 CounterWnd->Sensor->MeasureStop();
436
437
438 // 31.04.2004 MEMCORRECT (verwende IField) HeapReAlloc(GetProcessHeap(),0, CounterWnd->hMemG, CounterWnd->nBarCount*sizeof(float));
439 CounterWnd->IField.SetCount( CounterWnd->nBarCount );
440
441
442 CounterWnd->nIdx= 0;
443 CounterWnd->Sensor->MeasureStart();
444 sprintf(buf, "%u", CounterWnd->nBarCount);
445 SetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf);
446 }
447 else
448 {
449 sprintf(buf, "%u", CounterWnd->nBarCount);
450 SetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf);
451 return FALSE;
452 }
453
454 return TRUE;
455 };
456
457 // __LastLine__
458
459