Scope
MainDlgFrame.cpp
1 #include "StdAfx.h"
2 #include "MainDlgFrame.h"
3 #include "ChannelFrame.h"
4 #include "HistogramFrame.h"
5 #include "AboutDlg.h"
6 #include "controllers/ScopeController.h"
7 #include "controllers/ScopeLogger.h"
8 #include "LogFrame.h"
9 
10 namespace scope {
11  namespace gui {
12 
13 std::array<UINT, 4> CMainDlgFrame::viewareas_ids = { ID_NEWVIEW_AREA1, ID_NEWVIEW_AREA2, ID_NEWVIEW_AREA3, ID_NEWVIEW_AREA4};
14 std::array<UINT, 4> CMainDlgFrame::histogramareas_ids = { ID_NEWHISTOGRAM_AREA1, ID_NEWHISTOGRAM_AREA2, ID_NEWHISTOGRAM_AREA3, ID_NEWHISTOGRAM_AREA4};
15 
16 void CMainDlgFrame::NewChannelFrame(const uint32_t& _area, const RECT& _rect) {
17  RECT rect(_rect); // We need non-const here
18  CChannelFrame* pChild = new CChannelFrame(_area);
19  // set the CMainDlgFrame as parent, so the childs receives WM_DESTROY when the parent gets destroyed (correct cleanup this way!!)
20  pChild->CreateEx(m_hWnd, rect);
21  pChild->ShowWindow(SW_SHOWDEFAULT);
22 }
23 
24 void CMainDlgFrame::NewHistogramFrame(const uint32_t& _area, const RECT& _rect) {
25  // Do not open histogram we alread have a histogram for that area (since calculation is done inside an Active
26  // in CHistogramFrame this would mean twice the same calculation etc
27  if ( !scope_controller.HistogramAlreadyAttached(_area) ) {
28  RECT rect(_rect); // We need non-const here
29  CHistogramFrame* pChild = new CHistogramFrame(_area, scope_controller.GuiParameters.areas[_area]->daq.inputs->channels());
30  // set the CMainDlgFrame as parent, so the childs get destroyed when the parent gets WM_DESTROY (correct cleanup this way!!)
31  pChild->CreateEx(m_hWnd, rect);
32  pChild->ShowWindow(SW_SHOWDEFAULT);
33  }
34 }
35 
36 void CMainDlgFrame::NewLogFrame(const RECT& _rect) {
37  if ( !scope_logger.HasLogFrame() ) {
38  RECT rect(_rect); // We need non-const here
39  CLogFrame* logchild = new CLogFrame;
40  // set the CMainDlgFrame as parent, so the childs get destroyed when the parent gets destroyed (correct cleanup this way!!)
41  logchild->CreateEx(m_hWnd, rect);
42  logchild->ShowWindow(SW_SHOWDEFAULT);
43  }
44 }
45 
47  for ( const auto& w : scope_controller.GuiParameters.frames.collection ) {
48  RECT rect;
49  rect.top = w.top;
50  rect.left = w.left;
51  rect.bottom = w.bottom;
52  rect.right = w.right;
53  if ( w.type() == L"CChannelFrame" )
54  NewChannelFrame(w.area, rect);
55  if ( w.type() == L"CHistogramFrame" )
56  NewHistogramFrame(w.area, rect);
57  if ( w.type() == L"CLogFrame" )
58  NewLogFrame(rect);
59  }
60 }
61 
62 BOOL CMainDlgFrame::PreTranslateMessage(MSG* pMsg) {
63  if (CMainDlgFrameType::PreTranslateMessage(pMsg))
64  return TRUE;
65  return FALSE;
66 }
67 
69  // this is called way too often, memory check therefore implemented differently, with OnTimer
70 
71  // Update scope run state status
72  std::wstring str2(scope_controller.GuiParameters.run_state());
73  UISetText(0, str2.c_str());
74 
75  // Update shutter status in menu
76  UISetCheck(ID_TOOLS_SHUTTEROPEN, scope_controller.GetShutterState(0));
77 
78  UIUpdateStatusBar();
79  UIUpdateToolBar();
80  return FALSE;
81 }
82 
85  PostMessage(WM_CLOSE);
86 }
87 
88 void CMainDlgFrame::PrepareToolBarMenu(UINT nMenuID, HMENU hMenu) {
89  static_assert(SCOPE_NAREAS <= 4, "No resource IDs defined for more than 4 areas, but easy to do if you need it");
90 
91  if (nMenuID == IDR_NEWCHANNEL_MENU) {
92  CMenuHandle menu(hMenu);
93  for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
94  std::wostringstream stream;
95  stream << L"Area " << a+1;
96  menu.InsertMenu(0, MF_STRING, viewareas_ids[a], stream.str().c_str());
97  }
98  }
99  if (nMenuID == IDR_NEWHISTOGRAM_MENU) {
100  CMenuHandle menu(hMenu);
101  for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
102  std::wostringstream stream;
103  stream << L"Area " << a+1;
104  // Disable the menu entry if we alread have a histogram for that area (since calculation is done inside an Active
105  // in CHistogramFrame this would mean twice the same calculation etc
106  if ( scope_controller.HistogramAlreadyAttached(a) )
107  menu.InsertMenu(0, MF_STRING | MF_GRAYED, histogramareas_ids[a], stream.str().c_str());
108  else
109  menu.InsertMenu(0, MF_STRING, histogramareas_ids[a], stream.str().c_str());
110  }
111  }
112 }
113 
114 LRESULT CMainDlgFrame::OnCreate(LPCREATESTRUCT lParam) {
115  // Disable close button in title bar
116  HMENU m = GetSystemMenu(FALSE);
117  EnableMenuItem(m, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
118 
119  // create command bar window
120  HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
121  // attach menu
122  m_CmdBar.AttachMenu(GetMenu());
123  // load command bar images
124  m_CmdBar.LoadImages(IDR_MAINFRAME);
125  // remove old menu
126  SetMenu(HMENU(NULL));
127 
128  // Create toolbar
129  HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE_EX);
130 
131  // Add dropdown menus
132  AddToolBarDropDownMenu(hWndToolBar, IDC_NEWCHANNELDROPDOWN, IDR_NEWCHANNEL_MENU);
133  AddToolbarButtonText(hWndToolBar, IDC_NEWCHANNELDROPDOWN, L"New View");
134  AddToolBarDropDownMenu(hWndToolBar, IDC_NEWHISTOGRAMDROPDOWN, IDR_NEWHISTOGRAM_MENU);
135  AddToolbarButtonText(hWndToolBar, IDC_NEWHISTOGRAMDROPDOWN, L"New Histogram");
136 
137  // Create the rebar
138  CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
139  AddSimpleReBarBand(hWndCmdBar);
140  AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
141 
142  UIAddToolBar(hWndToolBar);
143  UISetCheck(ID_VIEW_TOOLBAR, 1);
144  UISetCheck(ID_VIEW_STATUS_BAR, 1);
145 
146  // Standard style but without SBARS_SIZEGRIP (no resize gripper)
147  m_hWndStatusBar = m_wndStatusBar.Create(*this, ATL_IDS_IDLEMESSAGE, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
148  UIAddStatusBar (m_hWndStatusBar);
149  // Create the status bar panes.
150  int32_t anPanes[] = { IDPANE_STATUS, IDPANE_MEMORY, IDPANE_CONFIG };
151  // Set status bar startup text
152  m_wndStatusBar.SetPanes ( anPanes, 3, false );
153  UISetText(0, L"Stopped");
154  m_wndStatusBar.SetPaneText(0, L"Stopped");
155  UISetText(1, L"Memory");
156  UISetText(2, scope_controller.CurrentConfigFile().c_str());
157  UIUpdateStatusBar();
158 
159  // Progress bar inside status bar (in case this is needed sometime...)
160  /*CRect rBar;
161  m_wndStatusBar.GetRect(0,&rBar);
162  CProgressBarCtrl wndProgressBar;
163  wndProgressBar.Create(m_wndStatusBar, rBar, NULL, WS_CHILD|WS_VISIBLE);
164  wndProgressBar.SetRange(0,100);
165  wndProgressBar.SetPos(50);
166  wndProgressBar.SetWindowTextW(L"Test");
167  UIUpdateStatusBar();
168  */
169 
170  // Update layout to move everything in position
171  UpdateLayout();
172 
173  // register object for message filtering and idle updates
174  CMessageLoop* pLoop = _Module.GetMessageLoop();
175  ATLASSERT(pLoop != NULL);
176  pLoop->AddMessageFilter(this);
177  pLoop->AddIdleHandler(this);
178 
179  // Fiddle with the window positioning to get a dialog view together with menu and toolbar
180  RECT toolbarrect;
181  ::GetWindowRect(hWndToolBar, &toolbarrect);
182  ScreenToClient(&toolbarrect);
183  RECT commandbarrect;
184  ::GetWindowRect(hWndCmdBar, &commandbarrect);
185  ScreenToClient(&commandbarrect);
186 
187  // Move the dialog view below the toolbar
188  RECT rec = {10,10,280,350};
189  HWND wnd = m_dlgView.Create(m_hWnd);
190  ::SetWindowPos(wnd,HWND_BOTTOM,0,53,430,939,NULL);
191 
192  // Connect the quit button
193  scope_controller.QuitButton.Connect(std::bind(&CMainDlgFrame::QuitApplication, this));
194 
195  // Set timer to 1000ms to regularly check and display memory consumption (see OnTimer)
196  SetTimer(1, 1000);
197 
198  return 0;
199 }
200 
201 void CMainDlgFrame::OnPaint(CDCHandle dc) {
202  // We recreate windows from here (after CMainDlgFrame is visible), if we would do it in OnCreate they would be the top windows!
203  if ( firstpaint ) {
204  // Recreate windows from stored positions in parameters xml file
205  RecreateWindows();
206  firstpaint = false;
207  }
208  SetMsgHandled(false);
209 }
210 
211 BOOL CMainDlgFrame::OnForwardMsg(LPMSG Msg, DWORD nUserData) {
212  return m_dlgView.PreTranslateMessage(Msg);
213 }
214 
215 void CMainDlgFrame::OnTimer(UINT_PTR nIDEvent) {
216  if ( nIDEvent == 1 ) {
217  // Update memory consumption status
218  PROCESS_MEMORY_COUNTERS pmc;
219  HANDLE proc = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ::GetCurrentProcessId());
220  ::GetProcessMemoryInfo(proc, &pmc, sizeof(pmc));
221  CloseHandle(proc);
222  CString str(L"");
223  str.Format(L"%d Mb", pmc.WorkingSetSize/1024/1024);
224  UISetText(1, str);
225  UIUpdateStatusBar();
226  }
227 }
228 
230  m_CmdBar.AttachMenu(NULL);
231  m_dlgView.DestroyWindow();
232 
233  // unregister message filtering and idle updates
234  CMessageLoop* pLoop = _Module.GetMessageLoop();
235  ATLASSERT(pLoop != NULL);
236  pLoop->RemoveMessageFilter(this);
237  pLoop->RemoveIdleHandler(this);
238  DBOUT(L"CMainDlgFrame::OnDestroy()\n");
239  SetMsgHandled(false); // for default destroy stuff
240 }
241 
242 LRESULT CMainDlgFrame::OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
243  QuitApplication();
244  return 0;
245 }
246 
247 LRESULT CMainDlgFrame::OnNewChannelFrame(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
248  uint32_t area = 0; // Default if we clicked on the big IDC_NEWCHANNELDROPDOWN button (not the dropdown arrow)
249 
250  // Check on which dropdown item was clicked
251  auto ait = std::find(std::begin(viewareas_ids), std::end(viewareas_ids), wID);
252  if ( ait != std::end(viewareas_ids) )
253  area = std::distance(std::begin(viewareas_ids), ait);
254 
255  const RECT rect = { 330, 5, 586, 261 };
256  NewChannelFrame(area, rect);
257 
258  return 0;
259 }
260 
261 LRESULT CMainDlgFrame::OnNewHistogramFrame(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
262  uint32_t area = 0; // Default if we clicked on the big IDC_NEWHISTOGRAMDROPDOWN button (not the dropdown arrow)
263 
264  auto ait = std::find(std::begin(histogramareas_ids), std::end(histogramareas_ids), wID);
265  if ( ait != std::end(histogramareas_ids) )
266  area = std::distance(std::begin(histogramareas_ids), ait); // If dropdown menu item/area select accordingly
267 
268  // with this CHistogramView/D2HistogramRender will be 512 pixel wide
269  RECT rect = { 330, 5, 330+532, 5+350 };
270  NewHistogramFrame(area, rect);
271 
272  return 0;
273 }
274 
275 LRESULT CMainDlgFrame::OnOpenLogbook(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
276  RECT rect = { 430, 5, 786, 261 };
277  NewLogFrame(rect);
278  return 0;
279 }
280 
281 LRESULT CMainDlgFrame::OnZeroGalvoOutputs(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
283  return 0;
284 }
285 
286 LRESULT CMainDlgFrame::OnShutterOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
287  static bool bOpen = false;
288  bOpen = !bOpen;
289  UISetCheck(ID_TOOLS_SHUTTEROPEN, bOpen);
291  return 0;
292 }
293 
294 LRESULT CMainDlgFrame::OnSaveWindowPositions(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
296  return 0;
297 }
298 
299 LRESULT CMainDlgFrame::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
300  CAboutDlg dlg;
301  dlg.DoModal(::GetActiveWindow());
302  return 0;
303 }
304 
305 LRESULT CMainDlgFrame::OnLoadParameters(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
306  // Open dialog to choose XML file
307  COMDLG_FILTERSPEC fileTypes[] = {{ L"XML parameter file", L"*.xml" }};
308  CShellFileOpenDialog dlg(NULL, FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST, L"xml", fileTypes, 1);
309  dlg.GetPtr()->SetTitle(L"Select parameter file");
310  IShellItem *psiFolder;
311  SHCreateItemFromParsingName(L"C:\\Temp\\", NULL, IID_PPV_ARGS(&psiFolder));
312  dlg.GetPtr()->SetFolder(psiFolder);
313 
314  // Crashes without GetDesktopWindow (see here: http://comments.gmane.org/gmane.comp.windows.wtl/16780), CMainDlgFrame is probably not a top level window?!
315  if ( IDOK == dlg.DoModal(::GetDesktopWindow()) ) {
316  CString filepath;
317  dlg.GetFilePath(filepath);
318  DBOUT(L"Filepath " << filepath.GetString());
319  scope_controller.LoadParameters(std::wstring(filepath.GetString()));
320  }
321 
322  psiFolder->Release();
323  return 0;
324 }
325 
326 LRESULT CMainDlgFrame::OnSaveParameters(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
327  // Open dialog to for file saving
328  COMDLG_FILTERSPEC fileTypes[] = {{ L"XML parameter file", L"*.xml" }};
329  CShellFileSaveDialog dlg(NULL, FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT, L"xml", fileTypes, 1);
330  dlg.GetPtr()->SetTitle(L"Select parameter file");
331  IShellItem *psiFolder;
332  SHCreateItemFromParsingName(L"C:\\Temp\\", NULL, IID_PPV_ARGS(&psiFolder));
333  dlg.GetPtr()->SetFolder(psiFolder);
334 
335  // Crashes without GetDesktopWindow (see here: http://comments.gmane.org/gmane.comp.windows.wtl/16780), CMainDlgFrame is probably not a top level window?!
336  if ( IDOK != dlg.DoModal(::GetDesktopWindow()) )
337  return 0;
338 
339  CString filepath;
340  dlg.GetFilePath(filepath);
341  DBOUT(L"Filepath " << filepath.GetString());
342  scope_controller.SaveParameters(std::wstring(filepath.GetString()));
343 
344  psiFolder->Release();
345  return 0;
346 }
347 
348 LRESULT CMainDlgFrame::OnSaveDefaultParameters(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
349  // Open dialog to for file saving
350  COMDLG_FILTERSPEC fileTypes[] = {{ L"XML parameter file", L"*.xml" }};
351  CShellFileSaveDialog dlg(NULL, FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT | FOS_FILEMUSTEXIST, L"xml", fileTypes, 1);
352  dlg.GetPtr()->SetTitle(L"Select parameter file");
353  IShellItem *psiFolder;
354  SHCreateItemFromParsingName(L"C:\\Temp\\", NULL, IID_PPV_ARGS(&psiFolder));
355  dlg.GetPtr()->SetFolder(psiFolder);
356 
357  // Crashes without GetDesktopWindow (see here: http://comments.gmane.org/gmane.comp.windows.wtl/16780), CMainDlgFrame is probably not a top level window?!
358  if ( IDOK == dlg.DoModal(::GetDesktopWindow()) ) {
359  CString filepath;
360  dlg.GetFilePath(filepath);
361  DBOUT(L"Filepath " << filepath.GetString());
362  // These are initialized via the default constructor
363  scope::parameters::Scope parameters;
364  parameters.Save(std::wstring(filepath.GetString()));
365  }
366  return 0;
367 }
368 
369 }}
std::wstring CurrentConfigFile() const
The master parameters class.
Definition: Scope.h:204
void OnPaint(CDCHandle dc)
Recreates stored frames on first call.
WindowCollection frames
The parameters for windows on the screen.
Definition: Scope.h:252
bool GetShutterState(const uint32_t &_area) const
Current state of the shutter.
std::array< std::unique_ptr< Area >, SCOPE_NAREAS > areas
holds AreaParameters for all areas.
Definition: Scope.h:231
LRESULT OnSaveWindowPositions(WORD, WORD, HWND, BOOL &)
Calls ScopeController::SaveCurrentWindowPositions.
LRESULT OnSaveDefaultParameters(WORD, WORD, HWND, BOOL &)
Opens dialog to save the default ScopeParameters.
LRESULT OnCreate(LPCREATESTRUCT lParam)
Creates the frame with all its stuff and the CMainDialogView inside.
LRESULT OnOpenLogbook(WORD, WORD, HWND, BOOL &)
Opens the LogFrame window.
LRESULT OnZeroGalvoOutputs(WORD, WORD, HWND, BOOL &)
Calls ScopeController::ZeroGalvoOutputs.
LRESULT OnLoadParameters(WORD, WORD, HWND, BOOL &)
Opens dialog to load ScopeParameters.
Manages the display of images.
Definition: ChannelFrame.h:26
void NewLogFrame(const RECT &_rect)
Opens a CLogFrame.
LRESULT OnFileExit(WORD, WORD, HWND, BOOL &)
Calls QuitApplication.
This is the include file for standard system include files, or project specific include files that ar...
CMainDlgView m_dlgView
the view with the dialog controls
Definition: MainDlgFrame.h:39
void QuitApplication()
Calls ScopeController::PrepareQuit and sends close message and subsequently quits the whole applicati...
LRESULT OnShutterOpen(WORD, WORD, HWND, BOOL &)
Calls ScopeController::OpenShutter.
scope::ScopeLogger scope_logger
our ScopeLogger here
Definition: MainDlgFrame.h:45
scope::ScopeController scope_controller
our ScopeController here
Definition: MainDlgFrame.h:42
Frame window class for the log.
Definition: LogFrame.h:10
void RecreateWindows()
Opens windows as saved.
void NewChannelFrame(const uint32_t &_area, const RECT &_rect)
Opens a new CChannelFrame.
LRESULT OnSaveParameters(WORD, WORD, HWND, BOOL &)
Opens dialog to save ScopeParameters.
static std::array< UINT, 4 > histogramareas_ids
ids for the new histogram toolbar dropdown menu items.
Definition: MainDlgFrame.h:51
CCommandBarCtrl m_CmdBar
the command bar.
Definition: MainDlgFrame.h:68
#define DBOUT(s)
A debug output to the debug console.
Definition: helpers.h:153
bool LoadParameters(const std::wstring &filepath)
Load a complete ScopeParameters set from disk.
LRESULT OnAppAbout(WORD, WORD, HWND, BOOL &)
Opens the about dialog.
void Save(const std::wstring &filename) const
Save all to file.
Definition: Scope.cpp:513
bool firstpaint
to recreate stored windows
Definition: MainDlgFrame.h:33
Manages the display of histograms.
BOOL OnForwardMsg(LPMSG Msg, DWORD nUserData)
Forwards to the view.
LRESULT OnNewHistogramFrame(WORD, WORD, HWND, BOOL &)
Opens a new CHistogramFrame, determines which dropdown menu item/area was choosen.
void ZeroGalvoOutputs()
Zeros galvo outputs.
bool SaveParameters(const std::wstring &filepath)
Store the current complete ScopeParameters set to disk.
ScopeValue< RunState > run_state
current RunState
Definition: Scope.h:276
virtual void PrepareToolBarMenu(UINT nMenuID, HMENU hMenu)
Used in CToolBarHelper to fill the dropdown menus.
void NewHistogramFrame(const uint32_t &_area, const RECT &_rect)
Opens a new CHistogramFrame.
void OnTimer(UINT_PTR nIDEvent)
Update the memory consumption display.
LRESULT OnNewChannelFrame(WORD, WORD, HWND, BOOL &)
Opens a new CChannelFrame, determines which dropdown menu item/area was choosen.
std::vector< Window > collection
Vector with Window.
Definition: Windows.h:48
Shows information about Scope.
Definition: AboutDlg.h:8
void OpenCloseShutter(const uint32_t &_area, const bool &_open)
Opens/closes the shutter.
CMultiPaneStatusBarCtrl m_wndStatusBar
the status bar
Definition: MainDlgFrame.h:36
CAppModule _Module
The ATL application module.
Definition: scope.cpp:10
boost::signals2::connection Connect(signalchange_t::slot_type slot)
Connect slot to signal.
Definition: ScopeButton.cpp:35
void SaveCurrentWindowPositions()
Saves current positions of windows by adding frames to WindowCollection of ScopeController::GuiParame...
void OnDestroy()
Destroys view and removes message stuff.
static parameters::Scope GuiParameters
The complete pseudo-global parameter set of the microscope.
static std::array< UINT, 4 > viewareas_ids
ids for the new view toolbar dropdown menu items.
Definition: MainDlgFrame.h:48
*virtual BOOL OnIdle()
=
void PrepareQuit()
Called by CMainDialogFrame::QuitApplication.