void CaptureWin::OnPause(wxCommandEvent& event) { paused = event.IsChecked(); if (paused) { stopwatch.Pause(); pauseButton->SetBitmapLabel(LoadPngResource(L"button_go")); } else { stopwatch.Resume(); pauseButton->SetBitmapLabel(LoadPngResource(L"button_pause")); } SetTitle(paused ? _T(APPNAME) L" - paused" : _T(APPNAME) L" - profiling"); if (win7taskBar) { win7taskBar->SetProgressState(GetHandle(), paused ? TBPF_PAUSED : TBPF_NORMAL); } }
CaptureWin::CaptureWin() : wxDialog(NULL, -1, wxString(_T(APPNAME) _T(" - profiling")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) { cancelled = stopped = paused = false; win7taskBar = NULL; wxBoxSizer *rootsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *panelsizer = new wxBoxSizer(wxVERTICAL); rootsizer->SetMinSize(400, 0); wxPanel *panel = new wxPanel(this); progressText = new wxStaticText( panel, -1, "Waiting..." ); progressBar = new wxGauge( panel, -1, 0, wxDefaultPosition, wxSize(100,18) ); progressBar->SetRange(MAX_RANGE); wxBitmap pause = LoadPngResource(L"button_pause"); pauseButton = new wxBitmapToggleButton( panel, CaptureWin_Pause, pause, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBU_EXACTFIT ); wxButton *okButton = new wxButton(panel, wxID_OK, "&Stop"); okButton->SetToolTip("Stop profiling and display collected results."); wxButton *cancelButton = new wxButton(panel, wxID_CANCEL, "&Abort"); cancelButton->SetToolTip("Stop profiling, discard collected results, and exit."); int border = ConvertDialogToPixels(wxSize(2, 0)).x; wxSizer *buttons = new wxBoxSizer(wxHORIZONTAL); buttons->Add(pauseButton, 0, wxALIGN_LEFT, border); buttons->AddStretchSpacer(); buttons->Add(okButton, 0, wxALIGN_RIGHT | wxLEFT|wxRIGHT, border); buttons->Add(cancelButton, 0, wxALIGN_RIGHT | wxLEFT, border); panelsizer->Add(progressText, 0, wxBOTTOM, 3); panelsizer->Add(progressBar, 0, wxBOTTOM|wxEXPAND, 10); panelsizer->Add(buttons, 0, wxEXPAND); okButton->SetDefault(); panel->SetSizer(panelsizer); panel->SetAutoLayout(TRUE); rootsizer->Add(panel, 1, wxEXPAND | wxALL, 10); SetSizer(rootsizer); rootsizer->SetSizeHints(this); SetAutoLayout(TRUE); Centre(); }
OptionsDlg::OptionsDlg() : wxDialog(NULL, -1, wxString(_T("Options")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) { wxBoxSizer *rootsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); wxStaticBoxSizer *symsizer = new wxStaticBoxSizer(wxVERTICAL, this, "Symbols"); wxStaticBoxSizer *symdirsizer = new wxStaticBoxSizer(wxVERTICAL, this, "Symbol search path"); wxStaticBoxSizer *symsrvsizer = new wxStaticBoxSizer(wxVERTICAL, this, "Symbol server"); symPaths = new wxListBox(this, Options_SymPath, wxDefaultPosition, wxSize(0, 75), 0, NULL, wxLB_SINGLE | wxLB_NEEDED_SB | wxLB_HSCROLL); wxBoxSizer *symPathSizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *symPathButtonSizer = new wxBoxSizer(wxVERTICAL); static const struct { wxButton * OptionsDlg::* button; OptionsId id; const wchar_t *icon; const char *tip; } symPathButtons[] = { { &OptionsDlg::symPathAdd , Options_SymPath_Add , L"button_add" , "Browse for a directory to add" }, { &OptionsDlg::symPathRemove , Options_SymPath_Remove , L"button_remove", "Remove selected directory" }, { &OptionsDlg::symPathMoveUp , Options_SymPath_MoveUp , L"button_up" , "Move selected directory up" }, { &OptionsDlg::symPathMoveDown, Options_SymPath_MoveDown, L"button_down" , "Move selected directory down" }, }; for (size_t n=0; n<_countof(symPathButtons); n++) { wxButton *b = this->*symPathButtons[n].button = new wxButton( this, symPathButtons[n].id, wxEmptyString, wxDefaultPosition, wxSize(20, 20), wxBU_EXACTFIT); b->SetBitmap(LoadPngResource(symPathButtons[n].icon)); b->SetToolTip(symPathButtons[n].tip); symPathButtonSizer->Add(b, 1); } UpdateSymPathButtons(); symPathSizer->Add(symPaths, 100, wxEXPAND); symPathSizer->Add(symPathButtonSizer, 1, wxSHRINK); useSymServer = new wxCheckBox(this, Options_UseSymServer, "Use symbol server"); symCacheDir = new wxDirPickerCtrl(this, -1, prefs.symCacheDir, "Select a directory to store local symbols in:", wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL); symServer = new wxTextCtrl(this, -1, prefs.symServer); wxBoxSizer *minGwDbgHelpSizer = new wxBoxSizer(wxHORIZONTAL); minGwDbgHelpSizer->Add(new wxStaticText(this, -1, "MinGW DbgHelp engine: ")); mingwWine = new wxRadioButton(this, -1, "Wine "); mingwWine->SetToolTip("Use Wine's DbgHelp implementation for MinGW symbols (dbghelpw.dll)."); minGwDbgHelpSizer->Add(mingwWine); mingwDrMingw = new wxRadioButton(this, -1, "Dr. MinGW"); mingwDrMingw->SetToolTip("Use Dr. MinGW's DbgHelp implementation for MinGW symbols (dbghelpdr.dll)."); minGwDbgHelpSizer->Add(mingwDrMingw); (prefs.useWinePref ? mingwWine : mingwDrMingw)->SetValue(true); wxBoxSizer *saveMinidumpSizer = new wxBoxSizer(wxHORIZONTAL); saveMinidump = new wxCheckBox(this, Options_SaveMinidump, "Save minidump after "); saveMinidump->SetToolTip( "Include a minidump in saved profiling results.\n" "This enables the \"Load symbols from minidump\" option,\n" "which allows profiling an application on a user machine without symbols,\n" "then examining the profile results on a developer machine with symbols."); saveMinidumpSizer->Add(saveMinidump); saveMinidumpTimeValue = prefs.saveMinidump < 0 ? 0 : prefs.saveMinidump; saveMinidumpTime = new wxTextCtrl( this, -1, wxEmptyString, wxDefaultPosition, wxSize(40, -1), 0, wxIntegerValidator<int>(&saveMinidumpTimeValue)); saveMinidumpTime->SetToolTip( "Saving a minidump at the very start of a profiling session\n" "may not work as expected, as not all DLLs may be loaded yet.\n" "You can set a delay after which a minidump will be saved."); saveMinidumpTime->Enable(prefs.saveMinidump >= 0); saveMinidumpSizer->Add(saveMinidumpTime, 0, wxTOP, -3); saveMinidumpSizer->Add(new wxStaticText(this, -1, " seconds")); symPaths->Append(wxSplit(prefs.symSearchPath, ';', 0)); useSymServer->SetValue(prefs.useSymServer); symCacheDir->Enable(prefs.useSymServer); symServer->Enable(prefs.useSymServer); saveMinidump->SetValue(prefs.saveMinidump >= 0); symdirsizer->Add(symPathSizer, 0, wxALL|wxEXPAND, 5); symsrvsizer->Add(useSymServer, 0, wxALL, 5); symsrvsizer->Add(new wxStaticText(this, -1, "Local cache directory:"), 0, wxLEFT|wxTOP, 5); symsrvsizer->Add(symCacheDir, 0, wxALL|wxEXPAND, 5); symsrvsizer->Add(new wxStaticText(this, -1, "Symbol server location:"), 0, wxLEFT|wxTOP, 5); symsrvsizer->Add(symServer, 0, wxALL|wxEXPAND, 5); symsizer->Add(symdirsizer, 0, wxALL|wxEXPAND, 5); symsizer->Add(symsrvsizer, 0, wxALL|wxEXPAND, 5); symsizer->Add(minGwDbgHelpSizer, 0, wxALL, 5); symsizer->Add(saveMinidumpSizer, 0, wxALL, 5); wxStaticBoxSizer *throttlesizer = new wxStaticBoxSizer(wxVERTICAL, this, "Sample rate control"); throttle = new wxPercentSlider(this, Options_Throttle, prefs.throttle, 1, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL|wxSL_TICKS|wxSL_TOP|wxSL_LABELS); throttle->SetTickFreq(10); throttlesizer->Add(new wxStaticText(this, -1, "Adjusts the sample rate speed. Useful for doing longer captures\n" "where you wish to reduce the profiler overhead.\n" "Higher values increase accuracy; lower values result in better\n" "performance."), 0, wxALL, 5); throttlesizer->Add(throttle, 0, wxEXPAND|wxLEFT|wxTOP, 5); topsizer->Add(symsizer, 0, wxEXPAND|wxALL, 0); topsizer->AddSpacer(5); topsizer->Add(throttlesizer, 0, wxEXPAND|wxALL, 0); rootsizer->Add(topsizer, 1, wxEXPAND|wxLEFT|wxTOP|wxRIGHT, 10); rootsizer->Add(CreateButtonSizer(wxOK|wxCANCEL), 0, wxEXPAND|wxALL, 10); SetSizer(rootsizer); rootsizer->SetSizeHints(this); SetAutoLayout(TRUE); SetSize(wxSize(400, -1)); Centre(); }
ThreadPicker::ThreadPicker() : wxModalFrame(NULL, -1, wxString(_T("Sleepy")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE) { SetIcon(sleepy_icon); wxMenu *menuFile = new wxMenu; menuFile->Append(wxID_OPEN, _T("&Open..."), _T("Opens an existing profile")); menuFile->Append(ProcWin_Launch, _T("&Launch..."), _T("Launches a new executable to profile")); menuFile->AppendSeparator(); menuFile->Append(ProcWin_Exit, _T("E&xit\tAlt-X"), _T("Quit this program")); wxMenu *menuTools = new wxMenu; menuTools->Append(ProcWin_Refresh, _T("&Refresh\tF5"), _T("Refreshes the process list")); menuTools->Append(ProcWin_Download, _T("&Download Symbols"), _T("Downloads symbols from a symbol server")); menuTools->AppendSeparator(); menuTools->Append(ProcWin_Options, _T("&Options..."), _T("Opens the options dialog")); // the "About" item should be in the help menu wxMenu *menuHelp = new wxMenu; menuHelp->Append(ProcWin_About, _T("&About...\tF1"), _T("Show about dialog")); // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar(); menuBar->Append(menuFile, _T("&File")); menuBar->Append(menuTools, _T("&Tools")); menuBar->Append(menuHelp, _T("&Help")); // ... and attach this menu bar to the frame SetMenuBar(menuBar); wxBoxSizer *rootsizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *dlgsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *topsizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *bottomsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *leftsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *rightsizer = new wxBoxSizer(wxVERTICAL); wxPanel *panel = new wxPanel(this); rootsizer->Add(panel, 1, wxEXPAND | wxALL); wxButton *ok_button = new wxButton(panel, wxID_OK, "Profile &Selected", wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBU_EXACTFIT); ok_button->SetBitmap(LoadPngResource(L"button_profilesel")); ok_button->SetBitmapPosition(wxRIGHT); ok_button->SetBitmapMargins(-1,-1); wxButton *all_button = new wxButton(panel, wxID_SELECTALL,"Profile &All", wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBU_EXACTFIT); all_button->SetBitmap(LoadPngResource(L"button_profileall")); all_button->SetBitmapPosition(wxRIGHT); all_button->SetBitmapMargins(-1,-1); all_button->Disable(); all_button->SetDefault(); // DE: 20090325 one list for processes and one list for selected process threads threadlist = new ThreadList(panel, wxDefaultPosition, wxDefaultSize, ok_button, all_button); processlist = new ProcessList(panel, wxDefaultPosition, wxDefaultSize, threadlist); leftsizer->Add(new wxStaticText(panel, -1, "Select a process to profile:"), 0, wxTOP, 5); leftsizer->Add(processlist, 1, wxEXPAND | wxTOP, 3); // DE: 20090325 title for thread list rightsizer->Add(new wxStaticText(panel, -1, "Select thread(s) to profile: (CTRL-click for multiple)"), 0, wxTOP, 5); rightsizer->Add(threadlist, 1, wxEXPAND | wxTOP, 3); wxButton *refreshButton = new wxButton(panel, ProcWin_Refresh, "Refresh", wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBU_EXACTFIT); refreshButton->SetBitmap(LoadPngResource(L"button_refresh")); refreshButton->SetBitmapPosition(wxRIGHT); refreshButton->SetBitmapMargins(-1,-1); refreshButton->SetToolTip("Refreshes the list of processes and threads."); wxButton *downloadButton = new wxButton(panel, ProcWin_Download, "Download", wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBU_EXACTFIT); downloadButton->SetBitmap(LoadPngResource(L"button_download")); downloadButton->SetBitmapPosition(wxRIGHT); downloadButton->SetBitmapMargins(-1,-1); downloadButton->SetToolTip("Downloads symbols from a remote symbol server."); wxSizer *buttons = new wxBoxSizer(wxHORIZONTAL); buttons->Add(refreshButton, 0, wxALIGN_LEFT | wxRIGHT, 5); buttons->Add(downloadButton, 0, wxALIGN_LEFT, 0); buttons->AddStretchSpacer(); buttons->Add(all_button, 0, wxALIGN_RIGHT, 0); buttons->Add(ok_button, 0, wxALIGN_RIGHT | wxLEFT, 5); bottomsizer->Add(buttons, 0, wxLEFT|wxRIGHT|wxEXPAND, 10); bottomsizer->AddSpacer(8); log = new wxTextCtrl(panel, ProcWin_Log, "", wxDefaultPosition, wxSize(100,100), wxTE_MULTILINE|wxTE_READONLY); bottomsizer->Add(log, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 10); topsizer->Add(leftsizer, 1, wxEXPAND | wxLEFT, 10); topsizer->AddSpacer(10); topsizer->Add(rightsizer, 1, wxEXPAND | wxRIGHT, 10); dlgsizer->Add(topsizer, 1, wxEXPAND); dlgsizer->AddSpacer(8); dlgsizer->Add(bottomsizer, 0, wxEXPAND); panel->SetSizer(dlgsizer); panel->SetAutoLayout(TRUE); SetSizer(rootsizer); rootsizer->SetSizeHints(this); SetAutoLayout(TRUE); SetSize(wxSize(800, 500)); Centre(); g_symLog = symLogCallback; cur_picker = this; }