23using namespace std::filesystem;
32class TTraceWindow::TGroupList
37 TGroupList(
TWindow* parent,
int id)
41 void AddItem(
const tstring& text,
bool checked, TDiagBase* group)
44 i->SetData(
reinterpret_cast<UINT_PTR
>(group));
48 auto GetData(
int index) -> TDiagBase*
54 void SetItemText(
int index,
const tstring& text)
62 void EvLButtonDown(
uint modKeys,
const TPoint& point)
68 SetGroupState(index, i->IsChecked());
76 if (i && i->IsEnabled() && key ==
_T(
' '))
77 SetGroupState(index, i->IsChecked());
80 void SetGroupState(
int index,
bool enabled)
82 const auto group = GetData(index);
84 group->Enable(enabled);
89 s << (group->IsEnabled() ? 1 : 0) <<
_T(
' ') << group->GetLevel();
91 ini.WriteString(
to_tstring(group->GetName()), s.str());
94 DECLARE_RESPONSE_TABLE(TGroupList);
143auto TTraceWindow::
GetInstance(
bool shouldCreateIfNeccessary) -> TTraceWindow*
145 if (shouldCreateIfNeccessary && !Instance)
146 Instance =
new TTraceWindow{};
165 TraceText +=
_T(
": ");
182 const auto title =
tstring{
_T(
"Diagnostic Window - ")} +
192 traceMenu.
AppendMenu(MF_STRING, Cm_SaveTrace,
_T(
"&Save messages...\tCtrl+S"));
194 traceMenu.
AppendMenu(MF_STRING, Cm_Top,
_T(
"Always On &Top"));
198 editMenu.
AppendMenu(MF_STRING, CM_EDITCOPY,
_T(
"&Copy\tCtrl+C"));
199 editMenu.
AppendMenu(MF_STRING, Cm_EditClear,
_T(
"C&lear"));
201 editMenu.
AppendMenu(MF_STRING, Cm_EditSelectAll,
_T(
"Select &all\tCtrl+A"));
204 menu.
AppendMenu(MF_POPUP, traceGroupMenu,
_T(
"&Group"));
205 traceGroupMenu.
AppendMenu(MF_STRING, Cm_SetLevel,
_T(
"Set level...\tEnter"));
210 const ACCEL accelerators[6]
212 {FVIRTKEY, VK_F11, Cm_SaveTrace},
213 {FVIRTKEY | FCONTROL,
'S', Cm_SaveTrace},
214 {FVIRTKEY | FCONTROL,
'A', Cm_EditSelectAll},
215 {FVIRTKEY, VK_RETURN, Cm_SetLevel},
216 {FVIRTKEY, VK_F6, Cm_NextPane},
217 {FVIRTKEY | FSHIFT, VK_F6, Cm_PreviousPane}
219 SethAccel(CreateAcceleratorTable(
const_cast<LPACCEL
>(accelerators),
static_cast<int>(
COUNTOF(accelerators))));
221 TraceMessages.LimitText(0);
223 Panels.SplitPane(&TraceMessages,
nullptr,
psNone);
224 Panels.SplitPane(&TraceMessages, &TraceModules,
psHorizontal, 0.50f);
225 Panels.SplitPane(&TraceModules, &TraceGroups,
psVertical, 0.50f);
228 TraceMessages.SetWindowFont(font,
false);
229 TraceModules.SetWindowFont(font,
false);
230 TraceGroups.SetWindowFont(font,
false);
243TTraceWindow::TTraceWindow()
247 TraceMessages{*new
TEdit{this, Idc_TraceEdit,
_T(
""), 0, 0, 0, 0, 0, true}},
248 TraceGroups{*new TGroupList(this, Idc_GroupListBox)},
249 TraceModules{*new
TListBox(this, Idc_ModuleListBox, 0, 0, 0, 0)},
258 TraceMessages.
ModifyStyle(WS_POPUP | WS_BORDER, ES_READONLY | WS_CHILD);
259 TraceModules.
ModifyStyle(WS_POPUP | WS_BORDER | LBS_SORT, WS_CHILD | LBS_NOINTEGRALHEIGHT);
261 TraceGroups.
ModifyStyle(WS_POPUP | WS_BORDER, WS_CHILD | LBS_SORT);
263 RestoreWindowState();
266TTraceWindow::~TTraceWindow()
272void TTraceWindow::CmSave()
274 auto data = TFileSaveDialog::TData{};
275 data.SetFilter(
_T(
"Text Files (*.txt)|*.txt|All Files (*.*)|*.*|"));
276 data.Flags |= OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT;
277 data.InitialDir =
const_cast<tchar*
>(TracePath.c_str());
279 auto f =
to_tstring(path{TracePath} /
_T(
"Trace-000.txt"));
280 const auto n = f.size();
287 const auto makeDigit = [](
size_t i) {
return static_cast<tchar>(
'0' + (i % 10)); };
288 f[n - 5] = makeDigit(i / 1);
289 f[n - 6] = makeDigit(i / 10);
290 f[n - 7] = makeDigit(i / 100);
292 _tcscpy_s(data.FileName, data.MaxPath,
to_tstring(path{f}.filename()).c_str());
294 TFileSaveDialog dlg{
this, data};
295 if (dlg.Execute() == IDOK)
297 const auto& s = TraceMessages.GetText();
299 TracePath =
to_tstring(path{data.FileName}.parent_path());
303void TTraceWindow::CmTop()
305 Attr.ExStyle ^= WS_EX_TOPMOST;
306 const auto topMost = (Attr.ExStyle & WS_EX_TOPMOST) != 0;
307 SetWindowPos(topMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
309 ini.WriteInt(
_T(
"TopMost"), topMost ? 1 : 0);
314 tce.SetCheck((Attr.ExStyle & WS_EX_TOPMOST) != 0);
317void TTraceWindow::CmEditClear()
319 TraceMessages.SetWindowText(
_T(
""));
322void TTraceWindow::CmEditSelectAll()
324 TraceMessages.SetSelection(0, -1);
325 TraceMessages.SetFocus();
328void TTraceWindow::CmSetLevel()
330 const auto i = TraceGroups.GetSelIndex();
331 if (i == LB_ERR)
return;
332 const auto group =
reinterpret_cast<TDiagBase*
>(TraceGroups.GetData(i));
334 s << group->GetLevel();
335 const auto levelString = s.str();
337 auto prompt =
tstring{
_T(
"Set level for ")};
338 prompt += FormatLink(group->GetDiagModule());
343 TInputDialog dlg{&TraceGroups,
_T(
"Diagnostic Window"), prompt, levelString, m,
new TRangeValidator{INT_MIN, INT_MAX}};
348 group->SetLevel(level);
349 TraceGroups.SetItemText(i, FormatGroup(group).c_str());
355 s << (group->IsEnabled() ? 1 : 0) <<
_T(
' ') << level;
356 ini.WriteString(
to_tstring(group->GetName()), s.str());
362 tce.Enable(TraceGroups.GetSelIndex() != LB_ERR);
365void TTraceWindow::CmNextPane()
368 if (w == TraceMessages.GetHandle())
369 TraceModules.SetFocus();
370 else if (w == TraceModules.GetHandle())
371 TraceGroups.SetFocus();
373 TraceMessages.SetFocus();
376void TTraceWindow::CmPreviousPane()
379 if (w == TraceMessages.GetHandle())
380 TraceGroups.SetFocus();
381 else if (w == TraceModules.GetHandle())
382 TraceMessages.SetFocus();
384 TraceModules.SetFocus();
387void TTraceWindow::EvActivate(
uint active,
bool minimized, HWND hWndOther)
393void TTraceWindow::LbnSelChangeModule()
395 const auto i = TraceModules.GetSelIndex();
396 if (i == LB_ERR)
return;
397 const auto module = reinterpret_cast<TModule*>(TraceModules.GetItemData(i));
398 TraceGroups.SetRedraw(
false);
399 TraceGroups.ClearList();
401 if (group->GetDiagModule() == module)
402 TraceGroups.AddItem(FormatGroup(group), group->IsEnabled(), group);
403 TraceGroups.SetRedraw(
true);
404 TraceGroups.Invalidate();
407void TTraceWindow::SaveWindowState()
411 const auto ws =
_T(
' ');
412 s << Attr.X << ws << Attr.Y << ws << (Attr.X + Attr.W) << ws << (Attr.Y + Attr.H);
413 ini.WriteString(
_T(
"Position"), s.str());
414 ini.WriteString(
_T(
"Path"), TracePath.c_str());
417void TTraceWindow::RestoreWindowState()
422 is >> r.left >> r.top >> r.right >> r.bottom;
430 bool topMost = ini.GetInt(
_T(
"TopMost"), 0) == 1;
433 TracePath = ini.GetString(
_T(
"Path"), TracePath);
436void TTraceWindow::AddModules(
TModule* module)
440 const auto i = TraceModules.AddString(FormatLink(m));
441 TraceModules.SetItemData(i,
reinterpret_cast<LPARAM
>(m));
444 if (g->GetDiagModule() == module)
445 TraceGroups.AddItem(FormatGroup(g), g->IsEnabled(), g);
448void TTraceWindow::UpdateTraceText()
451 const auto tmp = TraceText;
454 const auto n = TraceMessages.GetWindowTextLength();
455 TraceMessages.SetSelection(n, -1);
456 TraceMessages.Insert(tmp);
465 s << d <<
_T(
" (") << group->GetLevel() <<
_T(
')');
471 return module->GetName();
Definition of class TCheckList, an ownerdrawn listbox to select multiple items.
#define PRECONDITION(condition)
TFrameWindow * GetMainWindow()
Return the current main window.
TCheckList is an owner-drawn list box to select multiple items.
void EvLButtonDown(uint modKeys, const TPoint &point)
Toggles the checked state when the mouse is clicked in the checkbox.
int AddItem(TCheckListItem *item)
Adds the item into the checklist.
TCheckListItem * GetItem(int idx)
Returns the item at the specified index.
void EvChar(uint key, uint repeatCount, uint flags)
Toggles the checked state when the space key is pressed.
TCheckList(TWindow *parent, int id, int x, int y, int w, int h, TCheckListItem *=0, int numItems=0, TModule *=0)
Creates a checklist.
TCheckListItem()
Initializes the state of TCheckListItem.
UINT_PTR GetData()
Returns the user-defined data for this item.
void SetText(const tstring &text)
Copies the text string.
Base class for an extensible interface for auto enabling/disabling of commands (menu items,...
Encapsulates the system font used for a specific GUI element, e.g. icon, caption, menu,...
@ sfiMessage
Represents NONCLIENTMETRICS::lfMessageFont.
static TDiagBase * GetDiagGroup(TDiagBase *curr=nullptr)
static TDiagBaseHook * SetGlobalHook(TDiagBaseHook *hook=nullptr)
virtual TModule * GetDiagModule()=0
A TEdit is an interface object that represents an edit control interface element.
Derived from TWindow, TFrameWindow controls such window-specific behavior as keyboard navigation and ...
auto IdleAction(long idleCount) -> bool override
Overrides TWindow's virtual function.
virtual bool SetMenu(HMENU newMenu)
Overrides TWindow's non-virtual SetMenu function, thus allowing derived classes the opportunity to im...
void CleanupWindow() override
Cleans up any associated icons.
virtual TWindow * SetClientWindow(TWindow *clientWnd)
Sets the client window to the specified window.
void SetupWindow() override
Calls TWindow::SetUpWindow to create windows in a child list.
An interface object that represents a corresponding list box element.
int GetCaretIndex() const
Returns the index of the currently focused list-box item.
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
TPaneSplitter is a class that acts as a container for child windows (called panes) and splitters (pan...
An instance of TProfile encapsulates a setting within a system file, often referred to as a profile o...
bool GetString(LPCTSTR key, TCHAR *buff, unsigned buffSize, LPCTSTR defaultString=0)
Looks up and returns the string value associated with the given key string.
static void DestroyInstance()
static auto GetInstance(bool shouldCreateIfNeccessary=false) -> TTraceWindow *
void Output(TDiagBase *group, LPCTSTR str) override
auto IdleAction(long) -> bool override
void CleanupWindow() override
void SetupWindow() override
TApplication * GetApplication() const
Gets a pointer to the TApplication object associated with this.
void DrawMenuBar()
DrawMenuBar redraws the menu bar.
TWindow(TWindow *parent, LPCTSTR title=nullptr, TModule *module=nullptr)
Adds this to the child list of parent if nonzero, and calls EnableAutoCreate so that this will be cre...
bool SetWindowPos(HWND hWndInsertAfter, const TRect &rect, uint flags)
Changes the size of the window pointed to by rect.
virtual void Destroy(int retVal=0)
Destroys an MS-Windows element associated with the TWindow.
bool IsWindow() const
Returns true if an HWND is being used.
void EvActivate(uint active, bool minimized, HWND hWndOther)
Default message handler for WM_ACTIVATE.
bool ModifyStyle(uint32 offBits, uint32 onBits, uint swpFlags=0)
Modifies the style bits of the window.
LPCTSTR GetCaption() const
Returns the Title member of TWindow.
void SetWindowText(LPCTSTR str)
Sets the window's text to the given string (by copying).
bool ModifyExStyle(uint32 offBits, uint32 onBits, uint swpFlags=0)
Modifies the style bits of the window.
static HWND GetFocus()
Gets a handle to the window that has the focus.
Definition of class TEdit.
#define DEFINE_RESPONSE_TABLE1(cls, base)
Macro to define a response table for a class with one base.
static TModule * FindResModule(TResId id, TResId type)
Global search for resources.
LPCTSTR GetName() const
Returns the name of the module.
static TModule * NextModule(TModule *module=nullptr)
Definition of class TListBox and TlistBoxData.
Object Windows Library (OWLNext Core).
std::ostringstream tostringstream
@ psNone
Unspecified split.
@ psHorizontal
Horizontal split.
@ psVertical
Vertical split.
@ BF_UNCHECKED
Item is unchecked.
@ BF_CHECKED
Item is checked.
EV_LBN_DBLCLK(IDC_LIST, CmOK)
std::istringstream tistringstream
const int CheckList_BoxWidth
EV_COMMAND_ENABLE(CM_FILENEW, CeFileNew)
auto GetDiagIniFullFileName_(LPCSTR filename) -> tstring
EV_LBN_SELCHANGE(Idc_ModuleListBox, LbnSelChangeModule)
auto to_tstring(const T &v) -> tstring
EV_COMMAND(IDOK, CmOkCancel)
Definition of TOpenSave abstract, TFileOpen, TFileSave common Dialog classes.
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition of TProfile class.
Definition of private class TTraceWindow.